Add middle and top block entities to android charger

This commit is contained in:
DBotThePony 2023-07-06 13:57:13 +07:00
parent 4dbf7cdc1c
commit b578e9d8d8
Signed by: DBot
GPG Key ID: DCC23B5715498507
6 changed files with 179 additions and 14 deletions

View File

@ -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()
}
}
}
}
}
}

View File

@ -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<ProfiledEnergyStorage<*>>()
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<ProfiledEnergyStorage<*>>()
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)
}
}
}
}

View File

@ -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 <T : BlockEntity?> getTicker(p_153212_: Level, blockState: BlockState, p_153214_: BlockEntityType<T>): BlockEntityTicker<T>? {
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 {

View File

@ -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(
class AndroidChargerMenu : MatteryPoweredMenu {
val energyConfig: EnergyConfigPlayerInput
val profiledEnergy: ProfiledLevelGaugeWidget<*>
constructor(
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)
) : 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()

View File

@ -56,6 +56,8 @@ object MBlockEntities {
val MATTER_RECONSTRUCTOR: BlockEntityType<MatterReconstructorBlockEntity> by registry.register(MNames.MATTER_RECONSTRUCTOR) { BlockEntityType.Builder.of(::MatterReconstructorBlockEntity, MBlocks.MATTER_RECONSTRUCTOR).build(null) }
val FLUID_TANK: BlockEntityType<FluidTankBlockEntity> by registry.register(MNames.FLUID_TANK) { BlockEntityType.Builder.of(::FluidTankBlockEntity, MBlocks.FLUID_TANK).build(null) }
val ANDROID_CHARGER: BlockEntityType<AndroidChargerBlockEntity> by registry.register(MNames.ANDROID_CHARGER) { BlockEntityType.Builder.of(::AndroidChargerBlockEntity, MBlocks.ANDROID_CHARGER).build(null) }
val ANDROID_CHARGER_MIDDLE: BlockEntityType<AndroidChargerMiddleBlockEntity> by registry.register(MNames.ANDROID_CHARGER + "_middle") { BlockEntityType.Builder.of(::AndroidChargerMiddleBlockEntity, MBlocks.ANDROID_CHARGER).build(null) }
val ANDROID_CHARGER_TOP: BlockEntityType<AndroidChargerTopBlockEntity> by registry.register(MNames.ANDROID_CHARGER + "_top") { BlockEntityType.Builder.of(::AndroidChargerTopBlockEntity, MBlocks.ANDROID_CHARGER).build(null) }
val STORAGE_BUS: BlockEntityType<StorageBusBlockEntity> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) }
val STORAGE_IMPORTER: BlockEntityType<StorageImporterBlockEntity> by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) }

View File

@ -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<AndroidStationMenu> by registry.register(MNames.ANDROID_STATION) { MenuType(::AndroidStationMenu, FeatureFlags.VANILLA_SET) }
val ANDROID_CHARGER: MenuType<AndroidChargerMenu> by registry.register(MNames.ANDROID_CHARGER) { MenuType(::AndroidChargerMenu, FeatureFlags.VANILLA_SET) }
val ANDROID_CHARGER: MenuType<AndroidChargerMenu> by registry.register(MNames.ANDROID_CHARGER) { MenuType({ a, b -> AndroidChargerMenu(a, b, null as AndroidChargerBlockEntity?) }, FeatureFlags.VANILLA_SET) }
val BATTERY_BANK: MenuType<BatteryBankMenu> by registry.register(MNames.BATTERY_BANK) { MenuType(::BatteryBankMenu, FeatureFlags.VANILLA_SET) }
val MATTER_DECOMPOSER: MenuType<MatterDecomposerMenu> by registry.register(MNames.MATTER_DECOMPOSER) { MenuType(::MatterDecomposerMenu, FeatureFlags.VANILLA_SET) }
val MATTER_CAPACITOR_BANK: MenuType<MatterCapacitorBankMenu> by registry.register(MNames.MATTER_CAPACITOR_BANK) { MenuType(::MatterCapacitorBankMenu, FeatureFlags.VANILLA_SET) }