I guess it need a ActIndex in eax and player Unit* in ecx, But crush...
Code: Select all
__declspec(naked) void __fastcall D2GAME_UpdatePlayerStats (UnitAny* pPlayer, WORD nAct)
{
__asm
{
mov eax, nAct
call D2GAME.0x6FD0DD80
}
}
Moderators: Nefarius, Havvoric
Code: Select all
__declspec(naked) void __fastcall D2GAME_UpdatePlayerStats (UnitAny* pPlayer, WORD nAct)
{
__asm
{
mov eax, nAct
call D2GAME.0x6FD0DD80
}
}
Code: Select all
__declspec(naked) void __fastcall D2GAME_UpdatePlayerStats (UnitAny* pPlayer, WORD nAct)
{
__asm
{
mov eax,edx // nAct will be in edx because it's fastcall
call D2GAME.0x6FD0DD8
retn
}
}
Code: Select all
__declspec(naked) void __fastcall D2GAME_UpdatePlayerStats (game *pGame,UnitAny* pPlayer, BYTE nAct)
{
__asm
{
push [esp +0x04] // nAct
push ecx// pGame
mov ecx,edx //pPlayer
call D2GAME.0x6FD0DD8
retn 4
}
}
Code: Select all
6FC4701F |. 57 PUSH EDI ; /Arg1 = pGame
6FC47020 |. 8AC3 MOV AL,BL ; | = nAct
6FC47022 |. 8BCE MOV ECX,ESI ; | = pPlayer
6FC47024 |. E8 576D0C00 CALL 6FD0DD80 ; \D2Game.6FD0DD80
Code: Select all
__declspec(naked) void __fastcall D2GAME_UpdatePlayerStats (D2Game *pGame, D2Unit* pPlayer, BYTE nAct)
{
__asm{
MOVZX EAX, BYTE [ESP+0x04] // nAct
PUSH ECX // pGame arg1 to func
MOV ECX,EDX // pPlayer
CALL D2GAME_6FD0DD8 // pointer to 6FD0DD8
RETN 4
}
}
It worked!devurandom wrote: ↑Sat Feb 02, 2019 1:57 pmwith stubs I put a break on the call to the function, then ID what each arg is.
This is 6FD0B2C0 in 1.13c if someone wants that. I changed the name to StartActPlayerStats for my notes.
Code: Select all
6FC4701F |. 57 PUSH EDI ; /Arg1 = pGame 6FC47020 |. 8AC3 MOV AL,BL ; | = nAct 6FC47022 |. 8BCE MOV ECX,ESI ; | = pPlayer 6FC47024 |. E8 576D0C00 CALL 6FD0DD80 ; \D2Game.6FD0DD80
Code: Select all
__declspec(naked) void __fastcall D2GAME_UpdatePlayerStats (D2Game *pGame, D2Unit* pPlayer, BYTE nAct) { __asm{ MOVZX EAX, BYTE [ESP+0x04] // nAct PUSH ECX // pGame arg1 to func MOV ECX,EDX // pPlayer CALL D2GAME_6FD0DD8 // pointer to 6FD0DD8 RETN 4 } }
devurandom wrote: ↑Sat Feb 02, 2019 5:56 pmThat's cool!
Was thinking you could run some loops and reset all the quests, but not sure about reset questdata.
Maybe someone else has a suggestion, or you could look into how its done for character create.
Code: Select all
struct QuestFlags {
void* pBuffer; // 0x00
DWORD _1; // 0x04
};
void __fastcall ResetPlayerAllQuestFlags(UnitAny* pPlayer)
{
PlayerData* pPlayerData = pPlayer->pPlayerData;
int diff = 3;
do
{
auto pQuestFlags = pPlayerData->QuestsFlags[--diff];
memset(pQuestFlags->pBuffer, 0, 0x60);
} while (diff);
}
struct Waypoint {
BYTE flags; // 0x00
};
void __fastcall ResetPlayerAllWaypoints(UnitAny* pPlayer)
{
PlayerData* pPlayerData = pPlayer->pPlayerData;
int diff = 3;
do
{
auto pWaypoint = pPlayerData->pWaypoints[--diff];
memset(pWaypoint, 0, 0x0D);
} while (diff);
}
Code: Select all
struct WaypointData // size 0x10
{
WORD nData[8]; //0x00
};
Code: Select all
void __fastcall ResetPlayerAllWaypoints(UnitAny* pPlayer)
{
PlayerData* pPlayerData = pPlayer->pPlayerData;
int diff = 3;
do
{
WaypointData* pWaypoint = pPlayerData->pWaypoints[--diff];
memset(pWaypoint, 0, sizeof(pWaypoint));
} while (diff);
}
Code: Select all
struct D2ClientStrc
{
DWORD dwClientId; //0x000
DWORD dwClientState; //0x004
WORD wClassId; //0x008
BYTE nPlayerStatus; //0x00A
BYTE nCompleteActFlags; //0x00B
...
}
Code: Select all
char szClanTag[4]; //0x460
char szClanName[7]; //0x464
Code: Select all
char* szClanTag[4]; //0x460
char* szClanName[7]; //0x470