效果阈值检测类型

基本信息

属性 值
枚举类 ca.wescook.nutrition.effects.Effect.EnumDetectionType
取值数 4(ANY / AVERAGE / ALL / CUMULATIVE)
应用位置 EffectsManager.getEffectsInThreshold 的 switch 分支

功能

定义"玩家当前 Nutrient 值如何映射到效果是否触发 / amplifier 是几"的 4 种判定算法。每个 Effect 必须显式通过 detectionType(...) 设置一种,否则 Effect.build() 抛 IllegalStateException(“Must set a detection type”)。

4 种算法对比

ANY — 任一 Nutrient 命中即触发

case ANY -> {
    for (Nutrient nutrient : effect.nutrients) {
        if (manager.get(player, nutrient) >= effect.minimum
            && manager.get(player, nutrient) <= effect.maximum) {
            effectsInThreshold.add(effect);
            break;
        }
    }
}
  • 任一 Nutrient 处于 [minimum, maximum] 区间 → 触发(amplifier 固定)
  • EffectsList 中未使用
  • 典型场景:“任何一类营养超标即触发”

AVERAGE — 所有 Nutrient 平均值命中即触发

case AVERAGE -> {
    float total = 0f;
    for (Nutrient nutrient : effect.nutrients) total += manager.get(player, nutrient);
    int size = effect.nutrients.size();
    float average = (size != 0) ? total / size : -1f;
    if (average >= effect.minimum && average <= effect.maximum) effectsInThreshold.add(effect);
}
  • 所有 Nutrient 的算术平均在 [minimum, maximum] 内 → 触发(amplifier 固定)
  • EffectsList 中 4 个效果使用(mining_fatigue / strength / weakness / resistance / haste)
  • 典型场景:“整体营养水平高/低”

ALL — 所有 Nutrient 都命中才触发

case ALL -> {
    boolean allWithinThreshold = true;
    for (Nutrient nutrient : effect.nutrients) {
        if (!(manager.get(player, nutrient) >= effect.minimum
            && manager.get(player, nutrient) <= effect.maximum)) {
            allWithinThreshold = false;
        }
    }
    if (allWithinThreshold) effectsInThreshold.add(effect);
}
  • 所有 Nutrient 全部处于 [minimum, maximum] → 触发(amplifier 固定)
  • EffectsList 中未使用
  • 典型场景:“全面均衡营养”

CUMULATIVE — 命中数决定 amplifier

case CUMULATIVE -> {
    int cumulativeCount = 0;
    for (Nutrient nutrient : effect.nutrients) {
        if (manager.get(player, nutrient) >= effect.minimum
            && manager.get(player, nutrient) <= effect.maximum) cumulativeCount++;
    }
    effect.amplifier = (cumulativeCount * effect.cumulativeModifier) - 1;
    if (cumulativeCount > 0) effectsInThreshold.add(effect);
}
  • 每多一个 Nutrient 命中 → amplifier = (命中数 × cumulativeModifier) - 1
  • cumulativeModifier 默认 1(Effect.cumulativeModifier),只能用于 CUMULATIVE 检测类型,否则 Builder.cumulativeModifier 报"Cannot use cumulative modifier if detection type is not cumulative"
  • EffectsList 中 1 个效果使用(toughness)
  • 典型场景:“每多一类营养维持在极高水平,效果等级 +1”

触发后处理

public static void reapplyEffects(EntityPlayer player) {
    List<Effect> effects = removeDuplicates(getEffectsInThreshold(player));
    for (Effect effect : effects) {
        player.addPotionEffect(new PotionEffect(effect.potion.id, 619, effect.amplifier));
    }
}

去重逻辑

removeDuplicates 按 effect.potion 引用去重,保留 amplifier 最高的版本(例如同 Potion 上有 Strength I 和 Strength II 时只保留 Strength II)。

续期

应用时长固定 619 ticks(约 30.95 秒)。potionTicking 每 110 ticks(约 5.5 秒)调用一次 reapplyEffects 形成无限续期。

4 类型对比表

类型 触发条件 amplifier EffectsList 使用数 典型场景
ANY 任一 Nutrient 命中 固定 0 单类营养超标
AVERAGE 全部平均命中 固定 5 整体水平
ALL 全部命中 固定 0 全面均衡
CUMULATIVE ≥1 个 Nutrient 命中 命中数 × cumulativeModifier - 1 1 多营养叠加奖励

相关条目