Added energy counter in-world render

This commit is contained in:
DBotThePony 2022-01-25 12:53:22 +07:00
parent 5ff3771f81
commit 6cd04682d7
Signed by: DBot
GPG Key ID: DCC23B5715498507
9 changed files with 635 additions and 11 deletions

View File

@ -261,9 +261,9 @@ object DataGen {
val mdl = if (dir === Direction.WEST) west else east
part().modelFile(mdl).addModel().condition(BlockEnergyCounter.INPUT_DIRECTION, dir).condition(BlockEnergyCounter.IF_DIRECTION, Direction.NORTH)
part().modelFile(mdl).rotationX(90).addModel().condition(BlockEnergyCounter.INPUT_DIRECTION, dir).condition(BlockEnergyCounter.IF_DIRECTION, Direction.UP)
part().modelFile(mdl).rotationX(-90).addModel().condition(BlockEnergyCounter.INPUT_DIRECTION, dir).condition(BlockEnergyCounter.IF_DIRECTION, Direction.UP)
part().modelFile(mdl).rotationX(180).addModel().condition(BlockEnergyCounter.INPUT_DIRECTION, dir).condition(BlockEnergyCounter.IF_DIRECTION, Direction.SOUTH)
part().modelFile(mdl).rotationX(-90).addModel().condition(BlockEnergyCounter.INPUT_DIRECTION, dir).condition(BlockEnergyCounter.IF_DIRECTION, Direction.DOWN)
part().modelFile(mdl).rotationX(90).addModel().condition(BlockEnergyCounter.INPUT_DIRECTION, dir).condition(BlockEnergyCounter.IF_DIRECTION, Direction.DOWN)
}
}
}

View File

@ -48,6 +48,7 @@ import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityBlackHole;
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntityExplosionDebugger;
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlockEntitySphereDebugger;
import ru.dbotthepony.mc.otm.client.render.BlackHoleRenderer;
import ru.dbotthepony.mc.otm.client.render.EnergyCounterRenderer;
import ru.dbotthepony.mc.otm.client.render.GravitationStabilizerRenderer;
import ru.dbotthepony.mc.otm.client.render.SkinElement;
import ru.dbotthepony.mc.otm.core.Fraction;
@ -1007,6 +1008,7 @@ public class Registry {
public static void registerRenderers(final FMLClientSetupEvent event) {
BlockEntityRenderers.register(BLACK_HOLE, BlackHoleRenderer::new);
BlockEntityRenderers.register(GRAVITATION_STABILIZER, GravitationStabilizerRenderer::new);
BlockEntityRenderers.register(ENERGY_COUNTER, EnergyCounterRenderer::new);
}
}

View File

