Move mattery worker to kotlin and revise its code

This commit is contained in:
DBotThePony 2022-01-14 12:12:10 +07:00
parent 0307431b4b
commit 757f395004
Signed by: DBot
GPG Key ID: DCC23B5715498507
13 changed files with 301 additions and 326 deletions

View File

@ -3,25 +3,23 @@ package ru.dbotthepony.mc.otm.block.entity.worker;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.DoubleTag; import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public record MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier, public record MachineJob(ItemStack stack, double ticks, Fraction power,
CompoundTag data) { CompoundTag data) {
public MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier) { public MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier) {
this(stack, ticks_processing_time, power_consumption_multiplier, new CompoundTag()); this(stack, ticks_processing_time, power_consumption_multiplier, new CompoundTag());
} }
public MachineJob(ItemStack stack, double ticks_processing_time) { public MachineJob(ItemStack stack, double ticks_processing_time) {
this(stack, ticks_processing_time, Fraction.ONE); this(stack, ticks_processing_time, Fraction.ZERO);
} }
public CompoundTag serializeNBT() { public CompoundTag serializeNBT() {
@ -29,8 +27,8 @@ public record MachineJob(ItemStack stack, double ticks_processing_time, Fraction
store_job.put("data", data); store_job.put("data", data);
store_job.put("stack", stack.serializeNBT()); store_job.put("stack", stack.serializeNBT());
store_job.putDouble("ticks_processing_time", ticks_processing_time); store_job.putDouble("ticks", ticks);
store_job.put("power_consumption_multiplier", power_consumption_multiplier.serializeNBT()); store_job.put("power", power.serializeNBT());
return store_job; return store_job;
} }
@ -41,11 +39,11 @@ public record MachineJob(ItemStack stack, double ticks_processing_time, Fraction
return null; return null;
if (nbt instanceof CompoundTag tag) { if (nbt instanceof CompoundTag tag) {
if (tag.get("stack") instanceof CompoundTag stack_tag && tag.get("ticks_processing_time") instanceof DoubleTag ticks_processing_time && tag.contains("power_consumption_multiplier")) { if (tag.get("stack") instanceof CompoundTag stack_tag && tag.get("ticks") instanceof DoubleTag ticks_processing_time && tag.contains("power")) {
ItemStack stack = ItemStack.of(stack_tag); ItemStack stack = ItemStack.of(stack_tag);
if (!stack.isEmpty()) { if (!stack.isEmpty()) {
return new MachineJob(stack, ticks_processing_time.getAsDouble(), Fraction.deserializeNBT(tag.get("power_consumption_multiplier")), tag.getCompound("data")); return new MachineJob(stack, ticks_processing_time.getAsDouble(), Fraction.deserializeNBT(tag.get("power")), tag.getCompound("data"));
} }
} }
} }

View File

@ -4,11 +4,9 @@ import net.minecraft.MethodsReturnNonnullByDefault;
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public record WorkTickContext(MachineJob job, Fraction required_power, Fraction extracted_power, public record WorkTickContext(MachineJob job, Fraction requiredPower, Fraction extractedPower, Fraction workSpeed) {
Fraction work_speed) {
} }

View File

@ -46,7 +46,7 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
progress = new ProgressGaugeWidget(this); progress = new ProgressGaugeWidget(this);
} else { } else {
matter_widget = new LevelGaugeWidget(this, tile.getCapability(MatteryCapability.MATTER).resolve().get()); matter_widget = new LevelGaugeWidget(this, tile.getCapability(MatteryCapability.MATTER).resolve().get());
progress = new ProgressGaugeWidget(this, () -> (float) tile.getWorkProgress(), tile::cantProcessJob); progress = new ProgressGaugeWidget(this, () -> (float) tile.getWorkProgress(), tile::isUnableToProcess);
} }
addInventorySlots(); addInventorySlots();

View File

