2013-07-06, 10:52 AM
Here is reproduction of the damage formula with the ASM in /*comments*/
Code:
/*
00404470 83 EC 14    sub    esp,14h
00404473 53       push    ebxÂ
00404474 8B 5C 24 1C   mov    ebx,dword ptr [esp+1Ch]
00404478 81 7B 14 18 1A 9C 01 cmp    dword ptr [ebx+14h],19C1A18h
0040447F 56       push    esiÂ
00404480 C7 44 24 0C 00 00 00 00 mov    dword ptr [esp+0Ch],0
00404488 C7 44 24 10 00 00 00 00 mov    dword ptr [esp+10h],0
00404490 C7 44 24 14 00 00 00 00 mov    dword ptr [esp+14h],0
00404498 C7 44 24 18 00 00 00 00 mov    dword ptr [esp+18h],0
004044A0 C7 44 24 08 00 00 00 00 mov    dword ptr [esp+8],0
004044A8 75 2F      jne    004044D9
*/
float srcBase[2] = {0,0};
float dstBase[2] = {0,0};
if(*(DWORD*)(ebx+0x14)==0x19C1A18)
{
//always player, but src must be a weapon
//with the holder's stats in front instead???
//assert(src==player_src); Â
/*
004044AA 33 C0      xor    eax,eax
004044AC 66 8B 03    mov    ax,word ptr [ebx]
004044AF 33 C9      xor    ecx,ecx
004044B1 66 8B 4B 02   mov    cx,word ptr [ebx+2]
004044B5 89 44 24 20   mov    dword ptr [esp+20h],eax
004044B9 DB 44 24 20   fild    dword ptr [esp+20h]
004044BD 89 4C 24 20   mov    dword ptr [esp+20h],ecx
004044C1 D8 0D BC 82 45 00 fmul    dword ptr ds:[4582BCh]
004044C7 D9 5C 24 0C   fstp    dword ptr [esp+0Ch]
004044CB DB 44 24 20   fild    dword ptr [esp+20h]
004044CF D8 0D BC 82 45 00 fmul    dword ptr ds:[4582BCh]
004044D5 D9 5C 24 10   fstp    dword ptr [esp+10h]
*/
srcBase[0] = float(*(WORD*)(ebx))/5;
srcBase[1] = float(*(WORD*)(ebx+2))/5;
}
/*
004044D9 8B 73 40    mov    esi,dword ptr [ebx+40h]
004044DC 81 FE 18 1A 9C 01 cmp    esi,19C1A18h
004044E2 75 3A      jne    0040451E
*/
DWORD esi = *(DWORD*)(ebx+0x40);
if(esi==0x19C1A18)
{
assert(dst==player_dst); //19C1C24 is Strength. 19C1C28 Magic
/*
004044E4 8B 15 24 1C 9C 01 mov    edx,dword ptr ds:[19C1C24h]
004044EA A1 28 1C 9C 01 mov    eax,dword ptr ds:[019C1C28h]
004044EF 81 E2 FF FF 00 00 and    edx,0FFFFh
004044F5 89 54 24 20   mov    dword ptr [esp+20h],edx
004044F9 DB 44 24 20   fild    dword ptr [esp+20h]
004044FD 25 FF FF 00 00 and    eax,0FFFFh
00404502 89 44 24 20   mov    dword ptr [esp+20h],eax
00404506 D8 0D BC 82 45 00 fmul    dword ptr ds:[4582BCh]
0040450C D9 5C 24 14   fstp    dword ptr [esp+14h]
00404510 DB 44 24 20   fild    dword ptr [esp+20h]
00404514 D8 0D BC 82 45 00 fmul    dword ptr ds:[4582BCh]
0040451A D9 5C 24 18   fstp    dword ptr [esp+18h]
*/
dstBase[0] = float(SOM::L.pcstatus[SOM::PC::str])/5;
dstBase[1] = float(SOM::L.pcstatus[SOM::PC::mag])/5;
}
/*
0040451E 83 7B 3C 02   cmp    dword ptr [ebx+3Ch],2
00404522 55       push    ebpÂ
00404523 57       push    ediÂ
00404524 75 6A      jne    00404590
*/ Â
float mystery = 0; //???
if(*(DWORD*)(ebx+0x3C)==2)
{
/*
00404526 33 C0      xor    eax,eax
00404528 66 8B 46 20   mov    ax,word ptr [esi+20h]
0040452C 8D 0C 40    lea    ecx,[eax+eax*2]
0040452F 8D 0C 89    lea    ecx,[ecx+ecx*4]
00404532 8D 14 88    lea    edx,[eax+ecx*4]
00404535 8B 4E 68    mov    ecx,dword ptr [esi+68h]
00404538 33 C0      xor    eax,eax
0040453A 66 8B 04 D5 C8 A1 4D 00 mov    ax,word ptr [edx*8+4DA1C8h]
00404542 8D 3C D5 C8 A1 4D 00 lea    edi,[edx*8+4DA1C8h]
00404549 51       push    ecxÂ
0040454A 8B 2C 85 C8 67 4C 00 mov    ebp,dword ptr [eax*4+4C67C8h]
00404551 E8 3A CF 03 00 call    00441490
00404556 8B 8E 40 02 00 00 mov    ecx,dword ptr [esi+240h]
0040455C 83 C4 04    add    esp,4
0040455F 83 F9 0C    cmp    ecx,0Ch
00404562 75 2C      jne    00404590
*/
DWORD eax = *(WORD*)(esi+0x20), edx = eax+(eax*3*5*4);
DWORD ecx = *(DWORD*)(esi+0x68), edi = edx*8+0x4DA1C8;
eax = *(WORD*)(edi);
DWORD ebp = *(DWORD*)(eax*4+0x4C67C8);
DWORD before = *(DWORD*)(esi+0x240);
((VOID (__cdecl*)(DWORD))0x441490)(ecx);
DWORD after = *(DWORD*)(esi+0x240);
if(after==0) //cmp ecx,0Ch
{
/*
00404564 33 D2      xor    edx,edx
00404566 8A 95 89 00 00 00 mov    dl,byte ptr [ebp+89h]
0040456C 3B D0      cmp    edx,eax
0040456E 7F 20      jg     00404590
00404570 33 C9      xor    ecx,ecx
00404572 8A 8D 8A 00 00 00 mov    cl,byte ptr [ebp+8Ah]
00404578 3B C1      cmp    eax,ecx
0040457A 7F 14      jg     00404590
0040457C 33 D2      xor    edx,edx
0040457E 8A 97 46 01 00 00 mov    dl,byte ptr [edi+146h]
00404584 89 54 24 28   mov    dword ptr [esp+28h],edx
00404588 DB 44 24 28   fild    dword ptr [esp+28h]
0040458C D9 5C 24 10   fstp    dword ptr [esp+10h]
*/
edx = *(BYTE*)(ebp+0x89);
if(edx<=eax) //cmp edx,eax
{
ecx = *(BYTE*)(ebp+0x8A);
if(eax<=ecx) //cmp eax,ecx
{
edx = *(BYTE*)(edi+0x146);
mystery = edx; assert(0); //???
}
}
}
}
/*
00404590 8B 44 24 30   mov    eax,dword ptr [esp+30h]
00404594 8B 6C 24 2C   mov    ebp,dword ptr [esp+2Ch]
00404598 C7 00 00 00 00 00 mov    dword ptr [eax],0
*/
DWORD ebp = dst; *out = 0;
for(esi=0;esi<8;esi++,ebp+=2)
{
/*
0040459E 33 F6      xor    esi,esi
004045A0 33 C0      xor    eax,eax
004045A2 8A 44 33 04   mov    al,byte ptr [ebx+esi+4]
004045A6 84 C0      test    al,al
004045A8 74 77      je     00404621
004045AA 0F BF 4D 00   movsx   ecx,word ptr [ebp]
004045AE 25 FF 00 00 00 and    eax,0FFh
004045B3 83 FE 03    cmp    esi,3
004045B6 89 44 24 28   mov    dword ptr [esp+28h],eax
004045BA DB 44 24 28   fild    dword ptr [esp+28h]
004045BE 89 4C 24 28   mov    dword ptr [esp+28h],ecx
004045C2 DB 44 24 28   fild    dword ptr [esp+28h]
004045C6 D8 44 24 10   fadd    dword ptr [esp+10h]
004045CA D9 5C 24 28   fstp    dword ptr [esp+28h]
*/
float rating = *(BYTE*)(ebx+esi+4); if(!rating) continue;
//mystery: unsure what else fadd could be doing
float offset = *(SHORT*)(ebp); offset+=mystery;
/*
004045CE 7D 0E      jge    004045DE
004045D0 D8 44 24 14   fadd    dword ptr [esp+14h]
004045D4 D9 44 24 28   fld    dword ptr [esp+28h]
004045D8 D8 44 24 1C   fadd    dword ptr [esp+1Ch]
004045DC EB 0C      jmp    004045EA
004045DE D8 44 24 18   fadd    dword ptr [esp+18h]
004045E2 D9 44 24 28   fld    dword ptr [esp+28h]
004045E6 D8 44 24 20   fadd    dword ptr [esp+20h]
*/
rating+=srcBase[esi>=3]; offset+=dstBase[esi>=3];
/*
004045EA D9 C1      fld    st(1)
004045EC D8 D9      fcomp   st(1)
004045EE DF E0      fnstsw   axÂ
004045F0 F6 C4 41    test    ah,41h
004045F3 75 0D      jne    00404602
004045F5 D9 C1      fld    st(1)
004045F7 D8 E1      fsub    st,st(1)
004045F9 E8 3A B3 04 00 call    0044F938
004045FE 8B F8      mov    edi,eax
00404600 EB 02      jmp    00404604
00404602 33 FF      xor    edi,edi
*/ Â
LONG edi = rating-offset;
/*
00404604 D9 C1      fld    st(1)
00404606 D8 CA      fmul    st,st(2)
00404608 D9 C9      fxch    st(1)
0040460A DC C0      fadd    st(0),st
0040460C DE F9      fdivp   st(1),st
//not sure what this does but INF becomes 0//
0040460E E8 25 B3 04 00 call    0044F938
00404613 DD D8      fstp    st(0)
00404615 03 F8      add    edi,eax
*/
rating*=rating; offset+=offset;
if(offset) edi+=rating/offset;
/*
00404617 85 FF      test    edi,edi
00404619 7E 06      jle    00404621
0040461B 8B 44 24 30   mov    eax,dword ptr [esp+30h]
0040461F 01 38      add    dword ptr [eax],edi
00404621 46       inc    esi
00404622 83 C5 02    add    ebp,2
00404625 83 FE 08    cmp    esi,8
00404628 0F 8C 72 FF FF FF jl     004045A0
*/
*out+=edi;
}
/*
0040462E 8B 43 14    mov    eax,dword ptr [ebx+14h]
00404631 BF 18 1A 9C 01 mov    edi,19C1A18h
00404636 3B C7      cmp    eax,edi
00404638 75 1B      jne    00404655
*/
DWORD edi = 0x19C1A18;
if(*(DWORD*)(ebx+0x14)==edi) //0x19C1A18
{
//player power gauge
/*
0040463A 8B 4C 24 30   mov    ecx,dword ptr [esp+30h]
0040463E 33 D2      xor    edx,edx
00404640 66 8B 53 0E   mov    dx,word ptr [ebx+0Eh]
00404644 B8 59 17 B7 D1 mov    eax,0D1B71759h
00404649 0F AF 11    imul    edx,dword ptr [ecx]
0040464C F7 E2      mul    eax,edx
0040464E C1 EA 0C    shr    edx,0Ch
00404651 89 11      mov    dword ptr [ecx],edx
00404653 EB 04      jmp    00404659
*/
LONG edx = *out**(WORD*)(ebx+0xE);
edx = (0xD1B71759ULL*edx)>>32; //mul edx
*out = edx>>0xC;
}
/*
00404655 8B 4C 24 30   mov    ecx,dword ptr [esp+30h]
00404659 83 39 00    cmp    dword ptr [ecx],0
0040465C 75 06      jne    00404664
0040465E C7 01 01 00 00 00 mov    dword ptr [ecx],1
*/
if(*out==0) *out = 1;