超级合成核心修复影子库存问题
This commit is contained in:
parent
8fd56ce4ef
commit
4fef441e8d
|
|
@ -1,228 +1,87 @@
|
||||||
package com.extendedae_plus.content.matrix;
|
package com.extendedae_plus.content.matrix;
|
||||||
|
|
||||||
import appeng.api.config.Actionable;
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
|
||||||
import appeng.api.inventories.InternalInventory;
|
import appeng.api.inventories.InternalInventory;
|
||||||
import appeng.api.networking.IGridNode;
|
|
||||||
import appeng.api.networking.security.IActionSource;
|
import appeng.api.networking.security.IActionSource;
|
||||||
import appeng.api.networking.storage.IStorageService;
|
|
||||||
import appeng.api.networking.ticking.TickRateModulation;
|
|
||||||
import appeng.api.networking.ticking.TickingRequest;
|
|
||||||
import appeng.api.stacks.AEItemKey;
|
|
||||||
import appeng.api.stacks.GenericStack;
|
|
||||||
import appeng.api.stacks.KeyCounter;
|
|
||||||
import appeng.util.inv.CombinedInternalInventory;
|
import appeng.util.inv.CombinedInternalInventory;
|
||||||
import com.extendedae_plus.init.ModBlockEntities;
|
import com.extendedae_plus.init.ModBlockEntities;
|
||||||
|
import com.extendedae_plus.mixin.extendedae.accessor.TileAssemblerMatrixCrafterAccessor;
|
||||||
|
import com.extendedae_plus.mixin.minecraft.accessor.BlockEntityAccessor;
|
||||||
import com.glodblock.github.extendedae.common.me.CraftingMatrixThread;
|
import com.glodblock.github.extendedae.common.me.CraftingMatrixThread;
|
||||||
import com.glodblock.github.extendedae.common.me.CraftingThread;
|
import com.glodblock.github.extendedae.common.me.CraftingThread;
|
||||||
import com.glodblock.github.extendedae.common.me.matrix.ClusterAssemblerMatrix;
|
|
||||||
import com.glodblock.github.extendedae.common.tileentities.matrix.TileAssemblerMatrixCrafter;
|
import com.glodblock.github.extendedae.common.tileentities.matrix.TileAssemblerMatrixCrafter;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
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 java.util.List;
|
|
||||||
|
|
||||||
public class CrafterCorePlusBlockEntity extends TileAssemblerMatrixCrafter {
|
public class CrafterCorePlusBlockEntity extends TileAssemblerMatrixCrafter {
|
||||||
|
|
||||||
public static final int MAX_THREAD = 32;
|
public static final int MAX_THREAD = 32;
|
||||||
|
|
||||||
private final CraftingThread[] threads = new CraftingThread[MAX_THREAD];
|
private int activeThreadMask = 0;
|
||||||
private final InternalInventory internalInv;
|
|
||||||
private final BlockEntityType<?> overriddenType;
|
|
||||||
private short states = 0;
|
|
||||||
|
|
||||||
public CrafterCorePlusBlockEntity(BlockPos pos, BlockState blockState) {
|
public CrafterCorePlusBlockEntity(BlockPos pos, BlockState blockState) {
|
||||||
super(pos, blockState);
|
super(pos, blockState);
|
||||||
this.overriddenType = ModBlockEntities.ASSEMBLER_MATRIX_CRAFTER_PLUS_BE.get();
|
|
||||||
|
|
||||||
InternalInventory[] inventories = new InternalInventory[MAX_THREAD];
|
((BlockEntityAccessor) (Object) this)
|
||||||
for (int i = 0; i < MAX_THREAD; i++) {
|
.extendedae_plus$setType(ModBlockEntities.ASSEMBLER_MATRIX_CRAFTER_PLUS_BE.get());
|
||||||
int finalI = i;
|
|
||||||
this.threads[i] = new CraftingMatrixThread(this, this::getSrc, (signal) -> this.changeState(finalI, signal));
|
|
||||||
inventories[i] = this.threads[i].getInternalInventory();
|
|
||||||
}
|
|
||||||
this.internalInv = new CombinedInternalInventory(inventories);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void changeState(int index, boolean state) {
|
var threads = new CraftingThread[MAX_THREAD];
|
||||||
boolean oldState = this.states > 0;
|
var inventories = new InternalInventory[MAX_THREAD];
|
||||||
if (state) {
|
for (int x = 0; x < MAX_THREAD; x++) {
|
||||||
this.states |= (short)(1 << index);
|
final int index = x;
|
||||||
} else {
|
threads[index] = new CraftingMatrixThread(this, this::getSrc, signal -> this.changeState(index, signal));
|
||||||
this.states &= (short)(~(1 << index));
|
inventories[index] = threads[index].getInternalInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state) {
|
var accessor = (TileAssemblerMatrixCrafterAccessor) (Object) this;
|
||||||
if (!oldState) {
|
accessor.extendedae_plus$setThreads(threads);
|
||||||
this.getMainNode().ifPresent((grid, node) -> grid.getTickManager().wakeDevice(node));
|
accessor.extendedae_plus$setInternalInv(new CombinedInternalInventory(inventories));
|
||||||
}
|
|
||||||
} else if (oldState && this.states <= 0) {
|
|
||||||
this.getMainNode().ifPresent((grid, node) -> grid.getTickManager().sleepDevice(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private IActionSource getSrc() {
|
|
||||||
return this.cluster.getSrc();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int usedThread() {
|
|
||||||
int count = 0;
|
|
||||||
for (CraftingThread thread : this.threads) {
|
|
||||||
if (!thread.getInternalInventory().isEmpty()) {
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
double scale = (double) TileAssemblerMatrixCrafter.MAX_THREAD / MAX_THREAD;
|
|
||||||
int reported = (int) Math.ceil(count * scale);
|
|
||||||
return Math.min(TileAssemblerMatrixCrafter.MAX_THREAD, reported);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean pushJob(IPatternDetails patternDetails, KeyCounter[] inputHolder) {
|
|
||||||
for (CraftingThread thread : this.threads) {
|
|
||||||
if (thread.acceptJob(patternDetails, inputHolder, Direction.DOWN)) {
|
|
||||||
if (this.cluster != null) {
|
|
||||||
this.cluster.updateCrafter(this);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
for (CraftingThread thread : this.threads) {
|
|
||||||
thread.stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAdditional(CompoundTag tag) {
|
public void saveAdditional(CompoundTag tag) {
|
||||||
super.saveAdditional(tag);
|
super.saveAdditional(tag);
|
||||||
for (int i = 0; i < MAX_THREAD; i++) {
|
|
||||||
tag.put("#ct" + i, this.threads[i].writeNBT());
|
var threads = ((TileAssemblerMatrixCrafterAccessor) (Object) this).extendedae_plus$getThreads();
|
||||||
|
for (int x = TileAssemblerMatrixCrafter.MAX_THREAD; x < MAX_THREAD; x++) {
|
||||||
|
tag.put("#ct" + x, threads[x].writeNBT());
|
||||||
}
|
}
|
||||||
CompoundTag invTag = new CompoundTag();
|
|
||||||
for (int i = 0; i < this.internalInv.size(); i++) {
|
|
||||||
invTag.put("item" + i, this.internalInv.getStackInSlot(i).save(new CompoundTag()));
|
|
||||||
}
|
|
||||||
tag.put("inv", invTag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadTag(CompoundTag tag) {
|
public void loadTag(CompoundTag tag) {
|
||||||
super.loadTag(tag);
|
super.loadTag(tag);
|
||||||
for (int i = 0; i < MAX_THREAD; i++) {
|
|
||||||
if (tag.contains("#ct" + i)) {
|
var threads = ((TileAssemblerMatrixCrafterAccessor) (Object) this).extendedae_plus$getThreads();
|
||||||
this.threads[i].readNBT(tag.getCompound("#ct" + i));
|
for (int x = TileAssemblerMatrixCrafter.MAX_THREAD; x < MAX_THREAD; x++) {
|
||||||
|
if (tag.contains("#ct" + x)) {
|
||||||
|
threads[x].readNBT(tag.getCompound("#ct" + x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CompoundTag invTag = tag.getCompound("inv");
|
|
||||||
for (int i = 0; i < this.internalInv.size(); i++) {
|
|
||||||
this.internalInv.setItemDirect(i, ItemStack.of(invTag.getCompound("item" + i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ItemStack pushResult(ItemStack stack, Direction direction) {
|
|
||||||
if (stack.isEmpty()) {
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
var grid = this.getMainNode().getGrid();
|
|
||||||
if (grid != null) {
|
|
||||||
IStorageService storage = grid.getService(IStorageService.class);
|
|
||||||
if (storage != null) {
|
|
||||||
long inserted = storage.getInventory().insert(
|
|
||||||
AEItemKey.of(stack),
|
|
||||||
stack.getCount(),
|
|
||||||
Actionable.MODULATE,
|
|
||||||
this.cluster == null ? null : this.cluster.getSrc()
|
|
||||||
);
|
|
||||||
if (inserted == 0) {
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
this.saveChanges();
|
|
||||||
if (inserted != stack.getCount()) {
|
|
||||||
return stack.copyWithCount((int) (stack.getCount() - inserted));
|
|
||||||
}
|
|
||||||
return ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void add(ClusterAssemblerMatrix cluster) {
|
|
||||||
cluster.addCrafter(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TickingRequest getTickingRequest(IGridNode node) {
|
|
||||||
boolean isAwake = false;
|
|
||||||
for (CraftingThread thread : this.threads) {
|
|
||||||
thread.recalculatePlan();
|
|
||||||
thread.updateSleepiness();
|
|
||||||
isAwake |= thread.isAwake();
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TickingRequest(1, 1, !isAwake, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) {
|
|
||||||
if (this.cluster == null) {
|
|
||||||
return TickRateModulation.SLEEP;
|
|
||||||
}
|
|
||||||
|
|
||||||
TickRateModulation rate = TickRateModulation.SLEEP;
|
|
||||||
for (CraftingThread thread : this.threads) {
|
|
||||||
if (thread.isAwake()) {
|
|
||||||
TickRateModulation threadRate = thread.tick(this.cluster.getSpeedCore(), ticksSinceLastCall);
|
|
||||||
if (threadRate.ordinal() > rate.ordinal()) {
|
|
||||||
rate = threadRate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.cluster.updateCrafter(this);
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onChangeInventory(InternalInventory inv, int slot) {
|
|
||||||
for (CraftingThread thread : this.threads) {
|
|
||||||
if (inv == thread.getInternalInventory()) {
|
|
||||||
thread.recalculatePlan();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addAdditionalDrops(Level level, BlockPos pos, List<ItemStack> drops) {
|
|
||||||
super.addAdditionalDrops(level, pos, drops);
|
|
||||||
for (ItemStack stack : this.internalInv) {
|
|
||||||
GenericStack genericStack = GenericStack.unwrapItemStack(stack);
|
|
||||||
if (genericStack != null) {
|
|
||||||
genericStack.what().addDrops(genericStack.amount(), drops, level, pos);
|
|
||||||
} else {
|
|
||||||
drops.add(stack);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clearContent() {
|
|
||||||
super.clearContent();
|
|
||||||
this.internalInv.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockEntityType<?> getType() {
|
public BlockEntityType<?> getType() {
|
||||||
return this.overriddenType;
|
return ModBlockEntities.ASSEMBLER_MATRIX_CRAFTER_PLUS_BE.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IActionSource getSrc() {
|
||||||
|
return this.cluster == null ? null : this.cluster.getSrc();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeState(int index, boolean state) {
|
||||||
|
int oldMask = this.activeThreadMask;
|
||||||
|
if (state) {
|
||||||
|
this.activeThreadMask |= (1 << index);
|
||||||
|
} else {
|
||||||
|
this.activeThreadMask &= ~(1 << index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldMask == 0 && this.activeThreadMask != 0) {
|
||||||
|
this.getMainNode().ifPresent((grid, node) -> grid.getTickManager().wakeDevice(node));
|
||||||
|
} else if (oldMask != 0 && this.activeThreadMask == 0) {
|
||||||
|
this.getMainNode().ifPresent((grid, node) -> grid.getTickManager().sleepDevice(node));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.extendedae_plus.mixin.extendedae.accessor;
|
||||||
|
|
||||||
|
import appeng.api.inventories.InternalInventory;
|
||||||
|
import com.glodblock.github.extendedae.common.me.CraftingThread;
|
||||||
|
import com.glodblock.github.extendedae.common.tileentities.matrix.TileAssemblerMatrixCrafter;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(TileAssemblerMatrixCrafter.class)
|
||||||
|
public interface TileAssemblerMatrixCrafterAccessor {
|
||||||
|
|
||||||
|
@Accessor("threads")
|
||||||
|
CraftingThread[] extendedae_plus$getThreads();
|
||||||
|
|
||||||
|
@Accessor("threads")
|
||||||
|
@Mutable
|
||||||
|
void extendedae_plus$setThreads(CraftingThread[] threads);
|
||||||
|
|
||||||
|
@Accessor("internalInv")
|
||||||
|
@Mutable
|
||||||
|
void extendedae_plus$setInternalInv(InternalInventory inventory);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.extendedae_plus.mixin.extendedae.common.matrix;
|
||||||
|
|
||||||
|
import com.extendedae_plus.content.matrix.CrafterCorePlusBlockEntity;
|
||||||
|
import com.glodblock.github.extendedae.common.me.matrix.ClusterAssemblerMatrix;
|
||||||
|
import com.glodblock.github.extendedae.common.tileentities.matrix.TileAssemblerMatrixCrafter;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceSet;
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
@Mixin(value = ClusterAssemblerMatrix.class, remap = false)
|
||||||
|
public class ClusterAssemblerMatrixMixin {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private ReferenceSet<TileAssemblerMatrixCrafter> availableCrafters;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
@Final
|
||||||
|
private ReferenceSet<TileAssemblerMatrixCrafter> busyCrafters;
|
||||||
|
|
||||||
|
@Inject(method = "addCrafter", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onAddCrafter(TileAssemblerMatrixCrafter crafter, CallbackInfo ci) {
|
||||||
|
if (crafter instanceof CrafterCorePlusBlockEntity plusCrafter) {
|
||||||
|
if (plusCrafter.usedThread() < CrafterCorePlusBlockEntity.MAX_THREAD) {
|
||||||
|
this.availableCrafters.add(crafter);
|
||||||
|
} else {
|
||||||
|
this.busyCrafters.add(crafter);
|
||||||
|
}
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "getBusyCrafterAmount", at = @At("HEAD"), cancellable = true)
|
||||||
|
private void onGetBusyCrafterAmount(CallbackInfoReturnable<Integer> cir) {
|
||||||
|
int count = 0;
|
||||||
|
for (var crafter : this.busyCrafters) {
|
||||||
|
count += crafter instanceof CrafterCorePlusBlockEntity
|
||||||
|
? CrafterCorePlusBlockEntity.MAX_THREAD
|
||||||
|
: TileAssemblerMatrixCrafter.MAX_THREAD;
|
||||||
|
}
|
||||||
|
for (var crafter : this.availableCrafters) {
|
||||||
|
count += crafter.usedThread();
|
||||||
|
}
|
||||||
|
cir.setReturnValue(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -86,7 +86,9 @@
|
||||||
"ae2.parts.storagebus.StorageBusPartTickerChannelCardMixin",
|
"ae2.parts.storagebus.StorageBusPartTickerChannelCardMixin",
|
||||||
"ae2WTlib.ContainerUWirelessExPatternTerminalMixin",
|
"ae2WTlib.ContainerUWirelessExPatternTerminalMixin",
|
||||||
"appflux.AppfluxPatternProviderLogicMixin",
|
"appflux.AppfluxPatternProviderLogicMixin",
|
||||||
|
"extendedae.accessor.TileAssemblerMatrixCrafterAccessor",
|
||||||
"extendedae.accessor.TileAssemblerMatrixPatternAccessor",
|
"extendedae.accessor.TileAssemblerMatrixPatternAccessor",
|
||||||
|
"extendedae.common.matrix.ClusterAssemblerMatrixMixin",
|
||||||
"extendedae.common.PartExPatternProviderMixin",
|
"extendedae.common.PartExPatternProviderMixin",
|
||||||
"extendedae.common.TileExPatternProviderMixin",
|
"extendedae.common.TileExPatternProviderMixin",
|
||||||
"extendedae.container.ContainerAssemblerMatrixPatternSlotTrackerMixin",
|
"extendedae.container.ContainerAssemblerMatrixPatternSlotTrackerMixin",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user