From e3bc9e226f7fc2bccd0b92982b1067ebbc4207cc Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 27 Jun 2023 19:14:10 +0700 Subject: [PATCH] Wireless android charger and misc fixes --- .../mc/otm/datagen/lang/English.kt | 2 + .../mc/otm/datagen/lang/Russian.kt | 1 + .../mc/otm/datagen/loot/LootTablesData.kt | 1 + .../dbotthepony/mc/otm/datagen/tags/Tags.kt | 1 + .../block/entity/MatteryDeviceBlockEntity.kt | 81 +++++++---- .../block/entity/MatteryPoweredBlockEntity.kt | 2 +- .../entity/tech/AndroidChargerBlockEntity.kt | 52 +++++++ .../entity/tech/BatteryBankBlockEntity.kt | 2 +- .../entity/tech/EnergyServoBlockEntity.kt | 1 + .../mc/otm/block/tech/AndroidChargerBlock.kt | 135 ++++++++++++++++++ .../energy/BlockEnergyStorageImpl.kt | 6 +- .../capability/energy/IEnergyStorageImpl.kt | 21 ++- .../client/screen/panels/button/Buttons.kt | 18 ++- .../screen/tech/AndroidChargerScreen.kt | 47 ++++++ .../client/screen/tech/EnergyServoScreen.kt | 18 +-- .../mc/otm/config/MachinesConfig.kt | 12 ++ .../mc/otm/container/MatteryContainer.kt | 6 +- .../ru/dbotthepony/mc/otm/core/LevelExt.kt | 26 ++-- .../otm/menu/input/EnergyConfigPlayerInput.kt | 15 +- .../otm/menu/input/EnumInputWithFeedback.kt | 8 +- .../mc/otm/menu/tech/AndroidChargerMenu.kt | 21 +++ .../mc/otm/menu/tech/BatteryBankMenu.kt | 2 +- .../mc/otm/registry/MBlockEntities.kt | 1 + .../ru/dbotthepony/mc/otm/registry/MBlocks.kt | 2 + .../ru/dbotthepony/mc/otm/registry/MItems.kt | 3 +- .../ru/dbotthepony/mc/otm/registry/MMenus.kt | 4 + .../ru/dbotthepony/mc/otm/registry/MNames.kt | 1 + 27 files changed, 402 insertions(+), 87 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidChargerBlock.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index 1af4b870d..4898a13e3 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -226,6 +226,7 @@ private fun misc(provider: MatteryLanguageProvider) { misc("item.power.last_tick", "Last tick: %s") misc("item.power.storage", "Stored energy: %s / %s") + misc("item.power.storage0", "Stored energy: %s") misc("item.power.throughput", "Max I/O: %s / %s") misc("item.power.throughput_mono", "Max I/O: %s") misc("item.power.infinity", "∞ MtJ") @@ -362,6 +363,7 @@ private fun death(provider: MatteryLanguageProvider) { private fun blocks(provider: MatteryLanguageProvider) { with(provider.english) { add(MBlocks.ANDROID_STATION, "Android Station") + add(MBlocks.ANDROID_CHARGER, "Wireless Android Charger") add(MBlocks.BATTERY_BANK, "Battery Bank") add(MBlocks.MATTER_DECOMPOSER, "Matter Decomposer") add(MBlocks.MATTER_CAPACITOR_BANK, "Matter Capacitor Bank") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt index a2c5111a1..166f337bc 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/Russian.kt @@ -367,6 +367,7 @@ private fun death(provider: MatteryLanguageProvider) { private fun blocks(provider: MatteryLanguageProvider) { with(provider.russian) { add(MBlocks.ANDROID_STATION, "Станция андроидов") + add(MBlocks.ANDROID_CHARGER, "Беспроводной зарядник андроидов") add(MBlocks.BATTERY_BANK, "Банк аккумуляторов") add(MBlocks.MATTER_DECOMPOSER, "Декомпозитор материи") add(MBlocks.MATTER_CAPACITOR_BANK, "Банк накопителей материи") diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt index 3817e4fe7..971a5b63f 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/loot/LootTablesData.kt @@ -137,6 +137,7 @@ fun addLootTables(lootTables: LootTables) { lootTables.tile(MBlocks.HOLO_SIGN, "isLocked") lootTables.tile(MBlocks.STORAGE_CABLE) lootTables.tile(MBlocks.ANDROID_STATION) + lootTables.tile(MBlocks.ANDROID_CHARGER) lootTables.tile(MBlocks.BATTERY_BANK) lootTables.tile(MBlocks.DRIVE_VIEWER) diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt index 08f622e84..9932f8709 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/tags/Tags.kt @@ -180,6 +180,7 @@ fun addTags(tagsProvider: TagsProvider) { MBlocks.ESSENCE_STORAGE, MBlocks.MATTER_RECONSTRUCTOR, MBlocks.FLUID_TANK, + MBlocks.ANDROID_CHARGER, ), Tiers.IRON) tagsProvider.requiresPickaxe(MBlocks.TRITANIUM_ANVIL, Tiers.IRON) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt index 44ed68d03..18f816e35 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryDeviceBlockEntity.kt @@ -32,7 +32,6 @@ import ru.dbotthepony.mc.otm.core.math.Decimal import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.nbt.getJson import ru.dbotthepony.mc.otm.core.nbt.putJson -import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.util.ITickable import ru.dbotthepony.mc.otm.once @@ -235,27 +234,51 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo } inner class ConfigurableEnergy( - val capability: T, + val energy: T, - val possibleModes: FlowDirection = capability.energyFlow, + val modesFront: FlowDirection = energy.energyFlow, + val modesBack: FlowDirection = energy.energyFlow, + val modesLeft: FlowDirection = energy.energyFlow, + val modesRight: FlowDirection = energy.energyFlow, + val modesTop: FlowDirection = energy.energyFlow, + val modesBottom: FlowDirection = energy.energyFlow, - val frontDefault: FlowDirection = possibleModes, - val backDefault: FlowDirection = possibleModes, - val leftDefault: FlowDirection = possibleModes, - val rightDefault: FlowDirection = possibleModes, - val topDefault: FlowDirection = possibleModes, - val bottomDefault: FlowDirection = possibleModes, + val frontDefault: FlowDirection = modesFront, + val backDefault: FlowDirection = modesBack, + val leftDefault: FlowDirection = modesLeft, + val rightDefault: FlowDirection = modesRight, + val topDefault: FlowDirection = modesTop, + val bottomDefault: FlowDirection = modesBottom, ) { + constructor( + energy: T, + possibleModes: FlowDirection, + frontDefault: FlowDirection = possibleModes, + backDefault: FlowDirection = possibleModes, + leftDefault: FlowDirection = possibleModes, + rightDefault: FlowDirection = possibleModes, + topDefault: FlowDirection = possibleModes, + bottomDefault: FlowDirection = possibleModes, + ) : this( + energy, + modesFront = possibleModes, frontDefault = frontDefault, + modesBack = possibleModes, backDefault = backDefault, + modesLeft = possibleModes, leftDefault = leftDefault, + modesRight = possibleModes, rightDefault = rightDefault, + modesTop = possibleModes, topDefault = topDefault, + modesBottom = possibleModes, bottomDefault = bottomDefault, + ) + init { - exposeEnergySideless(capability) + exposeEnergySideless(energy) } - val front = Piece(RelativeSide.FRONT).also { it.energyFlow = frontDefault } - val back = Piece(RelativeSide.BACK).also { it.energyFlow = backDefault } - val left = Piece(RelativeSide.LEFT).also { it.energyFlow = leftDefault } - val right = Piece(RelativeSide.RIGHT).also { it.energyFlow = rightDefault } - val top = Piece(RelativeSide.TOP).also { it.energyFlow = topDefault } - val bottom = Piece(RelativeSide.BOTTOM).also { it.energyFlow = bottomDefault } + val front = Piece(RelativeSide.FRONT, modesFront).also { it.energyFlow = frontDefault } + val back = Piece(RelativeSide.BACK, modesBack).also { it.energyFlow = backDefault } + val left = Piece(RelativeSide.LEFT, modesLeft).also { it.energyFlow = leftDefault } + val right = Piece(RelativeSide.RIGHT, modesRight).also { it.energyFlow = rightDefault } + val top = Piece(RelativeSide.TOP, modesTop).also { it.energyFlow = topDefault } + val bottom = Piece(RelativeSide.BOTTOM, modesBottom).also { it.energyFlow = bottomDefault } val pieces = immutableMap { put(RelativeSide.FRONT, front) @@ -275,15 +298,15 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo put(RelativeSide.BOTTOM, bottomDefault) } - inner class Piece(val side: RelativeSide) : IMatteryEnergyStorage, ITickable { + inner class Piece(val side: RelativeSide, val possibleModes: FlowDirection) : IMatteryEnergyStorage, ITickable { private val capControllers = exposeEnergy(side, this@Piece) private val neighbour by sides[side]!!.track(ForgeCapabilities.ENERGY) - override var batteryLevel: Decimal by capability::batteryLevel - override val maxBatteryLevel: Decimal by capability::maxBatteryLevel - override val missingPower: Decimal by capability::missingPower + override var batteryLevel: Decimal by energy::batteryLevel + override val maxBatteryLevel: Decimal by energy::maxBatteryLevel + override val missingPower: Decimal by energy::missingPower - override val canSetBatteryLevel: Boolean by capability::canSetBatteryLevel + override val canSetBatteryLevel: Boolean by energy::canSetBatteryLevel // var automatePull by synchronizer.bool().property var automatePull = false @@ -299,33 +322,33 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo } override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal { - return capability.extractEnergy(howMuch, simulate) + return energy.extractEnergy(howMuch, simulate) } override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal { - return capability.receiveEnergy(howMuch, simulate) + return energy.receiveEnergy(howMuch, simulate) } override fun extractEnergyChecked(howMuch: Decimal, simulate: Boolean): Decimal { if (energyFlow.output) - return capability.extractEnergyChecked(howMuch, simulate) + return energy.extractEnergyChecked(howMuch, simulate) return Decimal.ZERO } override fun receiveEnergyChecked(howMuch: Decimal, simulate: Boolean): Decimal { if (energyFlow.input) - return capability.receiveEnergyChecked(howMuch, simulate) + return energy.receiveEnergyChecked(howMuch, simulate) return Decimal.ZERO } override fun drainBattery(): Boolean { - return capability.drainBattery() + return energy.drainBattery() } override fun fillBattery(): Boolean { - return capability.fillBattery() + return energy.fillBattery() } override fun tick() { @@ -334,11 +357,11 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo neighbour.ifPresentK { if (energyFlow.input && automatePull) { - moveEnergy(source = it, destination = capability, simulate = false) + moveEnergy(source = it, destination = energy, simulate = false) } if (energyFlow.output && automatePush) { - moveEnergy(source = capability, destination = it, simulate = false) + moveEnergy(source = energy, destination = it, simulate = false) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt index a563312ce..c1ef9e92e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryPoweredBlockEntity.kt @@ -32,7 +32,7 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229 super.tick() val energy = matteryEnergy - if (energy == null || !batteryContainer.any { !it.isEmpty }) + if (energy == null || batteryContainer.isEmpty) return var demand = energy.receiveEnergy(energy.missingPower, true) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt new file mode 100644 index 000000000..16749c109 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/AndroidChargerBlockEntity.kt @@ -0,0 +1,52 @@ +package ru.dbotthepony.mc.otm.block.entity.tech + +import net.minecraft.core.BlockPos +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.state.BlockState +import net.minecraft.world.phys.Vec3 +import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity +import ru.dbotthepony.mc.otm.capability.FlowDirection +import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage +import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage +import ru.dbotthepony.mc.otm.capability.matteryPlayer +import ru.dbotthepony.mc.otm.config.MachinesConfig +import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid +import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu +import ru.dbotthepony.mc.otm.registry.MBlockEntities + +class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ANDROID_CHARGER, blockPos, blockState) { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? { + return AndroidChargerMenu(containerID, inventory, this) + } + + val energyConfig = ConfigurableEnergy(ProfiledEnergyStorage(WorkerEnergyStorage(this::setChangedLight, MachinesConfig.ANDROID_CHARGER)), modesTop = FlowDirection.NONE) + + init { + savetables.stateful(energyConfig::energy, ENERGY_KEY) + } + + override fun tick() { + super.tick() + + val level = level ?: return + var available = energyConfig.energy.extractEnergy(energyConfig.energy.batteryLevel, true) + if (!available.isPositive) return + + val ents = level.getEntitiesInEllipsoid(blockPos.center, Vec3(MachinesConfig.AndroidCharger.RADIUS_WIDTH, MachinesConfig.AndroidCharger.RADIUS_HEIGHT, MachinesConfig.AndroidCharger.RADIUS_WIDTH)) { it is Player } + + ents.sort() + + for ((ent) in ents) { + val ply = ent.matteryPlayer ?: continue + + if (ply.isAndroid) { + val received = ply.androidEnergy.receiveEnergyChecked(available, false) + available -= received + energyConfig.energy.extractEnergy(received, false) + if (!available.isPositive) return + } + } + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt index f444512cd..f610bbe08 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/BatteryBankBlockEntity.kt @@ -181,7 +181,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte init { energyConfig.front.automatePush = true - savetables.stateful(Supplier { energyConfig.capability.savedata }, "energyUsageHistory") + savetables.stateful(Supplier { energyConfig.energy.savedata }, "energyUsageHistory") } override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt index e50396454..74f2edd4f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/tech/EnergyServoBlockEntity.kt @@ -62,6 +62,7 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte }) val energyConfig = ConfigurableEnergy(energy, possibleModes = FlowDirection.BI_DIRECTIONAL) + val itemConfig = ConfigurableItemHandler( input = charge.handler(HandlerFilter.OnlyIn.and(HandlerFilter.Chargeable)), output = discharge.handler(HandlerFilter.OnlyOut.and(HandlerFilter.Dischargeable)) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidChargerBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidChargerBlock.kt new file mode 100644 index 000000000..d7be418c5 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidChargerBlock.kt @@ -0,0 +1,135 @@ +package ru.dbotthepony.mc.otm.block.tech + +import net.minecraft.core.BlockPos +import net.minecraft.network.chat.Component +import net.minecraft.util.StringRepresentable +import net.minecraft.world.entity.LivingEntity +import net.minecraft.world.entity.player.Player +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.TooltipFlag +import net.minecraft.world.item.context.BlockPlaceContext +import net.minecraft.world.level.BlockGetter +import net.minecraft.world.level.Level +import net.minecraft.world.level.block.Block +import net.minecraft.world.level.block.Blocks +import net.minecraft.world.level.block.EntityBlock +import net.minecraft.world.level.block.entity.BlockEntity +import net.minecraft.world.level.block.entity.BlockEntityTicker +import net.minecraft.world.level.block.entity.BlockEntityType +import net.minecraft.world.level.block.state.BlockState +import net.minecraft.world.level.block.state.StateDefinition +import net.minecraft.world.level.block.state.properties.EnumProperty +import net.minecraft.world.level.material.PushReaction +import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock +import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerBlockEntity +import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage +import ru.dbotthepony.mc.otm.core.get +import ru.dbotthepony.mc.otm.core.gracefulBlockBreak +import ru.dbotthepony.mc.otm.core.math.plus +import ru.dbotthepony.mc.otm.oncePre + +class AndroidChargerBlock : RotatableMatteryBlock(Properties.of().destroyTime(2.5f).explosionResistance(40f).pushReaction(PushReaction.BLOCK).requiresCorrectToolForDrops()), EntityBlock { + enum class Type : StringRepresentable { + BASE, + MIDDLE, + TOP; + + override fun getSerializedName(): String { + return name.lowercase() + } + } + + override fun createBlockStateDefinition(builder: StateDefinition.Builder) { + super.createBlockStateDefinition(builder) + builder.add(PART) + } + + init { + registerDefaultState(defaultBlockState().setValue(PART, Type.BASE)) + } + + override fun getStateForPlacement(context: BlockPlaceContext): BlockState? { + val level = context.level + if (level.isOutsideBuildHeight(context.clickedPos + BlockPos(0, 0, 2))) return null + + for (i in 1 .. 2) { + val pos = context.clickedPos + BlockPos(0, 0, i) + if (!level.getBlockState(pos).canBeReplaced(context)) return null + } + + return super.getStateForPlacement(context) + } + + override fun setPlacedBy(level: Level, blockPos: BlockPos, blockState: BlockState, entity: LivingEntity?, itemStack: ItemStack) { + super.setPlacedBy(level, blockPos, blockState, entity, itemStack) + + if (blockState[PART] == Type.BASE) { + level.setBlock(blockPos.above(), blockState.setValue(PART, Type.MIDDLE), UPDATE_ALL) + level.setBlock(blockPos.above().above(), blockState.setValue(PART, Type.TOP), UPDATE_ALL) + } + } + + override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity? { + if (p_153216_[PART] != Type.BASE) return null + return AndroidChargerBlockEntity(p_153215_, p_153216_) + } + + override fun getTicker(p_153212_: Level, blockState: BlockState, p_153214_: BlockEntityType): BlockEntityTicker? { + if (p_153212_.isClientSide || blockState[PART] != Type.BASE) return null + return BlockEntityTicker { _, _, _, t -> if (t is AndroidChargerBlockEntity) t.tick() } + } + + override fun getDestroyProgress(p_60466_: BlockState, p_60467_: Player, p_60468_: BlockGetter, p_60469_: BlockPos): Float { + // запрет на ломание не нижнего блока игроком + if (p_60466_[PART] != Type.BASE) return 0f + return super.getDestroyProgress(p_60466_, p_60467_, p_60468_, p_60469_) + } + + override fun neighborChanged(state: BlockState, level: Level, pos: BlockPos, neighbour: Block, neighbourPos: BlockPos, movedByPiston: Boolean) { + super.neighborChanged(state, level, pos, neighbour, neighbourPos, movedByPiston) + + level.oncePre { + if (level.getBlockState(pos) == state) { + when (state[PART]!!) { + Type.BASE -> { + val a = level.getBlockState(pos.above()) + val b = level.getBlockState(pos.above().above()) + + if (a.block != this || b.block != this || a[PART] != Type.MIDDLE || b[PART] != Type.TOP) { + level.gracefulBlockBreak(pos, state) + } + } + + Type.MIDDLE -> { + val a = level.getBlockState(pos.below()) + val b = level.getBlockState(pos.above()) + + if (a.block != this || b.block != this || a[PART] != Type.BASE || b[PART] != Type.TOP) { + level.setBlock(pos, Blocks.AIR.defaultBlockState(), UPDATE_ALL) + } + } + + Type.TOP -> { + val a = level.getBlockState(pos.below()) + val b = level.getBlockState(pos.below().below()) + + if (a.block != this || b.block != this || a[PART] != Type.MIDDLE || b[PART] != Type.BASE) { + level.setBlock(pos, Blocks.AIR.defaultBlockState(), UPDATE_ALL) + } + } + } + } + } + } + + override fun appendHoverText(p_49816_: ItemStack, p_49817_: BlockGetter?, p_49818_: MutableList, 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_) + } + + companion object { + val PART: EnumProperty = EnumProperty.create("part", Type::class.java) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt index 42d35b2c7..4abaceb73 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/BlockEnergyStorageImpl.kt @@ -166,7 +166,7 @@ sealed class BlockEnergyStorageImpl( const val MAX_INPUT_KEY = "max_input" const val MAX_OUTPUT_KEY = "max_output" - fun makeConfigEntry(builder: ForgeConfigSpec.Builder, name: String? = null, capacity: Decimal = DEFAULT_MAX_CAPACITY, throughput: Decimal = DEFAULT_MAX_IO): ConciseBalanceValues { + fun makeConfigEntry(builder: ForgeConfigSpec.Builder, name: String? = null, capacity: Decimal = DEFAULT_MAX_CAPACITY, throughput: Decimal = DEFAULT_MAX_IO, configurator: ForgeConfigSpec.Builder.() -> Unit = {}): ConciseBalanceValues { if (name != null) builder.push(name) @@ -175,6 +175,8 @@ sealed class BlockEnergyStorageImpl( override val throughput: Decimal by builder.defineDecimal("throughput", throughput, Decimal.ONE) } + configurator.invoke(builder) + if (name != null) builder.pop() @@ -226,7 +228,7 @@ open class WorkerEnergyStorage( val tag = (itemStack.tag?.get(BlockItem.BLOCK_ENTITY_TAG) as? CompoundTag)?.get(MatteryBlockEntity.ENERGY_KEY) as? CompoundTag ?: return val cap = WorkerEnergyStorage({}, DEFAULT_MAX_CAPACITY) cap.deserializeNBT(tag) - batteryLevel(cap, tooltips) + batteryLevel(cap, tooltips, false) } fun appendHoverText(itemStack: ItemStack, blockGetter: BlockGetter?, tooltips: MutableList, flag: TooltipFlag) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt index a290fcb05..9903b26db 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IEnergyStorageImpl.kt @@ -23,13 +23,20 @@ internal fun batteryLevel(it: IEnergyStorage, tooltips: MutableList) ).withStyle(ChatFormatting.GRAY)) } -internal fun batteryLevel(it: IMatteryEnergyStorage, tooltips: MutableList) { - tooltips.add( - TranslatableComponent( - "otm.item.power.storage", - it.batteryLevel.formatPower(formatAsReadable = ShiftPressedCond), - it.maxBatteryLevel.formatPower(formatAsReadable = ShiftPressedCond) - ).withStyle(ChatFormatting.GRAY)) +internal fun batteryLevel(it: IMatteryEnergyStorage, tooltips: MutableList, displayMaxLevel: Boolean = true) { + if (displayMaxLevel) + tooltips.add( + TranslatableComponent( + "otm.item.power.storage", + it.batteryLevel.formatPower(formatAsReadable = ShiftPressedCond), + it.maxBatteryLevel.formatPower(formatAsReadable = ShiftPressedCond) + ).withStyle(ChatFormatting.GRAY)) + else + tooltips.add( + TranslatableComponent( + "otm.item.power.storage0", + it.batteryLevel.formatPower(formatAsReadable = ShiftPressedCond) + ).withStyle(ChatFormatting.GRAY)) if (it is IEnergyStorageImpl) { when (it.energyFlow) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt index d9bbffeec..759e7bdba 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/Buttons.kt @@ -128,6 +128,12 @@ private fun > makeEnergyModeButton(screen: S, parent: Frame button.finish() + if (input.possibleModes == FlowDirection.NONE) { + button.visible = false + } + + button.predicate = Predicate { input.possibleModes.isSupertype(it) } + return button } @@ -224,12 +230,12 @@ private fun > makeEnergyConfigPanel( } } - val front = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.FRONT]!!, RelativeSide.FRONT).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } } - val back = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.BACK]!!, RelativeSide.BACK).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } } - val left = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.LEFT]!!, RelativeSide.LEFT).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } } - val right = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.RIGHT]!!, RelativeSide.RIGHT).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } } - val top = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.TOP]!!, RelativeSide.TOP).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } } - val bottom = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.BOTTOM]!!, RelativeSide.BOTTOM).also { it.predicate = Predicate { inputs.possibleModes.isSupertype(it) } } + val front = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.FRONT]!!, RelativeSide.FRONT) + val back = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.BACK]!!, RelativeSide.BACK) + val left = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.LEFT]!!, RelativeSide.LEFT) + val right = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.RIGHT]!!, RelativeSide.RIGHT) + val top = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.TOP]!!, RelativeSide.TOP) + val bottom = makeEnergyModeButton(screen, frame, inputs.pieces[RelativeSide.BOTTOM]!!, RelativeSide.BOTTOM) moveButtons(front, back, left, right, top, bottom) screen.addPanel(frame) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt new file mode 100644 index 000000000..2c7037616 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidChargerScreen.kt @@ -0,0 +1,47 @@ +package ru.dbotthepony.mc.otm.client.screen.tech + +import net.minecraft.network.chat.Component +import net.minecraft.world.entity.player.Inventory +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.EditablePanel +import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls +import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel +import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel +import ru.dbotthepony.mc.otm.client.screen.panels.util.SpritePanel +import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel +import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalProfiledPowerGaugePanel +import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu + +class AndroidChargerScreen(menu: AndroidChargerMenu, inventory: Inventory, title: Component) : MatteryScreen(menu, inventory, title) { + override fun makeMainFrame(): FramePanel> { + val frame = super.makeMainFrame()!! + + frame.height = 42f + frame.width -= 20f + + val strip = EditablePanel(this, frame, height = AbstractSlotPanel.SIZE) + strip.dock = Dock.BOTTOM + + BatterySlotPanel(this, strip, menu.batterySlot).also { + it.dock = Dock.LEFT + it.dockRight = 2f + } + + SpritePanel(this, strip, ProgressGaugePanel.GAUGE_BACKGROUND).also { + it.dock = Dock.LEFT + it.dockRight = 2f + it.dockTop = 2f + } + + TallHorizontalProfiledPowerGaugePanel(this, strip, menu.profiledEnergy).also { + it.dock = Dock.LEFT + it.dockRight = 2f + } + + makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig) + + return frame + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt index 7729e32b3..bdaa7aeb4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/EnergyServoScreen.kt @@ -1,6 +1,5 @@ package ru.dbotthepony.mc.otm.client.screen.tech -import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.gui.GuiGraphics import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory @@ -14,9 +13,9 @@ import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel import ru.dbotthepony.mc.otm.client.screen.panels.PlayerEquipmentPanel import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls import ru.dbotthepony.mc.otm.client.screen.panels.makeCuriosPanel +import ru.dbotthepony.mc.otm.client.screen.panels.util.SpritePanel import ru.dbotthepony.mc.otm.client.screen.widget.HorizontalPowerGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel -import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalPowerGaugePanel import ru.dbotthepony.mc.otm.client.screen.widget.TallHorizontalProfiledPowerGaugePanel import ru.dbotthepony.mc.otm.menu.tech.EnergyServoMenu @@ -40,17 +39,10 @@ class EnergyServoScreen(menu: EnergyServoMenu, inventory: Inventory, title: Comp it.dockRight = 2f } - object : EditablePanel(this@EnergyServoScreen, strip) { - init { - dock = Dock.LEFT - dockRight = 2f - dockTop = 2f - width = ProgressGaugePanel.GAUGE_BACKGROUND.width - } - - override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { - ProgressGaugePanel.GAUGE_BACKGROUND.render(graphics) - } + SpritePanel(this, strip, ProgressGaugePanel.GAUGE_BACKGROUND).also { + it.dock = Dock.LEFT + it.dockRight = 2f + it.dockTop = 2f } TallHorizontalProfiledPowerGaugePanel(this, strip, menu.powerGauge).also { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt index 4efd5d53c..8fc6c4cef 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/config/MachinesConfig.kt @@ -30,4 +30,16 @@ object MachinesConfig : AbstractConfig("machines") { val ITEM_MONITOR = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.ITEM_MONITOR) val DRIVE_VIEWER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.DRIVE_VIEWER) val DRIVE_RACK = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.DRIVE_RACK, capacity = Decimal(80_000)) + + object AndroidCharger { + val RADIUS_WIDTH: Double by builder + .comment("Effective charger range on horizontal plane") + .defineInRange("RADIUS_WIDTH", 16.0, 1.0, Double.MAX_VALUE) + + val RADIUS_HEIGHT: Double by builder + .comment("Effective charger range on vertical plane") + .defineInRange("RADIUS_HEIGHT", 4.0, 1.0, Double.MAX_VALUE) + } + + val ANDROID_CHARGER = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.ANDROID_CHARGER, capacity = Decimal(400_000), throughput = Decimal(8192)) { AndroidCharger } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index 757662ebd..186726e8a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -360,11 +360,7 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I } override fun isEmpty(): Boolean { - for (stack in slots) - if (!stack.isEmpty) - return false - - return true + return slots.all { it.isEmpty } } operator fun get(slot: Int) = getItem(slot) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt index 38d70d4b8..6e03b8bff 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/LevelExt.kt @@ -9,10 +9,16 @@ import java.util.LinkedList import java.util.function.Predicate import kotlin.math.pow +data class EntityDistance(val entity: T, val distance: Double) : Comparable> { + override fun compareTo(other: EntityDistance<*>): Int { + return distance.compareTo(other.distance) + } +} + /** * Pair of entity and distance fraction to center of ellipsoid */ -fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, except: Entity?, predicate: Predicate): List> { +fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, except: Entity?, predicate: Predicate): MutableList> { val entities = getEntities(except, AABB( pos.x - dimensions.x, pos.y - dimensions.y, @@ -23,7 +29,7 @@ fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, except: Entity pos.z + dimensions.z, ), predicate) - val result = LinkedList>() + val result = ArrayList>() for (it in entities) { val a = (it.position - pos).let { vec -> @@ -41,7 +47,7 @@ fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, except: Entity val min = a.coerceAtMost(b) if (min <= 1.0) { - result.add(it to min) + result.add(EntityDistance(it, min)) } } @@ -51,7 +57,7 @@ fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, except: Entity /** * Pair of entity and distance fraction to center of ellipsoid */ -fun Level.getEntitiesInEllipsoid(type: Class, pos: Vector, dimensions: Vector, predicate: Predicate): List> { +fun Level.getEntitiesInEllipsoid(type: Class, pos: Vector, dimensions: Vector, predicate: Predicate): MutableList> { val entities = getEntitiesOfClass(type, AABB( pos.x - dimensions.x, pos.y - dimensions.y, @@ -62,7 +68,7 @@ fun Level.getEntitiesInEllipsoid(type: Class, pos: Vector, d pos.z + dimensions.z, ), predicate) - val result = LinkedList>() + val result = ArrayList>() for (it in entities) { val a = (it.position - pos).let { vec -> @@ -80,7 +86,7 @@ fun Level.getEntitiesInEllipsoid(type: Class, pos: Vector, d val min = a.coerceAtMost(b) if (min <= 1.0) { - result.add(it to min) + result.add(EntityDistance(it, min)) } } @@ -90,27 +96,27 @@ fun Level.getEntitiesInEllipsoid(type: Class, pos: Vector, d /** * Pair of entity and distance fraction to center of ellipsoid */ -fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, predicate: Predicate): List> { +fun Level.getEntitiesInEllipsoid(pos: Vector, dimensions: Vector, predicate: Predicate): MutableList> { return getEntitiesInEllipsoid(pos, dimensions, null, predicate) } /** * Pair of entity and distance fraction to center of ellipsoid */ -fun Level.getEntitiesInSphere(pos: Vector, radius: Double, except: Entity?, predicate: Predicate): List> { +fun Level.getEntitiesInSphere(pos: Vector, radius: Double, except: Entity?, predicate: Predicate): MutableList> { return getEntitiesInEllipsoid(pos, Vector(radius, radius, radius), except, predicate) } /** * Pair of entity and distance fraction to center of ellipsoid */ -fun Level.getEntitiesInSphere(pos: Vector, radius: Double, predicate: Predicate): List> { +fun Level.getEntitiesInSphere(pos: Vector, radius: Double, predicate: Predicate): MutableList> { return getEntitiesInEllipsoid(pos, Vector(radius, radius, radius), null, predicate) } /** * Pair of entity and distance fraction to center of ellipsoid */ -fun Level.getEntitiesInSphere(type: Class, pos: Vector, radius: Double, predicate: Predicate): List> { +fun Level.getEntitiesInSphere(type: Class, pos: Vector, radius: Double, predicate: Predicate): MutableList> { return getEntitiesInEllipsoid(type, pos, Vector(radius, radius, radius), predicate) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnergyConfigPlayerInput.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnergyConfigPlayerInput.kt index 3525c023f..0205c1d57 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnergyConfigPlayerInput.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnergyConfigPlayerInput.kt @@ -10,14 +10,14 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenu * [allowPull] and [allowPush] controls whenever player is allowed to change these options */ class EnergyConfigPlayerInput(val menu: MatteryMenu, config: MatteryDeviceBlockEntity.ConfigurableEnergy<*>? = null, val allowPull: Boolean = false, val allowPush: Boolean = false) { - var possibleModes by menu.mSynchronizer.enum(FlowDirection::class.java) - private set - inner class Piece(val side: RelativeSide) { val pull = BooleanInputWithFeedback(menu) val push = BooleanInputWithFeedback(menu) val input = EnumInputWithFeedback(menu) + var possibleModes by menu.mSynchronizer.enum(FlowDirection::class.java) + private set + var default by menu.mSynchronizer.enum(FlowDirection.NONE) init { @@ -25,20 +25,19 @@ class EnergyConfigPlayerInput(val menu: MatteryMenu, config: MatteryDeviceBlockE push.filter { allowPush && possibleModes.isSupertype(FlowDirection.OUTPUT) } } - fun with(config: MatteryDeviceBlockEntity.ConfigurableEnergy<*>.Piece, parent: MatteryDeviceBlockEntity.ConfigurableEnergy<*>) { + fun with(config: MatteryDeviceBlockEntity.ConfigurableEnergy<*>.Piece) { + possibleModes = config.possibleModes pull.with(config::automatePull) push.with(config::automatePush) - input.withSupplier { config.energyFlow }.withConsumer { if (parent.possibleModes.isSupertype(it)) config.energyFlow = it } + input.withSupplier { config.energyFlow }.withConsumer { if (possibleModes.isSupertype(it)) config.energyFlow = it } } } val pieces = immutableMap { for (side in RelativeSide.values()) put(side, Piece(side)) } fun with(config: MatteryDeviceBlockEntity.ConfigurableEnergy<*>) { - possibleModes = config.possibleModes - for ((side, v) in config.pieces) { - pieces[side]!!.with(v, config) + pieces[side]!!.with(v) pieces[side]!!.default = config.defaults[side]!! } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt index 457b3674b..61df43a35 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/input/EnumInputWithFeedback.kt @@ -6,7 +6,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenu import kotlin.reflect.KMutableProperty0 inline fun > EnumInputWithFeedback(menu: MatteryMenu) = EnumInputWithFeedback(menu, E::class.java) -inline fun > EnumInputWithFeedback(menu: MatteryMenu, state: KMutableProperty0) = EnumInputWithFeedback(menu, E::class.java, state) +inline fun > EnumInputWithFeedback(menu: MatteryMenu, state: KMutableProperty0?) = EnumInputWithFeedback(menu, E::class.java, state) inline fun > EnumInputWithFeedback(menu: MatteryMenu, state: GetterSetter) = EnumInputWithFeedback(menu, E::class.java, state) class EnumInputWithFeedback>(menu: MatteryMenu, clazz: Class) : AbstractPlayerInputWithFeedback() { @@ -16,8 +16,10 @@ class EnumInputWithFeedback>(menu: MatteryMenu, clazz: Class) : A override val input = menu.PlayerInput(codec, false) { consumer?.invoke(it) } override val value by menu.mSynchronizer.ComputedField(getter = { supplier?.invoke() ?: default }, codec) - constructor(menu: MatteryMenu, clazz: Class, state: KMutableProperty0) : this(menu, clazz) { - with(state) + constructor(menu: MatteryMenu, clazz: Class, state: KMutableProperty0?) : this(menu, clazz) { + if (state != null) { + with(state) + } } constructor(menu: MatteryMenu, clazz: Class, state: GetterSetter) : this(menu, clazz) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt new file mode 100644 index 000000000..9b50f53c5 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt @@ -0,0 +1,21 @@ +package ru.dbotthepony.mc.otm.menu.tech + +import net.minecraft.world.entity.player.Inventory +import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerBlockEntity +import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu +import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput +import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget +import ru.dbotthepony.mc.otm.registry.MMenus + +class AndroidChargerMenu( + p_38852_: Int, + inventory: Inventory, + tile: AndroidChargerBlockEntity? = null +) : MatteryPoweredMenu(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile) { + val energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) + val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energyConfig?.energy, energyWidget) + + init { + addInventorySlots() + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt index a9d284f09..af4335ec6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/BatteryBankMenu.kt @@ -21,7 +21,7 @@ class BatteryBankMenu @JvmOverloads constructor( inventory: Inventory, tile: BatteryBankBlockEntity? = null, ) : MatteryMenu(MMenus.BATTERY_BANK, p_38852_, inventory, tile) { - val powerLevel = ProfiledLevelGaugeWidget(this, tile?.energyConfig?.capability) + val powerLevel = ProfiledLevelGaugeWidget(this, tile?.energyConfig?.energy) val storageSlots: List val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java) val energyConfig = EnergyConfigPlayerInput(this, allowPull = false, allowPush = true) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt index 49767b43c..6bfc64e38 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -55,6 +55,7 @@ object MBlockEntities { val ESSENCE_STORAGE: BlockEntityType by registry.register(MNames.ESSENCE_STORAGE) { BlockEntityType.Builder.of(::EssenceStorageBlockEntity, MBlocks.ESSENCE_STORAGE).build(null) } val MATTER_RECONSTRUCTOR: BlockEntityType by registry.register(MNames.MATTER_RECONSTRUCTOR) { BlockEntityType.Builder.of(::MatterReconstructorBlockEntity, MBlocks.MATTER_RECONSTRUCTOR).build(null) } val FLUID_TANK: BlockEntityType by registry.register(MNames.FLUID_TANK) { BlockEntityType.Builder.of(::FluidTankBlockEntity, MBlocks.FLUID_TANK).build(null) } + val ANDROID_CHARGER: BlockEntityType by registry.register(MNames.ANDROID_CHARGER) { BlockEntityType.Builder.of(::AndroidChargerBlockEntity, MBlocks.ANDROID_CHARGER).build(null) } val STORAGE_BUS: BlockEntityType by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) } val STORAGE_IMPORTER: BlockEntityType by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt index 6e4b99881..474441f83 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlocks.kt @@ -58,6 +58,7 @@ import ru.dbotthepony.mc.otm.block.storage.StorageBusBlock import ru.dbotthepony.mc.otm.block.storage.StorageExporterBlock import ru.dbotthepony.mc.otm.block.storage.StorageImporterBlock import ru.dbotthepony.mc.otm.block.storage.StoragePowerSupplierBlock +import ru.dbotthepony.mc.otm.block.tech.AndroidChargerBlock import ru.dbotthepony.mc.otm.block.tech.CobblerBlock import ru.dbotthepony.mc.otm.block.tech.EssenceStorageBlock import ru.dbotthepony.mc.otm.core.TranslatableComponent @@ -71,6 +72,7 @@ object MBlocks { } val ANDROID_STATION: Block by registry.register(MNames.ANDROID_STATION) { AndroidStationBlock() } + val ANDROID_CHARGER: Block by registry.register(MNames.ANDROID_CHARGER) { AndroidChargerBlock() } val BATTERY_BANK: Block by registry.register(MNames.BATTERY_BANK) { BatteryBankBlock() } val MATTER_DECOMPOSER: Block by registry.register(MNames.MATTER_DECOMPOSER) { MatterDecomposerBlock() } val MATTER_CAPACITOR_BANK: Block by registry.register(MNames.MATTER_CAPACITOR_BANK) { MatterCapacitorBankBlock() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt index 6ab288fe1..4577d88c7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt @@ -44,6 +44,7 @@ object MItems { } val ANDROID_STATION: BlockItem by registry.register(MNames.ANDROID_STATION) { BlockItem(MBlocks.ANDROID_STATION, DEFAULT_PROPERTIES) } + val ANDROID_CHARGER: BlockItem by registry.register(MNames.ANDROID_CHARGER) { BlockItem(MBlocks.ANDROID_CHARGER, DEFAULT_PROPERTIES) } val BATTERY_BANK: BlockItem by registry.register(MNames.BATTERY_BANK) { BlockItem(MBlocks.BATTERY_BANK, DEFAULT_PROPERTIES) } val MATTER_DECOMPOSER: BlockItem by registry.register(MNames.MATTER_DECOMPOSER) { BlockItem(MBlocks.MATTER_DECOMPOSER, DEFAULT_PROPERTIES) } val MATTER_CAPACITOR_BANK: BlockItem by registry.register(MNames.MATTER_CAPACITOR_BANK) { BlockItem(MBlocks.MATTER_CAPACITOR_BANK, DEFAULT_PROPERTIES) } @@ -134,7 +135,7 @@ object MItems { } val MACHINES = SupplierList( - ::ANDROID_STATION, ::BATTERY_BANK, ::MATTER_DECOMPOSER, ::MATTER_CAPACITOR_BANK, ::MATTER_CABLE, ::PATTERN_STORAGE, + ::ANDROID_STATION, ::ANDROID_CHARGER, ::BATTERY_BANK, ::MATTER_DECOMPOSER, ::MATTER_CAPACITOR_BANK, ::MATTER_CABLE, ::PATTERN_STORAGE, ::MATTER_SCANNER, ::MATTER_PANEL, ::MATTER_REPLICATOR, ::MATTER_BOTTLER, ::ENERGY_COUNTER, ::CHEMICAL_GENERATOR, ::PLATE_PRESS, ::TWIN_PLATE_PRESS, ::MATTER_RECYCLER, // ::STORAGE_BUS, ::STORAGE_IMPORTER, ::STORAGE_EXPORTER, ::DRIVE_VIEWER, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt index 8e6f0e6f4..f4c515991 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt @@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.client.screen.storage.StorageBusScreen import ru.dbotthepony.mc.otm.client.screen.storage.StorageExporterScreen import ru.dbotthepony.mc.otm.client.screen.storage.StorageImporterScreen import ru.dbotthepony.mc.otm.client.screen.storage.StoragePowerSupplierScreen +import ru.dbotthepony.mc.otm.client.screen.tech.AndroidChargerScreen import ru.dbotthepony.mc.otm.client.screen.tech.AndroidStationScreen import ru.dbotthepony.mc.otm.client.screen.tech.BatteryBankScreen import ru.dbotthepony.mc.otm.client.screen.tech.ChemicalGeneratorScreen @@ -57,6 +58,7 @@ import ru.dbotthepony.mc.otm.menu.storage.StorageBusMenu import ru.dbotthepony.mc.otm.menu.storage.StorageExporterMenu import ru.dbotthepony.mc.otm.menu.storage.StorageImporterMenu import ru.dbotthepony.mc.otm.menu.storage.StoragePowerSupplierMenu +import ru.dbotthepony.mc.otm.menu.tech.AndroidChargerMenu import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu import ru.dbotthepony.mc.otm.menu.tech.BatteryBankMenu import ru.dbotthepony.mc.otm.menu.tech.ChemicalGeneratorMenu @@ -71,6 +73,7 @@ object MMenus { private val registry = DeferredRegister.create(ForgeRegistries.MENU_TYPES, OverdriveThatMatters.MOD_ID) val ANDROID_STATION: MenuType by registry.register(MNames.ANDROID_STATION) { MenuType(::AndroidStationMenu, FeatureFlags.VANILLA_SET) } + val ANDROID_CHARGER: MenuType by registry.register(MNames.ANDROID_CHARGER) { MenuType(::AndroidChargerMenu, FeatureFlags.VANILLA_SET) } val BATTERY_BANK: MenuType by registry.register(MNames.BATTERY_BANK) { MenuType(::BatteryBankMenu, FeatureFlags.VANILLA_SET) } val MATTER_DECOMPOSER: MenuType by registry.register(MNames.MATTER_DECOMPOSER) { MenuType(::MatterDecomposerMenu, FeatureFlags.VANILLA_SET) } val MATTER_CAPACITOR_BANK: MenuType by registry.register(MNames.MATTER_CAPACITOR_BANK) { MenuType(::MatterCapacitorBankMenu, FeatureFlags.VANILLA_SET) } @@ -110,6 +113,7 @@ object MMenus { private fun registerClient(event: FMLClientSetupEvent) { event.enqueueWork { MenuScreens.register(ANDROID_STATION, ::AndroidStationScreen) + MenuScreens.register(ANDROID_CHARGER, ::AndroidChargerScreen) MenuScreens.register(BATTERY_BANK, ::BatteryBankScreen) MenuScreens.register(MATTER_DECOMPOSER, ::MatterDecomposerScreen) MenuScreens.register(MATTER_CAPACITOR_BANK, ::MatterCapacitorBankScreen) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt index bafe6e318..37d3e2ad3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MNames.kt @@ -12,6 +12,7 @@ object MNames { const val ENGINE = "engine" const val HOLO_SIGN = "holo_sign" const val FLUID_TANK = "fluid_tank" + const val ANDROID_CHARGER = "android_charger" // blocks const val ANDROID_STATION = "android_station"