@ -12,10 +12,83 @@ import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class FormattingHelper {
public static final TranslatableComponent SUFFIX_KILO = new TranslatableComponent("otm.suffix_raw.kilo");
public static final TranslatableComponent SUFFIX_MEGA = new TranslatableComponent("otm.suffix_raw.mega");
public static final TranslatableComponent SUFFIX_GIGA = new TranslatableComponent("otm.suffix_raw.giga");
public static final TranslatableComponent SUFFIX_TERA = new TranslatableComponent("otm.suffix_raw.tera");
public static final TranslatableComponent SUFFIX_PETA = new TranslatableComponent("otm.suffix_raw.peta");
public static final TranslatableComponent SUFFIX_EXA = new TranslatableComponent("otm.suffix_raw.exa");
public static final TranslatableComponent SUFFIX_ZETTA = new TranslatableComponent("otm.suffix_raw.zetta");
public static final TranslatableComponent SUFFIX_YOTTA = new TranslatableComponent("otm.suffix_raw.yotta");
public static final TranslatableComponent SUFFIX_DECI = new TranslatableComponent("otm.suffix_raw.deci");
public static final TranslatableComponent SUFFIX_CENTI = new TranslatableComponent("otm.suffix_raw.centi");
public static final TranslatableComponent SUFFIX_MILLI = new TranslatableComponent("otm.suffix_raw.milli");
public static final TranslatableComponent SUFFIX_MICRO = new TranslatableComponent("otm.suffix_raw.micro");
public static final TranslatableComponent SUFFIX_NANO = new TranslatableComponent("otm.suffix_raw.nano");
public static final TranslatableComponent SUFFIX_PICO = new TranslatableComponent("otm.suffix_raw.pico");
public static final TranslatableComponent SUFFIX_FEMTO = new TranslatableComponent("otm.suffix_raw.femto");
public static final TranslatableComponent SUFFIX_ATTO = new TranslatableComponent("otm.suffix_raw.atto");
public static final TranslatableComponent SUFFIX_ZEPTO = new TranslatableComponent("otm.suffix_raw.zepto");
public static final TranslatableComponent SUFFIX_YOCTO = new TranslatableComponent("otm.suffix_raw.yocto");
public static final List<TranslatableComponent> BIG_SUFFIX_STRIPE = List.of(
SUFFIX_KILO,
SUFFIX_MEGA,
SUFFIX_GIGA,
SUFFIX_TERA,
SUFFIX_PETA,
SUFFIX_EXA,
SUFFIX_ZETTA,
SUFFIX_YOTTA
);
public static final List<TranslatableComponent> SMALL_SUFFIX_STRIPE = List.of(
SUFFIX_DECI,
SUFFIX_CENTI,
SUFFIX_MILLI,
SUFFIX_MICRO,
SUFFIX_NANO,
SUFFIX_PICO,
SUFFIX_FEMTO,
SUFFIX_ATTO,
SUFFIX_ZEPTO,
SUFFIX_YOCTO
);
public static final List<TranslatableComponent> BIG_SUFFIX_STRIPE_INV;
public static final List<TranslatableComponent> SMALL_SUFFIX_STRIPE_INV;
static {
var list = new ArrayList<TranslatableComponent>(BIG_SUFFIX_STRIPE.size());
int i2 = 0;
for (int i = BIG_SUFFIX_STRIPE.size() - 1; i >= 0; i--) {
list.add(BIG_SUFFIX_STRIPE.get(i2));
i2++;
}
BIG_SUFFIX_STRIPE_INV = List.copyOf(list);
}
static {
var list = new ArrayList<TranslatableComponent>(BIG_SUFFIX_STRIPE.size());
int i2 = 0;
for (int i = BIG_SUFFIX_STRIPE.size() - 1; i >= 0; i--) {
list.add(BIG_SUFFIX_STRIPE.get(i2));
i2++;
}
SMALL_SUFFIX_STRIPE_INV = List.copyOf(list);
}
public static final String[] SUFFIX_COMPONENTS_ABOVE_ONE = new String[] {
"otm.suffix.kilo",
"otm.suffix.mega",

View File

@ -7,6 +7,7 @@ import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import ru.dbotthepony.mc.otm.OverdriveThatMatters;
import ru.dbotthepony.mc.otm.block.entity.EnergyCounterPacket;
import ru.dbotthepony.mc.otm.menu.MenuDriveViewer;
import ru.dbotthepony.mc.otm.menu.data.*;
import ru.dbotthepony.mc.otm.network.android.*;
@ -221,5 +222,14 @@ public class MatteryNetworking {
MenuDriveViewer.FilterSetPacket::play,
Optional.of(NetworkDirection.PLAY_TO_SERVER)
);
CHANNEL.registerMessage(
next_network_id++,
EnergyCounterPacket.class,
EnergyCounterPacket::write,
EnergyCounterPacket.Companion::read,
EnergyCounterPacket::play,
Optional.of(NetworkDirection.PLAY_TO_CLIENT)
);
}
}

View File