@ -29,7 +29,7 @@ public class MatterReplicatorMenu extends PoweredMatteryMenu {
if (tile != null) { if (tile != null) {
matter_widget = new LevelGaugeWidget(this, tile.matter); matter_widget = new LevelGaugeWidget(this, tile.matter);
progress = new ProgressGaugeWidget(this, () -> (float) tile.getWorkProgress(), tile::cantProcessJob); progress = new ProgressGaugeWidget(this, () -> (float) tile.getWorkProgress(), tile::isUnableToProcess);
} else { } else {
matter_widget = new LevelGaugeWidget(this); matter_widget = new LevelGaugeWidget(this);
progress = new ProgressGaugeWidget(this); progress = new ProgressGaugeWidget(this);

View File

@ -25,7 +25,7 @@ import ru.dbotthepony.mc.otm.shapes.BlockShapes
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
class BlockMatterDecomposer : BlockMatteryRotatable(), EntityBlock { class BlockMatterDecomposer : BlockMatteryRotatable(), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? { override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
return BlockEntityMatterDecomposer(blockPos, blockState) return BlockEntityMatterDecomposer(blockPos, blockState)
} }

View File

@ -1,68 +1,67 @@
package ru.dbotthepony.mc.otm.block; package ru.dbotthepony.mc.otm.block
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos
import net.minecraft.core.BlockPos; import net.minecraft.core.Direction
import net.minecraft.core.Direction; 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; import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityTicker; 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.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.Registry
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterReplicator
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterReplicator; import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker; import ru.dbotthepony.mc.otm.shapes.BlockShapes
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
import ru.dbotthepony.mc.otm.shapes.BlockShapes;
import javax.annotation.Nullable; class BlockMatterReplicator : BlockMatteryRotatable(), EntityBlock {
import javax.annotation.ParametersAreNonnullByDefault; override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
import java.util.List; return BlockEntityMatterReplicator(blockPos, blockState)
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class BlockMatterReplicator extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityMatterReplicator(blockPos, blockState);
} }
@Nullable override fun <T : BlockEntity?> getTicker(
@Override p_153212_: Level,
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) { p_153213_: BlockState,
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_REPLICATOR ? null : BlockEntityMatteryWorker::basicTicker; p_153214_: BlockEntityType<T>
): BlockEntityTicker<T>? {
if (p_153212_.isClientSide || p_153214_ !== Registry.BlockEntities.MATTER_REPLICATOR)
return null
return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityMatterReplicator) tile.basicTicker() }
} }
@Override override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { super.createBlockStateDefinition(builder)
super.createBlockStateDefinition(builder); builder.add(WorkerState.WORKER_STATE)
builder.add(WorkerState.WORKER_STATE);
} }
private static final List<VoxelShape> SHAPES; override fun getShape(
p_60555_: BlockState,
static { p_60556_: BlockGetter,
var def = BlockShapes.MATTER_REPLICATOR.computeShape(); p_60557_: BlockPos,
p_60558_: CollisionContext
SHAPES = List.of( ): VoxelShape {
def, return SHAPES[p_60555_.getValue(FACING).ordinal]
def,
def,
BlockShapes.MATTER_REPLICATOR.rotate(Direction.NORTH).computeShape(),
BlockShapes.MATTER_REPLICATOR.rotate(Direction.WEST).computeShape(),
BlockShapes.MATTER_REPLICATOR.rotate(Direction.EAST).computeShape()
);
} }
@Override companion object {
@SuppressWarnings("deprecation") private val SHAPES: Array<VoxelShape>
public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
return SHAPES.get(p_60555_.getValue(FACING).ordinal()); init {
val def = BlockShapes.MATTER_REPLICATOR.computeShape()
SHAPES = arrayOf(
def,
def,
def,
BlockShapes.MATTER_REPLICATOR.rotate(Direction.NORTH).computeShape(),
BlockShapes.MATTER_REPLICATOR.rotate(Direction.WEST).computeShape(),
BlockShapes.MATTER_REPLICATOR.rotate(Direction.EAST).computeShape()
)
}
} }
} }

