Some unifications in tooltip handling

Fixes #74
This commit is contained in:
DBotThePony 2022-09-13 00:10:06 +07:00
parent 43c081277b
commit 26ebf1b3b2
Signed by: DBot
GPG Key ID: DCC23B5715498507
22 changed files with 466 additions and 84 deletions

View File

@ -155,11 +155,15 @@ private fun misc(provider: MatteryLanguageProvider) {
misc("item.power.last_20_ticks", "Last second: %s") misc("item.power.last_20_ticks", "Last second: %s")
misc("item.power.last_tick", "Last tick: %s") misc("item.power.last_tick", "Last tick: %s")
misc("item.power.normal.storage", "Stored energy: %s / %s") misc("item.power.storage", "Stored energy: %s / %s")
misc("item.power.normal.throughput", "Max I/O %s / %s") misc("item.power.throughput", "Max throughput: %s / %s")
misc("item.power.throughput_mono", "Max throughput: %s")
misc("item.power.infinity", "Infinity MtJ")
misc("item.power.output_only", "Max output %s") misc("item.worker.work_ticks_mono", "Work ticks: %s")
misc("item.power.input_only", "Max input %s") misc("item.worker.work_ticks", "Work ticks: %s / %s")
misc("item.block.stored_battery", "Battery: %s")
misc("item.pattern.stored", "Stored patterns: %s / %s") misc("item.pattern.stored", "Stored patterns: %s / %s")
misc("item.pattern.infinite.stored", "Stored patterns %s") misc("item.pattern.infinite.stored", "Stored patterns %s")

View File

@ -1,9 +1,12 @@
package ru.dbotthepony.mc.otm.block package ru.dbotthepony.mc.otm.block
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.player.Player import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
@ -17,8 +20,11 @@ import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.core.orNull
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -45,6 +51,17 @@ class AndroidStationBlock : MatteryBlock(), EntityBlock {
builder.add(WorkerState.SEMI_WORKER_STATE) builder.add(WorkerState.SEMI_WORKER_STATE)
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun getShape( override fun getShape(
p_151964_: BlockState, p_151964_: BlockState,
p_151965_: BlockGetter, p_151965_: BlockGetter,

View File

@ -1,7 +1,13 @@
package ru.dbotthepony.mc.otm.block package ru.dbotthepony.mc.otm.block
import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
@ -14,7 +20,13 @@ import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity import ru.dbotthepony.mc.otm.block.entity.ChemicalGeneratorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.GeneratorEnergyStorage
import ru.dbotthepony.mc.otm.capability.ItemEnergyStorageImpl
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.oncePre import ru.dbotthepony.mc.otm.oncePre
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -40,6 +52,26 @@ class ChemicalGeneratorBlock : RotatableMatteryBlock(), EntityBlock {
builder.add(WorkerState.SEMI_WORKER_STATE) builder.add(WorkerState.SEMI_WORKER_STATE)
} }
override fun appendHoverText(
itemStack: ItemStack,
p_49817_: BlockGetter?,
tooltips: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(itemStack, p_49817_, tooltips, p_49819_)
GeneratorEnergyStorage.appendHoverText(itemStack, p_49817_, tooltips, p_49819_)
val tag = itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag ?: return
val container = MatteryContainer(ChemicalGeneratorBlockEntity.SLOTS)
tag.map(MatteryBlockEntity.INVENTORY_KEY, container::deserializeNBT)
if (!container[ChemicalGeneratorBlockEntity.SLOT_BATTERY].isEmpty) {
tooltips.add(TranslatableComponent("otm.item.block.stored_battery", container[ChemicalGeneratorBlockEntity.SLOT_BATTERY].displayName).withStyle(ChatFormatting.GRAY))
ItemEnergyStorageImpl.appendHoverText(container[ChemicalGeneratorBlockEntity.SLOT_BATTERY], tooltips)
}
}
override fun neighborChanged( override fun neighborChanged(
state: BlockState, state: BlockState,
level: Level, level: Level,

View File

@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.block
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
@ -13,8 +16,10 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.state.StateDefinition import net.minecraft.world.level.block.state.StateDefinition
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.entity.MatteryWorkerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.PlatePressBlockEntity import ru.dbotthepony.mc.otm.block.entity.PlatePressBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -39,6 +44,16 @@ class PlatePressBlock(properties: Properties = DEFAULT_PROPERTIES) : RotatableMa
builder.add(WorkerState.WORKER_STATE) builder.add(WorkerState.WORKER_STATE)
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryWorkerBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun getShape( override fun getShape(
p_60555_: BlockState, p_60555_: BlockState,
p_60556_: BlockGetter, p_60556_: BlockGetter,

View File

@ -37,7 +37,7 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
} }
private var valid = true private var valid = true
val container = MatteryContainer(this::setChangedLight, 3) val container = MatteryContainer(this::setChangedLight, SLOTS)
override val droppableContainer: Container override val droppableContainer: Container
get() = container get() = container
val energy = GeneratorEnergyStorage(this::setChangedLight, MAX_ENERGY, THROUGHPUT) val energy = GeneratorEnergyStorage(this::setChangedLight, MAX_ENERGY, THROUGHPUT)
@ -236,6 +236,7 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
const val SLOT_INPUT = 0 const val SLOT_INPUT = 0
const val SLOT_BATTERY = 1 const val SLOT_BATTERY = 1
const val SLOT_RESIDUE = 2 const val SLOT_RESIDUE = 2
const val SLOTS = 3
const val WORK_TICKS_KEY = "workTicks" const val WORK_TICKS_KEY = "workTicks"
const val WORK_TICKS_TOTAL_KEY = "workTicksTotal" const val WORK_TICKS_TOTAL_KEY = "workTicksTotal"

View File

@ -1,8 +1,15 @@
package ru.dbotthepony.mc.otm.block.entity package ru.dbotthepony.mc.otm.block.entity
import net.minecraft.ChatFormatting
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
@ -14,6 +21,8 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.ifHas import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.container.set import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(p_155228_, p_155229_, p_155230_) { abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(p_155228_, p_155229_, p_155230_) {
@ -88,4 +97,18 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
batteryContainer.deserializeNBT(nbt[BATTERY_KEY]) batteryContainer.deserializeNBT(nbt[BATTERY_KEY])
super.load(nbt) super.load(nbt)
} }
companion object {
fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList<Component>, flag: TooltipFlag) {
val tag = itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag ?: return
val container = MatteryContainer(1)
tag.map(BATTERY_KEY, container::deserializeNBT)
if (!container[0].isEmpty) {
tooltips.add(TranslatableComponent("otm.item.block.stored_battery", container[0].displayName).withStyle(ChatFormatting.GRAY))
ItemEnergyStorageImpl.appendHoverText(container[0], tooltips)
}
}
}
} }

View File

@ -1,11 +1,16 @@
package ru.dbotthepony.mc.otm.block.entity package ru.dbotthepony.mc.otm.block.entity
import net.minecraft.ChatFormatting
import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.map import ru.dbotthepony.mc.otm.core.map
@ -338,8 +343,7 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
errorTicksAnim == 0 && errorTicksAnim == 0 &&
blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.hasProperty(WorkerState.WORKER_STATE) &&
blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING
) ) {
{
level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
} }
} }
@ -352,5 +356,25 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
companion object { companion object {
const val WORK_TICKS_KEY = "workTicks" const val WORK_TICKS_KEY = "workTicks"
const val JOB_KEY = "job" const val JOB_KEY = "job"
fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList<Component>, flag: TooltipFlag) {
val tag = itemStack.tag ?: return
val subtag = tag.get("BlockEntityTag") as? CompoundTag
if (subtag != null) {
if (subtag.contains(WORK_TICKS_KEY) && !subtag.contains(JOB_KEY)) {
if (subtag.getDouble(WORK_TICKS_KEY) != 0.0)
tooltips.add(TranslatableComponent("otm.item.worker.work_ticks_mono", "%.1f".format(subtag.getDouble(WORK_TICKS_KEY))).withStyle(ChatFormatting.GRAY))
} else if (subtag.contains(WORK_TICKS_KEY) && tag.contains(JOB_KEY)) {
tooltips.add(TranslatableComponent("otm.item.worker.work_ticks",
"%.1f".format(subtag.getDouble(WORK_TICKS_KEY)),
"%.1f".format(Job(subtag.getCompound(JOB_KEY)).ticks)).withStyle(ChatFormatting.GRAY))
}
}
WorkerEnergyStorage.appendHoverText(itemStack, blockGetter, tooltips, flag)
MatteryPoweredBlockEntity.appendHoverText(itemStack, blockGetter, tooltips, flag)
}
} }
} }

