以下二个均更新C4+

      大航海自定义栏设置的内存基本地址是&H00B082D4, 在打开自定义栏后,这个基址的指向了另一个内存段,在这内存段中连续存放了8个地址,这8个地址+偏移4的内容就是自定义栏F1-F8设置内容(技能或物品)的ID。如果F1=0,...Fn=(N-1),...F8=7的话,那么Fn的 ID=[[[ 基址]+(n-1)*4]+4]。要具体得到那个设置的技能或物品的名字,还得要另二个地址的内容作参数,一个计算技能名的,地址是&H00B07010,另一个是计算物品名的,地址是&H00B072CC,计算方法同以前计算商品或对象名的一样。下面是SP代码:

 

 1 function main    
 2     getCustomSet()    
 3 end function
 4 //得到自定义栏设置
 5 function getCustomSet()
 6     Addr=&HB17194
 7     ReadMemory(Addr,2,Addr) 
 8     For I=0 to 7
 9         ReadMemory(Addr+I*4,2,Addr1)
10         ReadMemory(addr1+4,2,ID)
11         print(addr1)
12         print("F" & I+1 & ": ID=" & ID & "  名称:" & GetName(ID))
13         ReadMemory(addr1+&H08,2,sl)    //addr1+&H10 是数量的地址
14         if sl =0 then
15             print("可用")
16         else    
17             print("不可用")
18         end if
19         ReadMemory(addr1+&H10,2,sl)    //addr1+&H10 是数量的地址
20         print("数量" & sl)
21     next
22 end function
23 
24 # 在此添加子函数
25 function GetAddr(addrBase,id)
26     id2=Int(id/16)
27     ReadMemory(addrBase+4,2,temp)                                
28     edx=id2 mod temp
29     ReadMemory(addrBase,2,ecx)                                
30     ReadMemory(ecx+edx*4,2,eax) 
31     do
32         ReadMemory(eax+&H0c,2,t2)
33         if t2=id2 then            
34             ReadMemory(eax,2,t1)                        
35             if t1=id then
36                 exit do
37             end if
38         end if
39         ReadMemory(eax+8,2,eax)                                
40     loop until eax=0    
41     ReadMemory(eax+4,2,eax)
42     GetAddr=eax
43 end function
44 
45 function GetName(id)    
46     if id=0 then 
47         GetName="空的"
48         exit function
49     end if
50     if ID < &H00FF then
51         addr=GetAddr(&HB15EC0,id)
52     else
53         addr=GetAddr(&HB1617C,id)
54     end if    
55     ReadMemory(addr+8,2,NameAddr)    
56     ReadMemory(NameAddr,5,24,Name)
57     GetName=UnicodeToGB(Name)
58 end function

     使用技能栏也类似,但相对复杂一些。大航海普通技能的ID的16进制码是从&H01至&H8F,因些游戏程序把这些技能按16进制的高位分成了9个段(后面是否还有不清楚,因我最后一个技能是望风,ID=&H84,如果有应以此类推),分别由9个地址指向某个段的首址,然后从首址得到该段的第一个技能ID和下一个技能的地址,一个接一个。如果该段的技能没学那这个段地址是0。但有些技能比较特殊,就是新增的一些船技,如“急加速”等,它们的ID都大于&HFF,这可能当时大航海设计人员也没考虑到,没留下放的位置,因此,就采用了插队的办法来解决,把这些技能插入到某个段中。下面是SP代码可得到技能ID和技能名:

 1 function main
 2     Jns()
 3     getjn()    
 4 end function
 5 //得到技能
 6 function getjn()
 7     jnAddr=&HB17178
 8     ReadMemory(jnAddr,2,jnAddr) 
 9     ReadMemory(jnAddr+&H04,2,jnAddr) 
10     for I=0 to 8
11         ReadMemory(jnAddr+I*4,2,Addr)
12         do until addr=0
13             ReadMemory(addr,2,JN)
14             print("技能ID:" & JN & "   技能名称:" & GetName(JN))
15             ReadMemory(addr+8,2,addr)
16         loop 
17     next
18 end function
19 //得到技能数
20 function Jns()
21     ReadMemory(&HB17178,2,temp)
22     ReadMemory(temp+&H0C,2,temp)
23     print("使用技能栏的技能数:" & temp)    
24 end function
25 
26 function GetAddr(addrBase,id)
27     id2=Int(id/16)
28     ReadMemory(addrBase+4,2,temp)                                
29     edx=id2 mod temp
30     ReadMemory(addrBase,2,ecx)                                
31     ReadMemory(ecx+edx*4,2,eax) 
32     do
33         ReadMemory(eax+&H0c,2,t2)
34         if t2=id2 then            
35             ReadMemory(eax,2,t1)                        
36             if t1=id then
37                 exit do
38             end if
39         end if
40         ReadMemory(eax+8,2,eax)                                
41     loop until eax=0    
42     ReadMemory(eax+4,2,eax)
43     GetAddr=eax
44 end function
45 
46 function GetName(id)
47     addr=GetAddr(&HB15EC0,id)
48     ReadMemory(addr+8,2,NameAddr)    
49     ReadMemory(NameAddr,5,24,Name)
50     GetName=UnicodeToGB(Name)
51 end function

 

posted on 2009-03-21 10:21  LazyGod  阅读(1208)  评论(0)    收藏  举报