View File

@ -1,68 +1,67 @@
package ru.dbotthepony.mc.otm.block; package ru.dbotthepony.mc.otm.block
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos
import net.minecraft.core.BlockPos; import net.minecraft.core.Direction
import net.minecraft.core.Direction; 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; import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityTicker
import net.minecraft.world.level.block.entity.BlockEntityTicker; 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.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.Registry
import ru.dbotthepony.mc.otm.Registry; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterScanner
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterScanner; import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker; import ru.dbotthepony.mc.otm.shapes.BlockShapes
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
import ru.dbotthepony.mc.otm.shapes.BlockShapes;
import javax.annotation.Nullable; class BlockMatterScanner : BlockMatteryRotatable(), EntityBlock {
import javax.annotation.ParametersAreNonnullByDefault; override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
import java.util.List; return BlockEntityMatterScanner(blockPos, blockState)
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class BlockMatterScanner extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityMatterScanner(blockPos, blockState);
} }
@Nullable override fun <T : BlockEntity?> getTicker(
@Override p_153212_: Level,
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) { p_153213_: BlockState,
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_SCANNER ? null : BlockEntityMatteryWorker::basicTicker; p_153214_: BlockEntityType<T>
): BlockEntityTicker<T>? {
if (p_153212_.isClientSide || p_153214_ !== Registry.BlockEntities.MATTER_SCANNER)
return null
return BlockEntityTicker { _, _, _, tile -> if (tile is BlockEntityMatterScanner) tile.basicTicker() }
} }
@Override override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) { super.createBlockStateDefinition(builder)
super.createBlockStateDefinition(builder); builder.add(WorkerState.WORKER_STATE)
builder.add(WorkerState.WORKER_STATE);
} }
private static final List<VoxelShape> SHAPES; override fun getShape(
p_60555_: BlockState,
static { p_60556_: BlockGetter,
var def = BlockShapes.MATTER_SCANNER.computeShape(); p_60557_: BlockPos,
p_60558_: CollisionContext
SHAPES = List.of( ): VoxelShape {
def, return SHAPES[p_60555_.getValue(FACING).ordinal]
def,
def,
BlockShapes.MATTER_SCANNER.rotate(Direction.NORTH).computeShape(),
BlockShapes.MATTER_SCANNER.rotate(Direction.WEST).computeShape(),
BlockShapes.MATTER_SCANNER.rotate(Direction.EAST).computeShape()
);
} }
@Override companion object {
@SuppressWarnings("deprecation") private val SHAPES: Array<VoxelShape>
public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
return SHAPES.get(p_60555_.getValue(FACING).ordinal()); init {
val def = BlockShapes.MATTER_SCANNER.computeShape()
SHAPES = arrayOf(
def,
def,
def,
BlockShapes.MATTER_SCANNER.rotate(Direction.NORTH).computeShape(),
BlockShapes.MATTER_SCANNER.rotate(Direction.WEST).computeShape(),
BlockShapes.MATTER_SCANNER.rotate(Direction.EAST).computeShape()
)
}
} }
} }

View File