View File

@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.block.storage
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.EntityBlock
@ -12,7 +15,9 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.DriveRackBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.DriveRackBlockEntity
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -32,6 +37,17 @@ class DriveRackBlock : RotatableMatteryBlock(), EntityBlock {
return BlockEntityTicker { _, _, _, tile -> if (tile is DriveRackBlockEntity) tile.tick() } return BlockEntityTicker { _, _, _, tile -> if (tile is DriveRackBlockEntity) tile.tick() }
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun getShape( override fun getShape(
p_60555_: BlockState, p_60555_: BlockState,
p_60556_: BlockGetter, p_60556_: BlockGetter,

View File

@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.block.storage
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.BlockPlaceContext import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
@ -16,8 +19,10 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.DriveViewerBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.DriveViewerBlockEntity
import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.block.entity.WorkerState
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -43,6 +48,17 @@ class DriveViewerBlock : RotatableMatteryBlock(), EntityBlock {
builder.add(DRIVE_PRESENT) builder.add(DRIVE_PRESENT)
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState { override fun getStateForPlacement(context: BlockPlaceContext): BlockState {
return super.getStateForPlacement(context)!!.setValue(DRIVE_PRESENT, false) return super.getStateForPlacement(context)!!.setValue(DRIVE_PRESENT, false)
} }

View File

@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.block.storage
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.EntityBlock
@ -12,7 +15,9 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorBlockEntity
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -32,6 +37,17 @@ class ItemMonitorBlock : RotatableMatteryBlock(), EntityBlock {
return BlockEntityTicker { _, _, _, tile -> if (tile is ItemMonitorBlockEntity) tile.tick() } return BlockEntityTicker { _, _, _, tile -> if (tile is ItemMonitorBlockEntity) tile.tick() }
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun getShape( override fun getShape(
p_60555_: BlockState, p_60555_: BlockState,
p_60556_: BlockGetter, p_60556_: BlockGetter,

View File

@ -1,6 +1,9 @@
package ru.dbotthepony.mc.otm.block.storage package ru.dbotthepony.mc.otm.block.storage
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.BlockPlaceContext import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
@ -18,7 +21,9 @@ import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.StorageCableBlock import ru.dbotthepony.mc.otm.block.StorageCableBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.StorageBusBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.StorageBusBlockEntity
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
import ru.dbotthepony.mc.otm.core.unaryMinus import ru.dbotthepony.mc.otm.core.unaryMinus
@ -45,6 +50,17 @@ class StorageBusBlock : RotatableMatteryBlock(), EntityBlock {
return super.getStateForPlacement(context)?.setValue(FACING_FULL, -context.clickedFace) return super.getStateForPlacement(context)?.setValue(FACING_FULL, -context.clickedFace)
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) { override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder) super.createBlockStateDefinition(builder)

View File

@ -1,6 +1,9 @@
package ru.dbotthepony.mc.otm.block.storage package ru.dbotthepony.mc.otm.block.storage
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.item.context.BlockPlaceContext import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
@ -18,8 +21,10 @@ import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.CableBlock
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.StorageCableBlock import ru.dbotthepony.mc.otm.block.StorageCableBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.StorageExporterBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.StorageExporterBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.StorageImporterBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.StorageImporterBlockEntity
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
import ru.dbotthepony.mc.otm.core.unaryMinus import ru.dbotthepony.mc.otm.core.unaryMinus
@ -70,6 +75,17 @@ class StorageImporterBlock : RotatableMatteryBlock(), EntityBlock {
return super.getStateForPlacement(context)?.setValue(FACING_FULL, -context.clickedFace) return super.getStateForPlacement(context)?.setValue(FACING_FULL, -context.clickedFace)
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
private val shapes = getShapeForEachState { private val shapes = getShapeForEachState {
val shapes = StorageCableBlock.getShapeFor(it) val shapes = StorageCableBlock.getShapeFor(it)
var finalShape = shapes[0] var finalShape = shapes[0]
@ -146,6 +162,17 @@ class StorageExporterBlock : RotatableMatteryBlock(), EntityBlock {
) )
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun <T : BlockEntity?> getTicker( override fun <T : BlockEntity?> getTicker(
p_153212_: Level, p_153212_: Level,
p_153213_: BlockState, p_153213_: BlockState,

View File

@ -2,6 +2,9 @@ package ru.dbotthepony.mc.otm.block.storage
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.EntityBlock
@ -12,7 +15,9 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.StoragePowerSupplierBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.StoragePowerSupplierBlockEntity
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.shapes.BlockShapes import ru.dbotthepony.mc.otm.shapes.BlockShapes
@ -32,6 +37,17 @@ class StoragePowerSupplierBlock : RotatableMatteryBlock(), EntityBlock {
return BlockEntityTicker { _, _, _, tile -> if (tile is StoragePowerSupplierBlockEntity) tile.tick() } return BlockEntityTicker { _, _, _, tile -> if (tile is StoragePowerSupplierBlockEntity) tile.tick() }
} }
override fun appendHoverText(
p_49816_: ItemStack,
p_49817_: BlockGetter?,
p_49818_: MutableList<Component>,
p_49819_: TooltipFlag
) {
super.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
WorkerEnergyStorage.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
MatteryPoweredBlockEntity.appendHoverText(p_49816_, p_49817_, p_49818_, p_49819_)
}
override fun getShape( override fun getShape(
p_60555_: BlockState, p_60555_: BlockState,
p_60556_: BlockGetter, p_60556_: BlockGetter,

View File

@ -3,38 +3,110 @@
package ru.dbotthepony.mc.otm.capability package ru.dbotthepony.mc.otm.capability
import net.minecraft.ChatFormatting
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.network.chat.Component
import net.minecraft.world.item.BlockItem
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.TooltipFlag
import net.minecraft.world.level.BlockGetter
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraftforge.common.capabilities.Capability import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.capabilities.ICapabilityProvider import net.minecraftforge.common.capabilities.ICapabilityProvider
import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.IEnergyStorage
import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.compat.mekanism.Mattery2MekanismEnergyWrapper import ru.dbotthepony.mc.otm.compat.mekanism.Mattery2MekanismEnergyWrapper
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.ifHas import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.formatPower
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.map import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.core.tagNotNull import ru.dbotthepony.mc.otm.core.tagNotNull
private enum class EnergyFlow { sealed interface IEnergyStorageImpl {
INPUT, OUTPUT, BI_DIRECTIONAL val maxInput: ImpreciseFraction?
val maxOutput: ImpreciseFraction?
val direction: FlowDirection
}
private fun batteryLevel(it: IEnergyStorage, tooltips: MutableList<Component>) {
tooltips.add(TranslatableComponent(
"otm.item.power.storage",
it.energyStored.formatPower(),
it.maxEnergyStored.formatPower()
).withStyle(ChatFormatting.GRAY))
}
private fun batteryLevel(it: IMatteryEnergyStorage, tooltips: MutableList<Component>) {
tooltips.add(TranslatableComponent(
"otm.item.power.storage",
it.batteryLevel.formatPower(),
it.maxBatteryLevel.formatPower()
).withStyle(ChatFormatting.GRAY))
if (it is IEnergyStorageImpl) {
when (it.direction) {
FlowDirection.INPUT -> {
if (it.maxInput != null) {
tooltips.add(TranslatableComponent("otm.item.power.throughput_mono", it.maxInput!!.formatPower()).withStyle(ChatFormatting.GRAY))
} else {
tooltips.add(TranslatableComponent("otm.item.power.throughput_mono", TranslatableComponent("item.power.infinity").withStyle(ChatFormatting.GRAY)).withStyle(ChatFormatting.GRAY))
}
}
FlowDirection.OUTPUT -> {
if (it.maxOutput != null) {
tooltips.add(TranslatableComponent("otm.item.power.throughput_mono", it.maxOutput!!.formatPower()).withStyle(ChatFormatting.GRAY))
} else {
tooltips.add(TranslatableComponent("otm.item.power.throughput_mono", TranslatableComponent("item.power.infinity").withStyle(ChatFormatting.GRAY)).withStyle(ChatFormatting.GRAY))
}
}
FlowDirection.BI_DIRECTIONAL -> {
val maxInput = it.maxInput
val maxOutput = it.maxOutput
if (maxInput != null && maxOutput != null) {
tooltips.add(TranslatableComponent("otm.item.power.throughput", maxInput.formatPower(), maxOutput.formatPower()).withStyle(ChatFormatting.GRAY))
} else if (maxInput != null) {
tooltips.add(TranslatableComponent("otm.item.power.throughput",
maxInput.formatPower(),
TranslatableComponent("item.power.infinity").withStyle(ChatFormatting.GRAY)
).withStyle(ChatFormatting.GRAY))
} else if (maxOutput != null) {
tooltips.add(TranslatableComponent("otm.item.power.throughput",
TranslatableComponent("item.power.infinity").withStyle(ChatFormatting.GRAY),
maxOutput.formatPower(),
).withStyle(ChatFormatting.GRAY))
} else {
tooltips.add(TranslatableComponent("otm.item.power.throughput",
TranslatableComponent("item.power.infinity").withStyle(ChatFormatting.GRAY),
TranslatableComponent("item.power.infinity").withStyle(ChatFormatting.GRAY),
).withStyle(ChatFormatting.GRAY))
}
}
}
}
} }
sealed class ItemEnergyStorageImpl( sealed class ItemEnergyStorageImpl(
private val direction: EnergyFlow, final override val direction: FlowDirection,
protected val itemStack: ItemStack, protected val itemStack: ItemStack,
maxBatteryLevel: ImpreciseFraction, maxBatteryLevel: ImpreciseFraction,
maxInput: ImpreciseFraction?, maxInput: ImpreciseFraction?,
maxOutput: ImpreciseFraction?, maxOutput: ImpreciseFraction?,
val initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO val initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO
) : IMatteryEnergyStorage, ICapabilityProvider { ) : IMatteryEnergyStorage, ICapabilityProvider, IEnergyStorageImpl {
var maxInput: ImpreciseFraction? = maxInput final override var maxInput: ImpreciseFraction? = maxInput
protected set protected set
var maxOutput: ImpreciseFraction? = maxOutput final override var maxOutput: ImpreciseFraction? = maxOutput
protected set protected set
private val resolver = LazyOptional.of { this } private val resolver = LazyOptional.of { this }
@ -54,20 +126,20 @@ sealed class ItemEnergyStorageImpl(
protected set protected set
override var batteryLevel: ImpreciseFraction override var batteryLevel: ImpreciseFraction
get() = itemStack.tag?.map(NBT_KEY, ImpreciseFraction::deserializeNBT) ?: initialBatteryLevel get() = itemStack.tag?.map(ENERGY_KEY, ImpreciseFraction::deserializeNBT) ?: initialBatteryLevel
protected set(value) { protected set(value) {
itemStack.tagNotNull[NBT_KEY] = value.serializeNBT() itemStack.tagNotNull[ENERGY_KEY] = value.serializeNBT()
} }
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (direction == EnergyFlow.INPUT) if (direction == FlowDirection.INPUT)
return ImpreciseFraction.ZERO return ImpreciseFraction.ZERO
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (direction == EnergyFlow.OUTPUT) if (direction == FlowDirection.OUTPUT)
return ImpreciseFraction.ZERO return ImpreciseFraction.ZERO
return receiveEnergyInner(howMuch, simulate) return receiveEnergyInner(howMuch, simulate)
@ -128,15 +200,29 @@ sealed class ItemEnergyStorageImpl(
} }
override fun canExtract(): Boolean { override fun canExtract(): Boolean {
return direction != EnergyFlow.INPUT return direction != FlowDirection.INPUT
} }
override fun canReceive(): Boolean { override fun canReceive(): Boolean {
return direction != EnergyFlow.OUTPUT return direction != FlowDirection.OUTPUT
} }
companion object { companion object {
const val NBT_KEY = "energy" const val ENERGY_KEY = "energy"
fun appendHoverText(itemStack: ItemStack, level: Level?, tooltips: MutableList<Component>, flag: TooltipFlag) {
appendHoverText(itemStack, tooltips)
}
fun appendHoverText(itemStack: ItemStack, tooltips: MutableList<Component>) {
val energy = itemStack.energy ?: return
if (energy is IMatteryEnergyStorage) {
batteryLevel(energy, tooltips)
} else {
batteryLevel(energy, tooltips)
}
}
} }
} }
@ -146,7 +232,7 @@ open class EnergyConsumerItem(
maxInput: ImpreciseFraction? = null, maxInput: ImpreciseFraction? = null,
maxOutput: ImpreciseFraction? = maxInput, maxOutput: ImpreciseFraction? = maxInput,
initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO
) : ItemEnergyStorageImpl(EnergyFlow.INPUT, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel) ) : ItemEnergyStorageImpl(FlowDirection.INPUT, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel)
open class EnergyProducerItem( open class EnergyProducerItem(
stack: ItemStack, stack: ItemStack,
@ -154,7 +240,7 @@ open class EnergyProducerItem(
maxInput: ImpreciseFraction? = null, maxInput: ImpreciseFraction? = null,
maxOutput: ImpreciseFraction? = maxInput, maxOutput: ImpreciseFraction? = maxInput,
initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO
) : ItemEnergyStorageImpl(EnergyFlow.OUTPUT, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel) ) : ItemEnergyStorageImpl(FlowDirection.OUTPUT, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel)
open class EnergyCapacitorItem( open class EnergyCapacitorItem(
stack: ItemStack, stack: ItemStack,
@ -162,30 +248,45 @@ open class EnergyCapacitorItem(
maxInput: ImpreciseFraction? = null, maxInput: ImpreciseFraction? = null,
maxOutput: ImpreciseFraction? = maxInput, maxOutput: ImpreciseFraction? = maxInput,
initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO initialBatteryLevel: ImpreciseFraction = ImpreciseFraction.ZERO
) : ItemEnergyStorageImpl(EnergyFlow.BI_DIRECTIONAL, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel) ) : ItemEnergyStorageImpl(FlowDirection.BI_DIRECTIONAL, stack, maxBatteryLevel, maxInput, maxOutput, initialBatteryLevel)
sealed class BlockEnergyStorageImpl constructor( sealed class BlockEnergyStorageImpl constructor(
protected val listener: () -> Unit, protected val listener: () -> Unit,
private val direction: EnergyFlow, final override val direction: FlowDirection,
maxBatteryLevel: ImpreciseFraction, maxBatteryLevel: ImpreciseFraction,
protected var maxInput: ImpreciseFraction?, maxInput: ImpreciseFraction?,
protected var maxOutput: ImpreciseFraction? maxOutput: ImpreciseFraction?,
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> { ) : IMatteryEnergyStorage, INBTSerializable<CompoundTag>, IEnergyStorageImpl {
override var maxBatteryLevel: ImpreciseFraction = maxBatteryLevel final override var maxInput: ImpreciseFraction? = maxInput
protected set protected set
final override var maxOutput: ImpreciseFraction? = maxOutput
protected set
override var maxBatteryLevel: ImpreciseFraction = maxBatteryLevel
protected set(value) {
if (value != field) {
field = value
listener.invoke()
}
}
override var batteryLevel = ImpreciseFraction.ZERO override var batteryLevel = ImpreciseFraction.ZERO
protected set protected set(value) {
if (value != field) {
field = value
listener.invoke()
}
}
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (direction == EnergyFlow.INPUT) if (direction == FlowDirection.INPUT)
return ImpreciseFraction.ZERO return ImpreciseFraction.ZERO
return extractEnergyInner(howMuch, simulate) return extractEnergyInner(howMuch, simulate)
} }
override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
if (direction == EnergyFlow.OUTPUT) if (direction == FlowDirection.OUTPUT)
return ImpreciseFraction.ZERO return ImpreciseFraction.ZERO
return receiveEnergyInner(howMuch, simulate) return receiveEnergyInner(howMuch, simulate)
@ -211,7 +312,6 @@ sealed class BlockEnergyStorageImpl constructor(
if (!simulate && batteryLevel != newLevel) { if (!simulate && batteryLevel != newLevel) {
batteryLevel = newLevel batteryLevel = newLevel
listener.invoke()
} }
return diff return diff
@ -237,36 +337,35 @@ sealed class BlockEnergyStorageImpl constructor(
if (!simulate && batteryLevel != newLevel) { if (!simulate && batteryLevel != newLevel) {
batteryLevel = newLevel batteryLevel = newLevel
listener.invoke()
} }
return diff return diff
} }
override fun canExtract(): Boolean { override fun canExtract(): Boolean {
return direction != EnergyFlow.INPUT return direction != FlowDirection.INPUT
} }
override fun canReceive(): Boolean { override fun canReceive(): Boolean {
return direction != EnergyFlow.OUTPUT return direction != FlowDirection.OUTPUT
} }
override fun serializeNBT(): CompoundTag { override fun serializeNBT(): CompoundTag {
val tag = CompoundTag() val tag = CompoundTag()
tag["energy_stored"] = batteryLevel.serializeNBT() tag[ENERGY_STORED_KEY] = batteryLevel.serializeNBT()
tag["energy_stored_max"] = maxBatteryLevel.serializeNBT() tag[ENERGY_STORED_MAX_KEY] = maxBatteryLevel.serializeNBT()
maxInput?.let { tag["max_input"] = it.serializeNBT() } maxInput?.let { tag[MAX_INPUT_KEY] = it.serializeNBT() }
maxOutput?.let { tag["max_output"] = it.serializeNBT() } maxOutput?.let { tag[MAX_OUTPUT_KEY] = it.serializeNBT() }
return tag return tag
} }
override fun deserializeNBT(nbt: CompoundTag) { override fun deserializeNBT(nbt: CompoundTag) {
nbt.ifHas("energy_stored") { batteryLevel = ImpreciseFraction.deserializeNBT(it) } batteryLevel = nbt.map(ENERGY_STORED_KEY, ImpreciseFraction.Companion::deserializeNBT) ?: ImpreciseFraction.ZERO
nbt.ifHas("energy_stored_max") { maxBatteryLevel = ImpreciseFraction.deserializeNBT(it) } maxBatteryLevel = nbt.map(ENERGY_STORED_MAX_KEY, ImpreciseFraction.Companion::deserializeNBT) ?: ImpreciseFraction.ZERO
nbt.ifHas("max_input") { maxInput = ImpreciseFraction.deserializeNBT(it) } maxInput = nbt.map(MAX_INPUT_KEY, ImpreciseFraction.Companion::deserializeNBT)
nbt.ifHas("max_output") { maxOutput = ImpreciseFraction.deserializeNBT(it) } maxOutput = nbt.map(MAX_OUTPUT_KEY, ImpreciseFraction.Companion::deserializeNBT)
} }
var resolver: LazyOptional<IMatteryEnergyStorage> = LazyOptional.of { this } var resolver: LazyOptional<IMatteryEnergyStorage> = LazyOptional.of { this }
@ -283,6 +382,11 @@ sealed class BlockEnergyStorageImpl constructor(
companion object { companion object {
val DEFAULT_MAX_IO = ImpreciseFraction(200) val DEFAULT_MAX_IO = ImpreciseFraction(200)
val DEFAULT_MAX_CAPACITY = ImpreciseFraction(60_000) val DEFAULT_MAX_CAPACITY = ImpreciseFraction(60_000)
const val ENERGY_STORED_KEY = "energy_stored"
const val ENERGY_STORED_MAX_KEY = "energy_stored_max"
const val MAX_INPUT_KEY = "max_input"
const val MAX_OUTPUT_KEY = "max_output"
} }
} }
@ -291,12 +395,25 @@ open class WorkerEnergyStorage(
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction? = DEFAULT_MAX_IO, maxInput: ImpreciseFraction? = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction? = maxInput maxOutput: ImpreciseFraction? = maxInput
) : BlockEnergyStorageImpl(listener, EnergyFlow.INPUT, maxBatteryLevel, maxInput, maxOutput) { ) : BlockEnergyStorageImpl(listener, FlowDirection.INPUT, maxBatteryLevel, maxInput, maxOutput) {
constructor( constructor(
listener: BlockEntity, listener: BlockEntity,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction? = DEFAULT_MAX_IO, maxInput: ImpreciseFraction? = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction? = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput) maxOutput: ImpreciseFraction? = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput)
companion object {
fun appendHoverText(itemStack: ItemStack, tooltips: MutableList<Component>) {
val tag = (itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?.get(MatteryBlockEntity.ENERGY_KEY) as? CompoundTag ?: return
val cap = WorkerEnergyStorage({})
cap.deserializeNBT(tag)
batteryLevel(cap, tooltips)
}
fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList<Component>, flag: TooltipFlag) {
return appendHoverText(itemStack, tooltips)
}
}
} }
open class GeneratorEnergyStorage( open class GeneratorEnergyStorage(
@ -304,12 +421,25 @@ open class GeneratorEnergyStorage(
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction? = DEFAULT_MAX_IO, maxInput: ImpreciseFraction? = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction? = maxInput maxOutput: ImpreciseFraction? = maxInput
) : BlockEnergyStorageImpl(listener, EnergyFlow.OUTPUT, maxBatteryLevel, maxInput, maxOutput) { ) : BlockEnergyStorageImpl(listener, FlowDirection.OUTPUT, maxBatteryLevel, maxInput, maxOutput) {
constructor( constructor(
listener: BlockEntity, listener: BlockEntity,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction? = DEFAULT_MAX_IO, maxInput: ImpreciseFraction? = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction? = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput) maxOutput: ImpreciseFraction? = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput)
companion object {
fun appendHoverText(itemStack: ItemStack, tooltips: MutableList<Component>) {
val tag = (itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?.get(MatteryBlockEntity.ENERGY_KEY) as? CompoundTag ?: return
val cap = GeneratorEnergyStorage({})
cap.deserializeNBT(tag)
batteryLevel(cap, tooltips)
}
fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList<Component>, flag: TooltipFlag) {
return appendHoverText(itemStack, tooltips)
}
}
} }
open class CapacitorEnergyStorage( open class CapacitorEnergyStorage(
@ -317,10 +447,23 @@ open class CapacitorEnergyStorage(
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction? = DEFAULT_MAX_IO, maxInput: ImpreciseFraction? = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction? = maxInput maxOutput: ImpreciseFraction? = maxInput
) : BlockEnergyStorageImpl(listener, EnergyFlow.BI_DIRECTIONAL, maxBatteryLevel, maxInput, maxOutput) { ) : BlockEnergyStorageImpl(listener, FlowDirection.BI_DIRECTIONAL, maxBatteryLevel, maxInput, maxOutput) {
constructor( constructor(
listener: BlockEntity, listener: BlockEntity,
maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY, maxBatteryLevel: ImpreciseFraction = DEFAULT_MAX_CAPACITY,
maxInput: ImpreciseFraction? = DEFAULT_MAX_IO, maxInput: ImpreciseFraction? = DEFAULT_MAX_IO,
maxOutput: ImpreciseFraction? = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput) maxOutput: ImpreciseFraction? = maxInput) : this({listener.setChanged()}, maxBatteryLevel, maxInput, maxOutput)
companion object {
fun appendHoverText(itemStack: ItemStack, tooltips: MutableList<Component>) {
val tag = (itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?.get(MatteryBlockEntity.ENERGY_KEY) as? CompoundTag ?: return
val cap = CapacitorEnergyStorage({})
cap.deserializeNBT(tag)
batteryLevel(cap, tooltips)
}
fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList<Component>, flag: TooltipFlag) {
return appendHoverText(itemStack, tooltips)
}
}
} }

View File

@ -0,0 +1,5 @@
package ru.dbotthepony.mc.otm.capability
enum class FlowDirection {
INPUT, OUTPUT, BI_DIRECTIONAL
}

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.core
import com.google.common.collect.ImmutableList import com.google.common.collect.ImmutableList
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.network.chat.MutableComponent
import java.math.BigDecimal import java.math.BigDecimal
import java.math.BigInteger import java.math.BigInteger
@ -91,6 +92,9 @@ enum class SiPrefix(
val impreciseFraction = ImpreciseFraction(string) val impreciseFraction = ImpreciseFraction(string)
val integer = if (!fractional) BigInteger(string) else null val integer = if (!fractional) BigInteger(string) else null
val long = if (!fractional) string.toLongOrNull() else null
val int = if (!fractional) string.toIntOrNull() else null
companion object { companion object {
val MULTIPLIES: List<SiPrefix> = ImmutableList.builder<SiPrefix>() val MULTIPLIES: List<SiPrefix> = ImmutableList.builder<SiPrefix>()
.add(KILO) .add(KILO)
@ -310,12 +314,44 @@ fun ImpreciseFraction.determineSiPrefix(): SiPrefix? {
return prev return prev
} }
fun Int.determineSiPrefix(): SiPrefix? {
if (this == 0) {
return null
}
var num = this
if (this < 0) {
num = -this
}
var prev: SiPrefix? = null
if (num >= 1) {
for (value in SiPrefix.MULTIPLIES) {
if (value.int != null && value.int <= num) {
prev = value
} else {
break
}
}
}
return prev
}
fun ImpreciseFraction.formatSi(decimalPlaces: Int = 2): String { fun ImpreciseFraction.formatSi(decimalPlaces: Int = 2): String {
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" } require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
val prefix = determineSiPrefix() ?: return toString(decimalPlaces) val prefix = determineSiPrefix() ?: return toString(decimalPlaces)
return (this / prefix.impreciseFraction).toString(decimalPlaces) + prefix.symbol return (this / prefix.impreciseFraction).toString(decimalPlaces) + prefix.symbol
} }
fun Int.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 2): Component {
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
val prefix = determineSiPrefix() ?: return if (suffix == "") TextComponent(toString()) else if (suffix is Component) TextComponent(toString() + " " + suffix.string) else TextComponent(toString() + " " + suffix)
return TranslatableComponent(prefix.formatLocaleKey, "%f.$decimalPlaces".format(this.toFloat() / prefix.int!!.toFloat()), suffix)
}
fun ImpreciseFraction.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 2): Component { fun ImpreciseFraction.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 2): Component {
require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" } require(decimalPlaces >= 0) { "Invalid amount of decimal places required: $decimalPlaces" }
val prefix = determineSiPrefix() ?: return if (suffix == "") TextComponent(toString(decimalPlaces)) else if (suffix is Component) TextComponent(toString(decimalPlaces) + " " + suffix.string) else TextComponent(toString(decimalPlaces) + " " + suffix) val prefix = determineSiPrefix() ?: return if (suffix == "") TextComponent(toString(decimalPlaces)) else if (suffix is Component) TextComponent(toString(decimalPlaces) + " " + suffix.string) else TextComponent(toString(decimalPlaces) + " " + suffix)
@ -325,6 +361,8 @@ fun ImpreciseFraction.formatSiComponent(suffix: Any = "", decimalPlaces: Int = 2
val POWER_NAME = TranslatableComponent("otm.gui.power.name") val POWER_NAME = TranslatableComponent("otm.gui.power.name")
val MATTER_NAME = TranslatableComponent("otm.gui.matter.name") val MATTER_NAME = TranslatableComponent("otm.gui.matter.name")
fun Int.formatPower(decimalPlaces: Int = 2) = formatSiComponent(POWER_NAME, decimalPlaces)
fun ImpreciseFraction.formatPower(decimalPlaces: Int = 2) = formatSiComponent(POWER_NAME, decimalPlaces) fun ImpreciseFraction.formatPower(decimalPlaces: Int = 2) = formatSiComponent(POWER_NAME, decimalPlaces)
fun ImpreciseFraction.formatMatter(decimalPlaces: Int = 2) = formatSiComponent(MATTER_NAME, decimalPlaces) fun ImpreciseFraction.formatMatter(decimalPlaces: Int = 2) = formatSiComponent(MATTER_NAME, decimalPlaces)
fun ImpreciseFraction.formatMatterFull(decimalPlaces: Int = 2) = TranslatableComponent("otm.gui.matter.format", formatSiComponent(MATTER_NAME, decimalPlaces)) fun ImpreciseFraction.formatMatterFull(decimalPlaces: Int = 2) = TranslatableComponent("otm.gui.matter.format", formatSiComponent(MATTER_NAME, decimalPlaces))

View File

@ -11,8 +11,8 @@ import net.minecraftforge.registries.ForgeRegistries
import net.minecraftforge.registries.IForgeRegistry import net.minecraftforge.registries.IForgeRegistry
// 1.19 being 1.19 // 1.19 being 1.19
fun TranslatableComponent(key: String, vararg values: Any) = MutableComponent.create(TranslatableContents(key, *values)) fun TranslatableComponent(key: String, vararg values: Any): MutableComponent = MutableComponent.create(TranslatableContents(key, *values))
fun TextComponent(value: String) = MutableComponent.create(LiteralContents(value)) fun TextComponent(value: String): MutableComponent = MutableComponent.create(LiteralContents(value))
fun <T> IForgeRegistry<T>.getKeyNullable(value: T): ResourceLocation? { fun <T> IForgeRegistry<T>.getKeyNullable(value: T): ResourceLocation? {
val key = getResourceKey(value) val key = getResourceKey(value)

View File

@ -100,21 +100,7 @@ open class BatteryItem : Item {
p_41423_.add(INFINITE_STORAGE) p_41423_.add(INFINITE_STORAGE)
p_41423_.add(TranslatableComponent("otm.item.power.infinite.throughput").withStyle(ChatFormatting.GRAY)) p_41423_.add(TranslatableComponent("otm.item.power.infinite.throughput").withStyle(ChatFormatting.GRAY))
} else { } else {
stack.getCapability(MatteryCapability.ENERGY).ifPresentK { ItemEnergyStorageImpl.appendHoverText(stack, p_41423_)
p_41423_.add(
TranslatableComponent(
"otm.item.power.normal.storage",
it.batteryLevel.formatPower(),
it.maxBatteryLevel.formatPower()
).withStyle(ChatFormatting.GRAY)
)
}
p_41423_.add(TranslatableComponent(
"otm.item.power.normal.throughput",
receive.formatPower(),
extract.formatPower()
).withStyle(ChatFormatting.GRAY))
} }
} }

View File

@ -337,10 +337,11 @@ class QuantumBatteryItem : Item {
if (isCreative) { if (isCreative) {
components.add(TranslatableComponent("otm.item.quantum_battery.creative_power", power.batteryLevel.formatPower()).withStyle(ChatFormatting.GRAY)) components.add(TranslatableComponent("otm.item.quantum_battery.creative_power", power.batteryLevel.formatPower()).withStyle(ChatFormatting.GRAY))
} else { } else {
components.add(TranslatableComponent("otm.item.power.normal.storage", power.batteryLevel.formatPower(), capacity!!.formatPower()).withStyle(ChatFormatting.GRAY)) components.add(TranslatableComponent("otm.item.power.storage", power.batteryLevel.formatPower(), capacity!!.formatPower()).withStyle(ChatFormatting.GRAY))
components.add( components.add(
TranslatableComponent( TranslatableComponent(
"otm.item.power.normal.throughput", "otm.item.power.throughput",
throughput!!.formatPower(), throughput!!.formatPower(),
throughput.formatPower() throughput.formatPower()
).withStyle(ChatFormatting.GRAY)) ).withStyle(ChatFormatting.GRAY))

View File

@ -19,8 +19,6 @@ open class SingleUseBatteryItem(
val throughput: ImpreciseFraction? = null, val throughput: ImpreciseFraction? = null,
properties: Properties = Properties().stacksTo(1).tab(OverdriveThatMatters.INSTANCE.CREATIVE_TAB) properties: Properties = Properties().stacksTo(1).tab(OverdriveThatMatters.INSTANCE.CREATIVE_TAB)
) : Item(properties) { ) : Item(properties) {
private val throughputText = throughput?.let { TranslatableComponent("otm.item.power.output_only", it.formatPower()).withStyle(ChatFormatting.GRAY) }
override fun appendHoverText( override fun appendHoverText(
itemStack: ItemStack, itemStack: ItemStack,
p_41422_: Level?, p_41422_: Level?,
@ -28,20 +26,8 @@ open class SingleUseBatteryItem(
p_41424_: TooltipFlag p_41424_: TooltipFlag
) { ) {
super.appendHoverText(itemStack, p_41422_, list, p_41424_) super.appendHoverText(itemStack, p_41422_, list, p_41424_)
list.add(SINGLE_USE) list.add(SINGLE_USE)
ItemEnergyStorageImpl.appendHoverText(itemStack, list)
if (throughputText != null) {
list.add(throughputText)
}
itemStack.getCapability(MatteryCapability.ENERGY).ifPresentK {
list.add(TranslatableComponent(
"otm.item.power.normal.storage",
it.batteryLevel.formatPower(),
it.maxBatteryLevel.formatPower()
).withStyle(ChatFormatting.GRAY))
}
} }
override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider { override fun initCapabilities(stack: ItemStack, nbt: CompoundTag?): ICapabilityProvider {

View File

@ -6,9 +6,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.inventory.CraftingContainer import net.minecraft.world.inventory.CraftingContainer
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.crafting.CraftingRecipe import net.minecraft.world.item.crafting.CraftingRecipe
import net.minecraft.world.item.crafting.Recipe
import net.minecraft.world.item.crafting.RecipeSerializer import net.minecraft.world.item.crafting.RecipeSerializer
import net.minecraft.world.item.crafting.RecipeType
import net.minecraft.world.item.crafting.ShapedRecipe import net.minecraft.world.item.crafting.ShapedRecipe
import net.minecraft.world.level.Level import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.capability.ItemEnergyStorageImpl import ru.dbotthepony.mc.otm.capability.ItemEnergyStorageImpl
@ -30,7 +28,7 @@ class EnergyContainerRecipe(
.findAny().orElse(null) .findAny().orElse(null)
if (battery != null) { if (battery != null) {
itemStack.tagNotNull[ItemEnergyStorageImpl.NBT_KEY] = battery.batteryLevel.serializeNBT() itemStack.tagNotNull[ItemEnergyStorageImpl.ENERGY_KEY] = battery.batteryLevel.serializeNBT()
} }
return itemStack return itemStack

View File

@ -30,6 +30,8 @@ protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_9
protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97723_ # doubleclick protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97723_ # doubleclick
protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97724_ # lastQuickMoved protected net.minecraft.client.gui.screens.inventory.AbstractContainerScreen f_97724_ # lastQuickMoved
public net.minecraft.world.item.BlockItem f_150696_ # BLOCK_ENTITY_TAG
public net.minecraft.client.gui.screens.InBedChatScreen f_242488_ # leaveBedButton public net.minecraft.client.gui.screens.InBedChatScreen f_242488_ # leaveBedButton
public net.minecraft.world.inventory.AbstractContainerMenu f_182405_ # stateId public net.minecraft.world.inventory.AbstractContainerMenu f_182405_ # stateId