197 lines
9.3 KiB
Markdown
197 lines
9.3 KiB
Markdown
# 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 本地证据为准。
|