Skip to content

Commit eceb1fc

Browse files
committed
Backport fix of #1636: use Redirect instead of Overwrite to avoid mixin conflict (see commit ddf420b); close #1636
1 parent 538ddd2 commit eceb1fc

File tree

1 file changed

+24
-189
lines changed

1 file changed

+24
-189
lines changed

arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java

+24-189
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,20 @@
22

33
import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge;
44
import io.izzel.arclight.common.bridge.core.util.IWorldPosCallableBridge;
5-
import net.minecraft.Util;
6-
import net.minecraft.network.chat.Component;
75
import net.minecraft.world.inventory.AbstractContainerMenu;
86
import net.minecraft.world.inventory.AnvilMenu;
97
import net.minecraft.world.inventory.DataSlot;
10-
import net.minecraft.world.item.EnchantedBookItem;
8+
import net.minecraft.world.inventory.ResultContainer;
119
import net.minecraft.world.item.ItemStack;
12-
import net.minecraft.world.item.Items;
13-
import net.minecraft.world.item.enchantment.Enchantment;
14-
import net.minecraft.world.item.enchantment.EnchantmentHelper;
15-
import net.minecraftforge.common.ForgeHooks;
1610
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
1711
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
1812
import org.bukkit.craftbukkit.v.inventory.CraftInventoryAnvil;
1913
import org.bukkit.craftbukkit.v.inventory.CraftInventoryView;
2014
import org.spongepowered.asm.mixin.Final;
2115
import org.spongepowered.asm.mixin.Mixin;
22-
import org.spongepowered.asm.mixin.Overwrite;
2316
import org.spongepowered.asm.mixin.Shadow;
24-
25-
import java.util.Map;
17+
import org.spongepowered.asm.mixin.injection.*;
18+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
2619

