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.nbt.CompoundTag;
import net.minecraft.nbt.DoubleTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.item.ItemStack;
import ru.dbotthepony.mc.otm.core.Fraction;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
@MethodsReturnNonnullByDefault
@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) {
public MachineJob(ItemStack stack, double ticks_processing_time, Fraction power_consumption_multiplier) {
this(stack, ticks_processing_time, power_consumption_multiplier, new CompoundTag());
}
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() {
@ -29,8 +27,8 @@ public record MachineJob(ItemStack stack, double ticks_processing_time, Fraction
store_job.put("data", data);
store_job.put("stack", stack.serializeNBT());
store_job.putDouble("ticks_processing_time", ticks_processing_time);
store_job.put("power_consumption_multiplier", power_consumption_multiplier.serializeNBT());
store_job.putDouble("ticks", ticks);
store_job.put("power", power.serializeNBT());
return store_job;
}
@ -41,11 +39,11 @@ public record MachineJob(ItemStack stack, double ticks_processing_time, Fraction
return null;
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);
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 javax.annotation.ParametersAreNonnullByDefault;
import java.math.BigDecimal;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public record WorkTickContext(MachineJob job, Fraction required_power, Fraction extracted_power,
Fraction work_speed) {
public record WorkTickContext(MachineJob job, Fraction requiredPower, Fraction extractedPower, Fraction workSpeed) {
}

View File

@ -46,7 +46,7 @@ public class MatterDecomposerMenu extends PoweredMatteryMenu {
progress = new ProgressGaugeWidget(this);
} else {
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();

View File

@ -29,7 +29,7 @@ public class MatterReplicatorMenu extends PoweredMatteryMenu {
if (tile != null) {
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 {
matter_widget = new LevelGaugeWidget(this);
progress = new ProgressGaugeWidget(this);

View File

@ -25,7 +25,7 @@ import ru.dbotthepony.mc.otm.shapes.BlockShapes
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
class BlockMatterDecomposer : BlockMatteryRotatable(), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
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.Direction;
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.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterReplicator;
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker;
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
import ru.dbotthepony.mc.otm.shapes.BlockShapes;
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
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.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterReplicator
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.shapes.BlockShapes
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class BlockMatterReplicator extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityMatterReplicator(blockPos, blockState);
class BlockMatterReplicator : BlockMatteryRotatable(), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
return BlockEntityMatterReplicator(blockPos, blockState)
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_REPLICATOR ? null : BlockEntityMatteryWorker::basicTicker;
override fun <T : BlockEntity?> getTicker(
p_153212_: Level,
p_153213_: BlockState,
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
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(WorkerState.WORKER_STATE);
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
builder.add(WorkerState.WORKER_STATE)
}
private static final List<VoxelShape> SHAPES;
static {
var def = BlockShapes.MATTER_REPLICATOR.computeShape();
SHAPES = List.of(
def,
def,
def,
BlockShapes.MATTER_REPLICATOR.rotate(Direction.NORTH).computeShape(),
BlockShapes.MATTER_REPLICATOR.rotate(Direction.WEST).computeShape(),
BlockShapes.MATTER_REPLICATOR.rotate(Direction.EAST).computeShape()
);
override fun getShape(
p_60555_: BlockState,
p_60556_: BlockGetter,
p_60557_: BlockPos,
p_60558_: CollisionContext
): VoxelShape {
return SHAPES[p_60555_.getValue(FACING).ordinal]
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
return SHAPES.get(p_60555_.getValue(FACING).ordinal());
companion object {
private val SHAPES: Array<VoxelShape>
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.Direction;
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.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterScanner;
import ru.dbotthepony.mc.otm.block.entity.worker.BlockEntityMatteryWorker;
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState;
import ru.dbotthepony.mc.otm.shapes.BlockShapes;
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
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.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape
import ru.dbotthepony.mc.otm.Registry
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterScanner
import ru.dbotthepony.mc.otm.block.entity.worker.WorkerState
import ru.dbotthepony.mc.otm.shapes.BlockShapes
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class BlockMatterScanner extends BlockMatteryRotatable implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
return new BlockEntityMatterScanner(blockPos, blockState);
class BlockMatterScanner : BlockMatteryRotatable(), EntityBlock {
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity {
return BlockEntityMatterScanner(blockPos, blockState)
}
@Nullable
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level p_153212_, BlockState p_153213_, BlockEntityType<T> p_153214_) {
return p_153212_.isClientSide || p_153214_ != Registry.BlockEntities.MATTER_SCANNER ? null : BlockEntityMatteryWorker::basicTicker;
override fun <T : BlockEntity?> getTicker(
p_153212_: Level,
p_153213_: BlockState,
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
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(WorkerState.WORKER_STATE);
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block, BlockState>) {
super.createBlockStateDefinition(builder)
builder.add(WorkerState.WORKER_STATE)
}
private static final List<VoxelShape> SHAPES;
static {
var def = BlockShapes.MATTER_SCANNER.computeShape();
SHAPES = List.of(
def,
def,
def,
BlockShapes.MATTER_SCANNER.rotate(Direction.NORTH).computeShape(),
BlockShapes.MATTER_SCANNER.rotate(Direction.WEST).computeShape(),
BlockShapes.MATTER_SCANNER.rotate(Direction.EAST).computeShape()
);
override fun getShape(
p_60555_: BlockState,
p_60556_: BlockGetter,
p_60557_: BlockPos,
p_60558_: CollisionContext
): VoxelShape {
return SHAPES[p_60555_.getValue(FACING).ordinal]
}
@Override
@SuppressWarnings("deprecation")
public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
return SHAPES.get(p_60555_.getValue(FACING).ordinal());
companion object {
private val SHAPES: Array<VoxelShape>
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()
}
override fun getNextJob(): MachineJob? {
override fun computeNextJob(): MachineJob? {
val stack = itemContainer.getItem(0)
if (!stack.isEmpty) {
@ -141,7 +141,7 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
if (value != Fraction.ZERO && matter.canReceiveAll(value)) {
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
}
override fun getBaseConsumption(): Fraction {
return BASE_CONSUMPTION
}
fun tick() {
batteryChargeLoop();
workerLoop();

View File

@ -70,10 +70,6 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
return MatterReplicatorMenu(containerID, inventory, this)
}
override fun getBaseConsumption(): Fraction {
return BASE_CONSUMPTION
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
if (!regularSlots.fullyAddItem(job.stack())) {
return MachineJobStatus(false, 20)
@ -84,15 +80,15 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
}
override fun onMatterTaskCreated(task: MatterTask) {
is_idling = false
isIdling = false
}
override fun onMatterTaskUpdated(new_state: MatterTask, old_state: MatterTask) {
is_idling = false
isIdling = false
}
override fun onPatternAdded(state: PatternState) {
is_idling = false
isIdling = false
}
override fun setRemoved() {
@ -107,14 +103,14 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
MatterNetworkGraph.discoverFull(this, node)
}
override fun getNextJob(): MachineJob? {
override fun computeNextJob(): MachineJob? {
val graph = node.graph as MatterNetworkGraph? ?: return null
val allocation = graph.allocateTask(false) ?: return null
val stack = allocation.task().stack(1)
// ????????
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()
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 {
val drainPerTick = MTU_PER_TICK_BD.times(context.work_speed())
val graph = node.graph as MatterNetworkGraph? ?: return MachineJobStatus(false, 20)
val drainPerTick = MTU_PER_TICK_BD.times(context.workSpeed())
val graph = node.graph as? MatterNetworkGraph ?: return MachineJobStatus(false, 20)
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(
{ slot: Int, stack: ItemStack? -> MatterRegistry.canDecompose(stack) },
{ slot: Int, amount: Int, stack: ItemStack? -> is_idling }
{ slot: Int, amount: Int, stack: ItemStack? -> isIdling }
)
// IMatterGraphNode
@ -47,15 +47,15 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
}
override fun onPatternAdded(state: PatternState) {
is_idling = false
isIdling = false
}
override fun onPatternRemoved(state: PatternState) {
is_idling = false
isIdling = false
}
override fun onPatternUpdated(new_state: PatternState, old_state: PatternState) {
is_idling = false
isIdling = false
}
// /IMatterGraphNode
@ -111,10 +111,6 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
super.load(nbt)
}
override fun getBaseConsumption(): Fraction {
return BASE_CONSUMPTION
}
override fun onJobFinish(job: MachineJob): MachineJobStatus {
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 stack = input_slot.getItem(0)
@ -177,7 +173,7 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
copy.count = 1
stack.shrink(1)
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

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

View File

@ -34,7 +34,7 @@ class MatterScannerMenu @JvmOverloads constructor(
addSlot(input)
if (tile != null) {
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }) { tile.cantProcessJob() }
progress = ProgressGaugeWidget(this, { tile.workProgress.toFloat() }, tile::isUnableToProcess)
patterns = LevelGaugeWidget(this,
{ Fraction(tile.getAsMatterGraph()?.getPatternCount()?.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())
batterySlot = BatterySlot(tile.batteryContainer, 0)
}
addSlot(batterySlot)
}
}