@ -129,7 +129,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
return MachineJobStatus() return MachineJobStatus()
} }
override fun getNextJob(): MachineJob? { override fun computeNextJob(): MachineJob? {
val stack = itemContainer.getItem(0) val stack = itemContainer.getItem(0)
if (!stack.isEmpty) { if (!stack.isEmpty) {
@ -141,7 +141,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
if (value != Fraction.ZERO && matter.canReceiveAll(value)) { if (value != Fraction.ZERO && matter.canReceiveAll(value)) {
stack.shrink(1) stack.shrink(1)
return MachineJob(copy, value.toDouble() * 12500.0) return MachineJob(copy, value.toDouble() * 12500.0, BASE_CONSUMPTION)
} }
} }
} }
@ -165,10 +165,6 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
return matter return matter
} }
override fun getBaseConsumption(): Fraction {
return BASE_CONSUMPTION
}
fun tick() { fun tick() {
batteryChargeLoop(); batteryChargeLoop();
workerLoop(); workerLoop();

View File

@ -70,10 +70,6 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
return MatterReplicatorMenu(containerID, inventory, this) return MatterReplicatorMenu(containerID, inventory, this)
} }
override fun getBaseConsumption(): Fraction {
return BASE_CONSUMPTION
}
override fun onJobFinish(job: MachineJob): MachineJobStatus { override fun onJobFinish(job: MachineJob): MachineJobStatus {
if (!regularSlots.fullyAddItem(job.stack())) { if (!regularSlots.fullyAddItem(job.stack())) {
return MachineJobStatus(false, 20) return MachineJobStatus(false, 20)
@ -84,15 +80,15 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
} }
override fun onMatterTaskCreated(task: MatterTask) { override fun onMatterTaskCreated(task: MatterTask) {
is_idling = false isIdling = false
} }
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) { override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
is_idling = false isIdling = false
} }
override fun onPatternAdded(state: PatternState) { override fun onPatternAdded(state: PatternState) {
is_idling = false isIdling = false
} }
override fun setRemoved() { override fun setRemoved() {
@ -107,14 +103,14 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
MatterNetworkGraph.discoverFull(this, node) MatterNetworkGraph.discoverFull(this, node)
} }
override fun getNextJob(): MachineJob? { override fun computeNextJob(): MachineJob? {
val graph = node.graph as MatterNetworkGraph? ?: return null val graph = node.graph as MatterNetworkGraph? ?: return null
val allocation = graph.allocateTask(false) ?: return null val allocation = graph.allocateTask(false) ?: return null
val stack = allocation.task().stack(1) val stack = allocation.task().stack(1)
// ???????? // ????????
if (!MatterRegistry.hasMatterValue(stack)) return null if (!MatterRegistry.hasMatterValue(stack)) return null
val job = MachineJob(stack, MatterRegistry.getMatterValue(stack).toDouble() * TICKS_PER_MTU) val job = MachineJob(stack, MatterRegistry.getMatterValue(stack).toDouble() * TICKS_PER_MTU, BASE_CONSUMPTION)
job.data["task"] = allocation.task.serializeNBT() job.data["task"] = allocation.task.serializeNBT()
if (allocation.pattern != null) job.data["pattern"] = allocation.pattern!!.serializeNBT() if (allocation.pattern != null) job.data["pattern"] = allocation.pattern!!.serializeNBT()
@ -123,8 +119,8 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
} }
override fun onWorkTick(context: WorkTickContext): MachineJobStatus { override fun onWorkTick(context: WorkTickContext): MachineJobStatus {
val drainPerTick = MTU_PER_TICK_BD.times(context.work_speed()) val drainPerTick = MTU_PER_TICK_BD.times(context.workSpeed())
val graph = node.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 20) val graph = node.graph as? MatterNetworkGraph ?: return MachineJobStatus(false, 20)
if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) { if (matter.extractMatterInner(drainPerTick, true) < drainPerTick) {
// в машине недостаточно материи // в машине недостаточно материи

View File

@ -38,7 +38,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
private val inputHandler = input_slot.handler( private val inputHandler = input_slot.handler(
{ slot: Int, stack: ItemStack? -> MatterRegistry.canDecompose(stack) }, { slot: Int, stack: ItemStack? -> MatterRegistry.canDecompose(stack) },
{ slot: Int, amount: Int, stack: ItemStack? -> is_idling } { slot: Int, amount: Int, stack: ItemStack? -> isIdling }
) )
// IMatterGraphNode // IMatterGraphNode
@ -47,15 +47,15 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
} }
override fun onPatternAdded(state: PatternState) { override fun onPatternAdded(state: PatternState) {
is_idling = false isIdling = false
} }
override fun onPatternRemoved(state: PatternState) { override fun onPatternRemoved(state: PatternState) {
is_idling = false isIdling = false
} }
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) { override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
is_idling = false isIdling = false
} }
// /IMatterGraphNode // /IMatterGraphNode
@ -111,10 +111,6 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
super.load(nbt) super.load(nbt)
} }
override fun getBaseConsumption(): Fraction {
return BASE_CONSUMPTION
}
override fun onJobFinish(job: MachineJob): MachineJobStatus { override fun onJobFinish(job: MachineJob): MachineJobStatus {
val grid = matterNode.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 100) val grid = matterNode.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 100)
@ -148,7 +144,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
} }
} }
override fun getNextJob(): MachineJob? { override fun computeNextJob(): MachineJob? {
val grid = matterNode.graph as MatterNetworkGraph? ?: return null val grid = matterNode.graph as MatterNetworkGraph? ?: return null
val stack = input_slot.getItem(0) val stack = input_slot.getItem(0)
@ -177,7 +173,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
copy.count = 1 copy.count = 1
stack.shrink(1) stack.shrink(1)
input_slot.setChanged() input_slot.setChanged()
return MachineJob(copy, MatterRegistry.getMatterValue(copy).toDouble() * 35000.0) return MachineJob(copy, MatterRegistry.getMatterValue(copy).toDouble() * 35000.0, BASE_CONSUMPTION)
} }
return null return null