2720
@Mixin(AnvilMenu.class)
2821
public abstract class RepairContainerMixin extends ItemCombinerMixin {
@@ -41,192 +34,34 @@ public abstract class RepairContainerMixin extends ItemCombinerMixin {
4134

4235
private CraftInventoryView bukkitEntity;
4336

44-
/**
37+
// Below overwrite is removed to support injecting into createResult()
38+
// See #1636
39+
/*
4540
* @author IzzelAliz
4641
* @reason
4742
*/
48-
@Overwrite
49-
public void createResult() {
50-
// define constants for ModifyConstant mixins to work
51-
cancelThisBySettingCostToMaximum = 40;
52-
maximumRenameCostThreshold = 40;
53-
maximumAllowedRenameCost = 39;
54-
maximumRepairCost = 40;
55-
56-
ItemStack itemstack = this.inputSlots.getItem(0);
57-
this.cost.set(1);
58-
int i = 0;
59-
int j = 0;
60-
int k = 0;
61-
if (itemstack.isEmpty()) {
62-
// this.outputSlot.setInventorySlotContents(0, ItemStack.EMPTY);
63-
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.EMPTY);
64-
this.cost.set(0);
65-
} else {
66-
ItemStack itemstack1 = itemstack.copy();
67-
ItemStack itemstack2 = this.inputSlots.getItem(1);
68-
Map<Enchantment, Integer> map = EnchantmentHelper.getEnchantments(itemstack1);
69-
j = j + itemstack.getBaseRepairCost() + (itemstack2.isEmpty() ? 0 : itemstack2.getBaseRepairCost());
70-
this.repairItemCountCost = 0;
71-
boolean flag = false;
72-
if (!ForgeHooks.onAnvilChange((AnvilMenu) (Object) this, itemstack, itemstack2, resultSlots, itemName, j, this.player))
73-
return;
74-
75-
if (!itemstack2.isEmpty()) {
76-
flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !EnchantedBookItem.getEnchantments(itemstack2).isEmpty();
77-
if (itemstack1.isDamageableItem() && itemstack1.getItem().isValidRepairItem(itemstack, itemstack2)) {
78-
int l2 = Math.min(itemstack1.getDamageValue(), itemstack1.getMaxDamage() / 4);
79-
if (l2 <= 0) {
80-
// this.outputSlot.setInventorySlotContents(0, ItemStack.EMPTY);
81-
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.EMPTY);
82-
this.cost.set(0);
83-
return;
84-
}
85-
86-
int i3;
87-
for (i3 = 0; l2 > 0 && i3 < itemstack2.getCount(); ++i3) {
88-
int j3 = itemstack1.getDamageValue() - l2;
89-
itemstack1.setDamageValue(j3);
90-
++i;
91-
l2 = Math.min(itemstack1.getDamageValue(), itemstack1.getMaxDamage() / 4);
92-
}
93-
94-
this.repairItemCountCost = i3;
95-
} else {
96-
if (!flag && (itemstack1.getItem() != itemstack2.getItem() || !itemstack1.isDamageableItem())) {
97-
// this.outputSlot.setInventorySlotContents(0, ItemStack.EMPTY);
98-
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.EMPTY);
99-
this.cost.set(0);
100-
return;
101-
}
102-
103-
if (itemstack1.isDamageableItem() && !flag) {
104-
int l = itemstack.getMaxDamage() - itemstack.getDamageValue();
105-
int i1 = itemstack2.getMaxDamage() - itemstack2.getDamageValue();
106-
int j1 = i1 + itemstack1.getMaxDamage() * 12 / 100;
107-
int k1 = l + j1;
108-
int l1 = itemstack1.getMaxDamage() - k1;
109-
if (l1 < 0) {
110-
l1 = 0;
111-
}
112-
113-
if (l1 < itemstack1.getDamageValue()) {
114-
itemstack1.setDamageValue(l1);
115-
i += 2;
116-
}
117-
}
118-
119-
Map<Enchantment, Integer> map1 = EnchantmentHelper.getEnchantments(itemstack2);
120-
boolean flag2 = false;
121-
boolean flag3 = false;
122-
123-
for (Enchantment enchantment1 : map1.keySet()) {
124-
if (enchantment1 != null) {
125-
int i2 = map.getOrDefault(enchantment1, 0);
126-
int j2 = map1.get(enchantment1);
127-
j2 = i2 == j2 ? j2 + 1 : Math.max(j2, i2);
128-
boolean flag1 = enchantment1.canEnchant(itemstack);
129-
if (this.player.getAbilities().instabuild || itemstack.getItem() == Items.ENCHANTED_BOOK) {
130-
flag1 = true;
131-
}
132-
133-
for (Enchantment enchantment : map.keySet()) {
134-
if (enchantment != enchantment1 && !enchantment1.isCompatibleWith(enchantment)) {
135-
flag1 = false;
136-
++i;
137-
}
138-
}
139-
140-
if (!flag1) {
141-
flag3 = true;
142-
} else {
143-
flag2 = true;
144-
if (j2 > enchantment1.getMaxLevel()) {
145-
j2 = enchantment1.getMaxLevel();
146-
}
147-
148-
map.put(enchantment1, j2);
149-
int k3 = 0;
150-
switch (enchantment1.getRarity()) {
151-
case COMMON:
152-
k3 = 1;
153-
break;
154-
case UNCOMMON:
155-
k3 = 2;
156-
break;
157-
case RARE:
158-
k3 = 4;
159-
break;
160-
case VERY_RARE:
161-
k3 = 8;
162-
}
43+
//@Overwrite
44+
//public void createResult()
16345

164-
if (flag) {
165-
k3 = Math.max(1, k3 / 2);
166-
}
167-
168-
i += k3 * j2;
169-
if (itemstack.getCount() > 1) {
170-
i = cancelThisBySettingCostToMaximum;
171-
}
172-
}
173-
}
174-
}
175-
176-
if (flag3 && !flag2) {
177-
// this.outputSlot.setInventorySlotContents(0, ItemStack.EMPTY);
178-
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), ItemStack.EMPTY);
179-
this.cost.set(0);
180-
return;
181-
}
182-
}
183-
}
184-
185-
if (this.itemName != null && !Util.isBlank(this.itemName)) {
186-
if (!this.itemName.equals(itemstack.getHoverName().getString())) {
187-
k = 1;
188-
i += k;
189-
itemstack1.setHoverName(Component.literal(this.itemName));
190-
}
191-
} else if (itemstack.hasCustomHoverName()) {
192-
k = 1;
193-
i += k;
194-
itemstack1.resetHoverName();
195-
}
196-
if (flag && !itemstack1.isBookEnchantable(itemstack2)) itemstack1 = ItemStack.EMPTY;
197-
198-
this.cost.set(j + i);
199-
if (i <= 0) {
200-
itemstack1 = ItemStack.EMPTY;
201-
}
202-
203-
if (k == i && k > 0 && this.cost.get() >= maximumRenameCostThreshold) {
204-
this.cost.set(maximumAllowedRenameCost);
205-
}
206-
207-
if (this.cost.get() >= maximumRepairCost && !this.player.getAbilities().instabuild) {
208-
itemstack1 = ItemStack.EMPTY;
209-
}
210-
211-
if (!itemstack1.isEmpty()) {
212-
int k2 = itemstack1.getBaseRepairCost();
213-
if (!itemstack2.isEmpty() && k2 < itemstack2.getBaseRepairCost()) {
214-
k2 = itemstack2.getBaseRepairCost();
215-
}
46+
@Redirect(method = "createResult", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/ResultContainer;setItem(ILnet/minecraft/world/item/ItemStack;)V"))
47+
private void arclight$callInventoryEvent(ResultContainer instance, int slot, ItemStack itemStack) {
48+
//The slot id is useless for DataSlot
49+
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemStack);
50+
}
21651

217-
if (k != i || k == 0) {
218-
k2 = calculateIncreasedRepairCost(k2);
219-
}
52+
@Inject(method = "createResult",at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/AnvilMenu;broadcastChanges()V"))
53+
private void arclight$sendData(CallbackInfo ci) {
54+
sendAllDataToRemote();
55+
}
22056

221-
itemstack1.setRepairCost(k2);
222-
EnchantmentHelper.setEnchantments(map, itemstack1);
223-
}
57+
@ModifyConstant(method = "createResult", constant = @Constant(intValue = 40), require = 0)
58+
private int arclight$maximumRepairCost(int raw) {
59+
return raw - 40 + maximumRepairCost;
60+
}
22461

225-
// this.outputSlot.setInventorySlotContents(0, itemstack1);
226-
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1);
227-
this.sendAllDataToRemote();
228-
this.broadcastChanges();
229-
}
62+
@ModifyConstant(method = "createResult", constant = @Constant(intValue = 39), require = 0)
63+
private int arclight$maximumRenameCost(int raw) {
64+
return raw - 40 + maximumRepairCost;
23065
}
23166

23267
@Override

0 commit comments

Comments
 (0)