mirror of
https://gitlab.com/hashborgir/plugy.git
synced 2024-11-30 12:36:02 +00:00
502 lines
16 KiB
C++
502 lines
16 KiB
C++
/*=================================================================
|
|
File created by Yohann NICOLAS.
|
|
Add support 1.13d by L'Autour.
|
|
|
|
Unassign Stats Point for futher re-assignment.
|
|
|
|
=================================================================*/
|
|
|
|
#include "plugYFiles.h" // Install_PlugYImagesFiles()
|
|
#include "interface_Stats.h" // Install_InterfaceStats()
|
|
#include "updateServer.h"
|
|
#include "common.h"
|
|
#include <stdio.h>
|
|
|
|
bool active_StatsPoints=0;
|
|
DWORD keyUsedForUnassignStatPoint=VK_CONTROL;
|
|
bool active_StatsShiftClickLimit=1;
|
|
DWORD limitValueToShiftClick=5;
|
|
|
|
void UnassignStr(Unit* ptChar, int nb)
|
|
{
|
|
log_msg("Start Unassign Strengh\n");
|
|
|
|
int currentStr, removePtsNb;
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
|
|
currentStr = D2GetPlayerBaseStat( ptChar, STATS_STRENGTH, 0 );
|
|
if (currentStr <= charStats->baseSTR) return;
|
|
removePtsNb = currentStr - charStats->baseSTR >= nb ? nb : currentStr - charStats->baseSTR;
|
|
if (currentStr - removePtsNb < 1) removePtsNb = currentStr - 1;
|
|
|
|
log_msg("Start Unassign Strengh (cur %d, base %d, rem %d)\n",currentStr,charStats->baseSTR,removePtsNb);
|
|
D2AddPlayerStat( ptChar, STATS_STRENGTH, -removePtsNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 );
|
|
}
|
|
|
|
void UnassignDex(Unit* ptChar, int nb)
|
|
{
|
|
log_msg("Start Unassign Dexterity\n");
|
|
|
|
int currentDex, removePtsNb;
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
|
|
currentDex = D2GetPlayerBaseStat( ptChar, STATS_DEXTERITY, 0 );
|
|
if (currentDex <= charStats->baseDEX) return;
|
|
removePtsNb = currentDex - charStats->baseDEX >= nb ? nb : currentDex - charStats->baseDEX;
|
|
if (currentDex - removePtsNb < 1) removePtsNb = currentDex - 1;
|
|
|
|
log_msg("Start Unassign Dexterity (cur %d, base %d, rem %d)\n",currentDex,charStats->baseDEX,removePtsNb);
|
|
D2AddPlayerStat( ptChar, STATS_DEXTERITY, -removePtsNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 );
|
|
}
|
|
|
|
void UnassignVit(Unit* ptChar, int nb)
|
|
{
|
|
log_msg("Start Unassign Vitality\n");
|
|
|
|
int currentVit, removePtsNb, removeVitNb, removeStaNb;
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
|
|
currentVit = D2GetPlayerBaseStat( ptChar, STATS_VITALITY, 0 );
|
|
if (currentVit <= charStats->baseVIT) return;
|
|
removePtsNb = currentVit - charStats->baseVIT >= nb ? nb : currentVit - charStats->baseVIT;
|
|
if (currentVit - removePtsNb < 1) removePtsNb = currentVit - 1;
|
|
removeVitNb = removePtsNb * (charStats->lifePerVitality << 6);
|
|
removeStaNb = removePtsNb * (charStats->staminaPerVitality << 6);
|
|
|
|
log_msg("Start Unassign Vitality (cur %d, base %d, rem %d)\n",currentVit,charStats->baseVIT,removePtsNb);
|
|
D2AddPlayerStat( ptChar, STATS_VITALITY, -removePtsNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_MAXHP, -removeVitNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_MAXSTAMINA, -removeStaNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 );
|
|
}
|
|
|
|
void UnassignEne(Unit* ptChar, int nb)
|
|
{
|
|
log_msg("Start Unassign Energy\n");
|
|
|
|
int currentEne, removePtsNb, removeManNb;
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
|
|
currentEne = D2GetPlayerBaseStat( ptChar, STATS_ENERGY, 0);
|
|
if (currentEne <= charStats->baseENE) return;
|
|
removePtsNb = currentEne - charStats->baseENE >= nb ? nb : currentEne - charStats->baseENE;
|
|
if (currentEne - removePtsNb < 1) removePtsNb = currentEne - 1;
|
|
removeManNb = removePtsNb * (charStats->manaPerMagic << 6);
|
|
|
|
log_msg("Start Unassign Energy (cur %d, base %d, rem %d)\n",currentEne,charStats->baseENE,removePtsNb);
|
|
D2AddPlayerStat( ptChar, STATS_ENERGY, -removePtsNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_MAXMANA, -removeManNb ,0 );
|
|
D2AddPlayerStat( ptChar, STATS_STATPTS, removePtsNb ,0 );
|
|
}
|
|
|
|
void UnassignStrPoint(Unit* ptChar)
|
|
{
|
|
UnassignStr(ptChar, 1);
|
|
}
|
|
|
|
void UnassignStrPoints(Unit* ptChar)
|
|
{
|
|
UnassignStr(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF);
|
|
}
|
|
|
|
void UnassignDexPoint(Unit* ptChar)
|
|
{
|
|
UnassignDex(ptChar, 1);
|
|
}
|
|
|
|
void UnassignDexPoints(Unit* ptChar)
|
|
{
|
|
UnassignDex(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF);
|
|
}
|
|
|
|
void UnassignVitPoint(Unit* ptChar)
|
|
{
|
|
UnassignVit(ptChar, 1);
|
|
}
|
|
|
|
void UnassignVitPoints(Unit* ptChar)
|
|
{
|
|
UnassignVit(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF);
|
|
}
|
|
|
|
void UnassignEnePoint(Unit* ptChar)
|
|
{
|
|
UnassignEne(ptChar, 1);
|
|
}
|
|
|
|
void UnassignEnePoints(Unit* ptChar)
|
|
{
|
|
UnassignEne(ptChar, active_StatsShiftClickLimit ? limitValueToShiftClick: 0x7FFFFFFF);
|
|
}
|
|
|
|
|
|
//////////////////////////////////
|
|
|
|
|
|
void STDCALL printDisabledStatsBtn(WORD statID, sDrawImageInfo* data, DWORD x, DWORD y, DWORD p4, DWORD p5, DWORD p6)
|
|
{
|
|
if ( onRealm || !D2isLODGame())
|
|
{
|
|
D2PrintImage(data,x,y,p4,p5,p6);
|
|
return;
|
|
}
|
|
Unit* ptChar = D2GetClientPlayer();
|
|
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
int minValue=1;
|
|
switch (statID)
|
|
{
|
|
case STATS_STRENGTH: minValue = charStats->baseSTR; break;
|
|
case STATS_DEXTERITY: minValue = charStats->baseDEX; break;
|
|
case STATS_VITALITY: minValue = charStats->baseVIT; break;
|
|
case STATS_ENERGY: minValue = charStats->baseENE; break;
|
|
}
|
|
int statValue = D2GetPlayerBaseStat(ptChar, statID, 0);
|
|
|
|
if (isOnRect(D2GetMouseX(),D2GetMouseY(),x+5,y+5,32,32))
|
|
{
|
|
WCHAR text[100];
|
|
if (active_StatsShiftClickLimit)
|
|
_snwprintf(text, sizeof(text) - 1, getLocalString(STR_STATS_UNASSIGN_WITH_LIMIT), limitValueToShiftClick);
|
|
else
|
|
_snwprintf(text, sizeof(text) - 1, getLocalString(STR_STATS_UNASSIGN_WITHOUT_LIMIT));
|
|
wcscat(text,L"\n");
|
|
int len = wcslen(text);
|
|
_snwprintf(text + len, sizeof(text) - len, getLocalString(STR_STATS_BASE_MIN), statValue, minValue);
|
|
D2SetFont(1);
|
|
D2PrintPopup(text, x+18, y-32, WHITE, 1);
|
|
}
|
|
|
|
if ( GetKeyState(keyUsedForUnassignStatPoint) >= 0) {
|
|
if ( D2GetPlayerBaseStat(ptChar, 4, 0) <= 0)
|
|
setFrame(data, 2);
|
|
} else {
|
|
setImage(data, unassignStatsBtnImages);
|
|
if (minValue >= statValue)
|
|
setFrame(data, 2);
|
|
}
|
|
|
|
D2PrintImage(data,x,y,p4,p5,p6);
|
|
}
|
|
|
|
FCT_ASM ( caller_printUnassignStatsBtn )
|
|
POP EAX
|
|
XOR ECX,ECX
|
|
MOV CX,WORD PTR DS:[ESI+8]
|
|
PUSH ECX
|
|
PUSH EAX
|
|
JMP printDisabledStatsBtn
|
|
}}
|
|
|
|
|
|
|
|
BYTE currentMsgID=0;
|
|
|
|
WORD UnassignStats()
|
|
{
|
|
if (onRealm || !D2isLODGame()) return 0;
|
|
return GetKeyState(keyUsedForUnassignStatPoint);
|
|
}
|
|
|
|
FCT_ASM ( caller_UnassignStats_9 )
|
|
PUSH EAX
|
|
CALL UnassignStats
|
|
TEST AX,AX
|
|
POP EAX
|
|
JNL NOT_CTRL
|
|
|
|
MOV currentMsgID,0x10
|
|
TEST AX,AX
|
|
JNL NOT_SHIFT
|
|
ADD currentMsgID,4
|
|
NOT_SHIFT:
|
|
MOV EAX,1
|
|
MOV ESI,EAX
|
|
RETN
|
|
|
|
NOT_CTRL:
|
|
MOV currentMsgID,0
|
|
TEST AX,AX
|
|
MOV EAX,1
|
|
RETN
|
|
}}
|
|
|
|
|
|
FCT_ASM ( caller_UnassignStats )
|
|
PUSH EAX
|
|
CALL UnassignStats
|
|
TEST AX,AX
|
|
POP EAX
|
|
JNL NOT_CTRL
|
|
|
|
MOV currentMsgID,0x10
|
|
TEST AX,AX
|
|
JNL NOT_SHIFT
|
|
ADD currentMsgID,4
|
|
NOT_SHIFT:
|
|
MOV ESI,1
|
|
ADD DWORD PTR SS:[ESP],0xB
|
|
RETN
|
|
|
|
NOT_CTRL:
|
|
MOV currentMsgID,0
|
|
TEST AX,AX
|
|
JNL END_UNASSGNSTATS
|
|
ADD DWORD PTR SS:[ESP],0x7
|
|
END_UNASSGNSTATS:
|
|
RETN
|
|
}}
|
|
|
|
|
|
FCT_ASM ( caller_setValue_111 )
|
|
ADD CL,currentMsgID
|
|
MOV WORD PTR SS:[ESP+0x19],CX
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM ( caller_setValue )
|
|
ADD DL,currentMsgID
|
|
JMP D2SendToServer3
|
|
}}
|
|
|
|
|
|
|
|
DWORD STDCALL pushDown (DWORD num)
|
|
{
|
|
Unit* ptChar = D2GetClientPlayer();
|
|
|
|
if ( !D2isLODGame() || GetKeyState(keyUsedForUnassignStatPoint) >= 0)//GetAsyncKeyState
|
|
{
|
|
if ( D2GetPlayerBaseStat(ptChar, 4, 0) > 0)
|
|
return 1;
|
|
} else {
|
|
CharStatsBIN* charStats = D2GetCharStatsBIN(ptChar->nPlayerClass);
|
|
switch (num)
|
|
{
|
|
case 0: if ((DWORD)charStats->baseSTR < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_STRENGTH, 0))
|
|
return 1; break;
|
|
case 1: if ((DWORD)charStats->baseDEX < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_DEXTERITY, 0))
|
|
return 1; break;
|
|
case 2: if ((DWORD)charStats->baseVIT < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_VITALITY, 0))
|
|
return 1; break;
|
|
case 3: if ((DWORD)charStats->baseENE < (DWORD)D2GetPlayerBaseStat(ptChar, STATS_ENERGY, 0))
|
|
return 1; break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
FCT_ASM ( caller_pushDown_111 )
|
|
PUSH EDX
|
|
PUSH EDX
|
|
CALL pushDown
|
|
POP EDX
|
|
TEST EAX,EAX
|
|
JNZ end_pushDown
|
|
SUB DWORD PTR SS:[ESP],0x22
|
|
RETN
|
|
end_pushDown:
|
|
MOV EDI,1
|
|
RETN
|
|
}}
|
|
|
|
FCT_ASM ( caller_pushDown )
|
|
PUSH EDX
|
|
PUSH EDX
|
|
CALL pushDown
|
|
POP EDX
|
|
TEST EAX,EAX
|
|
JNZ end_pushDown
|
|
SUB DWORD PTR SS:[ESP],0x22
|
|
RETN
|
|
end_pushDown:
|
|
LEA EAX,DWORD PTR DS:[EDX*8]
|
|
RETN
|
|
}}
|
|
|
|
|
|
void Install_StatsPoints()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
Install_PlugYImagesFiles();
|
|
// Install_InterfaceStats();
|
|
Install_UpdateServer();
|
|
|
|
log_msg("Patch D2Client for unassign stat points when specified key is press. (StatsPoints)\n");
|
|
|
|
// Always print stat button images.
|
|
mem_seek R7(D2Client, 29B12, 29B02, 30073, 82BBA, 8963A, 6B59A, BD1B5, BF955);
|
|
memt_byte( 0x8B, 0xEB ); // JMP SHORT D2Client.6FAD0088
|
|
memt_byte( 0x4C, V7(D2Client, 12, 12, 13, 13, 13, 13, 13, 13) );
|
|
memt_byte( 0x24, 0x90 ); // NOP
|
|
memt_byte( V7(D2Client, 20, 20, 14, 1C, 1C, 1C, 1C, 1C), 0x90 ); // NOP (V109d:0x20 , V110:0x14
|
|
//6FAD0073 8B4C24 14 MOV ECX,DWORD PTR SS:[ESP+14]
|
|
//6FB32BBA > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB3963A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB1B59A > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB6D1B5 |> 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
//6FB6F955 > 8B4C24 1C MOV ECX,DWORD PTR SS:[ESP+1C]
|
|
|
|
//print our buttons
|
|
mem_seek R7(D2Client, 29B9D, 29B8D, 300FD, 82C54, 896D4, 6B637, BD23E, BF9DE);
|
|
MEMJ_REF4( D2PrintImage, caller_printUnassignStatsBtn);
|
|
//6FB32C53 . E8 82A3F8FF CALL <JMP.&D2gfx.#10047>
|
|
//6FB396D3 . E8 D238F8FF CALL <JMP.&D2gfx.#10044>
|
|
//6FB1B636 . E8 431AFAFF CALL <JMP.&D2gfx.#10024>
|
|
//6FB6D23D . E8 54FEF4FF CALL <JMP.&D2gfx.#10041>
|
|
//6FB6F9DD . E8 ECD5F4FF CALL <JMP.&D2gfx.#10042>
|
|
|
|
// Always manage push down.
|
|
mem_seek R7(D2Client, 2AA7B, 2AA6B, 3134D, 827D9, 89259, 6B1B9, BCDD9, BF579);
|
|
memt_byte( 0x74, 0x90 ); // NOP
|
|
memt_byte( 0x4E, 0x90 ); // NOP
|
|
//6FAD134D 74 4E JE SHORT D2Client.6FAD139D
|
|
//6FB327D9 . 74 4E JE SHORT D2Client.6FB32829
|
|
//6FB39259 . 74 4E JE SHORT D2Client.6FB392A9
|
|
//6FB1B1B9 74 4E JE SHORT D2Client.6FB1B209
|
|
//6FB6CDD9 . 74 4E JE SHORT D2Client.6FB6CE29
|
|
//6FB6F579 . 74 4E JE SHORT D2Client.6FB6F5C9
|
|
|
|
if ( version_D2Client >= V111 )
|
|
{
|
|
// On Push down.
|
|
mem_seek R7(D2Client, 2AAE6, 2AAD6, 313B8, 82844, 892C4, 6B224, BCE44, BF5E4);
|
|
memt_byte( 0x6B, 0xE8 );
|
|
MEMT_REF4( 0x01BF0ED2, caller_pushDown_111);
|
|
memt_byte( 0x00, 0x6B ); // IMUL EDX,EDX,0E
|
|
memt_byte( 0x00, 0xD2 );
|
|
memt_byte( 0x00, 0x0E );
|
|
//6FB32844 > 6BD2 0E IMUL EDX,EDX,0E
|
|
//6FB32847 . BF 01000000 MOV EDI,1
|
|
//6FB392C4 > 6BD2 0E IMUL EDX,EDX,0E
|
|
//6FB392C7 . BF 01000000 MOV EDI,1
|
|
//6FB1B224 6BD2 0E IMUL EDX,EDX,0E
|
|
//6FB1B227 BF 01000000 MOV EDI,1
|
|
//6FB6CE44 > 6BD2 0E IMUL EDX,EDX,0E
|
|
//6FB6CE47 . BF 01000000 MOV EDI,1
|
|
//6FB6F5E4 > 6BD2 0E IMUL EDX,EDX,0E
|
|
//6FB6F5E7 . BF 01000000 MOV EDI,1
|
|
|
|
} else {
|
|
// On Push down.
|
|
mem_seek R7(D2Client, 2AAE6, 2AAD6, 313B8, 82844, 892C4, 0000, 0000, 0000);
|
|
memt_byte( 0x8D, 0xE8 ); // CALL
|
|
MEMT_REF4( 0x0000D504, caller_pushDown);
|
|
memt_byte( 0x00, 0x90 ); // NOP
|
|
memt_byte( 0x00, 0x90 ); // NOP
|
|
//6FAD13B8 8D04D5 00000000 LEA EAX,DWORD PTR DS:[EDX*8]
|
|
}
|
|
|
|
|
|
if ( version_D2Client >= V110 )
|
|
{
|
|
// Always manage push up.
|
|
mem_seek R7(D2Client, 0000, 0000, 3152E, 83869, 8A2E9, 6C249, BDE49, C05E9);
|
|
memt_byte( 0x74, 0x90 ); // NOP
|
|
memt_byte( version_D2Client >= V111 ? 0x65 : 0x68, 0x90 ); // NOP
|
|
//6FAD152E 74 68 JE SHORT D2Client.6FAD1598
|
|
//6FB33869 . 74 65 JE SHORT D2Client.6FB338D0
|
|
//6FB3A2E9 . 74 65 JE SHORT D2Client.6FB3A350
|
|
//6FB1C249 74 65 JE SHORT D2Client.6FB1C2B0
|
|
//6FB6DE49 . 74 65 JE SHORT D2Client.6FB6DEB0
|
|
//6FB705E9 . 74 65 JE SHORT D2Client.6FB70650
|
|
|
|
// Unassign stats point when ctrl is push.
|
|
mem_seek R7(D2Client, 0000, 0000, 315D3, 8391B, 8A39B, 6C2FB, BDEFB, C069B);
|
|
memt_byte( 0x66, 0xE8 ); // CALL
|
|
MEMT_REF4( 0x077CC085, caller_UnassignStats);
|
|
//6FAD15D3 . 66:85C0 TEST AX,AX
|
|
//6FAD15D6 . 7C 07 JL SHORT D2Client.6FAD15DF
|
|
//6FB3391B . 66:85C0 TEST AX,AX
|
|
//6FB3391E . 7C 07 JL SHORT D2Client.6FB33927
|
|
//6FB3A39B . 66:85C0 TEST AX,AX
|
|
//6FB3A39E . 7C 07 JL SHORT D2Client.6FB3A3A7
|
|
//6FB1C2FB . 66:85C0 TEST AX,AX
|
|
//6FB1C2FE . 7C 07 JL SHORT D2Client.6FB1C307
|
|
//6FB6DEFB . 66:85C0 TEST AX,AX
|
|
//6FB6DEFE . 7C 07 JL SHORT D2Client.6FB6DF07
|
|
//6FB7069B . 66:85C0 TEST AX,AX
|
|
//6FB7069E . 7C 07 JL SHORT D2Client.6FB706A7
|
|
} else {
|
|
// Always manage push up.
|
|
mem_seek R7(D2Client, 2AC55, 2AC45, 0000, 0000, 0000, 0000, 0000, 0000);
|
|
memt_byte( 0x0F, 0x90 ); // NOP
|
|
memt_byte( 0x84, 0x90 ); // NOP
|
|
memt_dword( 0x000000AE, 0x90909090 ); // NOP NOP NOP NOP
|
|
//6FACAC45 . 0F84 AE000000 JE D2Client.6FACACF9
|
|
|
|
// Unassign stats point when ctrl is push.
|
|
mem_seek R7(D2Client, 2ACD9, 2ACC9, 0000, 0000, 0000, 0000, 0000, 0000);
|
|
memt_byte( 0xB8, 0xE8 ); // CALL
|
|
MEMT_REF4( 0x00000001, caller_UnassignStats_9);
|
|
//6FACACC9 . B8 01000000 MOV EAX,1
|
|
}
|
|
|
|
// Set the id for the calling function.
|
|
mem_seek R7(D2Client, 2AD02, 2ACF2, 31611, 8395E, 8A3DE, 6C33E, BDF3E, C06DE);
|
|
if ( version_D2Client >= V111 ) {
|
|
memt_byte( 0x66, 0xE8 ); // CALL
|
|
MEMT_REF4( 0x15244C89, caller_setValue_111);
|
|
//6FB3395E . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX
|
|
//6FB3A3DE . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX
|
|
//6FB1C33E . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX ; |
|
|
//6FB6DF3E . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX ; |
|
|
//6FB706DE . 66:894C24 15 MOV WORD PTR SS:[ESP+15],CX ; |
|
|
} else {
|
|
MEMC_REF4( D2SendToServer3, caller_setValue);
|
|
//6FAD1610 . E8 7BC3FDFF CALL D2Client.6FAAD990
|
|
}
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
/*********************************************************************************/
|
|
|
|
|
|
FCT_ASM ( caller_LimitShift_111 )
|
|
CMP EDI,limitValueToShiftClick
|
|
JL DontTruncTheValue
|
|
MOV EDI,limitValueToShiftClick
|
|
DontTruncTheValue:
|
|
JMP DWORD PTR DS:[GetKeyState]
|
|
}}
|
|
|
|
FCT_ASM ( caller_LimitShift )
|
|
CMP ESI,limitValueToShiftClick
|
|
JL DontTruncTheValue
|
|
MOV ESI,limitValueToShiftClick
|
|
DontTruncTheValue:
|
|
JMP DWORD PTR DS:[GetKeyState]
|
|
}}
|
|
|
|
void Install_StatsLimitShiftClick()
|
|
{
|
|
static int isInstalled = false;
|
|
if (isInstalled) return;
|
|
|
|
log_msg("Patch D2Client for limit the assigment of stat points when shift is used. (LimitShift)\n");
|
|
|
|
// Limit the assigment of stat points.
|
|
mem_seek R7(D2Client, 2ACD0, 2ACC0, 315CD, 83915, 8A395, 6C2F5, BDEF5, C0695);
|
|
memt_byte( 0xFF, 0x90 ); // NOP
|
|
memt_byte( 0x15, 0xE8 ); // CALL
|
|
MEMD_REF4( GetKeyState, version_D2Client >= V111 ? caller_LimitShift_111 : caller_LimitShift);
|
|
//6FAD15CD . FF15 68E0B66F CALL DWORD PTR DS:[<&USER32.GetKeyState>]
|
|
//6FB33915 . FF15 CCF0B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>]
|
|
//6FB3A395 . FF15 08F1B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>]
|
|
//6FB1C2F5 . FF15 10F1B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>>; \GetKeyState
|
|
//6FB6DEF5 . FF15 04F1B76F CALL DWORD PTR DS:[<&USER32.GetKeyState>>; \GetKeyState
|
|
//6FB70695 . FF15 2001B86F CALL DWORD PTR DS:[<&USER32.GetKeyState>>; \GetKeyState
|
|
|
|
log_msg("\n");
|
|
|
|
isInstalled = true;
|
|
}
|
|
|
|
|
|
/*================================= END OF FILE =================================*/ |