再次重构新版本倍增
This commit is contained in:
parent
2c40e0800a
commit
be19dce5ab
|
|
@ -122,17 +122,17 @@ public class ScaledProcessingPattern implements IPatternDetails {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ScaledInput(IInput delegate, long mul) implements IInput {
|
private record ScaledInput(IInput original, long multiplier) implements IInput {
|
||||||
@Override
|
@Override
|
||||||
public GenericStack[] getPossibleInputs() {return delegate.getPossibleInputs();}
|
public GenericStack[] getPossibleInputs() {return original.getPossibleInputs();}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getMultiplier() {return delegate.getMultiplier() * mul;}
|
public long getMultiplier() {return original.getMultiplier() * multiplier;}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValid(AEKey input, Level level) {return delegate.isValid(input, level);}
|
public boolean isValid(AEKey input, Level level) {return original.isValid(input, level);}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable AEKey getRemainingKey(AEKey template) {return delegate.getRemainingKey(template);}
|
public @Nullable AEKey getRemainingKey(AEKey template) {return original.getRemainingKey(template);}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.extendedae_plus.api.smartDoubling;
|
||||||
|
|
||||||
|
import appeng.crafting.CraftingTreeProcess;
|
||||||
|
|
||||||
|
public interface ICraftingSimulationStateExt {
|
||||||
|
void setSourceProcess(CraftingTreeProcess process);
|
||||||
|
CraftingTreeProcess getSourceProcess();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.extendedae_plus.api.smartDoubling;
|
||||||
|
|
||||||
|
import appeng.api.networking.crafting.ICraftingService;
|
||||||
|
|
||||||
|
public interface ICraftingTreeProcessExt {
|
||||||
|
ICraftingService getCraftingService();
|
||||||
|
}
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
package com.extendedae_plus.mixin.ae2.autopattern;
|
|
||||||
|
|
||||||
import appeng.api.networking.crafting.ICraftingProvider;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Mixin(targets = "appeng.me.service.helpers.NetworkCraftingProviders$CraftingProviderList")
|
|
||||||
public interface CraftingProviderListAccessor {
|
|
||||||
@Accessor(value = "providers",remap = false)
|
|
||||||
List<ICraftingProvider> getProviders();
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.extendedae_plus.mixin.ae2.autopattern;
|
||||||
|
|
||||||
|
import appeng.api.crafting.IPatternDetails;
|
||||||
|
import appeng.crafting.inv.CraftingSimulationState;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mixin(value = CraftingSimulationState.class,remap = false)
|
||||||
|
public interface CraftingSimulationStateAccessor {
|
||||||
|
@Accessor("crafts")
|
||||||
|
Map<IPatternDetails, Long> getCrafts();
|
||||||
|
}
|
||||||
|
|
@ -1,101 +1,116 @@
|
||||||
package com.extendedae_plus.mixin.ae2.autopattern;
|
package com.extendedae_plus.mixin.ae2.autopattern;
|
||||||
|
|
||||||
import appeng.api.crafting.IPatternDetails;
|
import appeng.api.crafting.IPatternDetails;
|
||||||
|
import appeng.crafting.CraftingCalculation;
|
||||||
|
import appeng.crafting.CraftingPlan;
|
||||||
|
import appeng.crafting.CraftingTreeProcess;
|
||||||
import appeng.crafting.inv.CraftingSimulationState;
|
import appeng.crafting.inv.CraftingSimulationState;
|
||||||
import appeng.crafting.pattern.AEProcessingPattern;
|
import appeng.crafting.pattern.AEProcessingPattern;
|
||||||
|
import appeng.me.service.CraftingService;
|
||||||
import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern;
|
import com.extendedae_plus.ae.api.crafting.ScaledProcessingPattern;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ICraftingSimulationStateExt;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ICraftingTreeProcessExt;
|
||||||
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
import com.extendedae_plus.api.smartDoubling.ISmartDoublingAwarePattern;
|
||||||
import com.extendedae_plus.config.ModConfig;
|
import com.extendedae_plus.config.ModConfig;
|
||||||
import com.extendedae_plus.util.smartDoubling.PatternScaler;
|
import com.extendedae_plus.util.smartDoubling.PatternScaler;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import com.google.common.collect.Iterables;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import java.util.IdentityHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@SuppressWarnings({"AddedMixinMembersNamePattern", "MissingUnique"})
|
@SuppressWarnings({"AddedMixinMembersNamePattern"})
|
||||||
@Mixin(value = CraftingSimulationState.class, remap = false)
|
@Mixin(value = CraftingSimulationState.class, remap = false)
|
||||||
public abstract class CraftingSimulationStateMixin {
|
public abstract class CraftingSimulationStateMixin implements ICraftingSimulationStateExt {
|
||||||
|
@Unique private CraftingTreeProcess sourceProcess;
|
||||||
|
|
||||||
@Shadow @Final private Map<IPatternDetails, Long> crafts;
|
/**
|
||||||
|
* 替换 CraftingPlan 构建逻辑,在此统一处理样板倍率
|
||||||
|
*/
|
||||||
|
@Inject(method = "buildCraftingPlan", at = @At("HEAD"))
|
||||||
|
private static void onBuildCraftingPlan(CraftingSimulationState state, CraftingCalculation calculation, long calculatedAmount, CallbackInfoReturnable<CraftingPlan> cir) {
|
||||||
|
CraftingSimulationStateAccessor accessor = (CraftingSimulationStateAccessor) state;
|
||||||
|
Map<IPatternDetails, Long> crafts = accessor.getCrafts();
|
||||||
|
// 新建 Map 存放最终分配后的 crafts
|
||||||
|
Map<IPatternDetails, Long> finalCrafts = new LinkedHashMap<>();
|
||||||
|
|
||||||
/** 仅用于无限制缩放时的合并缓存 */
|
for (Map.Entry<IPatternDetails, Long> entry : crafts.entrySet()) {
|
||||||
private final Map<AEProcessingPattern, ScaledProcessingPattern> scaledCache = new IdentityHashMap<>();
|
IPatternDetails details = entry.getKey();
|
||||||
|
long totalAmount = entry.getValue();
|
||||||
|
|
||||||
@Inject(method = "addCrafting", at = @At("HEAD"), cancellable = true)
|
// 非 AEProcessingPattern 直接保留
|
||||||
private void onAddCrafting(IPatternDetails details, long craftsAmount, CallbackInfo ci) {
|
if (!(details instanceof AEProcessingPattern processingPattern)) {
|
||||||
ci.cancel();
|
finalCrafts.put(details, totalAmount);
|
||||||
if (craftsAmount <= 0 || details == null) return;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 仅处理 AEProcessingPattern
|
boolean allowScaling = false;
|
||||||
if (!(details instanceof AEProcessingPattern processingPattern)) {
|
int perCraftLimit = 0;
|
||||||
crafts.merge(details, craftsAmount, Long::sum);
|
if (processingPattern instanceof ISmartDoublingAwarePattern aware) {
|
||||||
return;
|
allowScaling = aware.eap$allowScaling();
|
||||||
|
perCraftLimit = aware.eap$getMultiplierLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allowScaling || totalAmount <= 1) {
|
||||||
|
finalCrafts.put(processingPattern, totalAmount);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (perCraftLimit <= 0 && ModConfig.INSTANCE.smartScalingMaxMultiplier > 0) {
|
||||||
|
perCraftLimit = ModConfig.INSTANCE.smartScalingMaxMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取供应器数量
|
||||||
|
CraftingTreeProcess process = ((ICraftingSimulationStateExt) state).getSourceProcess();
|
||||||
|
CraftingService craftingService = (CraftingService) ((ICraftingTreeProcessExt) process).getCraftingService();
|
||||||
|
long providerCount = Iterables.size(craftingService.getProviders(processingPattern));
|
||||||
|
if (providerCount <= 0) providerCount = 1;
|
||||||
|
|
||||||
|
if (perCraftLimit <= 0) {
|
||||||
|
// 无限倍率 → 按供应器均分并处理余数
|
||||||
|
long base = totalAmount / providerCount;
|
||||||
|
long remainder = totalAmount % providerCount;
|
||||||
|
|
||||||
|
if (remainder > 0) {
|
||||||
|
ScaledProcessingPattern scaled_r = PatternScaler.createScaled(processingPattern, base + remainder);
|
||||||
|
finalCrafts.put(scaled_r, 1L);
|
||||||
|
ScaledProcessingPattern scaled_b = PatternScaler.createScaled(processingPattern, base);
|
||||||
|
finalCrafts.put(scaled_b, providerCount - 1);
|
||||||
|
} else {
|
||||||
|
ScaledProcessingPattern scaled = PatternScaler.createScaled(processingPattern, base);
|
||||||
|
finalCrafts.put(scaled, providerCount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 有限制 → 拆分 full + remainder
|
||||||
|
long fullCrafts = totalAmount / perCraftLimit;
|
||||||
|
long remainder = totalAmount % perCraftLimit;
|
||||||
|
|
||||||
|
if (fullCrafts > 0) {
|
||||||
|
ScaledProcessingPattern scaledFull = PatternScaler.createScaled(processingPattern, perCraftLimit);
|
||||||
|
finalCrafts.put(scaledFull, fullCrafts);
|
||||||
|
}
|
||||||
|
if (remainder > 0) {
|
||||||
|
ScaledProcessingPattern scaledRem = PatternScaler.createScaled(processingPattern, remainder);
|
||||||
|
finalCrafts.put(scaledRem, 1L);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean allowScaling = false;
|
crafts.clear();
|
||||||
int perCraftLimit = 0;
|
crafts.putAll(finalCrafts);
|
||||||
|
|
||||||
if (processingPattern instanceof ISmartDoublingAwarePattern aware) {
|
|
||||||
allowScaling = aware.eap$allowScaling();
|
|
||||||
perCraftLimit = aware.eap$getMultiplierLimit(); // 样板供应器限制
|
|
||||||
}
|
|
||||||
|
|
||||||
// 样板不允许缩放 或者 需求量为 1 → 直接合并
|
|
||||||
if (!allowScaling || craftsAmount == 1) {
|
|
||||||
crafts.merge(processingPattern, craftsAmount, Long::sum);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 样板无限制时应用全局配置
|
|
||||||
if (perCraftLimit <= 0 && ModConfig.INSTANCE.smartScalingMaxMultiplier > 0) {
|
|
||||||
perCraftLimit = ModConfig.INSTANCE.smartScalingMaxMultiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据限制处理
|
|
||||||
if (perCraftLimit <= 0) {
|
|
||||||
// 无限制 → 合并倍率并复用对象
|
|
||||||
mergeUnlimited(processingPattern, craftsAmount);
|
|
||||||
} else {
|
|
||||||
// 有限制 → 拆分 full + remainder
|
|
||||||
splitLimited(processingPattern, craftsAmount, perCraftLimit);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 无限制:合并倍率并复用 ScaledProcessingPattern 或 AAE 扩展 */
|
@Override
|
||||||
private void mergeUnlimited(AEProcessingPattern original, long multiplier) {
|
public CraftingTreeProcess getSourceProcess() {
|
||||||
ScaledProcessingPattern existing = scaledCache.get(original);
|
return this.sourceProcess;
|
||||||
long total = multiplier;
|
|
||||||
|
|
||||||
if (existing != null) {
|
|
||||||
total += existing.getMultiplier();
|
|
||||||
crafts.remove(existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用 PatternScaler 自动选择原版或 AAE 扩展
|
|
||||||
ScaledProcessingPattern scaled = PatternScaler.createScaled(original, total);
|
|
||||||
|
|
||||||
scaledCache.put(original, scaled);
|
|
||||||
crafts.put(scaled, 1L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 有限制:拆分 full + remainder,并支持原版/AAE 扩展 */
|
@Override
|
||||||
private void splitLimited(AEProcessingPattern original, long totalAmount, int limit) {
|
public void setSourceProcess(CraftingTreeProcess process) {
|
||||||
long fullCrafts = totalAmount / limit;
|
this.sourceProcess = process;
|
||||||
long remainder = totalAmount % limit;
|
|
||||||
|
|
||||||
if (fullCrafts > 0) {
|
|
||||||
ScaledProcessingPattern scaledFull = PatternScaler.createScaled(original, limit);
|
|
||||||
crafts.merge(scaledFull, fullCrafts, Long::sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remainder > 0) {
|
|
||||||
ScaledProcessingPattern scaledRemainder = PatternScaler.createScaled(original, remainder);
|
|
||||||
crafts.merge(scaledRemainder, 1L, Long::sum);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.extendedae_plus.mixin.ae2.autopattern;
|
||||||
|
|
||||||
|
import appeng.api.crafting.IPatternDetails;
|
||||||
|
import appeng.api.networking.crafting.ICraftingService;
|
||||||
|
import appeng.crafting.CraftingCalculation;
|
||||||
|
import appeng.crafting.CraftingTreeNode;
|
||||||
|
import appeng.crafting.CraftingTreeProcess;
|
||||||
|
import appeng.crafting.inv.CraftingSimulationState;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ICraftingSimulationStateExt;
|
||||||
|
import com.extendedae_plus.api.smartDoubling.ICraftingTreeProcessExt;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@SuppressWarnings({"AddedMixinMembersNamePattern"})
|
||||||
|
@Mixin(value = CraftingTreeProcess.class, remap = false)
|
||||||
|
public class CraftingTreeProcessMixin implements ICraftingTreeProcessExt {
|
||||||
|
@Unique private ICraftingService craftingService;
|
||||||
|
|
||||||
|
@Inject(method = "<init>",at = @At("RETURN"))
|
||||||
|
private void init(ICraftingService cc, CraftingCalculation job, IPatternDetails details, CraftingTreeNode craftingTreeNode, CallbackInfo ci) {
|
||||||
|
this.craftingService = cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(
|
||||||
|
method = "request",
|
||||||
|
at = @At("HEAD")
|
||||||
|
)
|
||||||
|
private void bindSimulationState(CraftingSimulationState inv, long times, CallbackInfo ci) {
|
||||||
|
((ICraftingSimulationStateExt) inv).setSourceProcess((CraftingTreeProcess) (Object) this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ICraftingService getCraftingService() {
|
||||||
|
return this.craftingService;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -51,9 +51,10 @@
|
||||||
"ae2.accessor.PatternEncodingTermMenuAccessor",
|
"ae2.accessor.PatternEncodingTermMenuAccessor",
|
||||||
"ae2.accessor.PatternProviderLogicAccessor",
|
"ae2.accessor.PatternProviderLogicAccessor",
|
||||||
"ae2.accessor.PatternProviderMenuAccessor",
|
"ae2.accessor.PatternProviderMenuAccessor",
|
||||||
"ae2.autopattern.CraftingProviderListAccessor",
|
|
||||||
"ae2.autopattern.CraftingServiceGetProvidersMixin",
|
"ae2.autopattern.CraftingServiceGetProvidersMixin",
|
||||||
|
"ae2.autopattern.CraftingSimulationStateAccessor",
|
||||||
"ae2.autopattern.CraftingSimulationStateMixin",
|
"ae2.autopattern.CraftingSimulationStateMixin",
|
||||||
|
"ae2.autopattern.CraftingTreeProcessMixin",
|
||||||
"ae2.autopattern.PatternProviderLogicContainsRedirectMixin",
|
"ae2.autopattern.PatternProviderLogicContainsRedirectMixin",
|
||||||
"ae2.compat.PatternProviderCompatMixin",
|
"ae2.compat.PatternProviderCompatMixin",
|
||||||
"ae2.compat.PatternProviderLogicCompatMixin",
|
"ae2.compat.PatternProviderLogicCompatMixin",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user