Skip to content

Commit 3a01dd3

Browse files
committed
允许循环样板和缺失物品的状态下强制开启合成
未测试循环的合成样板
1 parent fa2e60a commit 3a01dd3

File tree

14 files changed

+383
-2
lines changed

14 files changed

+383
-2
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ show_testing_output = false
1616

1717
# Mod Information
1818
# HIGHLY RECOMMEND complying with SemVer for mod_version: https://semver.org/
19-
mod_version = 1.8.0
19+
mod_version = 1.8.1
2020
root_package = com.circulation
2121
mod_id = random_complement
2222
mod_name = RandomComplement
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.circulation.random_complement.common.interfaces;
2+
3+
import appeng.api.storage.data.IAEItemStack;
4+
5+
public interface RCCraftingJob {
6+
7+
IAEItemStack getWaitingItem();
8+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.circulation.random_complement.mixin.ae2;
2+
3+
import appeng.api.storage.data.IAEItemStack;
4+
import appeng.api.storage.data.IItemList;
5+
import appeng.crafting.CraftingTreeNode;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.gen.Accessor;
8+
9+
@Mixin(value = CraftingTreeNode.class, remap = false)
10+
public interface AccessorCraftingTreeNode {
11+
@Accessor
12+
IItemList<IAEItemStack> getUsed();
13+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.circulation.random_complement.mixin.ae2.miss_craft;
2+
3+
import appeng.api.networking.crafting.ICraftingJob;
4+
import appeng.container.implementations.ContainerCraftConfirm;
5+
import com.circulation.random_complement.common.interfaces.RCAEBaseContainer;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.injection.At;
8+
import org.spongepowered.asm.mixin.injection.Redirect;
9+
10+
@Mixin(value = ContainerCraftConfirm.class, remap = false)
11+
public abstract class MixinContainerCraftConfirm implements RCAEBaseContainer {
12+
13+
@Redirect(method = "detectAndSendChanges", at = @At(value = "INVOKE", target = "Lappeng/api/networking/crafting/ICraftingJob;isSimulation()Z", ordinal = 1))
14+
public boolean isSimulation1(ICraftingJob instance) {
15+
return true;
16+
}
17+
18+
@Redirect(method = "detectAndSendChanges", at = @At(value = "INVOKE", target = "Lappeng/api/networking/crafting/ICraftingJob;isSimulation()Z", ordinal = 2))
19+
public boolean isSimulation2(ICraftingJob instance) {
20+
return true;
21+
}
22+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.circulation.random_complement.mixin.ae2.miss_craft;
2+
3+
import appeng.api.config.Actionable;
4+
import appeng.api.networking.IGrid;
5+
import appeng.api.networking.crafting.ICraftingJob;
6+
import appeng.api.networking.crafting.ICraftingLink;
7+
import appeng.api.networking.crafting.ICraftingRequester;
8+
import appeng.api.networking.security.IActionSource;
9+
import appeng.api.storage.data.IAEItemStack;
10+
import appeng.me.cluster.implementations.CraftingCPUCluster;
11+
import com.circulation.random_complement.common.interfaces.RCCraftingJob;
12+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
13+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
14+
import com.llamalad7.mixinextras.sugar.Local;
15+
import org.spongepowered.asm.mixin.Mixin;
16+
import org.spongepowered.asm.mixin.Shadow;
17+
import org.spongepowered.asm.mixin.Unique;
18+
import org.spongepowered.asm.mixin.injection.At;
19+
import org.spongepowered.asm.mixin.injection.Inject;
20+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
21+
22+
@Mixin(value = CraftingCPUCluster.class, remap = false)
23+
public abstract class MixinCraftingCPUCluster {
24+
25+
@Shadow
26+
private IAEItemStack finalOutput;
27+
28+
@Unique
29+
private IAEItemStack r$waitInput;
30+
31+
@Shadow
32+
protected abstract void completeJob();
33+
34+
@Shadow
35+
protected abstract void updateCPU();
36+
37+
@WrapOperation(method = "injectItems", at = @At(value = "INVOKE", target = "Ljava/lang/Object;equals(Ljava/lang/Object;)Z"))
38+
public boolean injectItems(Object instance, Object o, Operation<Boolean> original, @Local(name = "type") Actionable type) {
39+
if (r$waitInput != null && r$waitInput.equals(o)) {
40+
if (type == Actionable.MODULATE) {
41+
var size = ((IAEItemStack) o).getStackSize();
42+
if (r$waitInput.getStackSize() <= size) {
43+
r$waitInput = null;
44+
} else {
45+
r$waitInput.decStackSize(size);
46+
}
47+
finalOutput.decStackSize(size);
48+
}
49+
return false;
50+
}
51+
return original.call(instance,o);
52+
}
53+
54+
@Inject(method = "injectItems", at = @At("RETURN"))
55+
public void onStop(IAEItemStack input, Actionable type, IActionSource src, CallbackInfoReturnable<IAEItemStack> cir) {
56+
if (this.finalOutput != null && this.finalOutput.getStackSize() <= 0) {
57+
this.completeJob();
58+
this.updateCPU();
59+
}
60+
}
61+
62+
@Inject(method = "submitJob", at = @At(value = "INVOKE", target = "Lappeng/crafting/CraftingTreeNode;setJob(Lappeng/crafting/MECraftingInventory;Lappeng/me/cluster/implementations/CraftingCPUCluster;Lappeng/api/networking/security/IActionSource;)V"))
63+
public void submitJob(IGrid g, ICraftingJob job, IActionSource src, ICraftingRequester requestingMachine, CallbackInfoReturnable<ICraftingLink> cir) {
64+
var s = ((RCCraftingJob) job).getWaitingItem();
65+
if (s != null && s.getStackSize() > 0) {
66+
r$waitInput = s.copy();
67+
s.reset();
68+
}
69+
}
70+
71+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.circulation.random_complement.mixin.ae2.miss_craft;
2+
3+
import appeng.api.networking.crafting.ICraftingGrid;
4+
import appeng.api.storage.data.IAEItemStack;
5+
import appeng.crafting.CraftBranchFailure;
6+
import appeng.crafting.CraftingJob;
7+
import appeng.crafting.CraftingTreeNode;
8+
import appeng.crafting.MECraftingInventory;
9+
import com.circulation.random_complement.common.interfaces.RCCraftingJob;
10+
import com.circulation.random_complement.mixin.ae2.AccessorCraftingTreeNode;
11+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
12+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
13+
import com.llamalad7.mixinextras.sugar.Share;
14+
import com.llamalad7.mixinextras.sugar.ref.LocalLongRef;
15+
import net.minecraft.world.World;
16+
import org.spongepowered.asm.mixin.Final;
17+
import org.spongepowered.asm.mixin.Intrinsic;
18+
import org.spongepowered.asm.mixin.Mixin;
19+
import org.spongepowered.asm.mixin.Shadow;
20+
import org.spongepowered.asm.mixin.Unique;
21+
import org.spongepowered.asm.mixin.injection.At;
22+
import org.spongepowered.asm.mixin.injection.Inject;
23+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
24+
25+
@Mixin(value = CraftingJob.class, remap = false)
26+
public abstract class MixinCraftingJob implements RCCraftingJob {
27+
28+
@Shadow
29+
@Final
30+
private IAEItemStack output;
31+
32+
@Shadow
33+
private CraftingTreeNode tree;
34+
35+
@Shadow
36+
@Final
37+
private ICraftingGrid cc;
38+
39+
@Shadow
40+
@Final
41+
private World world;
42+
43+
@Unique
44+
private IAEItemStack r$wait;
45+
46+
@WrapOperation(method = "run", at = @At(value = "INVOKE", target = "Lappeng/crafting/MECraftingInventory;ignore(Lappeng/api/storage/data/IAEItemStack;)V", ordinal = 0))
47+
public void record(MECraftingInventory instance, IAEItemStack what, Operation<Void> original, @Share("rcOutput") LocalLongRef stackLocalRef) {
48+
var stack = instance.getItemList().findPrecise(what);
49+
if (stack != null) {
50+
var size = stack.getStackSize();
51+
stackLocalRef.set(size);
52+
} else stackLocalRef.set(0);
53+
original.call(instance, what);
54+
}
55+
56+
@Inject(method = "run", at = @At(value = "INVOKE", target = "Lappeng/crafting/CraftingTreeNode;request(Lappeng/crafting/MECraftingInventory;JLappeng/api/networking/security/IActionSource;)Lappeng/api/storage/data/IAEItemStack;", shift = At.Shift.AFTER, ordinal = 0))
57+
public void supplementaryOutput(CallbackInfo ci, @Share("rcOutput") LocalLongRef stackLocalRef) throws CraftBranchFailure {
58+
final long out = stackLocalRef.get();
59+
if (out > 0) {
60+
for (var details : this.cc.getCraftingFor(this.output, null, 0, this.world)) {
61+
IAEItemStack repeatOutput = this.output.copy().setStackSize(0);
62+
for (var input : details.getCondensedOutputs()) {
63+
if (this.output.equals(input)) {
64+
repeatOutput.setStackSize(repeatOutput.getStackSize() + input.getStackSize());
65+
}
66+
}
67+
if (repeatOutput.getStackSize() == 0) return;
68+
69+
long outputQuantity = this.output.getStackSize() / repeatOutput.getStackSize();
70+
if (this.output.getStackSize() % repeatOutput.getStackSize() != 0) ++outputQuantity;
71+
72+
IAEItemStack repeatInput = this.output.copy().setStackSize(0);
73+
for (var input : details.getCondensedInputs()) {
74+
if (this.output.equals(input)) {
75+
repeatInput.setStackSize(repeatInput.getStackSize() + (input.getStackSize() * outputQuantity));
76+
}
77+
}
78+
if (repeatInput.getStackSize() > 0) {
79+
var tree = (AccessorCraftingTreeNode) this.tree;
80+
var size = Math.min(out, repeatInput.getStackSize());
81+
tree.getUsed().add(this.output.copy().setStackSize(size));
82+
r$wait = this.output.copy().setStackSize(repeatInput.getStackSize() - size);
83+
}
84+
break;
85+
}
86+
} else {
87+
for (var details : this.cc.getCraftingFor(this.output, null, 0, this.world)) {
88+
for (var input : details.getCondensedInputs()) {
89+
if (this.output.equals(input)) {
90+
throw new CraftBranchFailure(this.output, this.output.getStackSize());
91+
}
92+
}
93+
}
94+
}
95+
}
96+
97+
@Intrinsic
98+
public IAEItemStack getWaitingItem() {
99+
return r$wait;
100+
}
101+
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package com.circulation.random_complement.mixin.ae2.miss_craft;
2+
3+
import appeng.api.networking.crafting.ICraftingPatternDetails;
4+
import appeng.api.networking.security.IActionSource;
5+
import appeng.api.storage.data.IAEItemStack;
6+
import appeng.crafting.CraftingJob;
7+
import appeng.crafting.CraftingTreeNode;
8+
import appeng.crafting.CraftingTreeProcess;
9+
import appeng.crafting.MECraftingInventory;
10+
import appeng.util.Platform;
11+
import appeng.util.item.AEItemStack;
12+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
13+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
14+
import net.minecraft.item.ItemStack;
15+
import org.objectweb.asm.Opcodes;
16+
import org.spongepowered.asm.mixin.Final;
17+
import org.spongepowered.asm.mixin.Mixin;
18+
import org.spongepowered.asm.mixin.Shadow;
19+
import org.spongepowered.asm.mixin.injection.At;
20+
import org.spongepowered.asm.mixin.injection.Inject;
21+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
22+
23+
import java.util.ArrayList;
24+
25+
//TODO:允许开关而不是总是开启
26+
@Mixin(value = CraftingTreeNode.class, remap = false)
27+
public class MixinCraftingTreeNode {
28+
29+
@Shadow
30+
private long howManyEmitted;
31+
32+
@Shadow
33+
private int bytes;
34+
35+
@Shadow
36+
@Final
37+
private CraftingTreeProcess parent;
38+
39+
@Shadow
40+
@Final
41+
private IAEItemStack what;
42+
43+
@Shadow
44+
private boolean canEmit;
45+
46+
@Shadow
47+
@Final
48+
private ArrayList<CraftingTreeProcess> nodes;
49+
50+
@Shadow
51+
@Final
52+
private CraftingJob job;
53+
54+
@Inject(method = "request", at = @At(value = "INVOKE", target = "Lappeng/crafting/CraftingJob;isSimulation()Z", shift = At.Shift.BEFORE), cancellable = true)
55+
public void request(MECraftingInventory inv, long l, IActionSource src, CallbackInfoReturnable<IAEItemStack> cir) {
56+
if (canEmit) return;
57+
this.bytes = (int) ((long) this.bytes + l);
58+
if (this.parent != null && this.what.getItem().hasContainerItem(this.what.getDefinition())) {
59+
ItemStack is2 = Platform.getContainerItem(this.what.copy().setStackSize(1L).createItemStack());
60+
IAEItemStack o = AEItemStack.fromItemStack(is2);
61+
if (o != null) {
62+
this.parent.addContainers(o);
63+
}
64+
}
65+
this.howManyEmitted += l;
66+
IAEItemStack rv = this.what.copy();
67+
rv.setStackSize(l);
68+
cir.setReturnValue(rv);
69+
}
70+
71+
@WrapOperation(method = "setJob", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lappeng/crafting/CraftingTreeNode;howManyEmitted:J"))
72+
public long setJobHowManyEmitted(CraftingTreeNode instance, Operation<Long> original) {
73+
if (canEmit) return original.call(instance);
74+
if (this.what.equals(this.job.getOutput())) return 0;
75+
if (this.nodes.isEmpty()) return original.call(instance);
76+
return 0;
77+
}
78+
79+
@WrapOperation(method = "getPlan", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lappeng/crafting/CraftingTreeNode;missing:J"))
80+
public long getPlanMissing(CraftingTreeNode instance, Operation<Long> original) {
81+
if (canEmit) return original.call(instance);
82+
if (this.what.equals(this.job.getOutput())) return original.call(instance);
83+
return this.howManyEmitted;
84+
}
85+
86+
@WrapOperation(method = "getPlan", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lappeng/crafting/CraftingTreeNode;howManyEmitted:J"))
87+
public long getPlanHowManyEmitted(CraftingTreeNode instance, Operation<Long> original) {
88+
if (canEmit) return original.call(instance);
89+
if (this.what.equals(this.job.getOutput())) return 0;
90+
if (this.nodes.isEmpty()) return original.call(instance);
91+
return 0;
92+
}
93+
94+
@Inject(method = "notRecursive", at = @At("RETURN"), cancellable = true)
95+
public void notRecursive(ICraftingPatternDetails details, CallbackInfoReturnable<Boolean> cir) {
96+
if (canEmit) return;
97+
if (cir.getReturnValueZ()) {
98+
for (var input : details.getCondensedInputs()) {
99+
if (this.what.equals(input)) {
100+
cir.setReturnValue(Boolean.FALSE);
101+
break;
102+
}
103+
}
104+
}
105+
}
106+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.circulation.random_complement.mixin.ae2.miss_craft;
2+
3+
import appeng.api.storage.data.IAEItemStack;
4+
import appeng.api.storage.data.IItemList;
5+
import appeng.client.gui.implementations.GuiCraftConfirm;
6+
import appeng.container.implementations.ContainerCraftConfirm;
7+
import net.minecraft.client.gui.GuiButton;
8+
import net.minecraft.client.resources.I18n;
9+
import org.spongepowered.asm.mixin.Final;
10+
import org.spongepowered.asm.mixin.Mixin;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15+
16+
import java.util.List;
17+
18+
@Mixin(value = GuiCraftConfirm.class, remap = false)
19+
public abstract class MixinGuiCraftConfirm {
20+
21+
@Shadow
22+
@Final
23+
private IItemList<IAEItemStack> missing;
24+
25+
@Shadow
26+
private GuiButton start;
27+
28+
@Shadow
29+
@Final
30+
private ContainerCraftConfirm ccc;
31+
32+
@Inject(method = "postUpdate", at = @At("TAIL"))
33+
public void postUpdate(List<IAEItemStack> list, byte ref, CallbackInfo ci) {
34+
if (ref == 2 && !this.missing.isEmpty() && !this.ccc.noCPU) {
35+
this.start.x -= 20;
36+
this.start.width += 20;
37+
this.start.displayString = I18n.format("gui.rc.miss_craft.text");
38+
}
39+
}
40+
}

src/main/java/com/circulation/random_complement/mixin/rcLateMixinLoader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public class rcLateMixinLoader implements ILateMixinLoader {
2929

3030
if (modLoaded("appliedenergistics2")) {
3131
addMixinCFG("mixins.random_complement.ae2.json");
32+
addMixinCFG("mixins.random_complement.ae2.miss_craft.json");
3233
addMixinCFG("mixins.random_complement.ae2.new_patten_gui.json",
3334
() -> RCConfig.AE2.newPattenGui);
3435
addMixinCFG("mixins.random_complement.ae2fc.new_patten_gui.json",

src/main/java/com/circulation/random_complement/mixin/threng/MixinTileLevelMaintainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public void injectCraftedItems(ICraftingLink link, IAEItemStack stack, Actionabl
200200
} else {
201201
IEnergyGrid energyGrid = grid.getCache(IEnergyGrid.class);
202202
IMEMonitor<IAEItemStack> storageGrid = gridCache.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
203-
return Platform.poweredInsert(energyGrid, storageGrid, stack, this.actionSource, appeng.api.config.Actionable.MODULATE);
203+
return Platform.poweredInsert(energyGrid, storageGrid, stack, this.actionSource, Actionable.MODULATE);
204204
}
205205
}
206206

0 commit comments

Comments
 (0)