View File

@ -1,267 +1,258 @@
package ru.dbotthepony.mc.otm.block.entity.worker; package ru.dbotthepony.mc.otm.block.entity.worker
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault
import net.minecraft.core.BlockPos; import javax.annotation.ParametersAreNonnullByDefault
import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.nbt.DoubleTag; import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.block.Block; import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.nbt.CompoundTag
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.nbt.DoubleTag
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.Level
import ru.dbotthepony.mc.otm.OverdriveThatMatters; import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered; import net.minecraft.world.level.block.entity.BlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability; import ru.dbotthepony.mc.otm.core.Fraction
import ru.dbotthepony.mc.otm.core.Fraction; import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.set
import javax.annotation.Nonnull; abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) :
import javax.annotation.Nullable; BlockEntityMatteryPowered(p_155228_, p_155229_, p_155230_) {
import javax.annotation.ParametersAreNonnullByDefault; var workTicks = 0.0
import java.math.BigDecimal; protected set
@MethodsReturnNonnullByDefault var throttleTicks = 0
@ParametersAreNonnullByDefault protected set
abstract public class BlockEntityMatteryWorker extends BlockEntityMatteryPowered {
public BlockEntityMatteryWorker(BlockEntityType<?> p_155228_, BlockPos p_155229_, BlockState p_155230_) {
super(p_155228_, p_155229_, p_155230_);
}
protected abstract Fraction getBaseConsumption(); var currentJob: MachineJob? = null
protected set
protected Fraction consumptionPerWork() { // если isIdling То ничего не делать
return getBaseConsumption(); // isIdling должна быть выставлена в true если что то изменилось, что могло создать работу
} var isIdling = false
protected set
protected double work_ticks = 0; val isUnableToProcess: Boolean get() = throttleTicks > 0
protected int throttle_ticks = 0;
protected MachineJob current_job;
// if is_idling is true, then workerLoop() does nothing val workProgress: Double
protected boolean is_idling = false; get() {
val currentJob = currentJob ?: return 0.0
@Nullable return (workTicks / currentJob.ticks()).coerceAtMost(1.0)
public MachineJob getCurrentJob() {
return current_job;
}
public boolean cantProcessJob() {
return throttle_ticks > 0;
}
@Override
public void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
nbt.putDouble("work_ticks", work_ticks);
if (current_job != null) {
nbt.put("current_job", current_job.serializeNBT());
} }
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)
nbt["work_ticks"] = workTicks
currentJob?.let { nbt["current_job"] = it.serializeNBT() }
} }
@Override override fun load(nbt: CompoundTag) {
public void load(CompoundTag nbt) { super.load(nbt)
super.load(nbt);
if (nbt.get("work_ticks") instanceof DoubleTag tag) nbt.ifHas("work_ticks", DoubleTag::class.java) {
work_ticks = tag.getAsDouble(); workTicks = it.asDouble
}
current_job = MachineJob.deserializeNBT(nbt.get("current_job")); currentJob = MachineJob.deserializeNBT(nbt["current_job"])
if (currentJob == null)
if (current_job == null) workTicks = 0.0
work_ticks = 0d;
} }
@Override override fun setChanged() {
public void setChanged() { super.setChanged()
super.setChanged(); isIdling = false
is_idling = false; }
override fun setChangedLight() {
super.setChangedLight()
isIdling = false
} }
/** /**
* @param job current job * @param job current job
* @return whenever machine can finish it's job. return false if machine for whatever reason can't finish it's job, * @return whenever machine can finish it's job. return false if machine for whatever reason can't finish it's job,
* waiting on conditions to be met * waiting on conditions to be met
*/ */
abstract protected MachineJobStatus onJobFinish(MachineJob job); protected abstract fun onJobFinish(job: MachineJob): MachineJobStatus
/** /**
* @param context context for current job * @param context context for current job
* @return whenever machine can perform it * @return whenever machine can perform it
*/ */
protected MachineJobStatus onWorkTick(WorkTickContext context) { protected open fun onWorkTick(context: WorkTickContext): MachineJobStatus {
return new MachineJobStatus(); return MachineJobStatus()
} }
private int idle_ticks_anim = 0; private var idleTicksAnim = 0
private int working_ticks_anim = 0; private var workingTicksAnim = 0
private int error_ticks_anim = 0; private var errorTicksAnim = 0
@Override override fun redstoneStatusUpdated(new_blocked: Boolean, old_blocked: Boolean) {
protected void redstoneStatusUpdated(boolean new_blocked, boolean old_blocked) { super.redstoneStatusUpdated(new_blocked, old_blocked)
super.redstoneStatusUpdated(new_blocked, old_blocked); isIdling = new_blocked
is_idling = new_blocked;
} }
protected void workerLoop() { protected fun workerLoop() {
if (level != null && error_ticks_anim > 20 && getBlockState().hasProperty(WorkerState.WORKER_STATE) && getBlockState().getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) { val level = level ?: return
level.setBlock(getBlockPos(), getBlockState().setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS);
if (errorTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.ERROR) {
level.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.ERROR), Block.UPDATE_CLIENTS)
} }
if (throttle_ticks > 0) { if (throttleTicks > 0) {
working_ticks_anim = 0; workingTicksAnim = 0
idle_ticks_anim = 0; idleTicksAnim = 0
throttle_ticks--; throttleTicks--
error_ticks_anim++; errorTicksAnim++
if (throttle_ticks > 0) if (throttleTicks > 0)
return; return
} }
if (is_idling) { if (isIdling) {
working_ticks_anim = 0; workingTicksAnim = 0
error_ticks_anim = 0; errorTicksAnim = 0
idle_ticks_anim++; idleTicksAnim++
if (level != null && idle_ticks_anim > 20 && getBlockState().hasProperty(WorkerState.WORKER_STATE) && getBlockState().getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) { if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
level.setBlock(getBlockPos(), getBlockState().setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS); level.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
} }
return; return
} }
if (current_job == null) { var currentJob = currentJob
if (isBlockedByRedstone()) {
is_idling = true; if (currentJob == null) {
return; if (isBlockedByRedstone) {
isIdling = true
return
} }
MachineJob input = getNextJob(); val input = computeNextJob()
if (input == null) { if (input == null) {
is_idling = true; isIdling = true
working_ticks_anim = 0; workingTicksAnim = 0
return; return
} }
current_job = input; this.currentJob = input
currentJob = input
} }
if (isBlockedByRedstone()) { if (isBlockedByRedstone) {
is_idling = true; isIdling = true
return; return
} }
if (current_job.power_consumption_multiplier().compareTo(Fraction.ZERO) != 0 && energy.getBatteryLevel().compareTo(Fraction.ZERO) == 0) { if (!currentJob.power.isZero() && energy.batteryLevel.isZero()) {
idle_ticks_anim++; idleTicksAnim++
if (level != null && idle_ticks_anim > 20 && getBlockState().hasProperty(WorkerState.WORKER_STATE) && getBlockState().getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) { if (idleTicksAnim > 20 && blockState.hasProperty(WorkerState.WORKER_STATE) && blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.IDLE) {
level.setBlock(getBlockPos(), getBlockState().setValue(WorkerState.WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS); level.setBlock(
blockPos,
blockState.setValue(WorkerState.WORKER_STATE, WorkerState.IDLE),
Block.UPDATE_CLIENTS
)
} }
return; return
} }
idle_ticks_anim = 0; idleTicksAnim = 0
if (work_ticks < current_job.ticks_processing_time()) { if (workTicks < currentJob.ticks) {
if (current_job.power_consumption_multiplier().compareTo(Fraction.ZERO) != 0) { if (!currentJob.power.isZero()) {
var required_power = consumptionPerWork().times(current_job.power_consumption_multiplier()); val extractedPower = energy.extractEnergyInner(currentJob.power, true)
var extracted_power = energy.extractEnergyInner(required_power, true); val workSpeed = extractedPower.div(currentJob.power)
var work_speed = extracted_power.div(required_power);
MachineJobStatus status = onWorkTick(new WorkTickContext(current_job, required_power, extracted_power, work_speed)); val status = onWorkTick(WorkTickContext(currentJob, currentJob.power, extractedPower, workSpeed))
if (!status.valid()) { if (!status.valid()) {
throttle_ticks += status.throttle(); throttleTicks += status.throttle
return; return
} }
working_ticks_anim++; workingTicksAnim++
error_ticks_anim = 0; errorTicksAnim = 0
double new_work_ticks = work_speed.toDouble() + work_ticks; val updatedWorkTicks = workSpeed.toDouble() + workTicks
if (new_work_ticks > current_job.ticks_processing_time()) { if (updatedWorkTicks > currentJob.ticks) {
work_ticks = current_job.ticks_processing_time(); workTicks = currentJob.ticks
energy.extractEnergyInner(extracted_power.times(1d - (new_work_ticks - current_job.ticks_processing_time())), false);
energy.extractEnergyInner(
extractedPower.times(1.0 - (updatedWorkTicks - currentJob.ticks())),
false
)
} else { } else {
work_ticks = new_work_ticks; workTicks = updatedWorkTicks
energy.extractEnergyInner(extracted_power, false); energy.extractEnergyInner(extractedPower, false)
if (work_ticks >= current_job.ticks_processing_time()) { if (workTicks >= currentJob.ticks) {
MachineJobStatus finish = onJobFinish(current_job); val finish = onJobFinish(currentJob)
if (finish.valid()) { if (finish.valid) {
current_job = null; this.currentJob = null
work_ticks = 0d; workTicks = 0.0
} else { } else {
throttle_ticks += finish.throttle(); throttleTicks += finish.throttle
} }
} }
} }
} else { } else {
MachineJobStatus status = onWorkTick(new WorkTickContext(current_job, Fraction.ZERO, Fraction.ZERO, Fraction.ONE)); val status = onWorkTick(WorkTickContext(currentJob, Fraction.ZERO, Fraction.ZERO, Fraction.ONE))
if (!status.valid()) { if (!status.valid) {
throttle_ticks += status.throttle(); throttleTicks += status.throttle()
return; return
} }
working_ticks_anim++; workingTicksAnim++
error_ticks_anim = 0; errorTicksAnim = 0
work_ticks += 1d; workTicks += 1.0
if (work_ticks >= current_job.ticks_processing_time()) { if (workTicks >= currentJob.ticks) {
MachineJobStatus finish = onJobFinish(current_job); val finish = onJobFinish(currentJob)
if (finish.valid()) { if (finish.valid()) {
current_job = null; this.currentJob = null
work_ticks = 0d; workTicks = 0.0
} else { } else {
throttle_ticks += finish.throttle(); throttleTicks += finish.throttle
} }
} }
} }
} else { } else {
MachineJobStatus finish = onJobFinish(current_job); val finish = onJobFinish(currentJob)
if (finish.valid()) { if (finish.valid()) {
current_job = null; this.currentJob = null
work_ticks = 0d; workTicks = 0.0
error_ticks_anim = 0; errorTicksAnim = 0
} else { } else {
throttle_ticks += finish.throttle(); throttleTicks += finish.throttle
error_ticks_anim++; errorTicksAnim++
} }
} }
if (level != null && (working_ticks_anim > 20 && error_ticks_anim == 0) && getBlockState().hasProperty(WorkerState.WORKER_STATE) && getBlockState().getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING) { if (workingTicksAnim > 20 &&
level.setBlock(getBlockPos(), getBlockState().setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS); errorTicksAnim == 0 &&
blockState.hasProperty(WorkerState.WORKER_STATE) &&
blockState.getValue(WorkerState.WORKER_STATE) != WorkerState.WORKING)
{
level.setBlock(blockPos, blockState.setValue(WorkerState.WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
} }
} }
public double getWorkTicks() {
return work_ticks;
}
public double getWorkProgress() {
if (current_job == null)
return 0d;
return Math.min(1d, work_ticks / current_job.ticks_processing_time());
}
/** /**
* Determine which item can be processed from input slots if idling * Determine which item can be processed from input slots if idling
* @return any item in input slots. null if no work is available * @return any item in input slots. null if no work is available
*/ */
@Nullable protected abstract fun computeNextJob(): MachineJob?
protected abstract MachineJob getNextJob();
public static <T extends BlockEntity> void basicTicker(Level level, BlockPos blockPos, BlockState blockState, T t) { fun basicTicker() {
if (t instanceof BlockEntityMatteryWorker tile) { batteryChargeLoop()
tile.batteryChargeLoop(); workerLoop()
tile.workerLoop();
}
} }
} }

View File

@ -34,7 +34,7 @@ class MatterScannerMenu @JvmOverloads constructor(
addSlot(input) addSlot(input)
if (tile != null) { if (tile != null) {
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }) { tile.cantProcessJob() } progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }, tile::isUnableToProcess)
patterns = LevelGaugeWidget(this, patterns = LevelGaugeWidget(this,
{ Fraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) }, { Fraction(tile.getAsMatterGraph()?.getPatternCount()?.toBigInteger() ?: BigInteger.ZERO) },
{ Fraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) }) { Fraction(tile.getAsMatterGraph()?.getPatternCapacity()?.toBigInteger() ?: BigInteger.ZERO) })

View File

@ -24,5 +24,7 @@ abstract class PoweredMatteryMenu protected constructor(
powerWidget = LevelGaugeWidget(this, tile.getCapability(MatteryCapability.ENERGY).resolve().get()) powerWidget = LevelGaugeWidget(this, tile.getCapability(MatteryCapability.ENERGY).resolve().get())
batterySlot = BatterySlot(tile.batteryContainer, 0) batterySlot = BatterySlot(tile.batteryContainer, 0)
} }
addSlot(batterySlot)
} }
} }