Skip to content

Lead the returned point in sub_6FDAB940, not the path target - #248

Open
ResurrectedTrader wants to merge 1 commit into
ThePhrozenKeep:masterfrom
ResurrectedTrader:fix/path-target-lead-output-point
Open

ResurrectedTrader wants to merge 1 commit into
ThePhrozenKeep:masterfrom
ResurrectedTrader:fix/path-target-lead-output-point

Conversation

@ResurrectedTrader

Copy link
Copy Markdown
Contributor

sub_6FDAB940 returns where a path's target unit stands, led along the target's facing by the path's dwSpeed. MOO applies the lead through PATHUtil_AdvanceTowardsTarget_6FDAB890, which adds it to the path's own tTargetCoord and returns the unled point. As a result:

  • the per-step "target moved more than 5 subtiles" test (sub_6FD5DB70) compares against an unled point, and
  • every call moves the path's target a bit further along the facing.

1.10f

The whole of D2Common.0x6FDAB940. esi is the output point (ecx on entry), and the lead is added there:

6FDAB940  push    ecx
6FDAB941  push    esi
6FDAB942  push    edi
6FDAB943  mov     edi, edx                          ; ptPath
6FDAB945  mov     esi, ecx                          ; pOutPathPoint
6FDAB947  test    edi, edi
6FDAB949  jnz     short loc_6FDAB969
6FDAB94B  push    201h
6FDAB950  push    6FDE55ACh
6FDAB955  push    6FDE541Ch
6FDAB95A  call    6FDC4352h
6FDAB95F  add     esp, 0Ch
6FDAB962  push    0FFFFFFFFh
6FDAB964  call    6FDC446Fh
6FDAB969  mov     ecx, [edi+58h]                    ; pTargetUnit
6FDAB96C  test    ecx, ecx
6FDAB96E  jnz     short loc_6FDAB98E
6FDAB970  push    202h
6FDAB975  push    6FDE55ACh
6FDAB97A  push    6FDE529Ch
6FDAB97F  call    6FDC4352h
6FDAB984  add     esp, 0Ch
6FDAB987  push    0FFFFFFFFh
6FDAB989  call    6FDC446Fh
6FDAB98E  mov     eax, [ecx]
6FDAB990  cmp     eax, 2
6FDAB993  jz      short loc_6FDAB9B2
6FDAB995  cmp     eax, 3
6FDAB998  jle     short loc_6FDAB99F
6FDAB99A  cmp     eax, 5
6FDAB99D  jle     short loc_6FDAB9B2
6FDAB99F  mov     ecx, [ecx+2Ch]
6FDAB9A2  test    ecx, ecx
6FDAB9A4  jz      short loc_6FDAB9AE
6FDAB9A6  push    ecx
6FDAB9A7  call    D2Common_10162
6FDAB9AC  jmp     short loc_6FDAB9B8
6FDAB9AE  xor     eax, eax
6FDAB9B0  jmp     short loc_6FDAB9B8
6FDAB9B2  mov     eax, [ecx+2Ch]
6FDAB9B5  mov     eax, [eax+0Ch]
6FDAB9B8  mov     [esi], ax                         ; out.X = target X
6FDAB9BB  mov     ecx, [edi+58h]
6FDAB9BE  mov     eax, [ecx]
6FDAB9C0  cmp     eax, 2
6FDAB9C3  jz      short loc_6FDAB9E2
6FDAB9C5  cmp     eax, 3
6FDAB9C8  jle     short loc_6FDAB9CF
6FDAB9CA  cmp     eax, 5
6FDAB9CD  jle     short loc_6FDAB9E2
6FDAB9CF  mov     ecx, [ecx+2Ch]
6FDAB9D2  test    ecx, ecx
6FDAB9D4  jz      short loc_6FDAB9DE
6FDAB9D6  push    ecx
6FDAB9D7  call    D2Common_10163
6FDAB9DC  jmp     short loc_6FDAB9E8
6FDAB9DE  xor     eax, eax
6FDAB9E0  jmp     short loc_6FDAB9E8
6FDAB9E2  mov     ecx, [ecx+2Ch]
6FDAB9E5  mov     eax, [ecx+10h]
6FDAB9E8  mov     [esi+2], ax                       ; out.Y = target Y
6FDAB9EC  mov     al, [edi+68h]                     ; dwSpeed
6FDAB9EF  test    al, al
6FDAB9F1  jz      short loc_6FDABA49
6FDAB9F3  mov     edx, [edi+58h]
6FDAB9F6  mov     eax, [edx+2Ch]                    ; target's pDynamicPath
6FDAB9F9  push    eax
6FDAB9FA  call    D2Common_10158                    ; PATH_GetDirection
6FDAB9FF  xor     ecx, ecx
6FDABA01  and     eax, 0FFh
6FDABA06  mov     cl, [edi+68h]
6FDABA09  mov     [esp+0Ch+var_4], ecx
6FDABA0D  fild    [esp+0Ch+var_4]
6FDABA11  shl     eax, 3
6FDABA14  shl     ecx, 8
6FDABA17  fstp    [esp+0Ch+var_4]
6FDABA1B  sub     eax, ecx
6FDABA1D  and     eax, 1FFh                         ; (8 * dir - (speed << 8)) & 0x1FF
6FDABA22  mov     edi, eax
6FDABA24  push    edi
6FDABA25  call    6FDC440Ch                         ; cos LUT
6FDABA2A  fmul    [esp+0Ch+var_4]
6FDABA2E  call    6FDC4FD0h                         ; _ftol
6FDABA33  add     [esi], ax                         ; <== out.X += lead
6FDABA36  push    edi
6FDABA37  call    6FDC4406h                         ; sin LUT
6FDABA3C  fmul    [esp+0Ch+var_4]
6FDABA40  call    6FDC4FD0h
6FDABA45  add     [esi+2], ax                       ; <== out.Y += lead
6FDABA49  pop     edi
6FDABA4A  pop     esi
6FDABA4B  pop     ecx
6FDABA4C  retn

