diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/AndroidStationBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/AndroidStationBlock.kt index 8c958eb0a..40b71044c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/AndroidStationBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/AndroidStationBlock.kt @@ -6,15 +6,18 @@ import net.minecraft.world.InteractionResult import net.minecraft.world.entity.player.Player 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.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.phys.BlockHitResult import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.VoxelShape import ru.dbotthepony.mc.otm.block.entity.AndroidStationBlockEntity +import ru.dbotthepony.mc.otm.block.entity.WorkerState import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.core.orNull import ru.dbotthepony.mc.otm.registry.MBlockEntities @@ -37,6 +40,11 @@ class AndroidStationBlock : MatteryBlock(), EntityBlock { return super.use(blockState, level, blockPos, ply, hand, blockHitResult) } + override fun createBlockStateDefinition(builder: StateDefinition.Builder) { + super.createBlockStateDefinition(builder) + builder.add(WorkerState.SEMI_WORKER_STATE) + } + override fun getShape( p_151964_: BlockState, p_151965_: BlockGetter, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/AndroidStationBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/AndroidStationBlockEntity.kt index dadc3dd85..7899b6a43 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/AndroidStationBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/AndroidStationBlockEntity.kt @@ -2,17 +2,20 @@ package ru.dbotthepony.mc.otm.block.entity import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component +import net.minecraft.server.level.ServerPlayer import net.minecraft.world.MenuProvider import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Player import net.minecraft.world.inventory.AbstractContainerMenu +import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.phys.AABB import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage import ru.dbotthepony.mc.otm.core.ImpreciseFraction +import ru.dbotthepony.mc.otm.core.ifPresentK import ru.dbotthepony.mc.otm.menu.AndroidStationMenu import ru.dbotthepony.mc.otm.registry.MBlockEntities @@ -26,9 +29,41 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : override val defaultDisplayName: Component get() = MACHINE_NAME - override val energy = WorkerEnergyStorage(this, STORAGE, MAX_IO) + override val energy = object : WorkerEnergyStorage(this@AndroidStationBlockEntity, STORAGE, MAX_IO) { + override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + return super.extractEnergyInner(howMuch, simulate).also { + if (!simulate && this.batteryLevel.isZero) { + if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) { + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) + } + } + } + } + + override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction { + return super.receiveEnergyInner(howMuch, simulate).also { + if (!simulate && it.isPositive) { + if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) { + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) + } + } + } + } + } + + private var tickedOnve = false fun tick() { + if (!tickedOnve) { + tickedOnve = true + + if (energy.batteryLevel.isPositive && blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) { + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) + } else if (energy.batteryLevel.isZero && blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) { + level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) + } + } + batteryChargeLoop() if (isBlockedByRedstone) return @@ -37,10 +72,10 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : val y = blockPos.y.toDouble() val z = blockPos.z.toDouble() - for (ent in level.getEntitiesOfClass(LivingEntity::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0))) { - ent.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresent { + for (ent in level.getEntitiesOfClass(ServerPlayer::class.java, AABB(x, y, z, x + 1.0, y + 2.0, z + 1.0))) { + ent.getCapability(MatteryCapability.MATTERY_PLAYER).ifPresentK { if (!it.isAndroid) - return@ifPresent + return@ifPresentK val missing = it.missingPower diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/WorkerState.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/WorkerState.kt index 2c592bb86..fa98d9a60 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/WorkerState.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/WorkerState.kt @@ -3,19 +3,17 @@ package ru.dbotthepony.mc.otm.block.entity import net.minecraft.util.StringRepresentable import net.minecraft.world.level.block.state.properties.EnumProperty -enum class WorkerState : StringRepresentable { - IDLE, - WORKING, - ERROR; - - companion object { - @JvmField - val WORKER_STATE: EnumProperty = EnumProperty.create("worker", WorkerState::class.java) - @JvmField - val SEMI_WORKER_STATE: EnumProperty = EnumProperty.create("worker", WorkerState::class.java, IDLE, WORKING) - } +enum class WorkerState(private val str: String) : StringRepresentable { + IDLE("idle"), + WORKING("working"), + ERROR("error"); override fun getSerializedName(): String { - return if (this == IDLE) "idle" else if (this == WORKING) "working" else "error" + return str + } + + companion object { + val WORKER_STATE: EnumProperty = EnumProperty.create("worker", WorkerState::class.java) + val SEMI_WORKER_STATE: EnumProperty = EnumProperty.create("worker", WorkerState::class.java, IDLE, WORKING) } }