@ -29,9 +29,12 @@ class BlockEnergyCounter : BlockMattery(), EntityBlock {
blockState: BlockState,
blockEntityType: BlockEntityType<T>
): BlockEntityTicker<T>? {
if (level.isClientSide || blockEntityType !== Registry.BlockEntities.ENERGY_COUNTER)
if (blockEntityType !== Registry.BlockEntities.ENERGY_COUNTER)
return null
if (level.isClientSide)
return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityEnergyCounter) tile.clientTick() }
return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityEnergyCounter) tile.tick() }
}
@ -49,10 +52,6 @@ class BlockEnergyCounter : BlockMattery(), EntityBlock {
}
}
if ((inputDir === Direction.WEST || inputDir === Direction.EAST) && (dir === Direction.UP || dir === Direction.DOWN)) {
dir = dir.opposite
}
return defaultBlockState().setValue(INPUT_DIRECTION, inputDir).setValue(IF_DIRECTION, dir!!)
}
@ -96,8 +95,8 @@ class BlockEnergyCounter : BlockMattery(), EntityBlock {
shape = shape.rotateInv(iface)
} else if (input === Direction.EAST || input === Direction.WEST) {
when (iface) {
Direction.DOWN -> shape = shape.rotateAroundX(-Math.PI / 2)
Direction.UP -> shape = shape.rotateAroundX(Math.PI / 2)
Direction.DOWN -> shape = shape.rotateAroundX(Math.PI / 2)
Direction.UP -> shape = shape.rotateAroundX(-Math.PI / 2)
Direction.NORTH -> { /* уже в нужном положении */ }
Direction.SOUTH -> shape = shape.rotateAroundX(Math.PI)
Direction.WEST -> { /* недостижимо */ }

View File

@ -1,11 +1,13 @@
package ru.dbotthepony.mc.otm.block.entity
import net.minecraft.client.Minecraft
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.nbt.ByteArrayTag
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.IntTag
import net.minecraft.nbt.ListTag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.chat.Component
import net.minecraft.network.chat.TranslatableComponent
import net.minecraft.server.level.ServerLevel
@ -18,6 +20,8 @@ import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.CapabilityEnergy
import net.minecraftforge.energy.IEnergyStorage
import net.minecraftforge.network.NetworkEvent
import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.*
import ru.dbotthepony.mc.otm.block.BlockEnergyCounter
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
@ -26,19 +30,60 @@ import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.menu.MenuEnergyCounter
import ru.dbotthepony.mc.otm.network.MatteryNetworking
import java.lang.ref.WeakReference
import java.util.function.Supplier
data class EnergyCounterPacket(val pos: BlockPos, val thisTick: Fraction, val total: Fraction, val index: Int, val value: Fraction) {
fun write(buff: FriendlyByteBuf) {
buff.writeBlockPos(pos)
thisTick.write(buff)
total.write(buff)
buff.writeInt(index)
value.write(buff)
}
fun play(context: Supplier<NetworkEvent.Context>) {
context.get().packetHandled = true
context.get().enqueueWork {
val ply = Minecraft.getInstance().player ?: return@enqueueWork
val level = ply.level ?: return@enqueueWork
val tile = level.getBlockEntity(pos) as? BlockEntityEnergyCounter ?: return@enqueueWork
tile.lastTick = thisTick
tile.passed = total
tile[index] = value
}
}
companion object {
fun read(buff: FriendlyByteBuf): EnergyCounterPacket {
val pos = buff.readBlockPos()
val thisTick = Fraction.read(buff)
val total = Fraction.read(buff)
val index = buff.readInt()
val value = Fraction.read(buff)
return EnergyCounterPacket(pos, thisTick, total, index, value)
}
}
}
class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : BlockEntityMattery(Registry.BlockEntities.ENERGY_COUNTER, p_155229_, p_155230_) {
var passed = Fraction.ZERO
private set
internal set
private val history = Array(10 * 20) { Fraction.ZERO }
private var historyTick = 0
fun size() = history.size
operator fun get(i: Int) = history[i]
internal operator fun set(i: Int, value: Fraction) {
history[i] = value
}
var lastTick: Fraction = Fraction.ZERO
private set
internal set
fun getHistory(ticks: Int): Array<Fraction> {
require(!(ticks < 1 || ticks >= history.size)) { "Invalid history length provided" }
@ -241,6 +286,33 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return Fraction.ZERO
}
override val missingPower: Fraction
get() {
if (is_input) {
if (outputCapability.isPresent) {
val it = outputCapability.resolve().get()
if (it is IMatteryEnergyStorage) {
return it.missingPower
}
return Fraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0))
}
} else {
if (inputCapability.isPresent) {
val it = inputCapability.resolve().get()
if (it is IMatteryEnergyStorage) {
return it.missingPower
}
return Fraction((it.maxEnergyStored - it.energyStored).coerceAtLeast(0))
}
}
return Fraction.ZERO
}
override fun canExtract() = !is_input
override fun canReceive() = is_input
}
@ -339,10 +411,25 @@ class BlockEntityEnergyCounter(p_155229_: BlockPos, p_155230_: BlockState) : Blo
return super.getCapability(cap, side)
}
private fun distributor(): PacketDistributor.TargetPoint {
val x = blockPos.x.toDouble()
val y = blockPos.y.toDouble()
val z = blockPos.z.toDouble()
return PacketDistributor.TargetPoint(x, y, z, 32.0, level!!.dimension())
}
fun tick() {
lastTick = history[historyTick]
val index = historyTick
historyTick = (historyTick + 1) % history.size
val accumulated = history[historyTick]
history[historyTick] = Fraction.ZERO
MatteryNetworking.CHANNEL.send(PacketDistributor.NEAR.with(this::distributor), EnergyCounterPacket(blockPos, lastTick, passed, index, accumulated))
}
fun clientTick() {
passed += lastTick
}
companion object {

View File

@ -0,0 +1,71 @@
package ru.dbotthepony.mc.otm.client.render
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.core.Direction
import net.minecraft.network.chat.TranslatableComponent
import ru.dbotthepony.mc.otm.block.BlockEnergyCounter
import ru.dbotthepony.mc.otm.block.entity.BlockEntityEnergyCounter
import ru.dbotthepony.mc.otm.core.asAngle
import ru.dbotthepony.mc.otm.core.times
import ru.dbotthepony.mc.otm.menu.FormattingHelper
import kotlin.math.PI
class EnergyCounterRenderer(private val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<BlockEntityEnergyCounter> {
override fun render(
tile: BlockEntityEnergyCounter,
p_112308_: Float,
poseStack: PoseStack,
p_112310_: MultiBufferSource,
p_112311_: Int,
p_112312_: Int
) {
val screenDir: Direction = tile.blockState.getValue(BlockEnergyCounter.IF_DIRECTION)
val inputDir: Direction = tile.blockState.getValue(BlockEnergyCounter.INPUT_DIRECTION)
poseStack.pushPose()
poseStack.translate(0.5, 0.5, 0.5)
poseStack.translate(screenDir.normal * 0.44)
val font = Minecraft.getInstance().font
poseStack.scale(0.01f, 0.01f, 0.01f)
if (screenDir === Direction.DOWN) {
poseStack.rotateAroundPoint(poseStack.translation(), inputDir.asAngle().copy(pitch = PI, roll = PI / 2))
} else if (screenDir === Direction.UP) {
poseStack.rotateAroundPoint(poseStack.translation(), inputDir.asAngle().copy(pitch = 0.0, roll = PI / 2))
} else {
poseStack.rotateAroundPoint(poseStack.translation(), screenDir.asAngle().copy(pitch = PI))
}
var y = -16f
val finalX = font.drawAligned(poseStack, "00000000", TextAlign.CENTER_CENTER, -4f, y, 0x2C2C2C)
font.drawAligned(poseStack, "00000000", TextAlign.CENTER_CENTER, -4f, y + font.lineHeight, 0x2C2C2C)
font.drawAligned(poseStack, "/t", TextAlign.CENTER_LEFT, finalX.toFloat(), y, 0x2C2C2C)
font.drawAligned(poseStack, "/s", TextAlign.CENTER_LEFT, finalX.toFloat(), y + font.lineHeight, 0x2C2C2C)
poseStack.pushPose()
poseStack.translate(-0.1, -0.1, -0.1)
font.drawAligned(poseStack, tile.lastTick.decimalString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y, 0xFFFFFF)
font.drawAligned(poseStack, tile.sumHistory(20).decimalString(0), TextAlign.CENTER_RIGHT, finalX.toFloat(), y + font.lineHeight, 0xFFFFFF)
poseStack.popPose()
y += font.lineHeight * 3
font.drawAligned(poseStack, TOTAL, TextAlign.CENTER_CENTER, 0f, y, 0xFFFFFF)
font.drawAligned(poseStack, FormattingHelper.formatPower(tile.passed), TextAlign.CENTER_CENTER, 0f, y + font.lineHeight, 0xFFFFFF)
poseStack.popPose()
}
override fun getViewDistance() = 32
companion object {
private val TOTAL = TranslatableComponent("otm.gui.total_raw")
}
}

View File

@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.math.Matrix4f
import com.mojang.math.Vector3f
import net.minecraft.client.gui.Font
import net.minecraft.core.Vec3i
import net.minecraft.network.chat.Component
import net.minecraft.util.FormattedCharSequence
import ru.dbotthepony.mc.otm.core.*
@ -14,6 +15,7 @@ fun VertexConsumer.vertex(matrix4f: Matrix4f, vector: Vector) = vertex(matrix4f,
fun VertexConsumer.color(color: RGBAColor) = color(color.r, color.g, color.b, color.a)
fun PoseStack.translate(vector: Vector) = translate(vector.x, vector.y, vector.z)
fun PoseStack.translate(vector: Vec3i) = translate(vector.x.toDouble(), vector.y.toDouble(), vector.z.toDouble())
fun PoseStack.translate(vector: Vector3f) = last().pose().multiplyWithTranslation(vector.x(), vector.y(), vector.z())
fun PoseStack.rotateAroundPoint(point: Vector, axis: Vector, rotation: Float, isDegrees: Boolean = false) {
@ -117,3 +119,362 @@ fun Font.drawAligned(poseStack: PoseStack, text: Component, align: TextAlign, x:
fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: TextAlign, x: Float, y: Float, color: RGBAColor): Int {
return drawAligned(poseStack, text, align, x, y, color.toInt())
}
fun Font.drawAlignedLines(poseStack: PoseStack, text: List<Any?>, align: TextAlign, x: Float, y: Float, color: Int) {
var totalWidth = 0
var height = 0
for (line in text) {
var accumulate = 0
when (line) {
is Component -> {
accumulate += width(line)
height += lineHeight
}
is String -> {
accumulate += width(line)
height += lineHeight
}
is FormattedCharSequence -> {
accumulate += width(line)
height += lineHeight
}
else -> height += lineHeight
}
totalWidth = totalWidth.coerceAtLeast(accumulate)
}
if (height == 0 || totalWidth == 0) {
return
}
var y = y
when (align) {
TextAlign.TOP_LEFT -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x, y, color)
is String -> draw(poseStack, line, x, y, color)
is FormattedCharSequence -> draw(poseStack, line, x, y, color)
}
y += lineHeight
}
}
TextAlign.TOP_CENTER -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x - width(line) / 2f, y, color)
is String -> draw(poseStack, line, x - width(line) / 2f, y, color)
is FormattedCharSequence -> draw(poseStack, line, x - width(line) / 2f, y, color)
}
y += lineHeight
}
}
TextAlign.TOP_RIGHT -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x - width(line), y, color)
is String -> draw(poseStack, line, x - width(line), y, color)
is FormattedCharSequence -> draw(poseStack, line, x - width(line), y, color)
}
y += lineHeight
}
}
TextAlign.CENTER_LEFT -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x, y - height / 2f, color)
is String -> draw(poseStack, line, x, y - height / 2f, color)
is FormattedCharSequence -> draw(poseStack, line, x, y - height / 2f, color)
}
y += lineHeight
}
}
TextAlign.CENTER_CENTER -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x - width(line) / 2f, y - height / 2f, color)
is String -> draw(poseStack, line, x - width(line) / 2f, y - height / 2f, color)
is FormattedCharSequence -> draw(poseStack, line, x - width(line) / 2f, y - height / 2f, color)
}
y += lineHeight
}
}
TextAlign.CENTER_RIGHT -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x - width(line), y - height / 2f, color)
is String -> draw(poseStack, line, x - width(line), y - height / 2f, color)
is FormattedCharSequence -> draw(poseStack, line, x - width(line), y - height / 2f, color)
}
y += lineHeight
}
}
TextAlign.BOTTOM_LEFT -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x, y - height, color)
is String -> draw(poseStack, line, x, y - height, color)
is FormattedCharSequence -> draw(poseStack, line, x, y - height, color)
}
y += lineHeight
}
}
TextAlign.BOTTOM_CENTER -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x - width(line) / 2f, y - height, color)
is String -> draw(poseStack, line, x - width(line) / 2f, y - height, color)
is FormattedCharSequence -> draw(poseStack, line, x - width(line) / 2f, y - height, color)
}
y += lineHeight
}
}
TextAlign.BOTTOM_RIGHT -> {
for (line in text) {
when (line) {
is Component -> draw(poseStack, line, x - width(line), y - height, color)
is String -> draw(poseStack, line, x - width(line), y - height, color)
is FormattedCharSequence -> draw(poseStack, line, x - width(line), y - height, color)
}
y += lineHeight
}
}
}
}
fun Font.drawAlignedStripe(poseStack: PoseStack, text: List<Any>, align: TextAlign, x: Float, y: Float, color: Int) {
var totalWidth = 0
for (line in text) {
totalWidth += when (line) {
is Component -> {
width(line)
}
is String -> {
width(line)
}
is FormattedCharSequence -> {
width(line)
}
else -> throw IllegalArgumentException("Invalid stripe value ${line}")
}
}
if (totalWidth == 0) {
return
}
var x = x
when (align) {
TextAlign.TOP_LEFT -> {
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y, color)
x += width(line)
}
is String -> {
draw(poseStack, line, x, y, color)
x += width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y, color)
x += width(line)
}
}
}
}
TextAlign.TOP_CENTER -> {
x += totalWidth / 2f
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y, color)
x -= width(line)
}
is String -> {
draw(poseStack, line, x, y, color)
x -= width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y, color)
x -= width(line)
}
}
}
}
TextAlign.TOP_RIGHT -> {
x += totalWidth
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y, color)
x -= width(line)
}
is String -> {
draw(poseStack, line, x, y, color)
x -= width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y, color)
x -= width(line)
}
}
}
}
TextAlign.CENTER_LEFT -> {
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x += width(line)
}
is String -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x += width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x += width(line)
}
}
}
}
TextAlign.CENTER_CENTER -> {
x += totalWidth / 2f
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x -= width(line)
}
is String -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x -= width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x -= width(line)
}
}
}
}
TextAlign.CENTER_RIGHT -> {
x += totalWidth
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x -= width(line)
}
is String -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x -= width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y - lineHeight / 2f, color)
x -= width(line)
}
}
}
}
TextAlign.BOTTOM_LEFT -> {
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y - lineHeight, color)
x += width(line)
}
is String -> {
draw(poseStack, line, x, y - lineHeight, color)
x += width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y - lineHeight, color)
x += width(line)
}
}
}
}
TextAlign.BOTTOM_CENTER -> {
x += totalWidth / 2f
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y - lineHeight, color)
x -= width(line)
}
is String -> {
draw(poseStack, line, x, y - lineHeight, color)
x -= width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y - lineHeight, color)
x -= width(line)
}
}
}
}
TextAlign.BOTTOM_RIGHT -> {
x += totalWidth
for (line in text) {
when (line) {
is Component -> {
draw(poseStack, line, x, y - lineHeight, color)
x -= width(line)
}
is String -> {
draw(poseStack, line, x, y - lineHeight, color)
x -= width(line)
}
is FormattedCharSequence -> {
draw(poseStack, line, x, y - lineHeight, color)
x -= width(line)
}
}
}
}
}
}

View File

@ -24,6 +24,8 @@
"otm.gui.progress_widget": "Progress: %s%%",
"otm.gui.progress_widget_stuck": "The machine can not work, check configuration",
"otm.gui.total_raw": "Total:",
"otm.gui.matter.percentage_level": "Matter level: %s%%",
"otm.gui.matter.format": "Matter: %s",
"otm.gui.matter.name": "MtU",
@ -142,6 +144,25 @@
"otm.suffix.zepto": "%s z%s",
"otm.suffix.yocto": "%s y%s",
"otm.suffix_raw.kilo": "k",
"otm.suffix_raw.mega": "M",
"otm.suffix_raw.giga": "G",
"otm.suffix_raw.tera": "T",
"otm.suffix_raw.peta": "P",
"otm.suffix_raw.exa": "E",
"otm.suffix_raw.zetta": "Z",
"otm.suffix_raw.yotta": "Y",
"otm.suffix_raw.deci": "d",
"otm.suffix_raw.centi": "c",
"otm.suffix_raw.milli": "m",
"otm.suffix_raw.micro": "μ",
"otm.suffix_raw.nano": "n",
"otm.suffix_raw.pico": "p",
"otm.suffix_raw.femto": "f",
"otm.suffix_raw.atto": "a",
"otm.suffix_raw.zepto": "z",
"otm.suffix_raw.yocto": "y",
"death.attack.otm_become_android": "%1$s lost their humanity",
"death.attack.otm_become_humane": "%1$s regained their humanity",
"death.attack.otm_event_horizon": "%1$s never crossed event horizon",