Flywheel battery status GUI
This commit is contained in:
parent
2c741b45c3
commit
4a711783f5
@ -145,6 +145,9 @@ private fun sounds(provider: MatteryLanguageProvider) {
|
||||
|
||||
private fun misc(provider: MatteryLanguageProvider) {
|
||||
with(provider.english) {
|
||||
misc("misc.yes", "Yes")
|
||||
misc("misc.no", "No")
|
||||
|
||||
misc("pwr_alert1", "[%s]")
|
||||
misc("pwr_alert2", "PWR: ALERT")
|
||||
misc("pwr_alert3", "WARNING ERROR:")
|
||||
@ -941,6 +944,13 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
|
||||
|
||||
private fun gui(provider: MatteryLanguageProvider) {
|
||||
with(provider.english) {
|
||||
gui("multiblock.formed", "Multiblock is formed: %s")
|
||||
|
||||
gui("flywheel.current_loss_t", "Current energy loss per tick:")
|
||||
gui("flywheel.current_loss_s", "Current energy loss per second:")
|
||||
gui("flywheel.core_material", "Core material:")
|
||||
gui("flywheel.core_material_count", "(Core block count: %s)")
|
||||
|
||||
gui("flow_direction_set", "Flow direction set to %s")
|
||||
gui("tick_timer_set", "Timer set to %s ticks")
|
||||
|
||||
|
@ -159,6 +159,9 @@ private fun sounds(provider: MatteryLanguageProvider) {
|
||||
|
||||
private fun misc(provider: MatteryLanguageProvider) {
|
||||
with(provider.russian) {
|
||||
misc("misc.yes", "Да")
|
||||
misc("misc.no", "Нет")
|
||||
|
||||
misc("pwr_alert2", "ПТН: ВНИМАНИЕ")
|
||||
misc("pwr_alert3", "ПРЕДУПРЕЖДЕНИЕ ОБ ОШИБКЕ:")
|
||||
misc("pwr_alert5", "Ошибка %s была обнаружена по адресу %s:%s в %s")
|
||||
@ -934,6 +937,13 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
|
||||
|
||||
private fun gui(provider: MatteryLanguageProvider) {
|
||||
with(provider.russian) {
|
||||
gui("multiblock.formed", "Мультиблок сформирован: %s")
|
||||
|
||||
gui("flywheel.current_loss_t", "Текущая потеря энергии в тик:")
|
||||
gui("flywheel.current_loss_s", "Текущая потеря энергии в секунду:")
|
||||
gui("flywheel.core_material", "Материал сердечника:")
|
||||
gui("flywheel.core_material_count", "(Используется блоков сердечника: %s)")
|
||||
|
||||
gui("flow_direction_set", "Направление потока установлено на %s")
|
||||
gui("tick_timer_set", "Таймер установлен на %s тиков")
|
||||
|
||||
|
@ -2,10 +2,17 @@ package ru.dbotthepony.mc.otm.block.entity.tech
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Vec3i
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.Blocks
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage
|
||||
@ -19,15 +26,27 @@ import ru.dbotthepony.mc.otm.core.multiblock.ShapedMultiblockFactory
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.Strategy
|
||||
import ru.dbotthepony.mc.otm.core.multiblock.shapedMultiblock
|
||||
import ru.dbotthepony.mc.otm.data.FlywheelMaterials
|
||||
import ru.dbotthepony.mc.otm.menu.tech.FlywheelBatteryMenu
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.game.MBlocks
|
||||
|
||||
class FlywheelBatteryBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryBlockEntity(MBlockEntities.FLYWHEEL_BATTERY, blockPos, blockState), EnergyInterfaceBlockEntity.Target {
|
||||
class FlywheelBatteryBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.FLYWHEEL_BATTERY, blockPos, blockState), EnergyInterfaceBlockEntity.Target {
|
||||
private var multiblock: ShapedMultiblock? = null
|
||||
private var lastHeight = -1
|
||||
var batteryLevel = Decimal.ZERO
|
||||
private var cachedChargeEfficiency = Decimal.ONE
|
||||
|
||||
val formed: Boolean
|
||||
get() = multiblock?.isValid == true
|
||||
|
||||
// dangerous as Reference2IntMap.Entry reference live data, and its behavior is undefined once flywheel updates again
|
||||
val currentlyUsedCore: Reference2IntMap.Entry<Block>? get() {
|
||||
return multiblock?.blocks(FLYWHEEL_MATERIAL)?.reference2IntEntrySet()?.firstOrNull()
|
||||
}
|
||||
|
||||
var currentLossPerTick: Decimal = Decimal.ZERO
|
||||
private set
|
||||
|
||||
private inner class Storage : IMatteryEnergyStorage {
|
||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||
if (batteryLevel <= Decimal.ZERO) {
|
||||
@ -117,13 +136,19 @@ class FlywheelBatteryBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
|
||||
val material = FlywheelMaterials[entry.key]!!
|
||||
energy.parent.maxBatteryLevel = material.storage * entry.intValue
|
||||
cachedChargeEfficiency = material.receiveEfficiency
|
||||
energy.extractEnergy(energy.parent.batteryLevel * MachinesConfig.Flywheel.PASSIVE_LOSS * material.momentumLossSpeed, false)
|
||||
currentLossPerTick = energy.parent.batteryLevel * MachinesConfig.Flywheel.PASSIVE_LOSS * material.momentumLossSpeed
|
||||
energy.extractEnergy(currentLossPerTick, false)
|
||||
} else {
|
||||
energy.parent.maxBatteryLevel = Decimal.ZERO
|
||||
energy.extractEnergy(energy.parent.batteryLevel * MachinesConfig.Flywheel.ACTIVE_LOSS, false)
|
||||
currentLossPerTick = energy.parent.batteryLevel * MachinesConfig.Flywheel.ACTIVE_LOSS
|
||||
energy.extractEnergy(currentLossPerTick, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return FlywheelBatteryMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val FLYWHEEL_MATERIAL = Any()
|
||||
private val outerRing = listOf(
|
||||
|
@ -44,6 +44,42 @@ data class DockProperty(val left: Float = 0f, val top: Float = 0f, val right: Fl
|
||||
val horizontal get() = left + right
|
||||
val vertical get() = top + bottom
|
||||
|
||||
operator fun plus(other: DockProperty): DockProperty {
|
||||
return DockProperty(
|
||||
left + other.left,
|
||||
top + other.top,
|
||||
right + other.right,
|
||||
bottom + other.bottom
|
||||
)
|
||||
}
|
||||
|
||||
operator fun minus(other: DockProperty): DockProperty {
|
||||
return DockProperty(
|
||||
left - other.left,
|
||||
top - other.top,
|
||||
right - other.right,
|
||||
bottom - other.bottom
|
||||
)
|
||||
}
|
||||
|
||||
operator fun plus(other: Float): DockProperty {
|
||||
return DockProperty(
|
||||
left + other,
|
||||
top + other,
|
||||
right + other,
|
||||
bottom + other
|
||||
)
|
||||
}
|
||||
|
||||
operator fun minus(other: Float): DockProperty {
|
||||
return DockProperty(
|
||||
left - other,
|
||||
top - other,
|
||||
right - other,
|
||||
bottom - other
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val EMPTY = DockProperty()
|
||||
}
|
||||
@ -1391,8 +1427,8 @@ open class EditablePanel<out S : Screen>(
|
||||
* Attempts to tightly fit dimensions to all children
|
||||
*/
|
||||
open fun sizeToContents() {
|
||||
if (visibleChildrenInternal.isEmpty() || visibleChildrenInternal.any { it.dock == Dock.FILL }) {
|
||||
// nothing to size against OR there is "fill" children
|
||||
if (visibleChildrenInternal.isEmpty()) {
|
||||
// nothing to size against
|
||||
return
|
||||
}
|
||||
|
||||
@ -1407,16 +1443,7 @@ open class EditablePanel<out S : Screen>(
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
when (child.dock) {
|
||||
Dock.NONE -> {
|
||||
if (!child.ignoreWhenSizingToContents) {
|
||||
width = maxOf(width, child.x + child.width)
|
||||
height = maxOf(height, child.y + child.height)
|
||||
}
|
||||
}
|
||||
|
||||
Dock.FILL -> {
|
||||
throw RuntimeException()
|
||||
} // do nothing
|
||||
Dock.NONE, Dock.FILL -> {}
|
||||
|
||||
Dock.LEFT, Dock.RIGHT -> {
|
||||
if (previousDock != 1) {
|
||||
@ -1454,6 +1481,13 @@ open class EditablePanel<out S : Screen>(
|
||||
height = max(height, accumulatedHeight)
|
||||
}
|
||||
|
||||
for (child in visibleChildrenInternal) {
|
||||
if ((child.dock == Dock.NONE || child.dock == Dock.FILL) && !child.ignoreWhenSizingToContents) {
|
||||
width = maxOf(width, child.x + child.width)
|
||||
height = maxOf(height, child.y + child.height)
|
||||
}
|
||||
}
|
||||
|
||||
this.width = width + dockPadding.left + dockPadding.right
|
||||
this.height = height + dockPadding.top + dockPadding.bottom
|
||||
|
||||
|
@ -16,7 +16,7 @@ open class BackgroundPanel<out S : Screen>(
|
||||
height: Float = 10f,
|
||||
) : EditablePanel<S>(screen, parent, x, y, width, height) {
|
||||
init {
|
||||
dockPadding = DockProperty(3f, 3f, 3f, 3f)
|
||||
dockPadding = DEFAULT_PADDING
|
||||
}
|
||||
|
||||
var drawBackground = true
|
||||
@ -33,6 +33,9 @@ open class BackgroundPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_PADDING = DockProperty(3f, 3f, 3f, 3f)
|
||||
private val BLOCK = DEFAULT_PADDING + 2f
|
||||
|
||||
fun <S : Screen> padded(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
@ -42,6 +45,17 @@ open class BackgroundPanel<out S : Screen>(
|
||||
height: Float = 10f,
|
||||
) = BackgroundPanel(screen, parent, x, y, width + 6f, height + 6f)
|
||||
|
||||
fun <S : Screen> block(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
x: Float = 0f,
|
||||
y: Float = 0f,
|
||||
width: Float = 10f,
|
||||
height: Float = 10f,
|
||||
) = BackgroundPanel(screen, parent, x, y, width + 6f, height + 6f).also {
|
||||
it.dockPadding = BLOCK
|
||||
}
|
||||
|
||||
fun <S : Screen> paddedCenter(
|
||||
screen: S,
|
||||
parent: EditablePanel<*>?,
|
||||
|
@ -1,10 +1,12 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen.tech
|
||||
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleGeneratorBlockEntity
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.DynamicLabel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.Label
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.BooleanButtonPanel
|
||||
@ -17,10 +19,11 @@ 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.menu.tech.BlackHoleGeneratorMenu
|
||||
import java.util.function.Supplier
|
||||
|
||||
class BlackHoleGeneratorScreen(menu: BlackHoleGeneratorMenu, inventory: Inventory, title: Component) : MatteryScreen<BlackHoleGeneratorMenu>(menu, inventory, title) {
|
||||
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
|
||||
val frame = FramePanel.padded(this, 240f, 130f, title)
|
||||
val frame = FramePanel.padded(this, 240f, 150f, title)
|
||||
|
||||
frame.behaveAsWindow()
|
||||
frame.onClose { onClose() }
|
||||
@ -32,6 +35,19 @@ class BlackHoleGeneratorScreen(menu: BlackHoleGeneratorMenu, inventory: Inventor
|
||||
it.tooltips.add(TranslatableComponent("otm.gui.black_hole_generator.help3"))
|
||||
}
|
||||
|
||||
DynamicLabel(this, frame, textSupplier = Supplier {
|
||||
TranslatableComponent(
|
||||
"otm.gui.multiblock.formed",
|
||||
if (menu.formed.get())
|
||||
TranslatableComponent("otm.misc.yes").withStyle(ChatFormatting.DARK_GREEN)
|
||||
else
|
||||
TranslatableComponent("otm.misc.no")
|
||||
)
|
||||
}).also {
|
||||
it.dock = Dock.TOP
|
||||
it.dockTop = 4f
|
||||
}
|
||||
|
||||
val energy = ProfiledPowerGaugePanel(this, frame, menu.energy)
|
||||
val matter = ProfiledMatterGaugePanel(this, frame, menu.matter)
|
||||
|
||||
|
@ -0,0 +1,99 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen.tech
|
||||
|
||||
import net.minecraft.ChatFormatting
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.Items
|
||||
import ru.dbotthepony.mc.otm.client.render.RenderGravity
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.Dock
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.DynamicLabel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.Label
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.util.BackgroundPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalProfiledPowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
||||
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||
import ru.dbotthepony.mc.otm.menu.tech.FlywheelBatteryMenu
|
||||
import java.util.function.Supplier
|
||||
|
||||
class FlywheelBatteryScreen(menu: FlywheelBatteryMenu, inventory: Inventory, title: Component) : MatteryScreen<FlywheelBatteryMenu>(menu, inventory, title) {
|
||||
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
|
||||
val frame = FramePanel.padded(this, 240f, 0f, title)
|
||||
|
||||
frame.behaveAsWindow()
|
||||
frame.onClose { onClose() }
|
||||
|
||||
DynamicLabel(this, frame, textSupplier = Supplier {
|
||||
TranslatableComponent(
|
||||
"otm.gui.multiblock.formed",
|
||||
if (menu.formed.get())
|
||||
TranslatableComponent("otm.misc.yes").withStyle(ChatFormatting.DARK_GREEN)
|
||||
else
|
||||
TranslatableComponent("otm.misc.no")
|
||||
)
|
||||
}).also {
|
||||
it.dock = Dock.TOP
|
||||
it.dockTop = 4f
|
||||
}
|
||||
|
||||
Label(this, frame, TranslatableComponent("otm.gui.flywheel.current_loss_t")).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
|
||||
DynamicLabel(this, frame, textSupplier = Supplier { menu.currentLossPerTick.get().formatPower(decimalPlaces = 6) }).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
|
||||
Label(this, frame, TranslatableComponent("otm.gui.flywheel.current_loss_s")).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
|
||||
DynamicLabel(this, frame, textSupplier = Supplier { (menu.currentLossPerTick.get() * 20).formatPower() }).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
|
||||
TallHorizontalProfiledPowerGaugePanel(this, frame, menu.energy).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
|
||||
val coreStrip = BackgroundPanel.block(this, frame)
|
||||
|
||||
coreStrip.dock = Dock.TOP
|
||||
coreStrip.dockTop = 4f
|
||||
|
||||
val leftStrip = EditablePanel(this, coreStrip)
|
||||
leftStrip.dock = Dock.FILL
|
||||
|
||||
object : AbstractSlotPanel<FlywheelBatteryScreen>(this@FlywheelBatteryScreen, coreStrip) {
|
||||
override val itemStack: ItemStack
|
||||
get() = menu.core.get()?.key?.asItem()?.let { ItemStack(it) } ?: ItemStack.EMPTY
|
||||
|
||||
init {
|
||||
dock = Dock.RIGHT
|
||||
dockResize = DockResizeMode.NONE
|
||||
}
|
||||
}
|
||||
|
||||
Label(this, leftStrip, text = TranslatableComponent("otm.gui.flywheel.core_material")).also {
|
||||
it.dock = Dock.TOP
|
||||
it.gravity = RenderGravity.CENTER_LEFT
|
||||
}
|
||||
|
||||
DynamicLabel(this, leftStrip, textSupplier = Supplier { TranslatableComponent("otm.gui.flywheel.core_material_count", (menu.core.get()?.value ?: 0).toString()) }).also {
|
||||
it.dock = Dock.TOP
|
||||
}
|
||||
|
||||
leftStrip.sizeToContents()
|
||||
coreStrip.sizeToContents()
|
||||
|
||||
frame.sizeToContents()
|
||||
|
||||
return frame
|
||||
}
|
||||
}
|
@ -282,6 +282,10 @@ fun FriendlyByteBuf.writeBlockType(value: Block) {
|
||||
writeType(BuiltInRegistries.BLOCK, value)
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.writeBlockState(value: BlockState) {
|
||||
writeVarInt(Block.BLOCK_STATE_REGISTRY.getIdOrThrow(value))
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.writeItemType(value: Item) {
|
||||
writeType(BuiltInRegistries.ITEM, value)
|
||||
}
|
||||
@ -307,6 +311,10 @@ fun FriendlyByteBuf.readBlockType(): Block {
|
||||
return readType(BuiltInRegistries.BLOCK)
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readBlockState(): BlockState {
|
||||
return Block.BLOCK_STATE_REGISTRY.byIdOrThrow(readVarInt())
|
||||
}
|
||||
|
||||
fun FriendlyByteBuf.readItemType(): Item {
|
||||
return readType(BuiltInRegistries.ITEM)
|
||||
}
|
||||
|
@ -8,12 +8,14 @@ import ru.dbotthepony.mc.otm.menu.input.DecimalInputWithFeedback
|
||||
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
|
||||
import ru.dbotthepony.mc.otm.menu.widget.CombinedProfiledLevelGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.registry.game.MMenus
|
||||
import java.util.function.BooleanSupplier
|
||||
|
||||
class BlackHoleGeneratorMenu(
|
||||
p_38852_: Int,
|
||||
inventory: Inventory,
|
||||
tile: BlackHoleGeneratorBlockEntity? = null,
|
||||
) : MatteryMenu(MMenus.BLACK_HOLE_GENERATOR, p_38852_, inventory, tile) {
|
||||
val formed = mSynchronizer.computedBoolean(BooleanSupplier { tile?.multiblock?.isValid ?: false })
|
||||
val drawBuildingGuide = BooleanInputWithFeedback(this, tile?.let { it::drawBuildingGuide })
|
||||
val energy = CombinedProfiledLevelGaugeWidget(this, tile?.energy)
|
||||
val matter = CombinedProfiledLevelGaugeWidget(this, tile?.matter)
|
||||
|
@ -0,0 +1,29 @@
|
||||
package ru.dbotthepony.mc.otm.menu.tech
|
||||
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.level.block.Blocks
|
||||
import ru.dbotthepony.mc.otm.block.entity.tech.FlywheelBatteryBlockEntity
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.network.MatteryStreamCodec
|
||||
import ru.dbotthepony.mc.otm.network.StreamCodecs
|
||||
import ru.dbotthepony.mc.otm.network.nullable
|
||||
import ru.dbotthepony.mc.otm.registry.game.MMenus
|
||||
import java.util.function.BooleanSupplier
|
||||
import java.util.function.Supplier
|
||||
|
||||
class FlywheelBatteryMenu(
|
||||
containerId: Int,
|
||||
inventory: Inventory,
|
||||
tile: FlywheelBatteryBlockEntity? = null
|
||||
) : MatteryMenu(MMenus.FLYWHEEL_BATTERY, containerId, inventory, tile) {
|
||||
val formed = mSynchronizer.computedBoolean(BooleanSupplier { tile?.formed ?: false })
|
||||
val energy = ProfiledLevelGaugeWidget(this, tile?.energyInterfaceTarget)
|
||||
val core = mSynchronizer.computed(Supplier { tile?.currentlyUsedCore }, CORE_TYPE_CODEC)
|
||||
val currentLossPerTick = mSynchronizer.computedDecimal(Supplier { tile?.currentLossPerTick ?: Decimal.ZERO })
|
||||
|
||||
companion object {
|
||||
private val CORE_TYPE_CODEC = MatteryStreamCodec.MapEntry(StreamCodecs.BLOCK_TYPE, StreamCodecs.VAR_INT).nullable()
|
||||
}
|
||||
}
|
@ -74,6 +74,8 @@ fun FriendlyByteBuf.readByteList(): ByteArrayList {
|
||||
}
|
||||
|
||||
fun <S : ByteBuf, V> StreamCodec<S, V>.wrap(): MatteryStreamCodec<S, V> = MatteryStreamCodec.Wrapper(this)
|
||||
@Deprecated("Redundant wrapping", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("this"))
|
||||
fun <S : ByteBuf, V> MatteryStreamCodec<S, V>.wrap(): MatteryStreamCodec<S, V> = this
|
||||
fun <S : ByteBuf, V> MatteryStreamCodec<S, V>.nullable(): MatteryStreamCodec<S, V?> = MatteryStreamCodec.Nullable(this)
|
||||
fun <S : ByteBuf, V : Any> MatteryStreamCodec<S, V>.optional(): MatteryStreamCodec<S, Optional<V>> = MatteryStreamCodec.Optional(this)
|
||||
|
||||
|
@ -25,6 +25,76 @@ interface MatteryStreamCodec<in S : ByteBuf, V> : StreamCodec<@UnsafeVariance S,
|
||||
override fun decode(stream: S): V
|
||||
override fun encode(stream: S, value: V)
|
||||
|
||||
class Of<in S : ByteBuf, V>(private val writer: S.(V) -> Unit, private val reader: S.() -> V) : MatteryStreamCodec<S, V> {
|
||||
override fun decode(stream: S): V {
|
||||
return reader(stream)
|
||||
}
|
||||
|
||||
override fun encode(stream: S, value: V) {
|
||||
return writer(stream, value)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractPair<in S : ByteBuf, A, B, P>(private val first: MatteryStreamCodec<S, A>, private val second: MatteryStreamCodec<S, B>) : MatteryStreamCodec<S, P> {
|
||||
protected abstract fun getFirst(value: P): A
|
||||
protected abstract fun getSecond(value: P): B
|
||||
protected abstract fun construct(a: A, b: B): P
|
||||
|
||||
override fun decode(stream: S): P {
|
||||
return construct(first.decode(stream), second.decode(stream))
|
||||
}
|
||||
|
||||
override fun encode(stream: S, value: P) {
|
||||
first.encode(stream, getFirst(value))
|
||||
second.encode(stream, getSecond(value))
|
||||
}
|
||||
|
||||
override fun copy(value: P): P {
|
||||
val a = first.copy(getFirst(value))
|
||||
val b = second.copy(getSecond(value))
|
||||
|
||||
if (a === getFirst(value) && b === getSecond(value))
|
||||
return value
|
||||
|
||||
return construct(a, b)
|
||||
}
|
||||
|
||||
override fun compare(a: P, b: P): Boolean {
|
||||
return first.compare(getFirst(a), getFirst(b)) && second.compare(getSecond(a), getSecond(b))
|
||||
}
|
||||
}
|
||||
|
||||
class Pair<in S : ByteBuf, A, B>(first: MatteryStreamCodec<S, A>, second: MatteryStreamCodec<S, B>) : AbstractPair<S, A, B, kotlin.Pair<A, B>>(first, second) {
|
||||
override fun getFirst(value: kotlin.Pair<A, B>): A {
|
||||
return value.first
|
||||
}
|
||||
|
||||
override fun getSecond(value: kotlin.Pair<A, B>): B {
|
||||
return value.second
|
||||
}
|
||||
|
||||
override fun construct(a: A, b: B): kotlin.Pair<A, B> {
|
||||
return a to b
|
||||
}
|
||||
}
|
||||
|
||||
class MapEntry<in S : ByteBuf, A, B>(first: MatteryStreamCodec<S, A>, second: MatteryStreamCodec<S, B>) : AbstractPair<S, A, B, Map.Entry<A, B>>(first, second) {
|
||||
override fun getFirst(value: Map.Entry<A, B>): A {
|
||||
return value.key
|
||||
}
|
||||
|
||||
override fun getSecond(value: Map.Entry<A, B>): B {
|
||||
return value.value
|
||||
}
|
||||
|
||||
override fun construct(a: A, b: B): Map.Entry<A, B> {
|
||||
return object : Map.Entry<A, B> {
|
||||
override val key: A = a
|
||||
override val value: B = b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Wrapper<in S : ByteBuf, V>(parent: StreamCodec<S, V>) : MatteryStreamCodec<S, V>, StreamCodec<@UnsafeVariance S, V> by parent
|
||||
|
||||
class Nullable<in S : ByteBuf, V>(val parent: MatteryStreamCodec<S, V>) : MatteryStreamCodec<S, V?> {
|
||||
|
@ -6,27 +6,34 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.network.codec.ByteBufCodecs
|
||||
import net.minecraft.network.codec.StreamCodec
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.kommons.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.core.math.readDecimal
|
||||
import ru.dbotthepony.mc.otm.core.math.writeDecimal
|
||||
import ru.dbotthepony.mc.otm.core.readBlockType
|
||||
import ru.dbotthepony.mc.otm.core.readItemType
|
||||
import ru.dbotthepony.mc.otm.core.writeBlockType
|
||||
import ru.dbotthepony.mc.otm.core.writeItemType
|
||||
import java.util.*
|
||||
|
||||
object StreamCodecs {
|
||||
val NOTHING: MatteryStreamCodec<ByteBuf, Nothing?> = StreamCodec.of<ByteBuf, Nothing?>({ _, _ -> }, { null }).wrap()
|
||||
val NOTHING: MatteryStreamCodec<ByteBuf, Nothing?> = MatteryStreamCodec.Of({}, { null })
|
||||
|
||||
val BYTE: MatteryStreamCodec<ByteBuf, Byte> = StreamCodec.of({ s, v -> s.writeByte(v.toInt()) }, ByteBuf::readByte).wrap()
|
||||
val SHORT = ByteBufCodecs.SHORT.wrap()
|
||||
val INT = ByteBufCodecs.INT.wrap()
|
||||
val VAR_INT = ByteBufCodecs.VAR_INT.wrap()
|
||||
val BYTE: MatteryStreamCodec<ByteBuf, Byte> = MatteryStreamCodec.Of({ v -> writeByte(v.toInt()) }, ByteBuf::readByte)
|
||||
val SHORT: MatteryStreamCodec<ByteBuf, Short> = ByteBufCodecs.SHORT.wrap()
|
||||
val INT: MatteryStreamCodec<ByteBuf, Int> = ByteBufCodecs.INT.wrap()
|
||||
val VAR_INT: MatteryStreamCodec<ByteBuf, Int> = ByteBufCodecs.VAR_INT.wrap()
|
||||
val LONG = StreamCodec.of(ByteBuf::writeLong, ByteBuf::readLong).wrap()
|
||||
val VAR_LONG = ByteBufCodecs.VAR_LONG.wrap()
|
||||
val DOUBLE = ByteBufCodecs.DOUBLE.wrap()
|
||||
val FLOAT = ByteBufCodecs.FLOAT.wrap()
|
||||
val BOOLEAN = ByteBufCodecs.BOOL.wrap()
|
||||
val STRING = ByteBufCodecs.STRING_UTF8.wrap()
|
||||
val UUID = UUIDUtil.STREAM_CODEC.wrap()
|
||||
val VAR_LONG: MatteryStreamCodec<ByteBuf, Long> = ByteBufCodecs.VAR_LONG.wrap()
|
||||
val DOUBLE: MatteryStreamCodec<ByteBuf, Double> = ByteBufCodecs.DOUBLE.wrap()
|
||||
val FLOAT: MatteryStreamCodec<ByteBuf, Float> = ByteBufCodecs.FLOAT.wrap()
|
||||
val BOOLEAN: MatteryStreamCodec<ByteBuf, Boolean> = ByteBufCodecs.BOOL.wrap()
|
||||
val STRING: MatteryStreamCodec<ByteBuf, String> = ByteBufCodecs.STRING_UTF8.wrap()
|
||||
val UUID: MatteryStreamCodec<ByteBuf, UUID> = UUIDUtil.STREAM_CODEC.wrap()
|
||||
val RESOURCE_LOCATION = ResourceLocation.STREAM_CODEC.wrap()
|
||||
val BLOCK_STATE: MatteryStreamCodec<ByteBuf, BlockState> = ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY).wrap()
|
||||
val BLOCK_TYPE = MatteryStreamCodec.Of(FriendlyByteBuf::writeBlockType, FriendlyByteBuf::readBlockType)
|
||||
|
||||
val RGBA: MatteryStreamCodec<ByteBuf, RGBAColor> = StreamCodec.of<ByteBuf, RGBAColor>(
|
||||
{ s, v -> s.writeFloat(v.red); s.writeFloat(v.green); s.writeFloat(v.blue); s.writeFloat(v.alpha) },
|
||||
|
@ -39,6 +39,7 @@ import ru.dbotthepony.mc.otm.client.screen.tech.EnergyCounterScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.tech.EnergyHatchScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.tech.EnergyServoScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.tech.EssenceStorageScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.tech.FlywheelBatteryScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.tech.ItemHatchScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.tech.MatterHatchScreen
|
||||
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
|
||||
@ -73,6 +74,7 @@ import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.EnergyHatchMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.EssenceStorageMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.FlywheelBatteryMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.ItemHatchMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.MatterHatchMenu
|
||||
import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu
|
||||
@ -122,6 +124,7 @@ object MMenus {
|
||||
val ENERGY_INPUT_HATCH by registry.register(MNames.ENERGY_INPUT_HATCH) { MenuType(EnergyHatchMenu::input, FeatureFlags.VANILLA_SET) }
|
||||
val ENERGY_OUTPUT_HATCH by registry.register(MNames.ENERGY_OUTPUT_HATCH) { MenuType(EnergyHatchMenu::output, FeatureFlags.VANILLA_SET) }
|
||||
val BLACK_HOLE_GENERATOR by registry.register(MNames.BLACK_HOLE_GENERATOR) { MenuType(::BlackHoleGeneratorMenu, FeatureFlags.VANILLA_SET) }
|
||||
val FLYWHEEL_BATTERY by registry.register(MNames.FLYWHEEL_BATTERY) { MenuType(::FlywheelBatteryMenu, FeatureFlags.VANILLA_SET) }
|
||||
|
||||
val STORAGE_BUS by registry.register(MNames.STORAGE_BUS) { MenuType(::StorageBusMenu, FeatureFlags.VANILLA_SET) }
|
||||
val STORAGE_IMPORTER_EXPORTER by registry.register(MNames.STORAGE_IMPORTER) { MenuType(::StorageImporterExporterMenu, FeatureFlags.VANILLA_SET) }
|
||||
@ -175,5 +178,6 @@ object MMenus {
|
||||
event.register(ENERGY_INPUT_HATCH, ::EnergyHatchScreen)
|
||||
event.register(ENERGY_OUTPUT_HATCH, ::EnergyHatchScreen)
|
||||
event.register(BLACK_HOLE_GENERATOR, ::BlackHoleGeneratorScreen)
|
||||
event.register(FLYWHEEL_BATTERY, ::FlywheelBatteryScreen)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user