Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.moguang.ctnhbio.api.entity;

import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController;

import net.createmod.catnip.math.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
Expand Down Expand Up @@ -255,7 +257,9 @@ public void tick() {
if (tickCount % 40 == 0)
if (getHealth() < getMaxHealth()) {
if (getHost() != null && getHost().getHostMachine() instanceof ILivingMachine livingMachine) {
if (livingMachine.getNutrientAmount() >= 2) {
boolean structureOperational = !(livingMachine instanceof IMultiController controller) ||
controller.isStructureOperational();
if (structureOperational && livingMachine.getNutrientAmount() >= 2) {
livingMachine.extractNutrient(2);
heal(1);
var pos = getHost().getHostPos().getCenter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class WorkableLivingMultiblockMachine extends RecipeElectricMultiblockMac

protected LivingMetaMachineEntity machineEntity;
protected TickableSubscription entityBindingSubscription;
protected TickableSubscription growthSubscription;

public WorkableLivingMultiblockMachine(IMachineBlockEntity holder, Object... args) {
super(holder, args);
Expand All @@ -58,13 +59,17 @@ public WorkableLivingMultiblockMachine(IMachineBlockEntity holder, Object... arg

@Override
public LivingMetaMachineEntity getMachineEntity() {
if (machineEntity == null || !machineEntity.isAlive() || machineEntity.isRemoved()) {
if (!isStructureRevalidationPending() &&
(machineEntity == null || !machineEntity.isAlive() || machineEntity.isRemoved())) {
refreshMachineEntityBinding();
}
return machineEntity;
}

protected void refreshMachineEntityBinding() {
if (isStructureRevalidationPending()) {
return;
}
if (holder instanceof LivingMetaMachineBlockEntity blockEntity) {
blockEntity.refreshHostedEntityBinding(true);
machineEntity = blockEntity.getHostedEntity();
Expand All @@ -83,7 +88,9 @@ public float getNutrientCapacity() {

@Override
public void extractNutrient(float amount) {
nutrientHandler.extract(amount);
if (isStructureOperational()) {
nutrientHandler.extract(amount);
}
}

@Override
Expand All @@ -97,7 +104,7 @@ public InteractionResult tryToOpenUI(Player player, InteractionHand hand, BlockH

// 判断是否是食物
if (stack.isEdible()) {
if (!getLevel().isClientSide) {
if (!getLevel().isClientSide && !isStructureRevalidationPending()) {
// 消耗一个物品
if (!player.getAbilities().instabuild) {
stack.shrink(1);
Expand All @@ -109,7 +116,7 @@ public InteractionResult tryToOpenUI(Player player, InteractionHand hand, BlockH
getLevel().playSound(null, getPos().getX(), getPos().getY(), getPos().getZ(),
SoundEvents.GENERIC_EAT, SoundSource.PLAYERS,
1.0f, 1.0f);
if (!isFormed()) checkGrow();
if (!isStructureFormedSnapshot()) checkGrow();
}

return InteractionResult.sidedSuccess(getLevel().isClientSide);
Expand Down Expand Up @@ -150,9 +157,9 @@ public void onLoad() {
super.onLoad();
refreshMachineEntityBinding();
entityBindingSubscription = subscribeServerTick(entityBindingSubscription, this::refreshMachineEntityBinding);
// subscribeServerTick(this::checkGrow);
checkGrow();
subscribeServerTick(this::tickGrow);
// super.onLoad() has already queued the authoritative structure check. Growth waits for that check to
// distinguish a definitive mismatch from a temporarily unloaded structure.
growthSubscription = subscribeServerTick(growthSubscription, this::tickGrow);
}

@Override
Expand All @@ -171,32 +178,37 @@ public void onMachinePlaced(LivingEntity player, ItemStack stack) {
}

public boolean shouldTick(int interval) {
return (!isFormed() && getOffsetTimer() % interval == 0) || getOffsetTimer() % 10 * interval == 0;
return getOffsetTimer() % interval == 0;
}

public void checkGrow() {
if (true || shouldTick(20)) {
isFormed = false;
checkPattern();
if (!isFormed()) {
if (growingBlockPattern == null)
growingBlockPattern = GrowingBlockPattern.getGrowingBlockPattern(getPattern());

if (growingBlockPattern.growPlan.isCompleted())
growingBlockPattern.generateGrowPlan(this, new GrowingBlockPattern.GrowSetting());
}
private boolean canGrow() {
return !isStructureRevalidationPending() && !isStructureFormedSnapshot();
}

public void checkGrow() {
if (!canGrow() || isRemote()) {
return;
}
if (growingBlockPattern == null) {
growingBlockPattern = GrowingBlockPattern.getGrowingBlockPattern(getPattern());
}
if (growingBlockPattern != null && growingBlockPattern.growPlan.isCompleted()) {
growingBlockPattern.generateGrowPlan(this, new GrowingBlockPattern.GrowSetting());
}
}

public void tickGrow() {
if (!canGrow()) {
return;
}
if (shouldTick(20)) {
checkGrow();
}
if (shouldTick(2) &&
getNutrientAmount() >= NUTRIENT_NEEDED_FOR_GROWTH &&
growingBlockPattern != null &&
growingBlockPattern.growPlan.tick()) {
nutrientHandler.extract(NUTRIENT_NEEDED_FOR_GROWTH);
if (growingBlockPattern.growPlan.isCompleted()) checkPattern();
}
// updatePartPositions();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -139,7 +138,9 @@ public BuildTask(BlockPos pos, TraceabilityPredicate predicate) {
}

public boolean execute() {
updateWorldState(context.worldState, pos, predicate);
if (!context.worldState.update(pos, predicate)) {
return false;
}

if (!canReplaceExistingBlock(pos, predicate))
return false;
Expand Down Expand Up @@ -176,20 +177,30 @@ public void add(BuildTask task) {
}

public boolean tick() {
if (isCompleted()) return false;
if (isCompleted() || context.controller.isStructureRevalidationPending()) return false;

// 每tick处理一定数量的方块
try {
for (int i = 0; i < BLOCKS_PER_TICK && !isCompleted(); i++) {
BuildTask task = buildQueue.poll();
while (task != null) {
if (!context.world.isLoaded(task.pos)) {
buildQueue.add(task);
context.controller.setStructureRevalidationPending(true);
return false;
}
if (task.isFluid()) {
fluidQueue.add(task);
} else if (task.execute()) return true;
task = buildQueue.poll();
}
task = fluidQueue.poll();
if (task != null) {
if (!context.world.isLoaded(task.pos)) {
fluidQueue.add(task);
context.controller.setStructureRevalidationPending(true);
return false;
}
return task.execute();
}
}
Expand Down Expand Up @@ -273,17 +284,17 @@ private void initializeBuildContext(@NotNull IMultiController controller, GrowSe

context.world = controller.self().getLevel();

context.worldState = controller.getMultiblockState();
context.settings = setting;
context.controller = controller;
context.centerPos = controller.self().getPos();
// Growth predicates need scratch counters and match context, but must never clean or mutate the controller's
// authoritative state owned by GTM's queued validator.
context.worldState = new MultiblockState(context.world, context.centerPos);
context.worldState.clean();
context.facing = controller.self().getFrontFacing();
context.upwardsFacing = controller.self().getUpwardsFacing();
context.isFlipped = controller.self().isFlipped();
context.minZ = -centerOffset[4];

clearWorldState(context.worldState);
// context.blocks.put(context.centerPos, controller);
}

private int[] calculateLayerRepeatCounts(GrowSetting settings) {
Expand Down Expand Up @@ -470,25 +481,6 @@ public static class BuildContext {
boolean inFluid;
}

private void clearWorldState(MultiblockState worldState) {
try {
Class<?> clazz = Class.forName("com.gregtechceu.gtceu.api.pattern.MultiblockState");
// Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("clean");
method.setAccessible(true);
method.invoke(worldState);
} catch (Exception ignored) {}
}

private void updateWorldState(MultiblockState worldState, BlockPos posIn, TraceabilityPredicate predicate) {
try {
Class<?> clazz = Class.forName("com.gregtechceu.gtceu.api.pattern.MultiblockState");
Method method = clazz.getDeclaredMethod("update", BlockPos.class, TraceabilityPredicate.class);
method.setAccessible(true);
method.invoke(worldState, posIn, predicate);
} catch (Exception ignored) {}
}

private BlockPos setActualRelativeOffset(int x, int y, int z, Direction facing, Direction upwardsFacing,
boolean isFlipped) {
int[] c0 = new int[] { x, y, z }, c1 = new int[3];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public GreatFleshMachine(IMachineBlockEntity holder, Object... args) {
@Override
public void afterWorking() {
super.afterWorking();
if (!isRemote()) {
if (!isRemote() && isStructureOperational()) {
tryDifferentiate();
}
}
Expand All @@ -46,6 +46,9 @@ public void tryDifferentiate() {

// 2. 下一tick销毁所有机器
level.getServer().submit(() -> {
if (!isStructureOperational() || MetaMachine.getMachine(level, getPos()) != this) {
return;
}
for (BlockPos pos : positionsToDestroy) {
level.destroyBlock(pos, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget;
import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity;
import com.gregtechceu.gtceu.api.machine.feature.IMachineLife;
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController;
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IWorkableMultiController;
import com.gregtechceu.gtceu.api.machine.multiblock.RecipeMultiblockMachine;
import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine;
Expand All @@ -26,6 +25,7 @@
import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted;
import com.lowdragmc.lowdraglib.utils.Position;

import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
Expand All @@ -36,8 +36,6 @@
import com.moguang.ctnhbio.api.machine.trait.NeuralModelContainer;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.MustBeInvokedByOverriders;
import org.jetbrains.annotations.NotNull;
import tech.vixhentx.mcmod.ctnhlib.langprovider.Lang;

import java.util.List;
Expand Down Expand Up @@ -77,12 +75,11 @@ public NeuralModelAccessorMachine(IMachineBlockEntity holder, boolean isAdvanced
this.isAdvanced = isAdvanced;
}

@MustBeInvokedByOverriders
@Override
public void removedFromController(@NotNull IMultiController controller) {
super.removedFromController(controller);
if (controllers.isEmpty())
public void onControllerBindingRetired(BlockPos controllerPos, long instanceId) {
if (!isFormed()) {
setLocked(false);
}
}

@Override
Expand Down Expand Up @@ -130,7 +127,7 @@ public boolean canShared() {

private void tryOutputModel() {
var machine = getControllers().stream().findFirst().orElse(null);
if (machine instanceof RecipeMultiblockMachine r && r.isFormed()) {
if (machine instanceof RecipeMultiblockMachine r && r.isStructureOperational()) {
if (r.isActive()) tick = 0;
else if (isOutputModel() && !modelHolder.getStackInSlot(0).isEmpty()) tick++;
if (tick >= ticksPerCycle) {
Expand Down
Loading