Skip to content

Commit

Permalink
MoP: Fix shaking auras, and add support for 1.09d and 1.10f.
Browse files Browse the repository at this point in the history
  • Loading branch information
bolrog committed May 5, 2021
1 parent 7d9dd7f commit a9c5b85
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 111 deletions.
56 changes: 26 additions & 30 deletions src/d2dx/D2DXContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,8 +1179,6 @@ void D2DXContext::EndDrawText()
_isDrawingText = false;
}

#define MAKE_PLAYER_TYPE(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))

_Use_decl_annotations_
void D2DXContext::BeginDrawImage(
const D2::CellContext* cellContext,
Expand All @@ -1191,37 +1189,35 @@ void D2DXContext::BeginDrawImage(
return;
}


DrawParameters drawParameters = _gameHelper->GetDrawParameters(cellContext);

if (drawParameters.unitType == 0 && (
drawParameters.unitToken == MAKE_PLAYER_TYPE('A', 'M', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('S', 'O', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('N', 'E', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('P', 'A', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('B', 'A', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('A', 'M', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('D', 'Z', ' ', ' ') ||
drawParameters.unitToken == MAKE_PLAYER_TYPE('A', 'I', ' ', ' ')))
{
// The player unit itself.
_scratchBatch.SetTextureCategory(TextureCategory::Player);
_playerScreenPos = pos;
}
else if (_playerScreenPos.x > 0 &&
pos.x == _playerScreenPos.x &&
pos.y == _playerScreenPos.y)
if (currentlyDrawingUnit)
{
// Overlays will be drawn at the player position, so mark them as part of the player.
_scratchBatch.SetTextureCategory(TextureCategory::Player);
if (currentlyDrawingUnit == _gameHelper->GetPlayerUnit())
{
// The player unit itself.
_scratchBatch.SetTextureCategory(TextureCategory::Player);
_playerScreenPos = pos;
}
}
else if (
drawParameters.unitId == 0 &&
drawParameters.unitType == 0 &&
cellContext->dwMode == 0)
else
{
// UI elements have zero unit ID and unit type.
_scratchBatch.SetTextureCategory(TextureCategory::UserInterface);
DrawParameters drawParameters = _gameHelper->GetDrawParameters(cellContext);

//if (_playerScreenPos.x > 0 &&
// pos.x == _playerScreenPos.x &&
// pos.y == _playerScreenPos.y)
//{
// // Overlays will be drawn at the player position, so mark them as part of the player.
// _scratchBatch.SetTextureCategory(TextureCategory::Player);
//}
//else
if (
drawParameters.unitId == 0 &&
drawParameters.unitType == 0 &&
cellContext->dwMode == 0)
{
// UI elements have zero unit ID and unit type.
_scratchBatch.SetTextureCategory(TextureCategory::UserInterface);
}
}
}

Expand Down
159 changes: 98 additions & 61 deletions src/d2dx/D2Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,68 +103,105 @@ namespace d2dx
};

static_assert(sizeof(StaticPath) == 0x20, "StaticPath size");


struct UnitAny {
UnitType dwType; // 0x00
DWORD dwTxtFileNo; // 0x04
DWORD _1; // 0x08
DWORD dwUnitId; // 0x0C
DWORD dwMode; // 0x10
union {
void* pPlayerData;
void* pItemData;
void* pMonsterData;
void* pObjectData;
// TileData *pTileData doesn't appear to exist anymore
}; // 0x14
DWORD dwAct; // 0x18
void* pAct; // 0x1C
DWORD dwSeed[2]; // 0x20
DWORD _2; // 0x28
union {
Path* path;
StaticPath* staticPath;
}; // 0x2C
DWORD _3[2]; // 0x30
union {
Path* path2;
StaticPath* staticPath2;
}; // 0x38
DWORD unk[2];
DWORD dwGfxFrame; // 0x44
DWORD dwFrameRemain; // 0x48
WORD wFrameRate; // 0x4C
WORD _4; // 0x4E
BYTE* pGfxUnk; // 0x50
DWORD* pGfxInfo; // 0x54
DWORD _5; // 0x58
void* pStats; // 0x5C
void* pInventory; // 0x60
void* ptLight; // 0x64
DWORD dwStartLightRadius; // 0x68
WORD nPl2ShiftIdx; // 0x6C
WORD nUpdateType; // 0x6E
UnitAny* pUpdateUnit; // 0x70 - Used when updating unit.
DWORD* pQuestRecord; // 0x74
DWORD bSparklyChest; // 0x78 bool
DWORD* pTimerArgs; // 0x7C
DWORD dwSoundSync; // 0x80
DWORD _6[2]; // 0x84
WORD wX; // 0x8C
WORD wY; // 0x8E
DWORD _7; // 0x90
DWORD dwOwnerType; // 0x94
DWORD dwOwnerId; // 0x98
DWORD _8[2]; // 0x9C
void* pOMsg; // 0xA4
void* pInfo; // 0xA8
DWORD _9[6]; // 0xAC
DWORD dwFlags; // 0xC4
DWORD dwFlags2; // 0xC8
DWORD _10[5]; // 0xCC
UnitAny* pChangedNext; // 0xE0
UnitAny* pListNext; // 0xE4 -> 0xD8
UnitAny* pRoomNext; // 0xE8
struct UnitAny
{
union
{
struct
{
D2::UnitType dwType; // 0x00
DWORD dwClassId; // 0x04
void* pMemPool; // 0x08
DWORD dwUnitId; // 0x0C
DWORD dwMode; // 0x10
union {
void* pPlayerData;
void* pItemData;
void* pMonsterData;
void* pObjectData;
// TileData *pTileData doesn't appear to exist anymore
}; // 0x14
DWORD dwAct; // 0x18
void* pAct; // 0x1C
DWORD dwSeed[2]; // 0x20
DWORD _2; // 0x28
union {
Path* path;
StaticPath* staticPath;
}; // 0x2C
DWORD _3[2]; // 0x30
union {
Path* path2;
StaticPath* staticPath2;
}; // 0x38
} v109;

struct
{
UnitType dwType; // 0x00
DWORD dwTxtFileNo; // 0x04
DWORD _1; // 0x08
DWORD dwUnitId; // 0x0C
DWORD dwMode; // 0x10
union {
void* pPlayerData;
void* pItemData;
void* pMonsterData;
void* pObjectData;
// TileData *pTileData doesn't appear to exist anymore
}; // 0x14
DWORD dwAct; // 0x18
void* pAct; // 0x1C
DWORD dwSeed[2]; // 0x20
DWORD _2; // 0x28
union {
Path* path;
StaticPath* staticPath;
}; // 0x2C
DWORD _3[2]; // 0x30
union {
Path* path2;
StaticPath* staticPath2;
}; // 0x38
DWORD unk[2];
DWORD dwGfxFrame; // 0x44
DWORD dwFrameRemain; // 0x48
WORD wFrameRate; // 0x4C
WORD _4; // 0x4E
BYTE* pGfxUnk; // 0x50
DWORD* pGfxInfo; // 0x54
DWORD _5; // 0x58
void* pStats; // 0x5C
void* pInventory; // 0x60
void* ptLight; // 0x64
DWORD dwStartLightRadius; // 0x68
WORD nPl2ShiftIdx; // 0x6C
WORD nUpdateType; // 0x6E
UnitAny* pUpdateUnit; // 0x70 - Used when updating unit.
DWORD* pQuestRecord; // 0x74
DWORD bSparklyChest; // 0x78 bool
DWORD* pTimerArgs; // 0x7C
DWORD dwSoundSync; // 0x80
DWORD _6[2]; // 0x84
WORD wX; // 0x8C
WORD wY; // 0x8E
DWORD _7; // 0x90
DWORD dwOwnerType; // 0x94
DWORD dwOwnerId; // 0x98
DWORD _8[2]; // 0x9C
void* pOMsg; // 0xA4
void* pInfo; // 0xA8
DWORD _9[6]; // 0xAC
DWORD dwFlags; // 0xC4
DWORD dwFlags2; // 0xC8
DWORD _10[5]; // 0xCC
UnitAny* pChangedNext; // 0xE0
UnitAny* pListNext; // 0xE4 -> 0xD8
UnitAny* pRoomNext; // 0xE8
} v112;
} u;
};

static_assert(sizeof(UnitAny) == 0xEC, "UnitAny size");
Expand Down
9 changes: 6 additions & 3 deletions src/d2dx/Detours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ void __fastcall D2Win_DrawText_Hooked(

D2::UnitAny* currentlyDrawingUnit = nullptr;

__declspec(naked) void D2Client_DrawUnit_Hooked()
__declspec(naked) void D2Client_DrawUnit_Stack_Hooked()
{
static void* origReturnAddr = nullptr;

Expand Down Expand Up @@ -455,7 +455,7 @@ __declspec(naked) void D2Client_DrawUnit_Hooked()
}
}

__declspec(naked) void D2Client_DrawUnit114d_Hooked()
__declspec(naked) void D2Client_DrawUnit_ESI_Hooked()
{
static void* origReturnAddr = nullptr;

Expand Down Expand Up @@ -560,7 +560,10 @@ void d2dx::AttachLateDetours(
DetourAttach(&(PVOID&)D2Gfx_DrawShadow_Real, D2Gfx_DrawShadow_Hooked);
DetourAttach(&(PVOID&)D2Win_DrawText_Real, D2Win_DrawText_Hooked);

DetourAttach(&(PVOID&)D2Client_DrawUnit_Real, gameHelper->GetVersion() == GameVersion::Lod114d ? D2Client_DrawUnit114d_Hooked : D2Client_DrawUnit_Hooked);
DetourAttach(&(PVOID&)D2Client_DrawUnit_Real,
(gameHelper->GetVersion() == GameVersion::Lod109d ||
gameHelper->GetVersion() == GameVersion::Lod110 ||
gameHelper->GetVersion() == GameVersion::Lod114d)? D2Client_DrawUnit_ESI_Hooked : D2Client_DrawUnit_Stack_Hooked);

LONG lError = DetourTransactionCommit();

Expand Down
55 changes: 45 additions & 10 deletions src/d2dx/GameHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,19 +575,52 @@ D2::UnitAny* GameHelper::GetPlayerUnit() const
return nullptr;
}
}
Offset GameHelper::GetUnitPos(const D2::UnitAny* unit)

_Use_decl_annotations_
D2::UnitType GameHelper::GetUnitType(
const D2::UnitAny* unit) const
{
if (_version == GameVersion::Lod109d)
{
return unit->u.v109.dwType;
}
else
{
return unit->u.v112.dwType;
}
}

_Use_decl_annotations_
uint32_t GameHelper::GetUnitId(
const D2::UnitAny* unit) const
{
if (unit->dwType == D2::UnitType::Player ||
unit->dwType == D2::UnitType::Monster ||
unit->dwType == D2::UnitType::Missile)
if (_version == GameVersion::Lod109d)
{
D2::Path* path = _version == GameVersion::Lod109d ? unit->path2 : unit->path;
return unit->u.v109.dwUnitId;
}
else
{
return unit->u.v112.dwUnitId;
}
}

_Use_decl_annotations_
Offset GameHelper::GetUnitPos(
const D2::UnitAny* unit) const
{
auto unitType = GetUnitType(unit);

if (unitType == D2::UnitType::Player ||
unitType == D2::UnitType::Monster ||
unitType == D2::UnitType::Missile)
{
D2::Path* path = _version == GameVersion::Lod109d ? unit->u.v109.path2 : unit->u.v112.path;
return { (int32_t)path->x, (int32_t)path->y };
}
else
{
D2::StaticPath* path = _version == GameVersion::Lod109d ? unit->staticPath2 : unit->staticPath;
return { (int32_t)unit->staticPath->xPos * 65536 + (int32_t)unit->staticPath->xOffset, (int32_t)unit->staticPath->yPos * 65536 + (int32_t)unit->staticPath->yOffset };
D2::StaticPath* path = _version == GameVersion::Lod109d ? unit->u.v109.staticPath2 : unit->u.v112.staticPath;
return { (int32_t)path->xPos * 65536 + (int32_t)path->xOffset, (int32_t)path->yPos * 65536 + (int32_t)path->yOffset };
}
}

Expand Down Expand Up @@ -630,16 +663,18 @@ void* GameHelper::GetFunction(
hModule = _hD2GfxDll;
ordinal = 10076;
break;
case D2Function::D2Gfx_DrawShadow:
case D2Function::D2Gfx_DrawShadow:
hModule = _hD2GfxDll;
ordinal = 10075;
break;
break;
case D2Function::D2Win_DrawText:
hModule = _hD2WinDll;
ordinal = 10117;
break;
case D2Function::D2Client_DrawUnit:
return (void*)((uintptr_t)_hD2ClientDll + 0xBBA70);
return _version == GameVersion::Lod110 ?
(void*)((uintptr_t)_hD2ClientDll + 0xBA720) :
(void*)((uintptr_t)_hD2ClientDll + 0xB8350);
default:
break;
}
Expand Down
12 changes: 9 additions & 3 deletions src/d2dx/GameHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ namespace d2dx

virtual bool TryApplyFpsFix() override;

virtual Offset GetUnitPos(
_In_ const D2::UnitAny* unit) override;

virtual Offset GetPlayerTargetPos() const override;

virtual void* GetFunction(
Expand All @@ -62,6 +59,15 @@ namespace d2dx

virtual D2::UnitAny* GetPlayerUnit() const override;

virtual Offset GetUnitPos(
_In_ const D2::UnitAny* unit) const override;

virtual D2::UnitType GetUnitType(
_In_ const D2::UnitAny* unit) const override;

virtual uint32_t GetUnitId(
_In_ const D2::UnitAny* unit) const override;

private:
uint16_t ReadU16(HANDLE module, uint32_t offset) const;
uint32_t ReadU32(HANDLE module, uint32_t offset) const;
Expand Down
Loading

0 comments on commit a9c5b85

Please sign in to comment.