# VERTICAL SLICE - NOT FOR PRODUCTION # Validation Question: 玩家能否无指导在一场完整战斗中经历「开战→挖掘规划→轮末结算逐行兑现→胜/负」并逐行归因(P2) # 实现 GDD:design/gdd/systems/战斗循环/战斗结算.md(系统 ID B1·战斗结算——registry 追溯锚,命名规范见 CLAUDE.md) # 战斗结算·战斗段伤害公式族(零状态纯算术宿主——规范 1.2「工具性纯函数挂明确宿主类」; # 自 battle_orchestrator 拆出 2026-09-13,封装审查 O3)。池读取与表值读取仍归 战斗结算,本类只做算术。 # 护甲等级掷点批(2026-09-16):掷点查档与吃掷点分量算术收编本类(判定式参数化——表值零字面量纪律不变)。 class_name DamageMath extends RefCounted # F2 乘区(池值已由调用方 clamp 后传入):池内加算 → 池间乘算 → floor(单一取整规则) static func pool_damage(d_raw: int, p_hero: int, p_enemy: int) -> int: var v: int = int(floor(float(d_raw) * (100.0 + float(p_hero)) * (100.0 + float(p_enemy)) / 10000.0)) return maxi(0, v) # 充能分量:充能点数(调用方已按奖励定义换算)+ 克制修正点数(加法核——2026-09-18 换装,原 percent 乘区退役); # 空桶(点数 ≤ 0)不吃修正恒 0——零充能分量无伤害可修正,不产生负贡献(等价旧量纲 0×任何 percent = 0; # 空桶不受 landed_floor 影响——没有伤害落地就没有下限可言) # 类型化点数分量:点数 + 克制修正(加法核)——2026-09-19 充能退役后唯一消费方 = 奖励直伤道具(棋盘火力) # landed_floor:落地伤害全局下限(读 settlement.damage_floor,调用方传入)——2026-09-20 用户拍板 # 「任何伤害落地取值域 [1,+∞)」:克制修正后触底也保底 1,调参降档不可能打出 0/负伤害 static func counter_component(points: int, counter_delta: int, landed_floor: int = 0) -> int: if points <= 0: return 0 return maxi(landed_floor, points + counter_delta) # ---- 护甲等级掷点批(2026-09-16 用户拍板——判定式与档位参数全在 settlement.tres,本类只做算术)---- # 掷点折扣查档(纯函数):掷点 ≥ 阈值 → 100 全额;低掷按缺口(阈值 − 掷点)查升序边界落档, # 返回档位值 percent(档数 = 边界数 + 1:缺口 ∈ [1, bounds[0]] → discounts[0],(bounds[i], bounds[i+1]] → # discounts[i+1],> bounds 末值 → discounts 末位——档位不设零档,非归零)。nat 最大面的"恒全额"由调用方先行分支。 static func roll_discount_percent(roll: int, threshold: int, bounds: Array, discounts: Array) -> int: if roll >= threshold: return 100 var tier := 0 for i in bounds.size(): if threshold - roll > int(bounds[i]): tier = i + 1 return int(discounts[tier]) # 吃掷点分量算术(纯函数):基线值 × 掷点折扣 ×(暴击时)暴击倍率 → floor 后 + 克制修正点数(加法核)(单一取整; # 乘法交换——折扣/暴击次序无关,克制修正为整数点数加在 floor 之后,取整链保持现登记:每分量恰一次 floor)。暴击恒全额由 discount=100 承载。 static func rolled_component(base_value: float, discount_percent: int, crit: bool, crit_multiplier: int, counter_delta: int) -> int: var v: float = base_value * float(discount_percent) / 100.0 if crit: v *= float(crit_multiplier) / 100.0 return int(floor(v)) + counter_delta