|
5 | 5 |
|
6 | 6 | import java.lang.reflect.Field;
|
7 | 7 | import java.lang.reflect.Method;
|
| 8 | +import java.util.Arrays; |
8 | 9 | import java.util.List;
|
9 | 10 |
|
10 | 11 | import net.minecraft.client.gui.GuiButton;
|
@@ -70,30 +71,9 @@ public void operationHighlight(GuiScreenEvent.DrawScreenEvent.Post event) {
|
70 | 71 | int[] itemCraftingRules = anvilTE.itemCraftingRules;
|
71 | 72 | int[] itemRules = anvilTE.getItemRules();
|
72 | 73 | // 用于存储锻造要求,其中的值为Util类中operations的索引
|
73 |
| - int[] lastOperations = new int[3]; |
74 |
| - for (int i = 0; i < 3; i++) { |
75 |
| - switch (rules[i].Action) { |
76 |
| - case -1: |
77 |
| - case 3: |
78 |
| - lastOperations[i] = 4; |
79 |
| - break; |
80 |
| - case 0: |
81 |
| - lastOperations[i] = 3; |
82 |
| - break; |
83 |
| - case 1: |
84 |
| - lastOperations[i] = 0; |
85 |
| - break; |
86 |
| - case 4: |
87 |
| - lastOperations[i] = 5; |
88 |
| - break; |
89 |
| - case 5: |
90 |
| - lastOperations[i] = 6; |
91 |
| - break; |
92 |
| - case 6: |
93 |
| - lastOperations[i] = 7; |
94 |
| - break; |
95 |
| - } |
96 |
| - ruleOffset += Util.operations[lastOperations[i]]; |
| 74 | + int[] lastOperations = getRules(rules); |
| 75 | + for (Integer i : lastOperations) { |
| 76 | + ruleOffset += Util.operations[i]; |
97 | 77 | }
|
98 | 78 | // GuiAnvil中drawItemRulesImages方法绘制最后三步步骤,drawRulesImages方法绘制锻造要求
|
99 | 79 | // drawItemRulesImages中rules保存锻造要求,索引从左到右分别为012,itemRules保存最后三步,索引从左到右分别为012
|
@@ -224,4 +204,100 @@ private List<GuiButton> getButtonList(GuiContainerTFC gui) throws NoSuchFieldExc
|
224 | 204 | field.setAccessible(true);
|
225 | 205 | return (List<GuiButton>) field.get(gui);
|
226 | 206 | }
|
| 207 | + |
| 208 | + private int[] getRules(RuleEnum[] rules) { |
| 209 | + int[] lastOperations = new int[3]; |
| 210 | + // 将锻造要求初始化为-1,表示没有要求 |
| 211 | + Arrays.fill(lastOperations, -1); |
| 212 | + // 标志该位置要求是否已经被填充 |
| 213 | + boolean[] flag = new boolean[3]; |
| 214 | + // 首先遍历一次锻造目标,将确定位置的步骤填充到lastOperations中,例如HitLast,HitSecondFormLast,HitThirdFormLast |
| 215 | + for (RuleEnum rule : rules) { |
| 216 | + // 这三种序号对6取余后分别是2,3,4 |
| 217 | + if (rule.ordinal() % 6 == 2 && !flag[0]) { |
| 218 | + lastOperations[0] = Util.operationsTfc.get(rule.Action); |
| 219 | + flag[0] = true; |
| 220 | + } else if (rule.ordinal() % 6 == 3 && !flag[1]) { |
| 221 | + lastOperations[1] = Util.operationsTfc.get(rule.Action); |
| 222 | + flag[1] = true; |
| 223 | + } else if (rule.ordinal() % 6 == 4 && !flag[2]) { |
| 224 | + lastOperations[2] = Util.operationsTfc.get(rule.Action); |
| 225 | + flag[2] = true; |
| 226 | + } |
| 227 | + } |
| 228 | + // 第二次遍历,填充可以位于倒数第一步和倒数第二步的步骤,例如HitLastTwo |
| 229 | + for (RuleEnum rule : rules) { |
| 230 | + // 这一步的序号对6取余后是5 |
| 231 | + if (rule.ordinal() % 6 == 5) { |
| 232 | + // 如果最后一步已经填充,说明最后一步是已经定死的步骤,不可以更改,如果能进入这里的循环并且两个位置都已经填满,说明该锻造配方无法完成 |
| 233 | + // 所以当最后一步已经填充,就将倒数第二步填充为当前步骤,否则填充最后一步 |
| 234 | + if (flag[0]) { |
| 235 | + lastOperations[1] = Util.operationsTfc.get(rule.Action); |
| 236 | + flag[1] = true; |
| 237 | + } else { |
| 238 | + lastOperations[0] = Util.operationsTfc.get(rule.Action); |
| 239 | + flag[0] = true; |
| 240 | + } |
| 241 | + } |
| 242 | + } |
| 243 | + // 第三次遍历,填充可以位于倒数第二步和倒数第三步的步骤,例如HitNotLast |
| 244 | + for (RuleEnum rule : rules) { |
| 245 | + // 这一步的序号对6取余后是0,因为Any的序号是0,所以这里要判断当前步骤不是Any |
| 246 | + if (rule.Action != 0 && rule.ordinal() % 6 == 0) { |
| 247 | + // 这里和上面一样,因为这两个循环填充的步骤分别适用于非倒数第三步和非最后一步,因此填充顺序分别是01和21,这样能保证每一步都成功填充 |
| 248 | + if (flag[2]) { |
| 249 | + lastOperations[1] = Util.operationsTfc.get(rule.Action); |
| 250 | + flag[1] = true; |
| 251 | + } else { |
| 252 | + lastOperations[2] = Util.operationsTfc.get(rule.Action); |
| 253 | + flag[2] = true; |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | + // 最后一次遍历,填充剩余的步骤,这里的步骤是可以位于任意位置的步骤,例如BendAny |
| 258 | + o: for (RuleEnum rule : rules) { |
| 259 | + // 这个步骤的序号对6取余后是1 |
| 260 | + if (rule.ordinal() % 6 == 1) { |
| 261 | + // 遍历lastOperations,如果有空位就填充,并且因为锻造需求里每步出现一次,所以只填充一次,跳出大循环 |
| 262 | + for (int i = 0; i < 3; i++) { |
| 263 | + if (!flag[i]) { |
| 264 | + lastOperations[i] = Util.operationsTfc.get(rule.Action); |
| 265 | + flag[i] = true; |
| 266 | + break o; |
| 267 | + } |
| 268 | + } |
| 269 | + } |
| 270 | + } |
| 271 | + // 如果还有空位,说明锻造需求不满3个,这时将空位填入4,对应锻造数值是2,此时未遍历的需求只有Any,对于Any,填入的数值依然是4 |
| 272 | + for (int i = 0; i < 3; i++) { |
| 273 | + if (!flag[i]) { |
| 274 | + lastOperations[i] = 4; |
| 275 | + } |
| 276 | + } |
| 277 | + // 原代码,只能匹配正常顺序的锻造要求,其他非顺序但可以完成的配方不能匹配,因此上面换了另一种填充方法 |
| 278 | + // for (int i = 0; i < 3; i++) { |
| 279 | + // switch (rules[i].Action) { |
| 280 | + // case -1: |
| 281 | + // case 3: |
| 282 | + // lastOperations[i] = 4; |
| 283 | + // break; |
| 284 | + // case 0: |
| 285 | + // lastOperations[i] = 3; |
| 286 | + // break; |
| 287 | + // case 1: |
| 288 | + // lastOperations[i] = 0; |
| 289 | + // break; |
| 290 | + // case 4: |
| 291 | + // lastOperations[i] = 5; |
| 292 | + // break; |
| 293 | + // case 5: |
| 294 | + // lastOperations[i] = 6; |
| 295 | + // break; |
| 296 | + // case 6: |
| 297 | + // lastOperations[i] = 7; |
| 298 | + // break; |
| 299 | + // } |
| 300 | + // } |
| 301 | + return lastOperations; |
| 302 | + } |
227 | 303 | }
|
0 commit comments