PATHUtil_AdvanceTowardsTarget_6FDAB890 is the other variant. It has the same lead but adds it to the path's target (esi = ptPath there):

6FDAB8DB  mov     eax, [eax+2Ch]
6FDAB8DE  push    edi
6FDAB8DF  push    eax
6FDAB8E0  call    D2Common_10158                    ; PATH_GetDirection
6FDAB8E5  xor     ecx, ecx
6FDAB8E7  and     eax, 0FFh
6FDAB8EC  mov     cl, [esi+68h]
6FDAB8EF  mov     [esp+0Ch+var_4], ecx
6FDAB8F3  fild    [esp+0Ch+var_4]
6FDAB8F7  shl     eax, 3
6FDAB8FA  shl     ecx, 8
6FDAB8FD  fstp    [esp+0Ch+var_4]
6FDAB901  sub     eax, ecx
6FDAB903  and     eax, 1FFh
6FDAB908  mov     edi, eax
6FDAB90A  push    edi
6FDAB90B  call    6FDC440Ch
6FDAB910  fmul    [esp+0Ch+var_4]
6FDAB914  call    6FDC4FD0h
6FDAB919  add     [esi+10h], ax                     ; ptPath->tTargetCoord.X += lead
6FDAB91D  push    edi
6FDAB91E  call    6FDC4406h
6FDAB923  fmul    [esp+0Ch+var_4]
6FDAB927  call    6FDC4FD0h
6FDAB92C  add     [esi+12h], ax                     ; ptPath->tTargetCoord.Y += lead
6FDAB930  pop     edi
6FDAB931  pop     esi
6FDAB932  pop     ecx
6FDAB933  retn

1.14d

The same in DRLGPATH_GetMissileTargetPosition (Game.exe 0x679250):

