Files

197 lines
9.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HEROLL 2.0.1 掉落规则逆向报告
> 样本:`com.percent.aos.rollinghero`,versionName `2.0.1`,versionCode `113296145`
> 原始 XAPK SHA-256:`439D532704AFCCDBEBA8C01AF7869552387CDE31651963D0A45541F252B94E2F`
> 结论等级:**确认**=配置或 Native 正文直接证明;**高置信推导**=多项独立证据闭合;**未知**=不得用于原作还原。
## 1. 核心结论
HEROLL 的局内装备生成不是一次抽完,而是至少拆成四步:
1. 从 `WeaponDrop` 的 40 条局内装备中随机选装备身份。
2. 以六档相对权重生成品质,并叠加 Joker/局内效果及圈数相关修正。
3. 另行生成 `loopGrade` 与随机属性。
4. 检查封印等后处理,生成装备槽;槽满时先进入回收路径。
基础品质权重为:
`NORMAL : RARE : EPIC : LEGEND : MYTH : ARCANE = 210 : 60 : 28 : 4 : 1 : 4`
这些数值是**相对权重,不是百分比**。未激活任何动态修正时,总权重为 307,基线概率如下:
| 品质 | 权重 | 基线概率 |
|---|---:|---:|
| NORMAL | 210 | 68.4039% |
| RARE | 60 | 19.5440% |
| EPIC | 28 | 9.1205% |
| LEGEND | 4 | 1.3029% |
| MYTH | 1 | 0.3257% |
| ARCANE | 4 | 1.3029% |
`ARCANE` 的基础权重确实高于 `MYTH`;这是样本原值,不能为了“看起来合理”而改写。
## 2. Native 生成链
### 2.1 装备身份
`BattleController.GetMonoWeaponData`(VA `0x55BDCC0`)读取 `WeaponDrop` 表的总行数,以随机整数索引取一条,再写入 `weaponStringId`。
`weapondrop.csv` 正好有 40 条数据:
| 槽位类型 | 数量 | 基础身份概率 |
|---|---:|---:|
| Ingame_Weapon | 10 | 25%(单件 2.5%) |
| Ingame_Ring | 10 | 25%(单件 2.5%) |
| Ingame_Gauntlet | 10 | 25%(单件 2.5%) |
| Ingame_Boots | 10 | 25%(单件 2.5%) |
该等概率结论仅适用于走基础 `GetMonoWeaponData` 随机重载的奖励。`SpawnFixWeapon`、`SpawnTypeWeapon` 及其他带筛选参数的入口可以固定身份或限制类型,不能套用 2.5%。
### 2.2 品质
`BattleController.GetEWeaponGrade`(VA `0x55BDE8C`)执行以下流程:
```text
weights = [210, 60, 28, 4, 1, 4]
for gradeIndex in 0..5:
weights[gradeIndex] *= JokerEffectController.GetWeaponProbMultiplier(gradeIndex)
apply_loop_or_grade_related_modifiers(weights)
if excludeNormal:
weights[0] = 0
gradeIndex = Utils.GetRatioPercent(weights)
```
`Utils.GetRatioPercent` 是加权选择器,因此最终概率为 `修正后本档权重 / 修正后总权重`。
当调用入口设置 `excludeNormal=true` 且没有其他修正时,归一化结果为:RARE 61.8557%、EPIC 28.8660%、LEGEND 4.1237%、MYTH 1.0309%、ARCANE 4.1237%。这不是普通掉落率,只是该特殊分支的数学基线。
### 2.3 `loopGrade`、属性与后处理
`BattleController.GetWeaponLoop`(VA `0x55BE240`)另建一个三项权重列表,经 `Utils.GetRatioPercent` 抽取并叠加圈数/品质相关值。它不是六档品质抽取。
随后 `GetMonoWeaponData` 继续生成状态值、检查封印并写入 `MonoWeaponData`。随机装备协程的已闭合调用链为:
```text
CheckFullSlotRecycleFirstExtra
-> GetMonoWeaponData
-> MonoWeaponSlot.Spawn
-> AddWeaponRewardForEventLog
-> HandleJokerWeaponSpawnPostProcess
```
因此以下行为已确认:
- 满槽会在生成前进入回收处理。
- Joker 不只修正品质权重,装备生成后还有独立后处理。
- `GetWeaponDropDestroyChance` 表明某些 Joker 效果可令掉落销毁;具体活动值取决于当前效果状态。
## 3. 掉落“出现机会”与“掉落品质”必须分开
`ingameWeaponDropRatio` 只证明**已经进入装备生成时的品质分布**,不等于“每只敌人有多少概率掉装备”。
当前静态证据能确认多个系统会调用随机、固定或类型限定装备生成接口,包括战斗相关奖励、宝箱/事件、碎片交互、小游戏和特殊祝福效果。但 APK 中没有发现一个可直接解释为“所有普通敌人的统一装备掉率”的全局配置。
两个启用的祝福配置会改变装备出现机会:
| ID | StringId | 关键配置 | 可确认内容 | 尚未确认内容 |
|---:|---|---|---|---|
| 124 | KillInTimeGetGear | `timeValue=2.5` | 祝福启用,名称指向限时击杀装备奖励 | 2.5 的精确单位、触发对象及是否必掉 |
| 132 | KillForHeroGear | `Value=10` | 祝福启用,名称指向击杀换高品质装备 | “10”的计数/概率语义及品质下限 |
仅凭 StringId 不足以把这两项写成确定公式;需要继续闭合祝福消费者 Native 正文或做指定种子的动态采样。
## 4. 局内非装备奖励表
`ingamereward.csv` 配置了以下节点:
| 时机 | 奖励 | 配置 |
|---|---|---|
| `killStrong` | 钻石(item 101) | 数量 0、概率 0,等同关闭 |
| `loopClear` | 钻石(item 101) | 数量 1、概率 80 |
| `loopEndTileMove` | 金币(item 100) | 基数 10、概率 100、随目标关卡乘 `stageMult` |
| `loopClear` | 金币(item 100) | 基数 330、概率 100、随目标关卡乘 `stageMult` |
| `loopClear` | 四槽卷轴(119–122) | 各数量 1、配置概率数组均为 20 |
| `loopClear` | 四槽强化材料(126–129) | 各数量 1、配置概率数组均为 20 |
| `gameEnd` | 鱼饼(item 111) | 数量 1、概率 100 |
金币 `stageMult`:
| 目标关卡索引 | stageMult |
|---|---:|
| -1–16 | 0.30 |
| 17–21 | 0.29 |
| 22–25 | 0.28 |
| 26–30 | 0.27 |
| 31–33 | 0.26 |
| 34–37 | 0.25 |
| 38–44 | 0.24 |
| 45–99 | 0.23 |
表中 `itemCount × stageMult` 的小数取整规则尚未由消费者正文证明,不应自行选择 floor、round 或 ceil。四项 `20` 是配置事实,但“各自独立判定”还是“先选一项再判空”也需 Native 消费者闭合。
## 5. 抓娃娃掉落配置
`clawcraneminigame.csv` 说明场内出现 20 个胶囊,配置项包括:
| 奖励 | 普通 Prob | goodProb |
|---|---:|---:|
| 空 | 40 | 0 |
| 点数 | 70 | 0 |
| 药水 | 14 | 0 |
| NORMAL 装备 | 40 | 0 |
| RARE 装备 | 0 | 0 |
| EPIC 装备 | 0 | 0 |
| LEGEND 装备 | 0 | 1 |
| 祝福 | 0 | 0 |
| 药水祝福 | 0 | 0 |
这些是胶囊生成器的输入权重/概率字段,不应直接归一化为单次抓取概率;胶囊层级、20 个场内对象、好胶囊分支和物理抓取成功率都会影响最终获得率。
## 6. 保底与重复保护
结论:**未发现局内 `BattleController` 装备品质抽取的保底计数器或重复品排除逻辑。**
搜索到的保底实现属于其他系统:
- `gachaceildata.csv`:局外抽卡保底。
- `IdleDungeonController.RollGuaranteedIdleDungeonEquipmentGrade`:挂机地牢装备保底。
- `DestinyStatPage.RollGuaranteedHighGrade`:命运属性重掷保底。
它们不能迁移为普通局内装备掉落规则。公开社区所说的“20 抽保底”和 S 级装备抽取率也属于 Mimic Hunt/局外抽取,不是局内棋盘掉落。
## 7. 仍然未知的精确项
以下项目不应冒充已经还原:
1. 普通敌人自然产生一次装备奖励的基础触发率。
2. `GetEWeaponGrade` 中圈数对 EPIC/LEGEND/MYTH/ARCANE 的完整倍率公式。
3. 当前运行中各 Joker 的实际倍率、掉落销毁率及远程配置覆盖值。
4. `GetWeaponLoop` 三项权重的语义名称及最终 `loopGrade` 分布。
5. 卷轴/强化材料概率数组的精确判定顺序。
6. 小数奖励数量的取整方式。
要闭合 1–4,最小动态采样方案是固定 seed,分别在无祝福、获取 ID 124、获取 ID 132、不同圈数及指定 Joker 状态下,Hook `GetEWeaponGrade` 的入参、六项修正后权重和返回值,并记录每个 `SpawnRandomWeapon` 的调用栈。互联网资料无法替代这一步。
## 8. 证据索引
| 证据 | SHA-256 | 用途 |
|---|---|---|
| `gameconfig.csv` | `A57510DEDE13DAF1A597DE1EE73E47B0ABD830D96719DAD24B2CA7370E8DFE3D` | 六档基础权重 |
| `weapondrop.csv` | `AF8C97D022A83C1FF898D33FC541F157CAD1DC6C5732FF57D61A502E82914809` | 40 条局内装备身份 |
| `ingamereward.csv` | `BCD0E607C0F31A378960F3CD3BA25518A3F3D72D377EEDE11064A276849A9A74` | 圈结算与关卡结束奖励 |
| `augment.csv` | `E0B14AF4709E3F0D548973E124F679EF091589D7C99B0E35DE78C628A73D032A` | 装备掉落相关祝福 |
| `clawcraneminigame.csv` | `AE52FA502303678DE55D910BF07CD222C29A6995D0A4D96A785E84C660035015` | 抓娃娃胶囊配置 |
| `assembly-csharp.json` | `BA6D3F4BD91B0D3977EB1229AB46FE563118CC55793346796F93816BA7FEF526` | IL2CPP 类型、字段、方法映射 |
| `libil2cpp.runtime-decrypted.so` | `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA` | Native 规则正文 |
| `battlecontroller-drop-code.bin` | `DC28F8583A8AA60C2C3ED7CED8E5B9A60EDBF4A10E82370B32F2C169424FC0ED` | 原 SO 的只读函数区切片,便于 ARM64 复核 |
## 9. 互联网交叉检索结论
- [Heroll Wiki 的 Equipment 页面](https://heroll.fandom.com/wiki/Equipment)描述的是局外装备、Mimic Hunt、合成与升级,没有公开局内 `EMonoWeaponGrade` 的生成算法。
- [Heroll 社区的 S Legendary 讨论](https://www.reddit.com/r/heroll/comments/1mtb15a/the_thing_about_s_legendary_equipment/)出现了玩家声称的 0.5964% 以及评论中的“20 抽保底”,上下文明确是局外抽取/合成,不可用于本报告的局内掉落率。
因此,互联网没有补上 Native 中尚缺的圈数倍率;本报告以 APK 2.0.1 本地证据为准。