碎片修复修饰符 ModTGregRepair
vexatos.tgregworks.integration.modifiers.ModTGregRepair,注册名 "TGregRepair"。
本 mod 在无 IguanaTweaksTConstruct 时的默认修复方案,通过
ModifyBuilder.registerModifier(...) 注册,允许用碎片(或锭/宝石)修复 Tinkers’ 工具。
注册路径
TGregworks.postInit 的分支(见 依赖门控):
- 有 IguanaTweaksTConstruct 且
maxToolRepairs > -1→ModLimitedTGregRepair(继承本类) - 有 IguanaTweaksTConstruct 但
maxToolRepairs == -1→ 本类 - 无 IguanaTweaksTConstruct → 本类
所以同一时刻只注册一个修复类修饰符。
registry.registerModifiers()(preInit 阶段)里 ModifyBuilder.registerModifier(new ModifierTGregRepair())
是被注释掉的死代码,函数体实际为空。
构造
super(new ItemStack[0], 0, "TGregRepair");
new ItemStack[0] = 对所有物品都可能生效(canModify 自己判断),
0 = 不消耗任何 modifier 槽位,"TGregRepair" = 内部标识。
触发条件 canModify(tool, input)
NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
if (tags.getInteger("Damage") > 0) {
int headID = tags.getInteger("Head");
for (ItemStack curInput : input) {
if (curInput != null && headID != PatternBuilder.instance.getPartID(curInput)
&& !isValidRepairMaterial(curInput, headID)) { areInputsValid = false; break; }
}
if (areInputsValid) return calculateIfNecessary(tool, input, headID);
}
return false;
- 必须有损伤(
Damage > 0)才允许修复; - 每个非空输入要么本身就是该材料的部件(
PatternBuilder.getPartID相同 → 走标准 TiC 修复), 要么命中TGregworks.repair.repairMaterials里为该材料登记的修复材料; - 全部通过后进入
calculateIfNecessary。
修复材料表 TGregRepairRegistry
TGregworks.repair 是 TGregRepairRegistry,持有
HashMultimap<Materials, RepairMaterial> repairMaterials——按材料多值集合。
两个 RepairMaterial 子类:
| 子类 | matches 判据 |
登记值 | 开关 |
|---|---|---|---|
ShardRepairMaterial |
input.getItem() == toolParts.get(PartTypes.Chunk) 且 NBT material 等于该 Materials |
1 | addShardRepair(默认 true) |
OreDictRepairMaterial |
GT_OreDictUnificator.isItemStackInstanceOf(input, tag) |
2 | addIngotRepair(默认 false) |
registerIngotRepair 打开时对每个已注册材料
GT_OreDictUnificator.getOres(OrePrefixes.ingot, m) 取全部锭变体,
登记 OreDictRepairMaterial(m, OrePrefixes.ingot.get(m).toString(), 2);
gemToolPartRecipes 打开时额外登记 gem<材料> 同为 2。
OreDictRepairMaterial是private static内部类,只有registerOreDictRepairMaterial这个 public 方法能造出来,外部无法实例化。
修复量计算 calculateIncrease
damage = tags.getInteger("Damage");
dur = tags.getInteger("BaseDurability");
increase = (int)(50 * itemsUsed + (dur * 0.4f * materialValue));
materialValue 的来源
for (ItemStack curInput : input)
if (curInput != null) {
int partValue = PatternBuilder.instance.getPartValue(curInput);
materialValue += (partValue != 0) ? partValue : getRepairAmount(curInput, materialID);
numInputs++;
}
优先级:TiC 原生 getPartValue 优先,为 0 时才回退到本 mod 的 RepairMaterial.value。
getRepairAmount 遍历 repairMaterials.get(materialIDMap.get(材料ID)),
返回第一个 matches 为 true 的 RepairMaterial.value(集合是无序的 HashMultimap,
但同一材料只会登记同值的 1~2 种,实践上无歧义)。
所以:碎片价值 1,锭/宝石价值 2,一个 TiC 原生部件的价值由 TiC 自己定。
三层衰减
float mods = 1.0f;
if (modifiers == 2) mods = 0.9f;
else if (modifiers == 1) mods = 0.8f;
else if (modifiers == 0) mods = 0.7f;
increase *= mods; // ① 修饰符槽位惩罚
int repair = tags.getInteger("RepairCount");
float repairCount = (100 - repair) / 100f;
if (repairCount < 0.5f) repairCount = 0.5f;
increase *= repairCount; // ② 累计修复次数惩罚(下限 50%)
increase /= ((ToolCore) tool.getItem()).getRepairCost(); // ③ 工具的 repairCost 除数
return increase;
① 的判据是 Modifiers 恰好等于 0/1/2,其余(≥3)走默认 1.0——
即修饰符槽位用得越多,修复越划算,与直觉相反(TiC 原版是槽位越满修复越差)。
② RepairCount 每修一次 +1(modify 里累加),收益线性衰减到 50% 后不再降。
边界检查 calculateIfNecessary
int totalRepairValue = calculateIncrease(tool, materialValue, numInputs);
float averageRepairValue = totalRepairValue / numInputs;
return numInputs == 1 || (damage - totalRepairValue >= -averageRepairValue);
即不允许一次修到负耐久(留一点损伤)。
用整数除法 totalRepairValue / numInputs(float 接收),多个输入时平均值向下取整。
实际修改 modify
tags.setBoolean("Broken", false);
... 计算 increase ...
tags.setInteger("RepairCount", repair + itemsUsed);
damage -= increase; if (damage < 0) damage = 0;
tags.setInteger("Damage", damage);
AbilityHelper.damageTool(tool, 0, null, true);
Broken(已损坏标记)被清掉——这条能救回已经损坏的工具;RepairCount按输入个数累加(不是按次数);AbilityHelper.damageTool(tool, 0, null, true)传 damage 0 +true, 让 TiC 重新计算并刷新能力加成。
其他覆写
| 方法 | 行为 |
|---|---|
matches(input, tool) |
参数顺序与 ItemModifier 相反(matches(input, tool)) |
addMatchingEffect(tool) |
空实现——不给"当前可用材料"上色 |
validType(IModifyable input) |
input.getModifyType().equals("Tool"),但全仓库无调用者(死代码) |