您现在的位置: 首页>> NPC>> 从RR的符文几率对暗黑破坏神2中伪随机数进行研究

从RR的符文几率对暗黑破坏神2中伪随机数进行研究

为暗黑FANS提供最客观的资讯…… diablofans.com.cn

作者:佚名 更新:2025-11-28 收藏本文 标签: 暗黑破坏神2 暗黑2

有关Rune Run最后的敲石头,就是完成A4的第二个任务,将有一个符文的奖励,在地狱难度下面完成这个任务,可以获得15#~25#中的某个符文。网上大多研究表明,这个到底会得到那个符文,完全是随机的。

 
然后从理论的角度,由于伪随机并不是真正的随机,因此完全有可能找到其规律,从而实现敲石头的时候,只出25#。
 
因此,我上网找了一下相关的资料,得到如下信息:
1、敲石头掉落的符文产生方法,是硬编码在d2game.dll中的。这个和别的物品掉落不一样,别的物品基本上都是由一个公共函数产生,几率由配置文件决定。
2、Diablo2 1.10和Diablo2 1.11的符文掉落上,算法有变动。因此,如果按照1.10敲符文的经验在1.11里敲符文,很可能不理想。这个是我反汇编d2game.dll得出的结论。
 
下面说的都是在Diablo2 1.11B版本文件上进行分析的。
 
1、首先要找到d2game.dll中,与敲石头任务奖励相关的代码。这个很容易,在d2game.dll里面搜索r25,就看到了,引用这个数字的地方,就是相关的代码;
2、在相关的代码片断,其任务奖励过程是:首先产生完美宝石,然后产生无瑕疵的宝石,最后产生符文。
其中,完美宝石和无瑕疵的宝石产生极其类似,都是产生一个0~6的随机数,然后对应到相应的宝石即可。
3、符文的产生较为复杂。首先判断游戏难度,决定掉落的符文范围是多少?在普通难度,掉落的是1#~11#,而在噩梦难度,掉落的是12#~22#,地狱难度掉落的是15#~25#。
然后调用一个随机数函数,用于产生最终掉落符文的序号。最后根据这个序号产生对应的符文。
 
而最为感兴趣的自然就是其中的随机数函数RuneRandom了。。其代码如下:
.text:6FC21040 RuneRandom     proc near              ; CODE XREF: sub_6FC336B0+187p
.text:6FC21040                                        ; sub_6FC41C20+CCp ...
.text:6FC21040                push   esi
.text:6FC21041                mov    esi, eax       ; ESI=EAX=B
.text:6FC21043                test    esi, esi
.text:6FC21045                jg     short loc_6FC2104B
.text:6FC21047                xor    eax, eax
.text:6FC21049                pop    esi
.text:6FC2104A                retn
.text:6FC2104B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:6FC2104B
.text:6FC2104B loc_6FC2104B:                          ; CODE XREF: RuneRandom+5j
.text:6FC2104B                mov    eax, [ecx]
.text:6FC2104D                push   ebx
.text:6FC2104E                push   edi
.text:6FC2104F                mov    edx, 6AC690C5h  ; 初始化随机数种子
.text:6FC21054                lea    edi, [esi-1]   ; lea edi,[A]
.text:6FC21057                mul    edx
.text:6FC21059                xor    ebx, ebx
.text:6FC2105B                test    edi, esi
.text:6FC2105D                jz     short loc_6FC21075
.text:6FC2105F                mov    edi, [ecx+4]
.text:6FC21062                add    eax, edi
.text:6FC21064                adc    edx, ebx
.text:6FC21066                mov    [ecx+4], edx
.text:6FC21069                mov    [ecx], eax
.text:6FC2106B                xor    edx, edx
.text:6FC2106D                div    esi              ; ESI = A = 10
.text:6FC2106F                pop    edi
.text:6FC21070                pop    ebx
.text:6FC21071                pop    esi
.text:6FC21072                mov    eax, edx
.text:6FC21074                retn
.text:6FC21075 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:6FC21075
.text:6FC21075 loc_6FC21075:                          ; CODE XREF: RuneRandom+1Dj
.text:6FC21075                mov    esi, eax       ; EDI=ESI
.text:6FC21077                mov    eax, [ecx+4]
.text:6FC2107A                add    esi, eax
.text:6FC2107C                mov    eax, edi
.text:6FC2107E                adc    edx, ebx
.text:6FC21080                pop    edi
.text:6FC21081                pop    ebx
.text:6FC21082                mov    [ecx], esi
.text:6FC21084                and    eax, esi
.text:6FC21086                mov    [ecx+4], edx
.text:6FC21089                pop    esi
.text:6FC2108A                retn
.text:6FC2108A RuneRandom     endp
可以看出,它使用的是一种典型的伪随机数产生算法。
简单的说,就是用如下公式产生:
Rand_Number = (Rand_Seed * X + Y) mod Z
其中Rand_Seed固定是6AC690C5h, 而Z固定是10
因此,决定最终随机数的只有X和Y。
不幸的是,X和Y并不能简单的推算出来。。。
它的XY大概的产生过程是:
1、貌似系统初始的时候,有一个XY;
2、以后,每次使用随机数算法,将X更新为X*Rand_Seed + Y的低半部分;而Y更新为X*Rand_Seed + Y的高半部分。
 
最有可能的方法是,在游戏中,有地图工具,读取内存中的与随机数相关的XY,然后再推算出最终掉落的符文。
不过这个方法有个问题,貌似在打怪、开箱子等等,都会更新XY的值。。。。也许不能打怪或者做任何与随机函数有关的事情。
来源:收藏本文 点击:179504次 Www.diablofans.com.cn