00679250  push    ebp
00679251  mov     ebp, esp
00679253  sub     esp, 0Ch
00679256  push    esi
00679257  push    edi
00679258  mov     edi, edx                          ; ptPath
0067925A  test    edi, edi
0067925C  mov     esi, ecx                          ; pOutPathPoint
0067925E  jnz     short loc_67927F
00679260  push    201h
00679265  call    GetAddress
0067926A  push    eax
0067926B  push    offset Default
00679270  call    ERROR_UnrecoverableInternalError_Halt
00679275  add     esp, 0Ch
00679278  push    0FFFFFFFFh
0067927A  call    _exit
0067927F  mov     ecx, [edi+58h]
00679282  test    ecx, ecx
00679284  jnz     short loc_67928D
00679286  push    202h
0067928B  jmp     short loc_679265
0067928D  mov     eax, [ecx]
0067928F  cmp     eax, 2
00679292  jz      short loc_6792B1
00679294  cmp     eax, 3
00679297  jle     short loc_67929E
00679299  cmp     eax, 5
0067929C  jle     short loc_6792B1
0067929E  mov     ecx, [ecx+2Ch]
006792A1  test    ecx, ecx
006792A3  jz      short loc_6792AD
006792A5  push    ecx
006792A6  call    GetXPos
006792AB  jmp     short loc_6792B7
006792AD  xor     eax, eax
006792AF  jmp     short loc_6792B7
006792B1  mov     eax, [ecx+2Ch]
006792B4  mov     eax, [eax+0Ch]
006792B7  mov     [esi], ax                         ; out.X = target X
006792BA  mov     ecx, [edi+58h]
006792BD  mov     eax, [ecx]
006792BF  cmp     eax, 2
006792C2  jz      short loc_6792E1
006792C4  cmp     eax, 3
006792C7  jle     short loc_6792CE
006792C9  cmp     eax, 5
006792CC  jle     short loc_6792E1
006792CE  mov     ecx, [ecx+2Ch]
006792D1  test    ecx, ecx
006792D3  jz      short loc_6792DD
006792D5  push    ecx
006792D6  call    GetYPos
006792DB  jmp     short loc_6792E7
006792DD  xor     eax, eax
006792DF  jmp     short loc_6792E7
006792E1  mov     ecx, [ecx+2Ch]
006792E4  mov     eax, [ecx+10h]
006792E7  mov     [esi+2], ax                       ; out.Y = target Y
006792EB  cmp     byte ptr [edi+68h], 0             ; dwSpeed
006792EF  jz      short loc_679370
006792F1  mov     edx, [edi+58h]
006792F4  mov     eax, [edx+2Ch]
006792F7  push    eax
006792F8  call    GetDirection_0                    ; PATH_GetDirection
006792FD  movzx   ecx, byte ptr [edi+68h]
00679301  movzx   eax, al
00679304  add     eax, eax
00679306  add     eax, eax
00679308  mov     [ebp+var_8], ecx
0067930B  add     eax, eax
0067930D  shl     ecx, 8
00679310  fild    [ebp+var_8]
00679313  sub     eax, ecx
00679315  and     eax, 1FFh                         ; (8 * dir - (speed << 8)) & 0x1FF
0067931A  mov     edi, eax
0067931C  push    edi
0067931D  fstp    [ebp+var_8]
00679320  call    MATH_sinTable_f32_LookupOffset
00679325  push    edi
00679326  fmul    [ebp+var_8]
00679329  fnstcw  [ebp+var_2]
0067932C  movzx   eax, [ebp+var_2]
00679330  or      eax, 0C00h
00679335  mov     [ebp+var_C], eax
00679338  fldcw   word ptr [ebp+var_C]
0067933B  fistp   [ebp+var_C]
0067933E  mov     cx, word ptr [ebp+var_C]
00679342  add     [esi], cx                         ; <== out.X += lead
00679345  fldcw   [ebp+var_2]
00679348  call    MATH_sinTable_f32_Lookup
0067934D  fmul    [ebp+var_8]
00679350  fnstcw  [ebp+var_2]
00679353  movzx   eax, [ebp+var_2]
00679357  or      eax, 0C00h
0067935C  mov     [ebp+var_C], eax
0067935F  fldcw   word ptr [ebp+var_C]
00679362  fistp   [ebp+var_C]
00679365  mov     dx, word ptr [ebp+var_C]
00679369  add     [esi+2], dx                       ; <== out.Y += lead
0067936D  fldcw   [ebp+var_2]
00679370  pop     edi
00679371  pop     esi
00679372  mov     esp, ebp
00679374  pop     ebp
00679375  retn

Change

Apply the lead to pOutPathPoint in sub_6FDAB940. PATHUtil_AdvanceTowardsTarget_6FDAB890 still serves its other caller, PATH_UpdateTargetUnit (at solve time), which does move the path target; that call is unchanged. Not version-gated, since 1.10f and 1.14d agree.

🤖 Generated with Claude Code

sub_6FDAB940 returns where a path's target unit stands, led along the
target's facing by dwSpeed. MOO applied the lead through
PATHUtil_AdvanceTowardsTarget_6FDAB890, which moves the path's own
tTargetCoord and leaves the returned point unled.

1.10f (D2Common.0x6FDAB940) adds the lead to the output point: esi is
the output pointer, "add [esi], ax" at 0x6FDABA33 and
"add [esi+2], ax" at 0x6FDABA45. PATHUtil_AdvanceTowardsTarget_6FDAB890
(0x6FDAB890) is the variant that adds to [esi+10h] / [esi+12h]. 1.14d
is the same (Game.exe.0x679250).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant