Align power/matter history by biggest values
This commit is contained in:
parent
759c9863e2
commit
fdf8e47e5e
@ -24,6 +24,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.util.formatHistory
|
||||
import ru.dbotthepony.mc.otm.core.util.formatMatter
|
||||
import ru.dbotthepony.mc.otm.core.util.formatMatterLevel
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||
@ -137,21 +138,6 @@ open class MatterGaugePanel<out S : Screen> @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatLevel(a: Decimal, b: Decimal): Component {
|
||||
val diff = a - b
|
||||
|
||||
val fa = a.formatMatter(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_GREEN)
|
||||
val fb = b.formatMatter(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_RED)
|
||||
|
||||
if (diff.isZero) {
|
||||
return TranslatableComponent("otm.gui.diff", diff.formatMatter(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.GRAY), fa, fb)
|
||||
} else if (diff.isPositive) {
|
||||
return TranslatableComponent("otm.gui.diff", diff.formatMatter(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_GREEN), fa, fb)
|
||||
} else {
|
||||
return TranslatableComponent("otm.gui.diff", (-diff).formatMatter(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_RED), fa, fb)
|
||||
}
|
||||
}
|
||||
|
||||
open class ProfiledMatterGaugePanel<out S : Screen>(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>? = null,
|
||||
@ -161,29 +147,12 @@ open class ProfiledMatterGaugePanel<out S : Screen>(
|
||||
): MatterGaugePanel<S>(screen, parent, profiledWidget.gauge, x, y) {
|
||||
override fun makeTooltip(): MutableList<Component> {
|
||||
return super.makeTooltip().also {
|
||||
it.add(TextComponent(""))
|
||||
|
||||
if (minecraft.window.isShiftDown) {
|
||||
it.add(formatLevel(profiledWidget.lastTickReceive, profiledWidget.lastTickTransfer))
|
||||
it.add(TextComponent("---"))
|
||||
}
|
||||
|
||||
it.add(formatLevel(
|
||||
profiledWidget.weightedReceive,
|
||||
profiledWidget.weightedTransfer,
|
||||
))
|
||||
|
||||
if (minecraft.window.isShiftDown) {
|
||||
it.add(TextComponent("---"))
|
||||
val values = IntArrayList()
|
||||
|
||||
values.addAll(profiledWidget.tick downTo 0)
|
||||
values.addAll(AbstractProfiledStorage.HISTORY_SIZE - 1 downTo profiledWidget.tick + 1)
|
||||
|
||||
for (i in values.intIterator()) {
|
||||
it.add(formatLevel(profiledWidget.historyReceive[i].value, profiledWidget.historyTransfer[i].value))
|
||||
}
|
||||
}
|
||||
formatHistory(
|
||||
it,
|
||||
profiledWidget,
|
||||
verbose = ShiftPressedCond,
|
||||
suffix = TranslatableComponent("otm.gui.matter.name")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import ru.dbotthepony.mc.otm.client.render.*
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.util.formatHistory
|
||||
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||
import ru.dbotthepony.mc.otm.core.util.formatPowerLevel
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||
@ -94,21 +95,6 @@ fun <S : Screen> WidePowerGaugePanel(
|
||||
height: Float = 48f
|
||||
) = PowerGaugePanel(screen, parent, widget, x, y, width, height)
|
||||
|
||||
private fun formatLevel(a: Decimal, b: Decimal): Component {
|
||||
val diff = a - b
|
||||
|
||||
val fa = a.formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_GREEN)
|
||||
val fb = b.formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_RED)
|
||||
|
||||
if (diff.isZero) {
|
||||
return TranslatableComponent("otm.gui.diff", diff.formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.GRAY), fa, fb)
|
||||
} else if (diff.isPositive) {
|
||||
return TranslatableComponent("otm.gui.diff", diff.formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_GREEN), fa, fb)
|
||||
} else {
|
||||
return TranslatableComponent("otm.gui.diff", (-diff).formatPower(formatAsReadable = ShiftPressedCond).copy().withStyle(ChatFormatting.DARK_RED), fa, fb)
|
||||
}
|
||||
}
|
||||
|
||||
open class ProfiledPowerGaugePanel<out S : Screen>(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>? = null,
|
||||
@ -120,29 +106,12 @@ open class ProfiledPowerGaugePanel<out S : Screen>(
|
||||
) : PowerGaugePanel<S>(screen, parent, profiledWidget.gauge, x, y, width, height) {
|
||||
override fun makeTooltip(): MutableList<Component> {
|
||||
return super.makeTooltip().also {
|
||||
it.add(TextComponent(""))
|
||||
|
||||
if (minecraft.window.isShiftDown) {
|
||||
it.add(formatLevel(profiledWidget.lastTickReceive, profiledWidget.lastTickTransfer))
|
||||
it.add(TextComponent("---"))
|
||||
}
|
||||
|
||||
it.add(formatLevel(
|
||||
profiledWidget.weightedReceive,
|
||||
profiledWidget.weightedTransfer,
|
||||
))
|
||||
|
||||
if (minecraft.window.isShiftDown) {
|
||||
it.add(TextComponent("---"))
|
||||
val values = IntArrayList()
|
||||
|
||||
values.addAll(profiledWidget.tick downTo 0)
|
||||
values.addAll(AbstractProfiledStorage.HISTORY_SIZE - 1 downTo profiledWidget.tick + 1)
|
||||
|
||||
for (i in values.intIterator()) {
|
||||
it.add(formatLevel(profiledWidget.historyReceive[i].value, profiledWidget.historyTransfer[i].value))
|
||||
}
|
||||
}
|
||||
formatHistory(
|
||||
it,
|
||||
profiledWidget,
|
||||
verbose = ShiftPressedCond,
|
||||
suffix = TranslatableComponent("otm.gui.power.name")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,22 @@
|
||||
package ru.dbotthepony.mc.otm.core.util
|
||||
|
||||
import it.unimi.dsi.fastutil.chars.CharArrayList
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.MutableComponent
|
||||
import ru.dbotthepony.kommons.util.value
|
||||
import ru.dbotthepony.mc.otm.capability.AbstractProfiledStorage
|
||||
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.isNegative
|
||||
import ru.dbotthepony.mc.otm.core.math.isZero
|
||||
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
|
||||
import java.math.BigInteger
|
||||
import java.util.function.BooleanSupplier
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private fun concat(numbers: String, suffix: Any): Component {
|
||||
@ -127,7 +134,7 @@ private fun reformat(numbers: String): String {
|
||||
for (i in dot downTo 0) {
|
||||
if (++c == 4) {
|
||||
c = 1
|
||||
result.add(' ')
|
||||
result.add(' ')
|
||||
}
|
||||
|
||||
result.add(numbers[i])
|
||||
@ -138,6 +145,19 @@ private fun reformat(numbers: String): String {
|
||||
})
|
||||
}
|
||||
|
||||
// because minecraft's font 'Figure Space' (FSP) does not match width of numbers
|
||||
private fun resplice(number: String, decimals: Int): String {
|
||||
var i = if (decimals != 0) decimals + 4 else 3
|
||||
val resplice = number.toCharArray()
|
||||
|
||||
while (i < number.length) {
|
||||
resplice[resplice.size - i - 1] = ' '
|
||||
i += 3
|
||||
}
|
||||
|
||||
return String(resplice)
|
||||
}
|
||||
|
||||
fun Long.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 3, formatAsReadable: BooleanSupplier = never, bias: Int = 0): Component {
|
||||
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
|
||||
|
||||
@ -234,3 +254,85 @@ fun formatTickDuration(ticks: Int, longFormat: Boolean = false): String {
|
||||
return "${padded(minutes)}:$seconds"
|
||||
}
|
||||
}
|
||||
|
||||
fun formatHistory(
|
||||
result: MutableList<Component>,
|
||||
widget: ProfiledLevelGaugeWidget<*>,
|
||||
bias: Int = 0,
|
||||
decimals: Int = 3,
|
||||
verbose: BooleanSupplier = never,
|
||||
suffix: Any = "",
|
||||
) {
|
||||
data class Part(val formatted: String, val number: Decimal, val prefix: SiPrefix)
|
||||
data class Line(val delta: Part, val incoming: Part, val outgoing: Part)
|
||||
|
||||
val lines = ArrayList<Line>()
|
||||
|
||||
fun part(number: Decimal): Part {
|
||||
if (verbose.asBoolean && number.absoluteValue >= Decimal.ONE) {
|
||||
return Part(reformat(number.toString(decimals)), number, SiPrefix.NONE)
|
||||
}
|
||||
|
||||
val prefix = SiPrefix.determine(number).neighbour(bias)
|
||||
if (prefix.isEmpty) return Part(number.toString(decimals), number, prefix)
|
||||
return Part((number / prefix.decimal).toString(decimals), number, prefix)
|
||||
}
|
||||
|
||||
fun addLine(a: Decimal, b: Decimal) {
|
||||
lines.add(Line(part(a - b), part(a), part(b)))
|
||||
}
|
||||
|
||||
if (verbose.asBoolean) {
|
||||
addLine(widget.lastTickReceive, widget.lastTickTransfer)
|
||||
|
||||
val values = IntArrayList()
|
||||
values.addAll(widget.tick downTo 0)
|
||||
values.addAll(AbstractProfiledStorage.HISTORY_SIZE - 1 downTo widget.tick + 1)
|
||||
|
||||
for (i in values.intIterator()) {
|
||||
addLine(widget.historyReceive[i].value, widget.historyTransfer[i].value)
|
||||
}
|
||||
}
|
||||
|
||||
addLine(
|
||||
widget.weightedReceive,
|
||||
widget.weightedTransfer
|
||||
)
|
||||
|
||||
val maxWidthDeltaNumber = lines.maxOf { it.delta.formatted.length }
|
||||
val maxWidthInNumber = lines.maxOf { it.incoming.formatted.length }
|
||||
val maxWidthOutNumber = lines.maxOf { it.outgoing.formatted.length }
|
||||
|
||||
val maxWidthDeltaSi = lines.maxOf { it.delta.prefix.length }
|
||||
val maxWidthInSi = lines.maxOf { it.incoming.prefix.length }
|
||||
val maxWidthOutSi = lines.maxOf { it.outgoing.prefix.length }
|
||||
|
||||
fun Part.format(widthNumbers: Int, widthSi: Int): MutableComponent {
|
||||
return TranslatableComponent(
|
||||
prefix.formatLocaleKey,
|
||||
resplice("-".repeat(max(widthNumbers - formatted.length, 0)) + formatted, decimals) + "-".repeat(max(widthSi - prefix.length, 0)),
|
||||
suffix
|
||||
)
|
||||
}
|
||||
|
||||
fun Line.format(): Component {
|
||||
val deltaColor = if (delta.number.isZero) ChatFormatting.GRAY else if (delta.number.isPositive) ChatFormatting.DARK_GREEN else ChatFormatting.DARK_RED
|
||||
|
||||
return TranslatableComponent(
|
||||
"otm.gui.diff",
|
||||
delta.format(maxWidthDeltaNumber, maxWidthDeltaSi).withStyle(deltaColor),
|
||||
incoming.format(maxWidthInNumber, maxWidthInSi).withStyle(ChatFormatting.DARK_GREEN),
|
||||
outgoing.format(maxWidthOutNumber, maxWidthOutSi).withStyle(ChatFormatting.DARK_RED),
|
||||
)
|
||||
}
|
||||
|
||||
result.add(TextComponent(""))
|
||||
result.add(lines.removeFirst().format())
|
||||
|
||||
if (verbose.asBoolean) {
|
||||
result.add(TextComponent("---"))
|
||||
result.add(lines.removeFirst().format())
|
||||
result.add(TextComponent("---"))
|
||||
lines.forEach { result.add(it.format()) }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package ru.dbotthepony.mc.otm.core.util
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import net.minecraft.network.chat.Component
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.isZero
|
||||
import java.math.BigInteger
|
||||
@ -19,6 +21,9 @@ enum class SiPrefix(val power: Int, val symbol: String) {
|
||||
NONE(0, "") {
|
||||
override val isEmpty: Boolean
|
||||
get() = true
|
||||
|
||||
override val length: Int
|
||||
get() = 0
|
||||
},
|
||||
|
||||
KILO (1, "k"),
|
||||
@ -35,6 +40,10 @@ enum class SiPrefix(val power: Int, val symbol: String) {
|
||||
val formatLocaleKey = "otm.suffix.${name.lowercase()}".intern()
|
||||
val conciseFormatLocaleKey = "otm.suffix_concise.${name.lowercase()}".intern()
|
||||
val rawLocaleKey = "otm.suffix_raw.${name.lowercase()}".intern()
|
||||
val rawLocale: Component = TranslatableComponent(rawLocaleKey)
|
||||
|
||||
open val length: Int
|
||||
get() = rawLocale.string.length
|
||||
|
||||
val string: String
|
||||
|
||||
@ -72,18 +81,15 @@ enum class SiPrefix(val power: Int, val symbol: String) {
|
||||
|
||||
if (new < 0) {
|
||||
return YOCTO
|
||||
} else if (new >= VALUES.size) {
|
||||
} else if (new >= entries.size) {
|
||||
return YOTTA
|
||||
} else {
|
||||
return VALUES[new]
|
||||
return entries[new]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val VALUES: ImmutableList<SiPrefix> = ImmutableList.copyOf(values())
|
||||
|
||||
@JvmField
|
||||
val MULTIPLIES: ImmutableList<SiPrefix> = ImmutableList.builder<SiPrefix>()
|
||||
.add(NONE)
|
||||
|
Loading…
Reference in New Issue
Block a user