碎片修复修饰符 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"),但全仓库无调用者(死代码)

相关条目