This commit is contained in:
1820982382
2026-08-01 16:42:53 +08:00
parent e2ab0fb78b
commit 7b341980bd
322 changed files with 15941 additions and 0 deletions
@@ -0,0 +1,202 @@
package thaumicenergistics.common.tiles;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import thaumcraft.api.aspects.Aspect;
import thaumcraft.api.aspects.IEssentiaTransport;
import thaumcraft.common.essentia.EssentiaTransport;
import thaumicenergistics.ThaumicEnergistics;
import thaumicenergistics.api.storage.IAspectStack;
import thaumicenergistics.init.ModBlockEntities;
import thaumicenergistics.init.ModItems;
import java.util.List;
public class TileEssentiaProvider extends TileProviderBase implements IEssentiaTransport, EssentiaTransport {
private static final int TICK_RATE_IDLE = 15;
private static final int TICK_RATE_URGENT = 5;
private int tickCount;
private int tickRate = TICK_RATE_IDLE;
public TileEssentiaProvider(BlockPos pos, BlockState state) {
super(ModBlockEntities.ESSENTIA_PROVIDER.get(), pos, state);
}
@Override
protected ItemStack getItemFromTile() {
return new ItemStack(ModItems.ESSENTIA_PROVIDER_ITEM.get());
}
@Override
protected double getIdlePowerUsage() {
return 3.0;
}
/** getEssentiaList 短时缓存:TC 管道 suction 每 tick 调 getEssentiaType,避免每 tick 全量遍历。 */
private List<IAspectStack> cachedEssentiaList = java.util.List.of();
private int essentiaListCacheTimer = 0;
private static final int ESSENTIA_LIST_CACHE_TICKS = 20;
private List<thaumicenergistics.api.storage.IAspectStack> getCachedEssentiaList() {
if (essentiaListCacheTimer <= 0) {
essentiaListCacheTimer = ESSENTIA_LIST_CACHE_TICKS;
cachedEssentiaList = essentiaGrid != null ? essentiaGrid.getEssentiaList() : java.util.List.of();
}
return cachedEssentiaList;
}
public void serverTick() {
if (level == null || level.isClientSide()) return;
if (!mainNode.isActive()) return;
if (essentiaListCacheTimer > 0) essentiaListCacheTimer--;
if (++tickCount >= tickRate) {
tickCount = 0;
tickRate = TICK_RATE_IDLE;
takeEssentiaFromTransportNeighbors();
}
}
// ===== IEssentiaTransport =====
@Override
public boolean isConnectable(Direction side) {
return true;
}
@Override
public boolean canInputFrom(Direction side) {
return true;
}
@Override
public boolean canOutputTo(Direction side) {
return true;
}
@Override
public void setSuction(Aspect aspect, int amount) {
}
@Override
public Aspect getSuctionType(Direction side) {
return null; // 接受所有类型
}
@Override
public int getSuctionAmount(Direction side) {
return 8; // 最大吸力
}
@Override
public int takeEssentia(Aspect aspect, int amount, Direction side) {
ThaumicEnergistics.LOG.debug("[MyHano-E] takeEssentia: aspect={}, amount={}, side={}, active={}",
aspect != null ? aspect.getTag() : "null", amount, side, mainNode.isActive());
if (!mainNode.isActive()) return 0;
long extracted = extractEssentiaFromNetwork(aspect, amount, false);
ThaumicEnergistics.LOG.debug("[MyHano-E] takeEssentia result={}", extracted);
if (extracted > 0) {
tickRate = TICK_RATE_URGENT;
}
return (int) extracted;
}
@Override
public int addEssentia(Aspect aspect, int amount, Direction side) {
ThaumicEnergistics.LOG.debug("[MyHano-E] addEssentia: aspect={}, amount={}, side={}, active={}",
aspect != null ? aspect.getTag() : "null", amount, side, mainNode.isActive());
if (!mainNode.isActive()) return 0;
long rejected = injectEssentiaToNetwork(aspect, amount, false);
long accepted = amount - rejected;
if (accepted > 0) {
ThaumicEnergistics.LOG.debug("[MyHano-E] addEssentia accepted={}", accepted);
tickRate = TICK_RATE_URGENT;
}
return (int) accepted;
}
@Override
public Aspect getEssentiaType(Direction side) {
Aspect wanted = getNeighborWantedAspect(side);
if (wanted != null && getAspectAmountInNetwork(wanted) > 0) {
return wanted;
}
// 邻居无特定需求时,返回网络中第一种有存量的源质(列表短时缓存,避免 TC 管道每 tick suction 全量遍历)
if (essentiaGrid != null) {
for (var stack : getCachedEssentiaList()) {
if (stack.amount() > 0) {
return Aspect.getAspect(stack.aspectId().getPath());
}
}
}
return null;
}
@Override
public int getEssentiaAmount(Direction side) {
Aspect wanted = getNeighborWantedAspect(side);
if (wanted != null) {
return (int) Math.min(getAspectAmountInNetwork(wanted), Integer.MAX_VALUE);
}
return 0;
}
@Override
public int getMinimumSuction() {
return 1;
}
@Override
public boolean renderExtendedTube() {
return false;
}
// ===== 内部 =====
private Aspect getNeighborWantedAspect(Direction side) {
BlockPos neighborPos = worldPosition.relative(side);
BlockEntity neighbor = level.getBlockEntity(neighborPos);
if (neighbor instanceof IEssentiaTransport transport) {
return transport.getSuctionType(side.getOpposite());
}
return null;
}
private void takeEssentiaFromTransportNeighbors() {
for (Direction side : Direction.values()) {
if (!canInputFrom(side)) continue;
BlockPos sourcePos = worldPosition.relative(side);
BlockEntity sourceTile = level.getBlockEntity(sourcePos);
if (!(sourceTile instanceof IEssentiaTransport source)) continue;
Direction sourceSide = side.getOpposite();
if (!source.canOutputTo(sourceSide)) continue;
if (source.getEssentiaAmount(sourceSide) <= 0) continue;
int dSuck = getSuctionAmount(side);
if (dSuck < source.getMinimumSuction() || dSuck < source.getSuctionAmount(sourceSide)) {
continue;
}
Aspect sourceAspect = source.getEssentiaType(sourceSide);
if (sourceAspect == null) continue;
// 模拟注入
long simulated = injectEssentiaToNetwork(sourceAspect, 1, true);
if (simulated == 0) {
// 实际提取并注入
int taken = source.takeEssentia(sourceAspect, 1, sourceSide);
if (taken > 0) {
injectEssentiaToNetwork(sourceAspect, taken, false);
tickRate = TICK_RATE_URGENT;
}
}
}
}
}