From b578e9d8d8a7fc629fe1b21c8c727805e52a1b83 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 6 Jul 2023 13:57:13 +0700 Subject: [PATCH] Add middle and top block entities to android charger --- .../block/entity/MatteryDeviceBlockEntity.kt | 31 +++++- .../entity/tech/AndroidChargerBlockEntity.kt | 100 +++++++++++++++++- .../mc/otm/block/tech/AndroidChargerBlock.kt | 18 +++- .../mc/otm/menu/tech/AndroidChargerMenu.kt | 39 +++++-- .../mc/otm/registry/MBlockEntities.kt | 2 + .../ru/dbotthepony/mc/otm/registry/MMenus.kt | 3 +- 6 files changed, 179 insertions(+), 14 deletions(-) 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 6cfc56de3..fe8636ced 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 @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.block.entity import com.google.common.collect.ImmutableSet +import mekanism.common.tile.interfaces.IRedstoneControl import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.core.BlockPos import net.minecraft.world.level.block.state.BlockState @@ -42,7 +43,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo : MatteryBlockEntity(blockEntityType, blockPos, blockState), MenuProvider, IRedstoneControlled { var customDisplayName: Component? = null - override val redstoneControl = RedstoneControl { new, old -> + override val redstoneControl: AbstractRedstoneControl = RedstoneControl { new, old -> setChangedLight() if (new != old) @@ -307,6 +308,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo put(RelativeSide.BOTTOM, bottomDefault) } + fun invalidate(force: Boolean = false) { + for (piece in pieces.values) { + piece.invalidate(force) + } + } + inner class Piece(val side: RelativeSide, val possibleModes: FlowDirection) : IMatteryEnergyStorage, ITickable { private val capControllers = exposeEnergy(side, this@Piece) private val neighbour by sides[side]!!.trackEnergy() @@ -401,6 +408,28 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo } } }) + + fun invalidate(force: Boolean = false) { + if (force) { + for (controller in capControllers) { + controller.close() + controller.expose() + } + + if (energyFlow == FlowDirection.NONE) { + for (controller in capControllers) { + controller.close() + } + } + } else { + if (energyFlow != FlowDirection.NONE) { + for (controller in capControllers) { + controller.close() + controller.expose() + } + } + } + } } } 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 index 16749c109..943589746 100644 --- 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 @@ -1,14 +1,18 @@ package ru.dbotthepony.mc.otm.block.entity.tech import net.minecraft.core.BlockPos +import net.minecraft.network.chat.Component 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.AbstractRedstoneControl import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity +import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting import ru.dbotthepony.mc.otm.capability.FlowDirection import ru.dbotthepony.mc.otm.capability.energy.ProfiledEnergyStorage +import ru.dbotthepony.mc.otm.capability.energy.ProxiedEnergyStorage import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.config.MachinesConfig @@ -17,7 +21,7 @@ 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? { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu { return AndroidChargerMenu(containerID, inventory, this) } @@ -50,3 +54,97 @@ class AndroidChargerBlockEntity(blockPos: BlockPos, blockState: BlockState) : Ma } } } + +class AndroidChargerMiddleBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ANDROID_CHARGER_MIDDLE, blockPos, blockState) { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? { + if (proxy.parent == null || lastTileEntity == null) return null + return AndroidChargerMenu(containerID, inventory, this) + } + + private val proxy = ProxiedEnergyStorage>() + var lastTileEntity: AndroidChargerBlockEntity? = null + private set + val energyConfig = ConfigurableEnergy( + proxy, + modesBottom = FlowDirection.NONE, + modesTop = FlowDirection.NONE, + modesBack = FlowDirection.INPUT, + modesFront = FlowDirection.INPUT, + modesLeft = FlowDirection.INPUT, + modesRight = FlowDirection.INPUT, + ) + + override val redstoneControl = object : AbstractRedstoneControl() { + override var redstoneSetting: RedstoneSetting + get() = lastTileEntity?.redstoneControl?.redstoneSetting ?: RedstoneSetting.IGNORED + set(value) {} + override var redstoneSignal: Int + get() = lastTileEntity?.redstoneControl?.redstoneSignal ?: 0 + set(value) {} + } + + override fun getDisplayName(): Component { + return lastTileEntity?.getDisplayName() ?: super.getDisplayName() + } + + override fun tick() { + super.tick() + + if (proxy.parent == null || lastTileEntity?.isRemoved == true) { + lastTileEntity = level?.getBlockEntity(blockPos.below()) as? AndroidChargerBlockEntity + val energy = lastTileEntity?.energyConfig?.energy + + if (proxy.parent !== energy) { + proxy.parent = energy + energyConfig.invalidate(true) + } + } + } +} + +class AndroidChargerTopBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ANDROID_CHARGER_TOP, blockPos, blockState) { + override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu? { + if (proxy.parent == null || lastTileEntity == null) return null + return AndroidChargerMenu(containerID, inventory, this) + } + + private val proxy = ProxiedEnergyStorage>() + var lastTileEntity: AndroidChargerBlockEntity? = null + private set + val energyConfig = ConfigurableEnergy( + proxy, + modesBottom = FlowDirection.NONE, + modesTop = FlowDirection.INPUT, + modesBack = FlowDirection.INPUT, + modesFront = FlowDirection.INPUT, + modesLeft = FlowDirection.INPUT, + modesRight = FlowDirection.INPUT, + ) + + override val redstoneControl = object : AbstractRedstoneControl() { + override var redstoneSetting: RedstoneSetting + get() = lastTileEntity?.redstoneControl?.redstoneSetting ?: RedstoneSetting.IGNORED + set(value) {} + override var redstoneSignal: Int + get() = lastTileEntity?.redstoneControl?.redstoneSignal ?: 0 + set(value) {} + } + + override fun getDisplayName(): Component { + return lastTileEntity?.getDisplayName() ?: super.getDisplayName() + } + + override fun tick() { + super.tick() + + if (proxy.parent == null || lastTileEntity?.isRemoved == true) { + lastTileEntity = level?.getBlockEntity(blockPos.below(2)) as? AndroidChargerBlockEntity + val energy = lastTileEntity?.energyConfig?.energy + + if (proxy.parent !== energy) { + proxy.parent = energy + energyConfig.invalidate(true) + } + } + } +} 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 index c71cefd83..93faa46bc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidChargerBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/AndroidChargerBlock.kt @@ -25,6 +25,8 @@ import net.minecraft.world.phys.shapes.VoxelShape 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.block.entity.tech.AndroidChargerMiddleBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerTopBlockEntity import ru.dbotthepony.mc.otm.block.getShapeForEachState import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.core.get @@ -75,13 +77,21 @@ class AndroidChargerBlock : RotatableMatteryBlock(Properties.of().destroyTime(2. } override fun newBlockEntity(p_153215_: BlockPos, p_153216_: BlockState): BlockEntity? { - if (p_153216_[PART] != Type.BASE) return null - return AndroidChargerBlockEntity(p_153215_, p_153216_) + return when (p_153216_[PART]!!) { + Type.BASE -> AndroidChargerBlockEntity(p_153215_, p_153216_) + Type.MIDDLE -> AndroidChargerMiddleBlockEntity(p_153215_, p_153216_) + Type.TOP -> AndroidChargerTopBlockEntity(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() } + if (p_153212_.isClientSide) return null + + return when (blockState[PART]!!) { + Type.BASE -> BlockEntityTicker { _, _, _, t -> if (t is AndroidChargerBlockEntity) t.tick() } + Type.MIDDLE -> BlockEntityTicker { _, _, _, t -> if (t is AndroidChargerMiddleBlockEntity) t.tick() } + Type.TOP -> BlockEntityTicker { _, _, _, t -> if (t is AndroidChargerTopBlockEntity) t.tick() } + } } override fun getDestroyProgress(p_60466_: BlockState, p_60467_: Player, p_60468_: BlockGetter, p_60469_: BlockPos): Float { 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 index 9b50f53c5..ae6266a1b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/tech/AndroidChargerMenu.kt @@ -2,18 +2,43 @@ 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.block.entity.tech.AndroidChargerMiddleBlockEntity +import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerTopBlockEntity 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) +class AndroidChargerMenu : MatteryPoweredMenu { + val energyConfig: EnergyConfigPlayerInput + val profiledEnergy: ProfiledLevelGaugeWidget<*> + + constructor( + p_38852_: Int, + inventory: Inventory, + tile: AndroidChargerBlockEntity? = null + ) : super(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile) { + energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) + profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energyConfig?.energy, energyWidget) + } + + constructor( + p_38852_: Int, + inventory: Inventory, + tile: AndroidChargerTopBlockEntity? = null + ) : super(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile?.lastTileEntity) { + energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) + profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.lastTileEntity?.energyConfig?.energy, energyWidget) + } + + constructor( + p_38852_: Int, + inventory: Inventory, + tile: AndroidChargerMiddleBlockEntity? = null + ) : super(MMenus.ANDROID_CHARGER, p_38852_, inventory, tile?.lastTileEntity) { + energyConfig = EnergyConfigPlayerInput(this, tile?.energyConfig) + profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.lastTileEntity?.energyConfig?.energy, energyWidget) + } init { addInventorySlots() 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 f281a490f..493bb583b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MBlockEntities.kt @@ -56,6 +56,8 @@ object MBlockEntities { 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 ANDROID_CHARGER_MIDDLE: BlockEntityType by registry.register(MNames.ANDROID_CHARGER + "_middle") { BlockEntityType.Builder.of(::AndroidChargerMiddleBlockEntity, MBlocks.ANDROID_CHARGER).build(null) } + val ANDROID_CHARGER_TOP: BlockEntityType by registry.register(MNames.ANDROID_CHARGER + "_top") { BlockEntityType.Builder.of(::AndroidChargerTopBlockEntity, 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/MMenus.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt index f4c515991..113c4803a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MMenus.kt @@ -8,6 +8,7 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent import net.minecraftforge.registries.DeferredRegister import net.minecraftforge.registries.ForgeRegistries import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.block.entity.tech.AndroidChargerBlockEntity import ru.dbotthepony.mc.otm.client.screen.decorative.CargoCrateScreen import ru.dbotthepony.mc.otm.client.screen.decorative.FluidTankScreen import ru.dbotthepony.mc.otm.client.screen.decorative.HoloSignScreen @@ -73,7 +74,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 ANDROID_CHARGER: MenuType by registry.register(MNames.ANDROID_CHARGER) { MenuType({ a, b -> AndroidChargerMenu(a, b, null as AndroidChargerBlockEntity?) }, 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) }