mirror of
https://gitlab.com/hashborgir/plugy.git
synced 2025-04-27 14:55:37 +00:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
e89cfad117 | ||
|
f3b0abf9ab | ||
|
9a858693c5 | ||
|
6bef4f86c8 | ||
|
3b06e3ad08 | ||
|
8a3841f49b | ||
|
64792db947 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -38,3 +38,5 @@
|
||||
**/*.VC.VC.opendb
|
||||
**/UpgradeLog*
|
||||
/PlugYRun/PlugYRun.aps
|
||||
PlugY/Debug/
|
||||
|
||||
|
286
ASLR_fix.patch
Normal file
286
ASLR_fix.patch
Normal file
@ -0,0 +1,286 @@
|
||||
diff --git a/PlugY/D2wrapper.cpp b/PlugY/D2wrapper.cpp
|
||||
index d13608e..ffd02f2 100644
|
||||
--- a/PlugY/D2wrapper.cpp
|
||||
+++ b/PlugY/D2wrapper.cpp
|
||||
@@ -291,6 +291,7 @@ void loadCustomLibraries()
|
||||
log_msg("\n\n");
|
||||
}
|
||||
|
||||
+/*
|
||||
void loadLibrary(LPCSTR libName, int* libVersion, DWORD* libOffset, int shift, DWORD v109b, DWORD v109d, DWORD v110, DWORD v111, DWORD v111b, DWORD v112, DWORD v113c)
|
||||
{
|
||||
*libOffset = (DWORD)LoadLibrary(libName);
|
||||
@@ -386,6 +387,273 @@ void initD2modules()
|
||||
|
||||
log_msg("\n\n");
|
||||
}
|
||||
+*/
|
||||
+
|
||||
+IMAGE_NT_HEADERS* GetHeader(LPBYTE pBase) {
|
||||
+ if (pBase == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)pBase;
|
||||
+
|
||||
+ if (IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
+ return NULL;
|
||||
+
|
||||
+ IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(pBase + pDosHeader->e_lfanew);
|
||||
+ if (IsBadReadPtr(pHeader, sizeof(IMAGE_NT_HEADERS)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (pHeader->Signature != IMAGE_NT_SIGNATURE)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return pHeader;
|
||||
+}
|
||||
+
|
||||
+void initD2modules()
|
||||
+{
|
||||
+ log_msg("***** Get D2 Modules address and version *****\n\n");
|
||||
+
|
||||
+ offset_D2Client = (DWORD)LoadLibrary("D2Client.dll");
|
||||
+ offset_D2CMP = (DWORD)LoadLibrary("D2CMP.dll");
|
||||
+ offset_D2Common = (DWORD)LoadLibrary("D2Common.dll");
|
||||
+ offset_D2Game = (DWORD)LoadLibrary("D2Game.dll");
|
||||
+ offset_D2gfx = (DWORD)LoadLibrary("D2gfx.dll");
|
||||
+ offset_D2Lang = (DWORD)LoadLibrary("D2Lang.dll");
|
||||
+ offset_D2Launch = (DWORD)LoadLibrary("D2Launch.dll");
|
||||
+ offset_D2Net = (DWORD)LoadLibrary("D2Net.dll");
|
||||
+ offset_D2Win = (DWORD)LoadLibrary("D2Win.dll");
|
||||
+ offset_Fog = (DWORD)LoadLibrary("Fog.dll");
|
||||
+ offset_Storm = (DWORD)LoadLibrary("Storm.dll");
|
||||
+
|
||||
+ int count_109b = 0;
|
||||
+ int count_109d = 0;
|
||||
+ int count_110f = 0;
|
||||
+ int count_111 = 0;
|
||||
+ int count_111b = 0;
|
||||
+ int count_112a = 0;
|
||||
+ int count_113c = 0;
|
||||
+ int count_113d = 0;
|
||||
+ int count_114a = 0;
|
||||
+ int count_114b = 0;
|
||||
+ int count_114c = 0;
|
||||
+ int count_114d = 0;
|
||||
+
|
||||
+ IMAGE_NT_HEADERS* pHeader;
|
||||
+
|
||||
+ if (offset_D2Client != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Client);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C234D) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C16CD) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C1C1D) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045E6) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045EE) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045FA) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045F6) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045DE) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2CMP != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2CMP);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00010E61) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2Common != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Common);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074D1D) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074E2D) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000856DD) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C94) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8D) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C97) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8F) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000047C7) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2Game != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Game);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C66AC) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C6D5C) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000EDC2C) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000036E6) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373D) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000374B) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373C) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003747) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2gfx != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2gfx);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054A5) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2Lang != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Lang);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005148) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005138) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005048) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A6A) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5B) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A75) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A71) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5A) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2Launch != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Launch);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000172C3) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00017243) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00018DC7) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A87) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2Net != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Net);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C6E) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_D2Win != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_D2Win);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00012EC0) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000188E) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001887) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_Fog != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_Fog);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ if (offset_Storm != NULL) {
|
||||
+ pHeader = GetHeader((LPBYTE)offset_Storm);
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++;
|
||||
+ if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0003C3E0) count_113d++;
|
||||
+ }
|
||||
+
|
||||
+ int minimum_match_dll = 7;
|
||||
+
|
||||
+ if (count_109b >= minimum_match_dll) version_Game = V109b;
|
||||
+ if (count_109d >= minimum_match_dll) version_Game = V109d;
|
||||
+ if (count_110f >= minimum_match_dll) version_Game = V110;
|
||||
+ if (count_111 >= minimum_match_dll) version_Game = V111;
|
||||
+ if (count_111b >= minimum_match_dll) version_Game = V111b;
|
||||
+ if (count_112a >= minimum_match_dll) version_Game = V112;
|
||||
+ if (count_113c >= minimum_match_dll) version_Game = V113c;
|
||||
+ if (count_113d >= minimum_match_dll) version_Game = V113d;
|
||||
+
|
||||
+ //version_SmackW32 = version_Game;
|
||||
+ version_D2Common = version_Game;
|
||||
+ //version_ijl11 = version_Game;
|
||||
+ //version_D2Gdi = version_Game;
|
||||
+ version_D2Win = version_Game;
|
||||
+ //version_D2sound = version_Game;
|
||||
+ //version_D2MCPCLI = version_Game;
|
||||
+ version_D2Launch = version_Game;
|
||||
+ version_D2gfx = version_Game;
|
||||
+ version_D2Client = version_Game;
|
||||
+ version_D2Net = version_Game;
|
||||
+ version_D2Lang = version_Game;
|
||||
+ version_D2Game = version_Game;
|
||||
+ version_D2CMP = version_Game;
|
||||
+ //version_Bnclient = version;
|
||||
+ version_Fog = version_Game;
|
||||
+ version_Storm = version_Game;
|
||||
+
|
||||
+ log_msg("DLL match for version 1.09b :\t%d\n", count_109b);
|
||||
+ log_msg("DLL match for version 1.09d :\t%d\n", count_109d);
|
||||
+ log_msg("DLL match for version 1.10f :\t%d\n", count_110f);
|
||||
+ log_msg("DLL match for version 1.11 :\t%d\n", count_111);
|
||||
+ log_msg("DLL match for version 1.11b :\t%d\n", count_111b);
|
||||
+ log_msg("DLL match for version 1.12a :\t%d\n", count_112a);
|
||||
+ log_msg("DLL match for version 1.13c :\t%d\n", count_113c);
|
||||
+ log_msg("\n");
|
||||
+
|
||||
+ offset_Game = (DWORD)GetModuleHandle("Game.exe");
|
||||
+ if (offset_Game != NULL) {
|
||||
+ version_Game = GetD2Version((HMODULE)offset_Game);
|
||||
+ log_msg("Game.exe loaded at:\t%08X (%s)\n", offset_Game, GetVersionString(version_Game));
|
||||
+ if (version_Game >= V114a)
|
||||
+ {
|
||||
+ //version_SmackW32 = version_Game;
|
||||
+ version_D2Common = version_Game;
|
||||
+ //version_ijl11 = version_Game;
|
||||
+ //version_D2Gdi = version_Game;
|
||||
+ version_D2Win = version_Game;
|
||||
+ //version_D2sound = version_Game;
|
||||
+ //version_D2MCPCLI = version_Game;
|
||||
+ version_D2Launch = version_Game;
|
||||
+ version_D2gfx = version_Game;
|
||||
+ version_D2Client = version_Game;
|
||||
+ version_D2Net = version_Game;
|
||||
+ version_D2Lang = version_Game;
|
||||
+ version_D2Game = version_Game;
|
||||
+ version_D2CMP = version_Game;
|
||||
+ //version_Bnclient = version;
|
||||
+ version_Fog = version_Game;
|
||||
+ version_Storm = version_Game;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ //if (offset_Game != NULL) {
|
||||
+ // pHeader = GetHeader((LPBYTE)offset_Game);
|
||||
+ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00291342) count_114a++;
|
||||
+ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002854F2) count_114b++;
|
||||
+ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002850E2) count_114c++;
|
||||
+ // if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00282985) count_114d++;
|
||||
+ //}
|
||||
+
|
||||
+ log_msg("Version game is:\t(%s)\n\n", GetVersionString(version_Game));
|
||||
+
|
||||
+ if (version_Game == UNKNOWN)
|
||||
+ {
|
||||
+ MessageBoxA(NULL, "This version of Diablo II is not supported by Plugy. Please upgrade or downgrade to a supported version.", "Plugy 14.03", MB_OK);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
//////////////////////////////////// EXPORTS FUNCTIONS ////////////////////////////////////
|
||||
|
||||
|
@ -549,6 +549,12 @@ F8(FAST, D2Win, 10131,10131,10131,00000,00000,00000,00000,00000,00000, void, D2
|
||||
F8(FAST, D2Win, 10132,10132,10132,00000,00000,00000,00000,00000,00000, DWORD, D2PrintTextPopup,(LPWSTR s, DWORD x, DWORD y, DWORD uk, DWORD type, DWORD color) );//6F8AB080
|
||||
F8(STD, D2Win, 10017,10017,10017,10147,10113,10098,10098,10164,F93C0, void*, D2CreateTextBox,(DWORD* data) );
|
||||
|
||||
// Add a call wrapper for the following:
|
||||
// D2Win.0x6F8AA2A0 (#10121) // int __fastcall D2Win_10121_GetTextWidth(const Unicode* wszText)
|
||||
F8(FAST, D2Win, 10121, 10121, 10121, 10121, 10121, 10121, 10121, 10121, AA2A0, DWORD, D2Win_GetTextWidth, (const wchar_t* wszText));
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//D2CMP : ????0000
|
||||
|
887
HD_fix.patch
Normal file
887
HD_fix.patch
Normal file
@ -0,0 +1,887 @@
|
||||
diff --git a/PlugY/InfinityStash.cpp b/PlugY/InfinityStash.cpp
|
||||
index 22e9c35..ea09d36 100644
|
||||
--- a/PlugY/InfinityStash.cpp
|
||||
+++ b/PlugY/InfinityStash.cpp
|
||||
@@ -26,6 +26,7 @@ bool active_sharedStash = false;
|
||||
bool separateHardSoftStash = false;
|
||||
bool active_sharedGold=false;
|
||||
char* sharedStashFilename = NULL;
|
||||
+DWORD saveFileStackSize = 0x2000;
|
||||
|
||||
typedef int (*TchangeToSelectedStash)(Unit* ptChar, Stash* newStash, DWORD bOnlyItems, DWORD bIsClient);
|
||||
|
||||
@@ -422,7 +423,7 @@ void saveStashList(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DW
|
||||
|
||||
while(ptStash)
|
||||
{
|
||||
- if (*curSize + 0x2000 > *maxSize)
|
||||
+ if (*curSize + saveFileStackSize > *maxSize)
|
||||
{
|
||||
BYTE* oldData = *data;
|
||||
*maxSize *= 2;
|
||||
diff --git a/PlugY/Interface_Skills.cpp b/PlugY/Interface_Skills.cpp
|
||||
index 90178f7..8a07c2a 100644
|
||||
--- a/PlugY/Interface_Skills.cpp
|
||||
+++ b/PlugY/Interface_Skills.cpp
|
||||
@@ -49,9 +49,10 @@ Unit* STDCALL skillsPageMouseDown(sWinMessage* msg)
|
||||
if (active_SkillsPoints && !onRealm && D2isLODGame() && isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY()))
|
||||
{
|
||||
log_msg("push down left button unassign skill\n");
|
||||
- btnSkillIsDown = 1;
|
||||
+ //btnSkillIsDown = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
freeMessage(msg);
|
||||
+ updateServer(US_UNASSIGN_SKILLS);
|
||||
return NULL;
|
||||
}
|
||||
return ptChar;
|
||||
@@ -233,6 +234,7 @@ void Install_InterfaceSkills()
|
||||
//6FAE1112 > C745 18 00000000 MOV DWORD PTR SS:[EBP+18],0
|
||||
//004ABC1A |> C746 18 00000000 MOV DWORD PTR DS:[ESI+18],0
|
||||
|
||||
+ /* Conflicts with D2ExpRes
|
||||
// Manage mouse up
|
||||
mem_seek R8(D2Client, 7BC40, 7BC40, 78466, 17558, 8C078, 80248, 795F8, 30AA8, ABC96);
|
||||
MEMJ_REF4( D2FreeWinMessage, caller_skillsPageMouseUp);//0xFFF93B0A
|
||||
@@ -243,6 +245,7 @@ void Install_InterfaceSkills()
|
||||
//6FB295F7 .^E9 8828F9FF JMP <JMP.&Storm.#511>
|
||||
//6FAE0AA7 .^E9 E0B2FDFF JMP <JMP.&Storm.#511>
|
||||
//004ABC95 |. E8 F645F7FF CALL Game.00420290
|
||||
+ */
|
||||
|
||||
log_msg("\n");
|
||||
|
||||
diff --git a/PlugY/Interface_Stats.cpp b/PlugY/Interface_Stats.cpp
|
||||
index 85e6029..1d3a4cf 100644
|
||||
--- a/PlugY/Interface_Stats.cpp
|
||||
+++ b/PlugY/Interface_Stats.cpp
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
+/*
|
||||
static struct
|
||||
{
|
||||
union{
|
||||
@@ -35,6 +36,7 @@ static struct
|
||||
#define getYNextPageBtn() RY(D2GetResolution()?0x40:0x70)
|
||||
#define getHNextPageBtn() 32
|
||||
#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn())
|
||||
+*/
|
||||
|
||||
|
||||
|
||||
@@ -49,7 +51,7 @@ void STDCALL printStatsPageBtns()
|
||||
sDrawImageInfo data;
|
||||
ZeroMemory(&data,sizeof(data));
|
||||
|
||||
- if (printBackgroundOnMainPage && D2GetResolution())
|
||||
+ if (printBackgroundOnMainPage)
|
||||
{
|
||||
setImage(&data, statsBackgroundImages);
|
||||
setFrame(&data, 1);
|
||||
@@ -57,16 +59,14 @@ void STDCALL printStatsPageBtns()
|
||||
}
|
||||
|
||||
setImage(&data, D2LoadBuySelBtn());
|
||||
- if (D2GetResolution())
|
||||
- {
|
||||
- setFrame(&data, 12 + isDownBtn.previousPage);
|
||||
- D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0);
|
||||
- }
|
||||
+ setFrame(&data, 12 + isDownBtn.previousPage);
|
||||
+ D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0);
|
||||
+
|
||||
setFrame(&data, 14 + isDownBtn.nextPage);
|
||||
D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0);
|
||||
|
||||
D2SetFont(1);
|
||||
- if (D2GetResolution() && isOnPreviousPageBtn(mx,my)) //print popup "previous page"
|
||||
+ if (isOnPreviousPageBtn(mx,my)) //print popup "previous page"
|
||||
{
|
||||
lpText = getLocalString(STR_PREVIOUS_PAGE);
|
||||
D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1);
|
||||
@@ -84,6 +84,12 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg)
|
||||
|
||||
if (!active_newInterfaces || !D2isLODGame() ) return ptChar;
|
||||
|
||||
+ if (statsLeftDown(msg)) {
|
||||
+ freeMessage(msg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push down left button previous page\n");
|
||||
@@ -100,6 +106,7 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg)
|
||||
freeMessage(msg);
|
||||
return NULL;
|
||||
}
|
||||
+ */
|
||||
return ptChar;
|
||||
}
|
||||
|
||||
@@ -110,6 +117,13 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg)
|
||||
|
||||
if (!active_newInterfaces || !D2isLODGame() ) return ptChar;
|
||||
|
||||
+ if (statsLeftUp(msg)) {
|
||||
+ isDownBtn.all=0;
|
||||
+ freeMessage(msg);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push up left button previous page\n");
|
||||
@@ -134,6 +148,7 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+ */
|
||||
|
||||
isDownBtn.all=0;
|
||||
return ptChar;
|
||||
diff --git a/PlugY/LocalizedStrings.cpp b/PlugY/LocalizedStrings.cpp
|
||||
index 70595ee..3c76d87 100644
|
||||
--- a/PlugY/LocalizedStrings.cpp
|
||||
+++ b/PlugY/LocalizedStrings.cpp
|
||||
@@ -51,7 +51,7 @@ LPCWSTR getLocalTypeString(DWORD code)
|
||||
{
|
||||
if (sLocalizedTypeStrings[i].code == code)
|
||||
{
|
||||
- log_msg("Code=%08X\n", code);
|
||||
+ //log_msg("Code=%08X\n", code);
|
||||
if (sLocalizedTypeStrings[i].itemStr)
|
||||
return StripGender(D2GetStringFromString(sLocalizedTypeStrings[i].itemStr));
|
||||
LPWSTR text = StripGender(sLocalizedTypeStrings[i].typeLocalizedString);
|
||||
@@ -300,6 +300,8 @@ void loadLocalizedStrings(int language)
|
||||
LOAD(STR_SHARED_GOLD_QUANTITY);
|
||||
LOAD(STR_PREVIOUS_PAGE);
|
||||
LOAD(STR_NEXT_PAGE);
|
||||
+ LOAD(STR_PREVIOUS_RUNE);
|
||||
+ LOAD(STR_NEXT_RUNE);
|
||||
LOAD(STR_ITEM_LEVEL);
|
||||
LOAD(STR_PAGE_TYPE_CHANGE);
|
||||
|
||||
diff --git a/PlugY/LocalizedStrings.h b/PlugY/LocalizedStrings.h
|
||||
index 9fb08e7..0e7b83d 100644
|
||||
--- a/PlugY/LocalizedStrings.h
|
||||
+++ b/PlugY/LocalizedStrings.h
|
||||
@@ -37,6 +37,8 @@ enum eStringList
|
||||
STR_SHARED_GOLD_QUANTITY,
|
||||
STR_PREVIOUS_PAGE,
|
||||
STR_NEXT_PAGE,
|
||||
+ STR_PREVIOUS_RUNE,
|
||||
+ STR_NEXT_RUNE,
|
||||
STR_ITEM_LEVEL,
|
||||
STR_PAGE_TYPE_CHANGE,
|
||||
//
|
||||
diff --git a/PlugY/NewInterface_CubeListing.cpp b/PlugY/NewInterface_CubeListing.cpp
|
||||
index 1c54331..d50c8bc 100644
|
||||
--- a/PlugY/NewInterface_CubeListing.cpp
|
||||
+++ b/PlugY/NewInterface_CubeListing.cpp
|
||||
@@ -233,12 +233,6 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize)
|
||||
printInputItem(&curForm->input6, buf, len, &realNbInputs);
|
||||
printInputItem(&curForm->input7, buf, len, &realNbInputs);
|
||||
|
||||
- if (realNbInputs != curForm->numinputs)
|
||||
- {
|
||||
- PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs);
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
PRINT(BUF,L" => ");
|
||||
int realNbOutputs=0;
|
||||
|
||||
@@ -269,6 +263,9 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize)
|
||||
// if (curForm->version == 100)
|
||||
// sprintf(BUF, " [expansion only]");
|
||||
|
||||
+ if (realNbInputs != curForm->numinputs)
|
||||
+ PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs);
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
#undef BUF
|
||||
diff --git a/PlugY/NewInterface_Runewords.cpp b/PlugY/NewInterface_Runewords.cpp
|
||||
index 99d1f38..13efd9f 100644
|
||||
--- a/PlugY/NewInterface_Runewords.cpp
|
||||
+++ b/PlugY/NewInterface_Runewords.cpp
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
+/*
|
||||
#define NB_RUNES_PER_PAGE 25
|
||||
|
||||
#define getXCloseBtn() 360
|
||||
@@ -53,6 +54,7 @@ static struct
|
||||
};
|
||||
};
|
||||
} isDownBtn;
|
||||
+*/
|
||||
|
||||
|
||||
void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
@@ -64,7 +66,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
D2SetFont(6);
|
||||
DWORD nbPixel = D2GetPixelLen(lpText);
|
||||
DWORD x1 = (nbPixel >= 195) ? 0 : 195-nbPixel;
|
||||
- D2PrintString(lpText, x1, 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel)
|
||||
+ D2PrintString(lpText, posXRunesList + RX(x1), posYRunesList + 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel)
|
||||
|
||||
typesList[0]=L'\0';
|
||||
DWORD numItype=0;
|
||||
@@ -80,7 +82,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
}
|
||||
nbPixel = D2GetPixelLen(typesList);
|
||||
x1 = (nbPixel >= 195) ? 0 : 195-nbPixel;
|
||||
- D2PrintString(typesList, x1, 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel)
|
||||
+ D2PrintString(typesList, posXRunesList + RX(x1), posYRunesList + 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel)
|
||||
|
||||
runesList[0]=L'\0';
|
||||
DWORD numRune=0;
|
||||
@@ -115,7 +117,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
}
|
||||
|
||||
// x1 = (nbPixel < 145) ? 155 : 300-nbPixel;
|
||||
- D2PrintString(runesList, x1, y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel)
|
||||
+ D2PrintString(runesList, posXRunesList + RX(x1), posYRunesList + y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel)
|
||||
}
|
||||
|
||||
|
||||
@@ -123,48 +125,58 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
//6FB21FAA
|
||||
void STDCALL printRunewordsPage()
|
||||
{
|
||||
- if (!D2isLODGame() || !D2GetResolution()) return D2PrintStatsPage();
|
||||
+ if (!D2isLODGame()) return D2PrintStatsPage();
|
||||
|
||||
LPWSTR lpText;
|
||||
- bDontPrintBorder = true;
|
||||
+ bDontPrintBorder = D2GetResolution()? true : false;
|
||||
|
||||
//Init data for print image
|
||||
sDrawImageInfo data;
|
||||
ZeroMemory(&data,sizeof(data));
|
||||
|
||||
//print background
|
||||
-/* setImage(&data, newStatsInterfaceImages);
|
||||
+ fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5);
|
||||
+ setImage(&data, newStatsInterfaceImages);
|
||||
setFrame(&data, 0);
|
||||
- D2PrintImage(&data, 0, 256, -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 1);
|
||||
- D2PrintImage(&data, 256,256, -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 2);
|
||||
- D2PrintImage(&data, 0, 512, -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 3);
|
||||
- D2PrintImage(&data, 256,512, -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 4);
|
||||
- D2PrintImage(&data, 0, 552, -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0);
|
||||
setFrame(&data, 5);
|
||||
- D2PrintImage(&data, 256,552, -1, 5, 0);
|
||||
-*/
|
||||
- fillRect(0,0,400,552,0,5);
|
||||
+ D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0);
|
||||
+
|
||||
+ if (printBackgroundOnMainPage)
|
||||
+ {
|
||||
+ setImage(&data, statsBackgroundImages);
|
||||
+ setFrame(&data, 1);
|
||||
+ D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0);
|
||||
+ D2PrintImage(&data, getXPrevRunesBtn()-7, getYPrevRunesBtn()+8, -1, 5, 0);
|
||||
+ }
|
||||
|
||||
//print button close
|
||||
setImage(&data, D2LoadBuySelBtn());
|
||||
setFrame(&data, 10 + isDownBtn.close);
|
||||
D2PrintImage(&data, getXCloseBtn(), getYCloseBtn(), -1, 5, 0);
|
||||
|
||||
+ //print previous page button
|
||||
+ setFrame(&data, 12 + isDownBtn.previousPage);
|
||||
+ D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0);
|
||||
+
|
||||
//print next page button
|
||||
- setFrame(&data, isDownBtn.nextPage);
|
||||
+ setFrame(&data, 14 + isDownBtn.nextPage);
|
||||
D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0);
|
||||
|
||||
//print previous runes button
|
||||
- setImage(&data, stashBtnsImages);
|
||||
- setFrame(&data, isDownBtn.prevRunes);
|
||||
+ setFrame(&data, 12 + isDownBtn.prevRunes);
|
||||
D2PrintImage(&data, getXPrevRunesBtn(), getYPrevRunesBtn(), -1, 5, 0);
|
||||
|
||||
//print previous runes button
|
||||
- setFrame(&data, 2 + isDownBtn.nextRunes);
|
||||
+ setFrame(&data, 14 + isDownBtn.nextRunes);
|
||||
D2PrintImage(&data, getXNextRunesBtn(), getYNextRunesBtn(), -1, 5, 0);
|
||||
|
||||
D2SetFont(6);
|
||||
@@ -181,11 +193,11 @@ void STDCALL printRunewordsPage()
|
||||
{
|
||||
if (!runesData->Complete || runesData->Server) continue;
|
||||
nbRunesCompleted++;
|
||||
- if ( (curRunesPage * NB_RUNES_PER_PAGE < nbRunesCompleted) &&
|
||||
- (nbRunesCompleted <= (curRunesPage+1) * NB_RUNES_PER_PAGE) )
|
||||
+ if ( (curRunesPage * runesPerPage < nbRunesCompleted) &&
|
||||
+ (nbRunesCompleted <= (curRunesPage+1) * runesPerPage) )
|
||||
printRuneword(runesData, curNbRunes++);
|
||||
}
|
||||
- maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / NB_RUNES_PER_PAGE : 0;
|
||||
+ maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / runesPerPage : 0;
|
||||
|
||||
|
||||
//////////////////// POPUP PRINTING ////////////////////
|
||||
@@ -197,11 +209,26 @@ void STDCALL printRunewordsPage()
|
||||
{
|
||||
D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1);
|
||||
}
|
||||
+ else if (isOnPreviousPageBtn(x,y)) //print popup "previous page"
|
||||
+ {
|
||||
+ lpText = getLocalString(STR_PREVIOUS_PAGE);
|
||||
+ D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1);
|
||||
+ }
|
||||
else if (isOnNextPageBtn(x,y)) // print popup "next page"
|
||||
{
|
||||
lpText = getLocalString(STR_NEXT_PAGE);
|
||||
D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1);
|
||||
}
|
||||
+ else if (isOnPrevRunesBtn(x,y)) // print popup "previous rune"
|
||||
+ {
|
||||
+ lpText = getLocalString(STR_PREVIOUS_RUNE);
|
||||
+ D2PrintPopup(lpText, getXPrevRunesBtn()+getLPrevRunesBtn()/2, getYPrevRunesBtn()-getHPrevRunesBtn(), WHITE, 1);
|
||||
+ }
|
||||
+ else if (isOnNextRunesBtn(x,y)) // print popup "next rune"
|
||||
+ {
|
||||
+ lpText = getLocalString(STR_NEXT_RUNE);
|
||||
+ D2PrintPopup(lpText, getXNextRunesBtn()+getLNextRunesBtn()/2, getYNextRunesBtn()-getHNextRunesBtn(), WHITE, 1);
|
||||
+ }
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
diff --git a/PlugY/NewInterface_Stats.cpp b/PlugY/NewInterface_Stats.cpp
|
||||
index 10fa32d..d73c5da 100644
|
||||
--- a/PlugY/NewInterface_Stats.cpp
|
||||
+++ b/PlugY/NewInterface_Stats.cpp
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
+/*
|
||||
#define getXCloseBtn() 360
|
||||
#define getLCloseBtn() 32
|
||||
#define getYCloseBtn() (ResolutionY - 60)
|
||||
@@ -92,6 +93,7 @@ void** ptD2AssignStatsPointsBtnImages = (void**)0x6FBB5BB4;
|
||||
|
||||
|
||||
|
||||
+/*
|
||||
static struct
|
||||
{
|
||||
union{
|
||||
@@ -111,6 +113,7 @@ static struct
|
||||
};
|
||||
};
|
||||
} isDownBtn;
|
||||
+*/
|
||||
|
||||
|
||||
void print2Lines(WORD id, LPWSTR lpText, DWORD x, DWORD l, DWORD y)
|
||||
diff --git a/PlugY/NewInterface_StatsPageTwo.cpp b/PlugY/NewInterface_StatsPageTwo.cpp
|
||||
index dfdc8a1..6215dd6 100644
|
||||
--- a/PlugY/NewInterface_StatsPageTwo.cpp
|
||||
+++ b/PlugY/NewInterface_StatsPageTwo.cpp
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
+/*
|
||||
#define getXCloseBtn() RX(0x110)
|
||||
#define getLCloseBtn() 32
|
||||
#define getYCloseBtn() RY(0x40)
|
||||
@@ -29,11 +30,13 @@
|
||||
#define getYNextPageBtn() RY(0x40)
|
||||
#define getHNextPageBtn() 32
|
||||
#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn())
|
||||
+*/
|
||||
|
||||
const char * STATS_INTERFACE_FILENAME = "PlugY\\statsinterface.txt";
|
||||
|
||||
#define BUFSIZE 0x400
|
||||
|
||||
+/*
|
||||
static struct
|
||||
{
|
||||
union{
|
||||
@@ -45,6 +48,7 @@ static struct
|
||||
};
|
||||
};
|
||||
} isDownBtn;
|
||||
+*/
|
||||
|
||||
|
||||
struct statsInterfaceBIN
|
||||
@@ -337,8 +341,7 @@ void STDCALL printNewStatsPageTwo(int currentPage)
|
||||
|
||||
WCHAR text[BUFSIZE];
|
||||
LPWSTR lpText;
|
||||
- bDontPrintBorder = false;
|
||||
-
|
||||
+ bDontPrintBorder = D2GetResolution()? true : false;
|
||||
Unit* ptChar = D2GetClientPlayer();
|
||||
|
||||
d2_assert(!ptChar, "Printing stats page : no character selected",__FILE__,__LINE__);
|
||||
@@ -349,16 +352,20 @@ void STDCALL printNewStatsPageTwo(int currentPage)
|
||||
ZeroMemory(&data,sizeof(data));
|
||||
|
||||
//print background
|
||||
- fillRect(RX(0),RY(480),320,432,0,5);//552
|
||||
+ fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5);
|
||||
setImage(&data, newStatsInterfaceImages);
|
||||
setFrame(&data, 0);
|
||||
- D2PrintImage(&data, RX(0), RY(224), -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 1);
|
||||
- D2PrintImage(&data, RX(256),RY(224), -1, 5, 0);//256
|
||||
+ D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 2);
|
||||
- D2PrintImage(&data, RX(0), RY(48), -1, 5, 0);//432
|
||||
+ D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 3);
|
||||
- D2PrintImage(&data, RX(256),RY(48), -1, 5, 0);
|
||||
+ D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0);
|
||||
+ setFrame(&data, 4);
|
||||
+ D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0);
|
||||
+ setFrame(&data, 5);
|
||||
+ D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0);
|
||||
|
||||
D2SetFont(1);
|
||||
for (int i=0; i<nbStatsInterface; i++)
|
||||
@@ -392,10 +399,12 @@ void STDCALL printNewStatsPageTwo(int currentPage)
|
||||
D2PrintString(text, x, y, WHITE, 0);
|
||||
*/
|
||||
|
||||
- //print background previous/next page buttons
|
||||
- setImage(&data, statsBackgroundImages);
|
||||
- setFrame(&data, D2GetResolution()?1:0);
|
||||
- D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0);
|
||||
+ if (printBackgroundOnMainPage) {
|
||||
+ //print background previous/next page buttons
|
||||
+ setImage(&data, statsBackgroundImages);
|
||||
+ setFrame(&data, 1);
|
||||
+ D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0);
|
||||
+ }
|
||||
|
||||
//print button close
|
||||
setImage(&data, D2LoadBuySelBtn());
|
||||
diff --git a/PlugY/NewInterfaces.cpp b/PlugY/NewInterfaces.cpp
|
||||
index 2bcb2f1..91003fb 100644
|
||||
--- a/PlugY/NewInterfaces.cpp
|
||||
+++ b/PlugY/NewInterfaces.cpp
|
||||
@@ -22,11 +22,39 @@ bool active_newInterfaces=false;
|
||||
bool selectMainPageOnOpenning=true;
|
||||
bool printBackgroundOnMainPage=true;
|
||||
|
||||
+int posXNextPageBtn = -1;
|
||||
+int posYNextPageBtn = -1;
|
||||
+int posXPrevPageBtn = -1;
|
||||
+int posYPrevPageBtn = -1;
|
||||
+int posXClosePageBtn = -1;
|
||||
+int posYClosePageBtn = -1;
|
||||
+int posXNextRuneBtn = -1;
|
||||
+int posYNextRuneBtn = -1;
|
||||
+int posXPrevRuneBtn = -1;
|
||||
+int posYPrevRuneBtn = -1;
|
||||
+int posXRunesList = -1;
|
||||
+int posYRunesList = -1;
|
||||
+int runesPerPage = -1;
|
||||
+
|
||||
+DWORD getXNextPageBtn() {return RX(posXNextPageBtn);}
|
||||
+DWORD getYNextPageBtn() {return RY(posYNextPageBtn);}
|
||||
+DWORD getXPreviousPageBtn() {return RX(posXPrevPageBtn);}
|
||||
+DWORD getYPreviousPageBtn() {return RY(posYPrevPageBtn);}
|
||||
+DWORD getXCloseBtn() {return RX(posXClosePageBtn);}
|
||||
+DWORD getYCloseBtn() {return RY(posYClosePageBtn);}
|
||||
+DWORD getXNextRunesBtn() {return RX(posXNextRuneBtn);}
|
||||
+DWORD getYNextRunesBtn() {return RY(posYNextRuneBtn);}
|
||||
+DWORD getXPrevRunesBtn() {return RX(posXPrevRuneBtn);}
|
||||
+DWORD getYPrevRunesBtn() {return RY(posYPrevRuneBtn);}
|
||||
+
|
||||
DWORD bDontPrintBorder=false;
|
||||
|
||||
int selectedPage=0;
|
||||
int lastPage=0;
|
||||
int extraHiddenPage=0;
|
||||
+int curRunesPage=0;
|
||||
+int maxRunesPage=0xFFFF;
|
||||
+BtnState isDownBtn={0};
|
||||
|
||||
void GoNextStatPage()
|
||||
{
|
||||
@@ -44,8 +72,12 @@ void GoPreviousStatPage()
|
||||
|
||||
void GoStatPage(int page)
|
||||
{
|
||||
- if ( (page >= 0) && (page <= lastPage + (D2GetResolution()? extraHiddenPage : 0)) )
|
||||
+ if ( (page >= 0) && (page <= (lastPage + extraHiddenPage)) )
|
||||
selectedPage = page;
|
||||
+ else if (page < 0)
|
||||
+ selectedPage = lastPage + extraHiddenPage;
|
||||
+ else
|
||||
+ selectedPage = 0;
|
||||
}
|
||||
|
||||
int GetCurrentPage()
|
||||
@@ -83,6 +115,16 @@ DWORD STDCALL mouseCustomPageLeftDown(sWinMessage* msg)
|
||||
DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg)
|
||||
{
|
||||
if(onRealm) return -1;
|
||||
+
|
||||
+ if (selectedPage == 0) return -1;
|
||||
+ if (!isOnStatsPage(msg->x,msg->y)) return 1;
|
||||
+ statsLeftUp(msg);
|
||||
+ D2CleanStatMouseUp();
|
||||
+ freeMessage(msg);
|
||||
+ isDownBtn.all=0;
|
||||
+ return 0;
|
||||
+
|
||||
+ /*
|
||||
if ( (selectedPage > 0) && (selectedPage <= lastPage) )
|
||||
return mouseNewStatsPageTwoLeftUp(msg);
|
||||
else if (selectedPage == lastPage+1)
|
||||
@@ -91,6 +133,87 @@ DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg)
|
||||
return mouseNewStatsPageLeftUp(msg);
|
||||
else
|
||||
return -1;
|
||||
+ */
|
||||
+}
|
||||
+
|
||||
+DWORD STDCALL statsLeftDown(sWinMessage* msg)
|
||||
+{
|
||||
+ if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0)
|
||||
+ {
|
||||
+ log_msg("push down left button close\n");
|
||||
+ isDownBtn.close = 1;
|
||||
+ D2PlaySound(4,0,0,0,0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnPreviousPageBtn(msg->x,msg->y))
|
||||
+ {
|
||||
+ log_msg("push down left button previous page\n");
|
||||
+ isDownBtn.previousPage = 1;
|
||||
+ D2PlaySound(4,0,0,0,0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnNextPageBtn(msg->x,msg->y))
|
||||
+ {
|
||||
+ log_msg("push down left button next page\n");
|
||||
+ isDownBtn.nextPage = 1;
|
||||
+ D2PlaySound(4,0,0,0,0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
+ {
|
||||
+ log_msg("push down left button prev runes\n");
|
||||
+ isDownBtn.prevRunes = 1;
|
||||
+ D2PlaySound(4,0,0,0,0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
+ {
|
||||
+ log_msg("push down left button next runes\n");
|
||||
+ isDownBtn.nextRunes = 1;
|
||||
+ D2PlaySound(4,0,0,0,0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+DWORD STDCALL statsLeftUp(sWinMessage* msg)
|
||||
+{
|
||||
+ if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0)
|
||||
+ {
|
||||
+ log_msg("push up left button close\n");
|
||||
+ if (isDownBtn.close)
|
||||
+ D2TogglePage(2,1,0);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnPreviousPageBtn(msg->x,msg->y))
|
||||
+ {
|
||||
+ log_msg("push up left button previous page\n");
|
||||
+ if (isDownBtn.previousPage)
|
||||
+ GoStatPage(selectedPage-1);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnNextPageBtn(msg->x,msg->y))
|
||||
+ {
|
||||
+ log_msg("push up left button next page\n");
|
||||
+ if (isDownBtn.nextPage)
|
||||
+ GoStatPage(selectedPage+1);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
+ {
|
||||
+ log_msg("push up left button prev runes\n");
|
||||
+ if (isDownBtn.prevRunes && curRunesPage)
|
||||
+ curRunesPage--;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
+ {
|
||||
+ log_msg("push up left button next runes\n");
|
||||
+ if (isDownBtn.nextRunes && (curRunesPage < maxRunesPage))
|
||||
+ curRunesPage++;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
FCT_ASM ( caller_DontPrintBorder_114 )
|
||||
@@ -474,6 +597,7 @@ void Install_NewInterfaces()
|
||||
//00498636 |. 6A 48 PUSH 48
|
||||
//00498638 |. 8D45 B8 LEA EAX,DWORD PTR SS:[EBP-48]
|
||||
|
||||
+ /* Conflicts with D2ExpRes
|
||||
// Manage mouse down (Play sound)
|
||||
mem_seek R8(D2Client, 2A9DC, 2A9CC, 312A5, 82736, 891B6, 6B116, BCD36, BF4D6, A7731);
|
||||
memt_byte( 0x8D, 0xE8 ); // CALL
|
||||
@@ -486,6 +610,7 @@ void Install_NewInterfaces()
|
||||
//6FB6CD36 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80]
|
||||
//6FB6F4D6 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80]
|
||||
//004A7731 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80]
|
||||
+ */
|
||||
|
||||
// Manage mouse up
|
||||
mem_seek R8(D2Client, 2ABBB, 2ABAB, 3148D, 836D9, 8A159, 6C0B9, BDCB9, C0459, A78DA);
|
||||
diff --git a/PlugY/Parameters.cpp b/PlugY/Parameters.cpp
|
||||
index b4dc915..392c112 100644
|
||||
--- a/PlugY/Parameters.cpp
|
||||
+++ b/PlugY/Parameters.cpp
|
||||
@@ -58,6 +58,7 @@ const char* S_dllFilenames2 = "DllToLoad2";
|
||||
const char* S_active_Commands = "ActiveCommands";
|
||||
const char* S_active_CheckMemory = "ActiveCheckMemory";
|
||||
const char* S_active_othersFeatures = "ActiveAllOthersFeatures";
|
||||
+const char* S_saveFileStackSize = "SaveFileStackSize";
|
||||
|
||||
const char* S_WINDOWED = "WINDOWED";
|
||||
const char* S_ActiveWindowed = "ActiveWindowed";
|
||||
@@ -214,6 +215,19 @@ const char* S_INTERFACE = "INTERFACE";
|
||||
const char* S_active_newInterfaces = "ActiveNewStatsInterface";
|
||||
const char* S_selectMainPageOnOpenning = "SelectMainPageOnOpenning";
|
||||
const char* S_printBackgroundOnMainPage = "PrintButtonsBackgroundOnMainStatsPage";
|
||||
+const char* S_posXNextPageBtn = "PosXNextPageBtn";
|
||||
+const char* S_posYNextPageBtn = "PosYNextPageBtn";
|
||||
+const char* S_posXPrevPageBtn = "PosXPrevPageBtn";
|
||||
+const char* S_posYPrevPageBtn = "PosYPrevPageBtn";
|
||||
+const char* S_posXClosePageBtn = "PosXClosePageBtn";
|
||||
+const char* S_posYClosePageBtn = "PosYClosePageBtn";
|
||||
+const char* S_posXNextRuneBtn = "PosXNextRuneBtn";
|
||||
+const char* S_posYNextRuneBtn = "PosYNextRuneBtn";
|
||||
+const char* S_posXPrevRuneBtn = "PosXPrevRuneBtn";
|
||||
+const char* S_posYPrevRuneBtn = "PosYPrevRuneBtn";
|
||||
+const char* S_posXRunesList = "PosXRunesList";
|
||||
+const char* S_posYRunesList = "PosYRunesList";
|
||||
+const char* S_runesPerPage = "RunesPerPage";
|
||||
|
||||
const char* S_EXTRA = "EXTRA";
|
||||
const char* S_active_RunLODs = "ActiveLaunchAnyNumberOfLOD";
|
||||
@@ -316,6 +330,10 @@ void init_General(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFi
|
||||
active_othersFeatures = atoi(buffer) != 0;
|
||||
log_msg("active_othersFeatures\t\t= %u\n", active_othersFeatures);
|
||||
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_saveFileStackSize, "8192");
|
||||
+ saveFileStackSize = atoi(buffer);
|
||||
+ log_msg("SaveFileStackSize\t\t\t= %u\n", saveFileStackSize);
|
||||
+
|
||||
log_msg("\n");
|
||||
}
|
||||
|
||||
@@ -1032,6 +1050,52 @@ void init_NewInterfaces(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDef
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_printBackgroundOnMainPage, "1");
|
||||
printBackgroundOnMainPage = atoi(buffer) != 0;
|
||||
log_msg("printBackgroundOnMainPage\t= %u\n", printBackgroundOnMainPage);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextPageBtn, "161");
|
||||
+ posXNextPageBtn = atoi(buffer);
|
||||
+ log_msg("posXNextPageBtn\t= %d\n", posXNextPageBtn);
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextPageBtn, "64");
|
||||
+ posYNextPageBtn = atoi(buffer);
|
||||
+ log_msg("posYNextPageBtn\t= %d\n", posYNextPageBtn);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevPageBtn, "119");
|
||||
+ posXPrevPageBtn = atoi(buffer);
|
||||
+ log_msg("posXPrevPageBtn\t= %d\n", posXPrevPageBtn);
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevPageBtn, "64");
|
||||
+ posYPrevPageBtn = atoi(buffer);
|
||||
+ log_msg("posYPrevPageBtn\t= %d\n", posYPrevPageBtn);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXClosePageBtn, "360");
|
||||
+ posXClosePageBtn = atoi(buffer);
|
||||
+ log_msg("posXClosePageBtn\t= %d\n", posXClosePageBtn);
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYClosePageBtn, "64");
|
||||
+ posYClosePageBtn = atoi(buffer);
|
||||
+ log_msg("posYClosePageBtn\t= %d\n", posYClosePageBtn);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextRuneBtn, "302");
|
||||
+ posXNextRuneBtn = atoi(buffer);
|
||||
+ log_msg("posXNextRuneBtn\t= %d\n", posXNextRuneBtn);
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextRuneBtn, "64");
|
||||
+ posYNextRuneBtn = atoi(buffer);
|
||||
+ log_msg("posYNextRuneBtn\t= %d\n", posYNextRuneBtn);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevRuneBtn, "260");
|
||||
+ posXPrevRuneBtn = atoi(buffer);
|
||||
+ log_msg("posXPrevRuneBtn\t= %d\n", posXPrevRuneBtn);
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevRuneBtn, "64");
|
||||
+ posYPrevRuneBtn = atoi(buffer);
|
||||
+ log_msg("posYPrevRuneBtn\t= %d\n", posYPrevRuneBtn);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXRunesList, "50");
|
||||
+ posXRunesList = atoi(buffer);
|
||||
+ log_msg("posXRunesList\t= %d\n", posXRunesList);
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYRunesList, "45");
|
||||
+ posYRunesList = atoi(buffer);
|
||||
+ log_msg("posYRunesList\t= %d\n", posYRunesList);
|
||||
+
|
||||
+ GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_runesPerPage, "30");
|
||||
+ runesPerPage = atoi(buffer);
|
||||
+ log_msg("runesPerPage\t= %d\n", runesPerPage);
|
||||
}
|
||||
log_msg("\n");
|
||||
}
|
||||
diff --git a/PlugY/infinityStash.h b/PlugY/infinityStash.h
|
||||
index 0ca6b4d..123705d 100644
|
||||
--- a/PlugY/infinityStash.h
|
||||
+++ b/PlugY/infinityStash.h
|
||||
@@ -18,6 +18,7 @@ extern bool active_sharedStash;
|
||||
extern bool active_sharedGold;
|
||||
extern bool separateHardSoftStash;
|
||||
extern char* sharedStashFilename;
|
||||
+extern DWORD saveFileStackSize;
|
||||
|
||||
extern bool displaySharedSetItemNameInGreen;
|
||||
extern int posXPreviousBtn;
|
||||
diff --git a/PlugY/newInterfaces.h b/PlugY/newInterfaces.h
|
||||
index de51f26..c4c4ff3 100644
|
||||
--- a/PlugY/newInterfaces.h
|
||||
+++ b/PlugY/newInterfaces.h
|
||||
@@ -9,20 +9,94 @@
|
||||
#include "common.h"
|
||||
|
||||
#define MILIEU(X,L,N) (X + ((N<L)? (L-N)/2 : 0))
|
||||
-#define isOnStatsPage(x,y) ((x<400) && (y<553))
|
||||
+#define isOnStatsPage(x,y) (x<RX(512))
|
||||
|
||||
extern DWORD bDontPrintBorder;
|
||||
+extern int selectedPage;
|
||||
extern int extraHiddenPage;
|
||||
+extern int curRunesPage;
|
||||
+extern int maxRunesPage;
|
||||
|
||||
void GoNextStatPage();
|
||||
void GoPreviousStatPage();
|
||||
void GoStatPage(int page);
|
||||
int GetCurrentPage();
|
||||
|
||||
+struct BtnState
|
||||
+{
|
||||
+ union{
|
||||
+ DWORD all;
|
||||
+ struct{
|
||||
+ DWORD AssSTR:1;
|
||||
+ DWORD AssDEX:1;
|
||||
+ DWORD AssVIT:1;
|
||||
+ DWORD AssENE:1;
|
||||
+ DWORD UnaSTR:1;
|
||||
+ DWORD UnaDEX:1;
|
||||
+ DWORD UnaVIT:1;
|
||||
+ DWORD UnaENE:1;
|
||||
+ DWORD close:1;
|
||||
+ DWORD previousPage:1;
|
||||
+ DWORD nextPage:1;
|
||||
+ DWORD prevRunes:1;
|
||||
+ DWORD nextRunes:1;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+extern BtnState isDownBtn;
|
||||
+
|
||||
extern bool active_newInterfaces;
|
||||
extern bool selectMainPageOnOpenning;
|
||||
extern bool printBackgroundOnMainPage;
|
||||
|
||||
+extern int posXNextPageBtn;
|
||||
+extern int posYNextPageBtn;
|
||||
+extern int posXPrevPageBtn;
|
||||
+extern int posYPrevPageBtn;
|
||||
+extern int posXClosePageBtn;
|
||||
+extern int posYClosePageBtn;
|
||||
+extern int posXNextRuneBtn;
|
||||
+extern int posYNextRuneBtn;
|
||||
+extern int posXPrevRuneBtn;
|
||||
+extern int posYPrevRuneBtn;
|
||||
+extern int posXRunesList;
|
||||
+extern int posYRunesList;
|
||||
+extern int runesPerPage;
|
||||
+
|
||||
+DWORD getXNextPageBtn();
|
||||
+DWORD getYNextPageBtn();
|
||||
+DWORD getXPreviousPageBtn();
|
||||
+DWORD getYPreviousPageBtn();
|
||||
+DWORD getXCloseBtn();
|
||||
+DWORD getYCloseBtn();
|
||||
+DWORD getXNextRunesBtn();
|
||||
+DWORD getYNextRunesBtn();
|
||||
+DWORD getXPrevRunesBtn();
|
||||
+DWORD getYPrevRunesBtn();
|
||||
+
|
||||
+#define getLCloseBtn() 32
|
||||
+#define getHCloseBtn() 32
|
||||
+#define isOnCloseBtn(x,y) isOnRect(x, y, getXCloseBtn(), getYCloseBtn(), getLCloseBtn(), getHCloseBtn())
|
||||
+
|
||||
+#define getLPreviousPageBtn() 32
|
||||
+#define getHPreviousPageBtn() 32
|
||||
+#define isOnPreviousPageBtn(x,y) isOnRect(x, y, getXPreviousPageBtn(), getYPreviousPageBtn(), getLPreviousPageBtn(), getHPreviousPageBtn())
|
||||
+
|
||||
+#define getLNextPageBtn() 32
|
||||
+#define getHNextPageBtn() 32
|
||||
+#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn())
|
||||
+
|
||||
+#define getLPrevRunesBtn() 32
|
||||
+#define getHPrevRunesBtn() 32
|
||||
+#define isOnPrevRunesBtn(x,y) isOnRect(x, y, getXPrevRunesBtn(), getYPrevRunesBtn(), getLPrevRunesBtn(), getHPrevRunesBtn())
|
||||
+
|
||||
+#define getLNextRunesBtn() 32
|
||||
+#define getHNextRunesBtn() 32
|
||||
+#define isOnNextRunesBtn(x,y) isOnRect(x, y, getXNextRunesBtn(), getYNextRunesBtn(), getLNextRunesBtn(), getHNextRunesBtn())
|
||||
+
|
||||
+DWORD STDCALL statsLeftDown(sWinMessage* msg);
|
||||
+DWORD STDCALL statsLeftUp(sWinMessage* msg);
|
||||
+
|
||||
void Install_NewInterfaces();
|
||||
|
||||
/*================================= END OF FILE =================================*/
|
||||
\ No newline at end of file
|
||||
diff --git a/PlugY/parameters.h b/PlugY/parameters.h
|
||||
index d426c99..1cf884c 100644
|
||||
--- a/PlugY/parameters.h
|
||||
+++ b/PlugY/parameters.h
|
||||
@@ -6,7 +6,7 @@
|
||||
=================================================================*/
|
||||
#pragma once
|
||||
|
||||
-#define PLUGY_VERSION "14.03"
|
||||
+#define PLUGY_VERSION "14.03 HD"
|
||||
|
||||
enum TargetMod
|
||||
{
|
20
PlugY/Backup/PlugY.sln
Normal file
20
PlugY/Backup/PlugY.sln
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugY", "PlugY.vcproj", "{EB63DF4E-A019-4522-A140-9E8C7350B331}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{EB63DF4E-A019-4522-A140-9E8C7350B331}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{EB63DF4E-A019-4522-A140-9E8C7350B331}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{EB63DF4E-A019-4522-A140-9E8C7350B331}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{EB63DF4E-A019-4522-A140-9E8C7350B331}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -291,6 +291,7 @@ void loadCustomLibraries()
|
||||
log_msg("\n\n");
|
||||
}
|
||||
|
||||
/*
|
||||
void loadLibrary(LPCSTR libName, int* libVersion, DWORD* libOffset, int shift, DWORD v109b, DWORD v109d, DWORD v110, DWORD v111, DWORD v111b, DWORD v112, DWORD v113c)
|
||||
{
|
||||
*libOffset = (DWORD)LoadLibrary(libName);
|
||||
@ -386,6 +387,273 @@ void initD2modules()
|
||||
|
||||
log_msg("\n\n");
|
||||
}
|
||||
*/
|
||||
|
||||
IMAGE_NT_HEADERS* GetHeader(LPBYTE pBase) {
|
||||
if (pBase == NULL)
|
||||
return NULL;
|
||||
|
||||
IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)pBase;
|
||||
|
||||
if (IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)))
|
||||
return NULL;
|
||||
|
||||
if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
IMAGE_NT_HEADERS* pHeader = (IMAGE_NT_HEADERS*)(pBase + pDosHeader->e_lfanew);
|
||||
if (IsBadReadPtr(pHeader, sizeof(IMAGE_NT_HEADERS)))
|
||||
return NULL;
|
||||
|
||||
if (pHeader->Signature != IMAGE_NT_SIGNATURE)
|
||||
return NULL;
|
||||
|
||||
return pHeader;
|
||||
}
|
||||
|
||||
void initD2modules()
|
||||
{
|
||||
log_msg("***** Get D2 Modules address and version *****\n\n");
|
||||
|
||||
offset_D2Client = (DWORD)LoadLibrary("D2Client.dll");
|
||||
offset_D2CMP = (DWORD)LoadLibrary("D2CMP.dll");
|
||||
offset_D2Common = (DWORD)LoadLibrary("D2Common.dll");
|
||||
offset_D2Game = (DWORD)LoadLibrary("D2Game.dll");
|
||||
offset_D2gfx = (DWORD)LoadLibrary("D2gfx.dll");
|
||||
offset_D2Lang = (DWORD)LoadLibrary("D2Lang.dll");
|
||||
offset_D2Launch = (DWORD)LoadLibrary("D2Launch.dll");
|
||||
offset_D2Net = (DWORD)LoadLibrary("D2Net.dll");
|
||||
offset_D2Win = (DWORD)LoadLibrary("D2Win.dll");
|
||||
offset_Fog = (DWORD)LoadLibrary("Fog.dll");
|
||||
offset_Storm = (DWORD)LoadLibrary("Storm.dll");
|
||||
|
||||
int count_109b = 0;
|
||||
int count_109d = 0;
|
||||
int count_110f = 0;
|
||||
int count_111 = 0;
|
||||
int count_111b = 0;
|
||||
int count_112a = 0;
|
||||
int count_113c = 0;
|
||||
int count_113d = 0;
|
||||
int count_114a = 0;
|
||||
int count_114b = 0;
|
||||
int count_114c = 0;
|
||||
int count_114d = 0;
|
||||
|
||||
IMAGE_NT_HEADERS* pHeader;
|
||||
|
||||
if (offset_D2Client != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Client);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C234D) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C16CD) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C1C1D) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045E6) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045EE) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045FA) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045F6) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000045DE) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2CMP != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2CMP);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00011361) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00010E61) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C23) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2Common != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Common);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074D1D) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00074E2D) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000856DD) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C94) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8D) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C97) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C8F) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000047C7) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2Game != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Game);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C66AC) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000C6D5C) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000EDC2C) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000036E6) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373D) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000374B) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000373C) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003747) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2gfx != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2gfx);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054EB) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000054A5) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001807) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2Lang != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Lang);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005148) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005138) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00005048) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A6A) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5B) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A75) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A71) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A5A) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2Launch != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Launch);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000172C3) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00017243) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00018DC7) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A85) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A87) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001A84) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2Net != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Net);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002BCE) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00002C6E) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001676) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000167E) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_D2Win != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_D2Win);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00014F38) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00012EC0) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000188E) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000187E) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00001887) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_Fog != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_Fog);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_113d++;
|
||||
}
|
||||
|
||||
if (offset_Storm != NULL) {
|
||||
pHeader = GetHeader((LPBYTE)offset_Storm);
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00013658) count_109b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000142E7) count_109d++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x000162B0) count_110f++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003159) count_111++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003142) count_111b++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0000314A) count_112a++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00003162) count_113c++;
|
||||
if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x0003C3E0) count_113d++;
|
||||
}
|
||||
|
||||
int minimum_match_dll = 7;
|
||||
|
||||
if (count_109b >= minimum_match_dll) version_Game = V109b;
|
||||
if (count_109d >= minimum_match_dll) version_Game = V109d;
|
||||
if (count_110f >= minimum_match_dll) version_Game = V110;
|
||||
if (count_111 >= minimum_match_dll) version_Game = V111;
|
||||
if (count_111b >= minimum_match_dll) version_Game = V111b;
|
||||
if (count_112a >= minimum_match_dll) version_Game = V112;
|
||||
if (count_113c >= minimum_match_dll) version_Game = V113c;
|
||||
if (count_113d >= minimum_match_dll) version_Game = V113d;
|
||||
|
||||
//version_SmackW32 = version_Game;
|
||||
version_D2Common = version_Game;
|
||||
//version_ijl11 = version_Game;
|
||||
//version_D2Gdi = version_Game;
|
||||
version_D2Win = version_Game;
|
||||
//version_D2sound = version_Game;
|
||||
//version_D2MCPCLI = version_Game;
|
||||
version_D2Launch = version_Game;
|
||||
version_D2gfx = version_Game;
|
||||
version_D2Client = version_Game;
|
||||
version_D2Net = version_Game;
|
||||
version_D2Lang = version_Game;
|
||||
version_D2Game = version_Game;
|
||||
version_D2CMP = version_Game;
|
||||
//version_Bnclient = version;
|
||||
version_Fog = version_Game;
|
||||
version_Storm = version_Game;
|
||||
|
||||
log_msg("DLL match for version 1.09b :\t%d\n", count_109b);
|
||||
log_msg("DLL match for version 1.09d :\t%d\n", count_109d);
|
||||
log_msg("DLL match for version 1.10f :\t%d\n", count_110f);
|
||||
log_msg("DLL match for version 1.11 :\t%d\n", count_111);
|
||||
log_msg("DLL match for version 1.11b :\t%d\n", count_111b);
|
||||
log_msg("DLL match for version 1.12a :\t%d\n", count_112a);
|
||||
log_msg("DLL match for version 1.13c :\t%d\n", count_113c);
|
||||
log_msg("\n");
|
||||
|
||||
offset_Game = (DWORD)GetModuleHandle("Game.exe");
|
||||
if (offset_Game != NULL) {
|
||||
version_Game = GetD2Version((HMODULE)offset_Game);
|
||||
log_msg("Game.exe loaded at:\t%08X (%s)\n", offset_Game, GetVersionString(version_Game));
|
||||
if (version_Game >= V114a)
|
||||
{
|
||||
//version_SmackW32 = version_Game;
|
||||
version_D2Common = version_Game;
|
||||
//version_ijl11 = version_Game;
|
||||
//version_D2Gdi = version_Game;
|
||||
version_D2Win = version_Game;
|
||||
//version_D2sound = version_Game;
|
||||
//version_D2MCPCLI = version_Game;
|
||||
version_D2Launch = version_Game;
|
||||
version_D2gfx = version_Game;
|
||||
version_D2Client = version_Game;
|
||||
version_D2Net = version_Game;
|
||||
version_D2Lang = version_Game;
|
||||
version_D2Game = version_Game;
|
||||
version_D2CMP = version_Game;
|
||||
//version_Bnclient = version;
|
||||
version_Fog = version_Game;
|
||||
version_Storm = version_Game;
|
||||
}
|
||||
}
|
||||
|
||||
//if (offset_Game != NULL) {
|
||||
// pHeader = GetHeader((LPBYTE)offset_Game);
|
||||
// if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00291342) count_114a++;
|
||||
// if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002854F2) count_114b++;
|
||||
// if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x002850E2) count_114c++;
|
||||
// if (pHeader->OptionalHeader.AddressOfEntryPoint == 0x00282985) count_114d++;
|
||||
//}
|
||||
|
||||
log_msg("Version game is:\t(%s)\n\n", GetVersionString(version_Game));
|
||||
|
||||
if (version_Game == UNKNOWN)
|
||||
{
|
||||
MessageBoxA(NULL, "This version of Diablo II is not supported by Plugy. Please upgrade or downgrade to a supported version.", "Plugy 14.03", MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////// EXPORTS FUNCTIONS ////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -26,6 +26,7 @@ bool active_sharedStash = false;
|
||||
bool separateHardSoftStash = false;
|
||||
bool active_sharedGold=false;
|
||||
char* sharedStashFilename = NULL;
|
||||
DWORD saveFileStackSize = 0x2000;
|
||||
|
||||
typedef int (*TchangeToSelectedStash)(Unit* ptChar, Stash* newStash, DWORD bOnlyItems, DWORD bIsClient);
|
||||
|
||||
@ -355,11 +356,7 @@ DWORD loadStashList(Unit* ptChar, BYTE* data, DWORD maxSize, DWORD* curSize, boo
|
||||
}
|
||||
}
|
||||
|
||||
if (nbStash == 1)
|
||||
{
|
||||
newStash = addStash(ptChar, isShared, true, newStash);
|
||||
changeToSelectedStash(ptChar, newStash, 0, false);
|
||||
}
|
||||
changeToSelectedStash(ptChar, isShared?PCPY->sharedStash:PCPY->selfStash, 0, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -426,7 +423,7 @@ void saveStashList(Unit* ptChar, Stash* ptStash, BYTE** data, DWORD* maxSize, DW
|
||||
|
||||
while(ptStash)
|
||||
{
|
||||
if (*curSize + 0x2000 > *maxSize)
|
||||
if (*curSize + saveFileStackSize > *maxSize)
|
||||
{
|
||||
BYTE* oldData = *data;
|
||||
*maxSize *= 2;
|
||||
|
@ -49,9 +49,10 @@ Unit* STDCALL skillsPageMouseDown(sWinMessage* msg)
|
||||
if (active_SkillsPoints && !onRealm && D2isLODGame() && isOnButtonUnassignSkill(D2GetMouseX(),D2GetMouseY()))
|
||||
{
|
||||
log_msg("push down left button unassign skill\n");
|
||||
btnSkillIsDown = 1;
|
||||
//btnSkillIsDown = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
freeMessage(msg);
|
||||
updateServer(US_UNASSIGN_SKILLS);
|
||||
return NULL;
|
||||
}
|
||||
return ptChar;
|
||||
@ -233,6 +234,7 @@ void Install_InterfaceSkills()
|
||||
//6FAE1112 > C745 18 00000000 MOV DWORD PTR SS:[EBP+18],0
|
||||
//004ABC1A |> C746 18 00000000 MOV DWORD PTR DS:[ESI+18],0
|
||||
|
||||
/* Conflicts with D2ExpRes
|
||||
// Manage mouse up
|
||||
mem_seek R8(D2Client, 7BC40, 7BC40, 78466, 17558, 8C078, 80248, 795F8, 30AA8, ABC96);
|
||||
MEMJ_REF4( D2FreeWinMessage, caller_skillsPageMouseUp);//0xFFF93B0A
|
||||
@ -243,6 +245,7 @@ void Install_InterfaceSkills()
|
||||
//6FB295F7 .^E9 8828F9FF JMP <JMP.&Storm.#511>
|
||||
//6FAE0AA7 .^E9 E0B2FDFF JMP <JMP.&Storm.#511>
|
||||
//004ABC95 |. E8 F645F7FF CALL Game.00420290
|
||||
*/
|
||||
|
||||
log_msg("\n");
|
||||
|
||||
|
@ -13,6 +13,13 @@
|
||||
#include "plugYFiles.h" // Install_PlugYImagesFiles()
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
#include <ctime> // Include ctime for srand and rand functions
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <Windows.h>
|
||||
|
||||
static struct
|
||||
{
|
||||
@ -69,6 +76,9 @@ int posYStashGoldField = -1;
|
||||
int posWStashGoldField = 152;
|
||||
int posHStashGoldField = 18;
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
||||
|
||||
DWORD PersonalNormalPageColor = WHITE;
|
||||
DWORD PersonalIndexPageColor = DARK_GREEN;
|
||||
@ -331,6 +341,671 @@ DWORD STDCALL manageBtnUp(sWinMessage* msg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int frame = 0;
|
||||
long nEndTime = 0;
|
||||
int nTip = 0;
|
||||
long DURATION = 15000;
|
||||
std::vector<std::wstring> diablo2Tips = {
|
||||
L"Consume spirits like potions to increase Spirits Quaffed stat in character stat sheet page.",
|
||||
L"Cube Souls with Energy Sphere to capture Soul Energy and use it to create powerful items. Recipes will come later.",
|
||||
L"Collect Demon souls from demons and regular souls from monsters; Demon souls morph you into the demon whose soul you have.",
|
||||
L"Spirits can be consumed like potions or put on as rings to add to Souls Consumed count.",
|
||||
L"Cube underused magic, rare, set, unique items with Energy Sphere to collect their magic energy for creating new items.",
|
||||
L"Cube white items with Energy Sphere to break down into simple item parts for creating base item types with smithing hammers.",
|
||||
L"Use Rare Shard, Set Stone, or Unique Particle with smithing hammers and Energy Sphere to create rare, set, unique items.",
|
||||
L"Acquire smithing hammers to create base item types, each requiring X number of collected item parts.",
|
||||
L"Capture Talisman of Corruption and cube to corrupt items for new magical properties; a gamble with potential rewards.",
|
||||
L"Use Experience Book for extra experience, Infinite Mana Elixir for massive mana regeneration, and Regeneration Elixir for life regeneration.",
|
||||
L"Use Elixirs to permanently boost stats like Strength, Dexterity, Health, Stamina, Mana, and resistances.",
|
||||
L"Equip Sling Stone for increased throwing potion damage, various elemental stones for resistance boosts, and Mastery Stones for skill damage boosts.",
|
||||
L"Use Portable Shrines for temporary buffs like increased defense, damage, experience gained, mana regeneration, and skill levels.",
|
||||
L"In Ironman, gold is nonexistent, town portals are disabled; rely on items, waypoints, and strategic gameplay to progress.",
|
||||
L"Inventory management is critical; use items conservatively and intelligently switch gear based on monster types and situations.",
|
||||
L"Hybrid character builds and creative weapon choices are encouraged in Ironman; experiment and adapt strategies accordingly.",
|
||||
L"Protect hirelings actively as they are essential allies; they can be hired for 0 gold but lose items if they die.",
|
||||
L"Coordinate with teammates in MultiPlayer; teamwork, resource sharing, and strategy are key to success in Ironman.",
|
||||
L"In Hardcore Ironman, caution and careful planning are crucial; falling back, potion management, and adaptability are essential for survival.",
|
||||
L"Utilize waypoints for inter-level travel in Ironman; waypoints become crucial for navigating the game world.",
|
||||
L"Always have backup gear in your backpack in Ironman; switch out gear intelligently based on monster types and challenges.",
|
||||
L"Experiment with different weapons and gear in Ironman; adapt your strategies to overcome various monster types and situations.",
|
||||
L"Keep a close watch on your hirelings' health in Ironman; losing a hireling means losing their equipped items as well.",
|
||||
L"Plan and communicate effectively in MultiPlayer Ironman games; teamwork and coordination are key to overcoming challenges.",
|
||||
L"Be conservative with resources in Hardcore Ironman; strategic planning and careful execution are vital for survival.",
|
||||
L"Craft rare, set, unique items using collected item parts and smithing hammers in Ironman; choose item types wisely for your build.",
|
||||
L"Capture and corrupt items using Talisman of Corruption for new magical properties in Ironman; take calculated risks for potential rewards.",
|
||||
L"Use Portable Shrines strategically in Ironman for temporary buffs; timing and placement of shrines can turn the tide of battle.",
|
||||
L"Keep track of Souls Consumed and Spirits Quaffed stats in Ironman; they reflect your progress and resource utilization in the game.",
|
||||
L"Enhance your character with Elixirs and Stones for permanent stat boosts and bonuses in Ironman; plan your upgrades wisely.",
|
||||
L"Master the art of retreating and regrouping in Hardcore Ironman; strategic fallbacks can save your character's life in tough situations.",
|
||||
L"Stay vigilant and adapt your strategies in MultiPlayer Ironman games; synergy and cooperation with teammates are essential for success.",
|
||||
L"Experiment with different skill synergies and builds in Ironman; explore the full potential of your character's abilities.",
|
||||
L"Craft and equip powerful unique items using collected Magic Essence Points and recipes in Ironman; customize your gear for optimal performance.",
|
||||
L"Explore new areas and challenges in Ironman; discover hidden secrets and encounters by venturing off the beaten path.",
|
||||
L"Combine different magic, rare, set, unique items with the Energy Sphere to collect their magic energy in Ironman.",
|
||||
L"Cube white items with the Energy Sphere to break them down into simple item parts for crafting in Ironman.",
|
||||
L"Use smithing hammers with the Energy Sphere to create base item types for crafting in Ironman.",
|
||||
L"Combine Rare Shard, Set Stone, or Unique Particle with base item types and Magic Essence Points to create rare, set, unique, items in Ironman.",
|
||||
L"Cube Souls with the Energy Sphere to capture their energy and use it for creating more powerful items in Ironman.",
|
||||
|
||||
L"Prioritize survivability over damage output. In Hardcore Ironman, staying alive is paramount.",
|
||||
L"Scout ahead before engaging enemies. Knowing what's coming can help you prepare and avoid deadly surprises.",
|
||||
L"Always have an escape route planned. Without town portals, strategic positioning and waypoints are your lifelines.",
|
||||
L"Collect and hoard potions. You never know when you'll need a sudden burst of healing or mana.",
|
||||
L"Experiment with different skill combinations. Adaptability is key to overcoming the diverse challenges of Hardcore mode.",
|
||||
L"Know your enemy. Understanding monster types and behaviors can give you a significant advantage in combat.",
|
||||
L"Stock up on antidote and thawing potions. Poison and cold damage are particularly deadly in Hardcore.",
|
||||
L"Maintain a diverse arsenal of weapons and armor. You never know when you'll need a specific resistance or damage type.",
|
||||
L"Train your mercenary well. They can be a valuable asset in battles, providing support and distraction when needed.",
|
||||
L"Don't be afraid to retreat. Sometimes, discretion is the better part of valor in Hardcore Ironman.",
|
||||
L"Watch your surroundings. Traps and ambushes can quickly turn a routine exploration into a fight for survival.",
|
||||
L"Stay informed about the latest patches and updates. Changes to game mechanics can have a significant impact on Hardcore gameplay.",
|
||||
L"Join Hardcore Ironman communities. Sharing tips and strategies with fellow players can enhance your survival chances.",
|
||||
L"Back up your save files regularly. Losing a Hardcore character to a technical glitch can be devastating.",
|
||||
L"Practice patience and caution. Rushing into battles recklessly is a surefire way to meet an untimely demise.",
|
||||
L"Embrace the challenge. Hardcore Ironman may be unforgiving, but overcoming its trials is immensely rewarding.",
|
||||
L"Develop a keen eye for loot. Every item could be the difference between life and death in Hardcore mode.",
|
||||
L"Learn from your mistakes. Each death is an opportunity to refine your strategies and become a better Hardcore player.",
|
||||
L"Respect your limits. Sometimes, it's better to retreat and live to fight another day than to press on recklessly.",
|
||||
L"Communicate with your party. Clear communication can prevent misunderstandings and ensure everyone's safety.",
|
||||
L"Stay focused. Even the smallest lapse in concentration can be fatal in Hardcore Ironman.",
|
||||
L"Build a strong network of allies. Having friends to watch your back can make all the difference in Hardcore mode.",
|
||||
L"Experiment with different character builds. There's no one-size-fits-all approach to Hardcore survival.",
|
||||
L"Avoid unnecessary risks. The thrill of danger may be tempting, but it's not worth losing your Hardcore character over.",
|
||||
L"Take breaks when needed. Hardcore Ironman can be mentally exhausting, so don't hesitate to step away and recharge.",
|
||||
L"Stay vigilant at all times. Complacency is the enemy of survival in Hardcore mode.",
|
||||
L"Adapt to changing circumstances. Flexibility is key to thriving in the ever-evolving world of Hardcore Ironman.",
|
||||
L"Trust your instincts. Sometimes, your gut feeling is your best guide in Hardcore survival.",
|
||||
L"Never underestimate your enemies. Even the weakest foes can pose a threat in Hardcore mode.",
|
||||
L"Explore every corner of the map. You never know what valuable resources or hidden dangers you might uncover.",
|
||||
L"Prepare for the worst. Always have a backup plan in case things go south in Hardcore Ironman.",
|
||||
L"Keep your equipment in top condition. A well-maintained arsenal can mean the difference between victory and defeat.",
|
||||
L"Study the terrain. Knowing the lay of the land can give you a strategic advantage in Hardcore battles.",
|
||||
L"Coordinate your attacks with your party members. Working together is essential for success in Hardcore mode.",
|
||||
L"Be mindful of your surroundings. Environmental hazards can be just as deadly as enemy attacks in Hardcore Ironman.",
|
||||
L"Stay cool under pressure. Panicking will only lead to mistakes and, ultimately, your demise in Hardcore mode.",
|
||||
L"Focus on survival skills first. Offensive prowess means nothing if you can't stay alive in Hardcore Ironman.",
|
||||
L"Be wary of traps and ambushes. The world of Hardcore is full of dangers lurking around every corner.",
|
||||
L"Pay attention to your health and mana reserves. Running out at the wrong moment can be fatal in Hardcore mode.",
|
||||
L"Plan your routes carefully. Avoiding unnecessary risks is crucial in Hardcore Ironman.",
|
||||
L"Learn from the mistakes of others. Watching other Hardcore players can provide valuable insights into effective survival strategies.",
|
||||
L"Stay disciplined in your gameplay. Taking unnecessary risks can quickly lead to your demise in Hardcore mode.",
|
||||
L"Keep a clear head. Emotional decisions are rarely the right ones in Hardcore Ironman.",
|
||||
L"Learn to prioritize threats. Not every enemy is worth engaging in Hardcore mode.",
|
||||
L"Practice patience. Rushing into battles blindly is a surefire way to meet a premature end in Hardcore Ironman.",
|
||||
L"Stockpile essential supplies. You never know when you'll need that extra potion or scroll in Hardcore mode.",
|
||||
L"Be proactive in your approach. Waiting for danger to come to you is a recipe for disaster in Hardcore Ironman.",
|
||||
L"Stay informed about the latest strategies and tactics. Knowledge is power in Hardcore mode.",
|
||||
L"Stay humble. Arrogance is a sure path to failure in Hardcore Ironman.",
|
||||
L"Trust your instincts. If something feels wrong, it probably is in Hardcore mode.",
|
||||
L"Take calculated risks. Sometimes, a bold move is necessary to secure victory in Hardcore Ironman.",
|
||||
L"Keep your wits about you. Panic is the enemy of survival in Hardcore mode.",
|
||||
L"Never let your guard down. Complacency is a luxury you can't afford in Hardcore Ironman.",
|
||||
L"Respect the power of your enemies. Underestimating them is a sure path to defeat in Hardcore mode.",
|
||||
L"Stay focused on your goals. Losing sight of your objectives can lead to costly mistakes in Hardcore Ironman.",
|
||||
L"Adapt to adversity. Flexibility is key to surviving the ever-changing challenges of Hardcore mode.",
|
||||
L"Stay vigilant. Danger can lurk around every corner in Hardcore Ironman.",
|
||||
L"Know when to retreat. Sometimes, discretion is the better part of valor in Hardcore mode.",
|
||||
L"Be mindful of your surroundings. Environmental hazards can be just as deadly as enemy attacks in Hardcore Ironman.",
|
||||
L"Stay cool under pressure. Panicking will only lead to mistakes and, ultimately, your demise in Hardcore mode.",
|
||||
L"Focus on survival skills first. Offensive prowess means nothing if you can't stay alive in Hardcore Ironman.",
|
||||
L"Be wary of traps and ambushes. The world of Hardcore is full of dangers lurking around every corner.",
|
||||
L"Pay attention to your health and mana reserves. Running out at the wrong moment can be fatal in Hardcore mode.",
|
||||
L"Plan your routes carefully. Avoiding unnecessary risks is crucial in Hardcore Ironman.",
|
||||
L"Learn from the mistakes of others. Watching other Hardcore players can provide valuable insights into effective survival strategies.",
|
||||
L"Stay disciplined in your gameplay. Taking unnecessary risks can quickly lead to your demise in Hardcore mode.",
|
||||
L"Keep a clear head. Emotional decisions are rarely the right ones in Hardcore Ironman.",
|
||||
L"Learn to prioritize threats. Not every enemy is worth engaging in Hardcore mode.",
|
||||
L"Practice patience. Rushing into battles blindly is a surefire way to meet a premature end in Hardcore Ironman.",
|
||||
L"Stockpile essential supplies. You never know when you'll need that extra potion or scroll in Hardcore mode.",
|
||||
L"Be proactive in your approach. Waiting for danger to come to you is a recipe for disaster in Hardcore Ironman.",
|
||||
L"Stay informed about the latest strategies and tactics. Knowledge is power in Hardcore mode.",
|
||||
L"Stay humble. Arrogance is a sure path to failure in Hardcore Ironman.",
|
||||
L"Trust your instincts. If something feels wrong, it probably is in Hardcore mode.",
|
||||
L"Take calculated risks. Sometimes, a bold move is necessary to secure victory in Hardcore Ironman.",
|
||||
L"Keep your wits about you. Panic is the enemy of survival in Hardcore mode.",
|
||||
L"Never let your guard down. Complacency is a luxury you can't afford in Hardcore Ironman.",
|
||||
L"Respect the power of your enemies. Underestimating them is a sure path to defeat in Hardcore mode.",
|
||||
L"Stay focused on your goals. Losing sight of your objectives can lead to costly mistakes in Hardcore Ironman.",
|
||||
L"Adapt to adversity. Flexibility is key to surviving the ever-changing challenges of Hardcore mode.",
|
||||
L"Stay vigilant. Danger can lurk around every corner in Hardcore Ironman.",
|
||||
L"Know when to retreat. Sometimes, discretion is the better part of valor in Hardcore mode.",
|
||||
|
||||
L"In Hardcore Ironman, survival is your top priority. Every decision you make should revolve around keeping your character alive in the harsh world of Diablo 2.",
|
||||
L"Take your time to carefully explore each area, scanning for potential threats and planning your route accordingly. Rushing into battles or unknown territory is a surefire way to meet an untimely demise.",
|
||||
L"Without the safety net of town portals, strategic planning is essential. Always have an escape route in mind, whether it's a nearby waypoint or a path back to a safe area.",
|
||||
L"Inventory management is critical in Hardcore mode. Keep your inventory organized and prioritize essential items like potions, scrolls, and emergency gear.",
|
||||
L"Be cautious when engaging enemies. Assess their strengths and weaknesses before committing to battle, and don't hesitate to retreat if the odds are against you.",
|
||||
L"Experiment with different skill combinations and character builds to find what works best for your playstyle. Adaptability is key to surviving the challenges of Hardcore Ironman.",
|
||||
L"Study your surroundings and learn to anticipate potential dangers. Traps, ambushes, and environmental hazards can quickly turn a routine exploration into a fight for survival.",
|
||||
L"Maintain a diverse arsenal of weapons and armor to handle a variety of threats. Prioritize gear that boosts your resistances and provides additional layers of protection.",
|
||||
L"Train your mercenary companion well and equip them with gear that complements your own strengths and weaknesses. They can provide invaluable support in battles and serve as a valuable distraction for enemies.",
|
||||
L"Communication is key, especially in multiplayer games. Coordinate with your party members and share information about enemy locations, tactics, and potential dangers.",
|
||||
L"Stay informed about the latest strategies, tactics, and updates. Knowledge is power in Hardcore mode, and being aware of changes to the game can give you a significant advantage.",
|
||||
L"Develop a backup plan for emergencies. Whether it's a stash of emergency potions or a hidden escape route, always have a contingency plan in place.",
|
||||
L"Practice patience and resilience. Setbacks and challenges are inevitable in Hardcore Ironman, but perseverance will ultimately lead to success.",
|
||||
L"Build a network of allies and fellow Hardcore players. Sharing tips, strategies, and experiences can help you learn and grow as a player.",
|
||||
L"Trust your instincts and intuition. If something feels wrong or too risky, it's better to err on the side of caution.",
|
||||
L"Embrace the challenge of Hardcore Ironman and enjoy the thrill of survival. The adrenaline rush of narrowly escaping death is what makes Hardcore mode so rewarding.",
|
||||
L"Stay disciplined in your gameplay and avoid taking unnecessary risks. Remember, one wrong move can cost you your character in Hardcore mode.",
|
||||
L"Keep a cool head and stay focused, especially in intense or dangerous situations. Panic and fear are your worst enemies in Hardcore Ironman.",
|
||||
L"Learn from your mistakes and use them as opportunities for growth. Every death is a chance to refine your strategies and improve your gameplay.",
|
||||
L"Be mindful of your surroundings at all times. Even the smallest oversight can prove fatal in Hardcore mode.",
|
||||
L"Prioritize defensive stats and survival skills over offensive abilities. A strong defense is crucial for staying alive in Hardcore Ironman.",
|
||||
L"Stockpile essential supplies like potions, scrolls, and emergency gear. You never know when you'll need them in Hardcore mode.",
|
||||
L"Plan your routes carefully and avoid unnecessary risks. Rushing headlong into danger is a recipe for disaster in Hardcore Ironman.",
|
||||
L"Stay adaptable and be prepared to adjust your tactics on the fly. The ability to think quickly and react to changing situations is essential for survival in Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and work together to overcome challenges. Teamwork is key to success in Hardcore Ironman.",
|
||||
L"Be cautious when exploring new areas, especially in Hardcore mode. Unknown dangers lurk around every corner, and it's better to proceed with caution than to rush in blindly.",
|
||||
L"Equip gear that complements your playstyle and provides the best possible protection against enemy attacks. Prioritize resistances and defensive bonuses over offensive stats in Hardcore mode.",
|
||||
L"Stay informed about the strengths and weaknesses of different enemy types. Knowing your foes is essential for developing effective strategies and staying alive in Hardcore Ironman.",
|
||||
L"Practice patience and perseverance in Hardcore mode. Success often requires multiple attempts and learning from your mistakes.",
|
||||
L"Develop a backup plan for emergencies, such as a stash of emergency potions or a hidden escape route. Always have a contingency plan in place in Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and communicate effectively to overcome challenges together. Teamwork is essential for survival in Hardcore Ironman.",
|
||||
L"Stay vigilant and be prepared for anything in Hardcore mode. Unexpected dangers and challenges can arise at any moment, and it's important to stay alert.",
|
||||
L"Learn from your mistakes and use them as opportunities for growth. Every death is a chance to refine your strategies and become a better Hardcore player.",
|
||||
L"Stock up on essential supplies like potions, scrolls, and emergency gear. You never know when you'll need them in Hardcore mode.",
|
||||
L"Plan your routes carefully and avoid unnecessary risks. Rushing into danger blindly is a surefire way to meet an untimely demise in Hardcore Ironman.",
|
||||
L"Stay adaptable and be prepared to adjust your tactics on the fly. Flexibility is key to surviving the ever-changing challenges of Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and work together to overcome challenges. Teamwork is essential for success in Hardcore Ironman.",
|
||||
L"Be cautious when exploring new areas, especially in Hardcore mode. Unknown dangers lurk around every corner, and it's better to proceed with caution than to rush in blindly.",
|
||||
L"Equip gear that complements your playstyle and provides the best possible protection against enemy attacks. Prioritize defensive bonuses and resistances over offensive stats in Hardcore mode.",
|
||||
L"Stay informed about the strengths and weaknesses of different enemy types. Knowing your foes is essential for developing effective strategies and staying alive in Hardcore Ironman.",
|
||||
L"Practice patience and perseverance in Hardcore mode. Success often requires multiple attempts and learning from your mistakes.",
|
||||
L"Develop a backup plan for emergencies, such as a stash of emergency potions or a hidden escape route. Always have a contingency plan in place in Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and communicate effectively to overcome challenges together. Teamwork is essential for survival in Hardcore Ironman.",
|
||||
L"Stay vigilant and be prepared for anything in Hardcore mode. Unexpected dangers and challenges can arise at any moment, and it's important to stay alert.",
|
||||
L"Learn from your mistakes and use them as opportunities for growth. Every death is a chance to refine your strategies and become a better Hardcore player.",
|
||||
L"Stock up on essential supplies like potions, scrolls, and emergency gear. You never know when you'll need them in Hardcore mode.",
|
||||
L"Plan your routes carefully and avoid unnecessary risks. Rushing into danger blindly is a surefire way to meet an untimely demise in Hardcore Ironman.",
|
||||
L"Stay adaptable and be prepared to adjust your tactics on the fly. Flexibility is key to surviving the ever-changing challenges of Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and work together to overcome challenges. Teamwork is essential for success in Hardcore Ironman.",
|
||||
L"Be cautious when exploring new areas, especially in Hardcore mode. Unknown dangers lurk around every corner, and it's better to proceed with caution than to rush in blindly.",
|
||||
L"Equip gear that complements your playstyle and provides the best possible protection against enemy attacks. Prioritize defensive bonuses and resistances over offensive stats in Hardcore mode.",
|
||||
L"Stay informed about the strengths and weaknesses of different enemy types. Knowing your foes is essential for developing effective strategies and staying alive in Hardcore Ironman.",
|
||||
L"Practice patience and perseverance in Hardcore mode. Success often requires multiple attempts and learning from your mistakes.",
|
||||
L"Develop a backup plan for emergencies, such as a stash of emergency potions or a hidden escape route. Always have a contingency plan in place in Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and communicate effectively to overcome challenges together. Teamwork is essential for survival in Hardcore Ironman.",
|
||||
L"Stay vigilant and be prepared for anything in Hardcore mode. Unexpected dangers and challenges can arise at any moment, and it's important to stay alert.",
|
||||
L"Learn from your mistakes and use them as opportunities for growth. Every death is a chance to refine your strategies and become a better Hardcore player.",
|
||||
L"Stock up on essential supplies like potions, scrolls, and emergency gear. You never know when you'll need them in Hardcore mode.",
|
||||
L"Plan your routes carefully and avoid unnecessary risks. Rushing into danger blindly is a surefire way to meet an untimely demise in Hardcore Ironman.",
|
||||
L"Stay adaptable and be prepared to adjust your tactics on the fly. Flexibility is key to surviving the ever-changing challenges of Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and work together to overcome challenges. Teamwork is essential for success in Hardcore Ironman.",
|
||||
L"Be cautious when exploring new areas, especially in Hardcore mode. Unknown dangers lurk around every corner, and it's better to proceed with caution than to rush in blindly.",
|
||||
L"Equip gear that complements your playstyle and provides the best possible protection against enemy attacks. Prioritize defensive bonuses and resistances over offensive stats in Hardcore mode.",
|
||||
L"Stay informed about the strengths and weaknesses of different enemy types. Knowing your foes is essential for developing effective strategies and staying alive in Hardcore Ironman.",
|
||||
L"Practice patience and perseverance in Hardcore mode. Success often requires multiple attempts and learning from your mistakes.",
|
||||
L"Develop a backup plan for emergencies, such as a stash of emergency potions or a hidden escape route. Always have a contingency plan in place in Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and communicate effectively to overcome challenges together. Teamwork is essential for survival in Hardcore Ironman.",
|
||||
L"Stay vigilant and be prepared for anything in Hardcore mode. Unexpected dangers and challenges can arise at any moment, and it's important to stay alert.",
|
||||
L"Learn from your mistakes and use them as opportunities for growth. Every death is a chance to refine your strategies and become a better Hardcore player.",
|
||||
L"Stock up on essential supplies like potions, scrolls, and emergency gear. You never know when you'll need them in Hardcore mode.",
|
||||
L"Plan your routes carefully and avoid unnecessary risks. Rushing into danger blindly is a surefire way to meet an untimely demise in Hardcore Ironman.",
|
||||
L"Stay adaptable and be prepared to adjust your tactics on the fly. Flexibility is key to surviving the ever-changing challenges of Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and work together to overcome challenges. Teamwork is essential for success in Hardcore Ironman.",
|
||||
L"Be cautious when exploring new areas, especially in Hardcore mode. Unknown dangers lurk around every corner, and it's better to proceed with caution than to rush in blindly.",
|
||||
L"Equip gear that complements your playstyle and provides the best possible protection against enemy attacks. Prioritize defensive bonuses and resistances over offensive stats in Hardcore mode.",
|
||||
L"Stay informed about the strengths and weaknesses of different enemy types. Knowing your foes is essential for developing effective strategies and staying alive in Hardcore Ironman.",
|
||||
L"Practice patience and perseverance in Hardcore mode. Success often requires multiple attempts and learning from your mistakes.",
|
||||
L"Develop a backup plan for emergencies, such as a stash of emergency potions or a hidden escape route. Always have a contingency plan in place in Hardcore mode.",
|
||||
L"Coordinate your actions with your party members and communicate effectively to overcome challenges together. Teamwork is essential for survival in Hardcore Ironman.",
|
||||
L"Stay vigilant and be prepared for anything in Hardcore mode. Unexpected dangers and challenges can arise at any moment, and it's important to stay alert.",
|
||||
L"Learn from your mistakes and use them as opportunities for growth. Every death is a chance to refine your strategies and become a better Hardcore player.",
|
||||
|
||||
L"Stock up on essential supplies like potions, scrolls, and emergency gear. You never know when you'll need them in Hardcore mode.",
|
||||
|
||||
L"In Hardcore Ironman, your character's survival is paramount above all else. Every decision you make, every action you take, should be with the singular goal of keeping your character alive in the unforgiving world of Diablo 2.",
|
||||
L"Before engaging enemies or venturing into unknown territory, take the time to thoroughly scout your surroundings. Look for potential threats, plan escape routes, and assess the level of danger you may face.",
|
||||
L"With town portals disabled, strategic planning becomes even more critical. Always have a backup plan in place for emergencies, whether it's knowing the location of the nearest waypoint or having a stash of emergency supplies hidden away.",
|
||||
L"Effective inventory management can mean the difference between life and death in Hardcore mode. Organize your inventory carefully, prioritize essential items such as potions and scrolls, and be mindful of your carrying capacity at all times.",
|
||||
L"When facing challenging foes or uncertain situations, don't hesitate to retreat and regroup if necessary. Survival in Hardcore Ironman requires patience, caution, and a willingness to make strategic withdrawals when the odds are against you.",
|
||||
L"Experiment with different skill builds and character setups to find what works best for your playstyle and the challenges you face. Adaptability and versatility are key attributes for success in Hardcore mode.",
|
||||
L"Stay vigilant and be constantly aware of your surroundings. Traps, ambushes, and environmental hazards can pose just as much of a threat as enemy attacks, so always proceed with caution and remain alert.",
|
||||
L"Equip gear that emphasizes defense and survivability over offensive power. Prioritize items with high resistances, damage reduction, and life-saving bonuses to maximize your chances of survival in Hardcore Ironman.",
|
||||
L"Your mercenary companion can be a valuable asset in Hardcore mode, providing additional firepower, support, and distraction in battle. Invest in their equipment and skills wisely to ensure they can effectively complement your own abilities.",
|
||||
L"In multiplayer games, effective communication and cooperation are essential for survival. Coordinate with your party members, share information about enemy locations and tactics, and work together to overcome challenges.",
|
||||
|
||||
L"Stay informed about the latest updates, patches, and strategies in the Diablo 2 community. Knowledge is power in Hardcore mode, and staying up-to-date with the latest developments can give you a significant advantage.",
|
||||
L"Develop a contingency plan for emergencies. Whether it's having a reserve of emergency potions, escape routes planned out in advance, or backup characters ready to take over in case of death, always be prepared for the worst-case scenario.",
|
||||
L"Practice patience and resilience in the face of adversity. Setbacks and challenges are inevitable in Hardcore Ironman, but maintaining a positive mindset and persevering through tough times is key to ultimate success.",
|
||||
L"Build connections with other Hardcore players and join communities or forums where you can share tips, strategies, and experiences. Learning from the insights of others can help you improve your own Hardcore gameplay.",
|
||||
L"Trust your instincts and intuition when navigating the dangers of Hardcore mode. If something feels too risky or dangerous, don't hesitate to err on the side of caution and take a safer approach.",
|
||||
L"Embrace the thrill and challenge of Hardcore Ironman, and savor the adrenaline rush that comes with narrowly escaping death. The high stakes and permanent consequences make every victory all the more rewarding in Hardcore mode.",
|
||||
L"Maintain discipline and avoid taking unnecessary risks that could jeopardize your character's survival. Exercise caution in all your actions, and remember that one careless mistake could cost you dearly in Hardcore Ironman.",
|
||||
L"Keep a clear mind and remain focused, especially during intense or dangerous situations. Panic and anxiety can cloud your judgment and lead to fatal errors in Hardcore mode, so strive to stay calm and composed at all times.",
|
||||
L"Learn from your mistakes and use each death as an opportunity for growth and improvement. Analyze what went wrong, identify areas for improvement, and apply those lessons to future gameplay to become a stronger Hardcore player.",
|
||||
L"Be vigilant and attentive to your surroundings, as danger can lurk around every corner in Hardcore mode. Take nothing for granted, and always be prepared to react quickly to unexpected threats or challenges.",
|
||||
L"Prioritize defensive capabilities and survival skills when choosing gear and allocating skill points. A sturdy defense and reliable survivability are essential for weathering the dangers of Hardcore Ironman.",
|
||||
L"Stock up on essential supplies such as potions, scrolls, and emergency gear to ensure you're always prepared for whatever challenges may arise in Hardcore mode. It's better to have too much than too little when your life is on the line.",
|
||||
L"Plan your routes and engagements carefully, avoiding unnecessary risks and ensuring you always have a viable escape plan. Rushing headlong into danger is a surefire way to meet an untimely end in Hardcore Ironman.",
|
||||
L"Remain adaptable and flexible in your approach, adjusting your tactics and strategies as needed to overcome the ever-changing challenges of Hardcore mode. The ability to think on your feet and adapt to new situations is crucial for survival.",
|
||||
L"Communicate effectively with your party members in multiplayer games, coordinating your actions and sharing information to maximize your chances of success. Teamwork is essential for conquering the toughest challenges in Hardcore Ironman.",
|
||||
L"Exercise caution and prudence when exploring new areas, taking care to avoid potential traps, ambushes, and other hazards that could spell doom for your character. Proceed with caution and always be prepared for the unexpected.",
|
||||
L"Equip gear that emphasizes defensive bonuses and survivability over raw offensive power, prioritizing items that offer high resistances, damage reduction, and other life-saving properties. In Hardcore mode, staying alive is the ultimate goal.",
|
||||
L"Study the strengths and weaknesses of different enemy types, learning their attack patterns and behaviors to better anticipate and counter their threats. Knowledge is power in Hardcore Ironman, and understanding your foes is key to victory.",
|
||||
L"Embrace the virtues of patience and perseverance, knowing that success in Hardcore mode often requires multiple attempts and learning from your mistakes. Stay determined and keep pushing forward, even in the face of adversity.",
|
||||
L"Develop a backup plan for emergencies, ensuring you have contingencies in place for unexpected situations such as running out of potions or finding yourself cornered by powerful enemies. Preparation is key to survival in Hardcore Ironman.",
|
||||
L"Coordinate your actions with your party members, leveraging each other's strengths and abilities to overcome challenges that would be insurmountable alone. In Hardcore mode, teamwork can mean the difference between life and death.",
|
||||
L"Remain vigilant and alert at all times, keeping a watchful eye on your surroundings and being prepared to react swiftly to any threats or dangers that may arise. In Hardcore Ironman, constant vigilance is essential for survival.",
|
||||
L"Learn from your mistakes and use each death as an opportunity for growth and improvement. Analyze what went wrong, identify areas for improvement, and apply those lessons to your future gameplay to become a stronger and more resilient Hardcore player.",
|
||||
L"Stock up on essential supplies such as potions, scrolls, and emergency gear to ensure you're always prepared for whatever challenges may arise in Hardcore mode. It's better to have too much than too little when your life is on the line.",
|
||||
L"Plan your routes and engagements carefully, avoiding unnecessary risks and ensuring you always have a viable escape plan. Rushing headlong into danger is a surefire way to meet an untimely end in Hardcore Ironman.",
|
||||
L"Remain adaptable and flexible in your approach, adjusting your tactics and strategies as needed to overcome the ever-changing challenges of Hardcore mode. The ability to think on your feet and adapt to new situations is crucial for survival.",
|
||||
L"Communicate effectively with your party members in multiplayer games, coordinating your actions and sharing information to maximize your chances of success. Teamwork is essential for conquering the toughest challenges in Hardcore Ironman.",
|
||||
L"Exercise caution and prudence when exploring new areas, taking care to avoid potential traps, ambushes, and other hazards that could spell doom for your character. Proceed with caution and always be prepared for the unexpected.",
|
||||
L"Equip gear that emphasizes defensive bonuses and survivability over raw offensive power, prioritizing items that offer high resistances, damage reduction, and other life-saving properties. In Hardcore mode, staying alive is the ultimate goal.",
|
||||
L"Study the strengths and weaknesses of different enemy types, learning their attack patterns and behaviors to better anticipate and counter their threats. Knowledge is power in Hardcore Ironman, and understanding your foes is key to victory.",
|
||||
L"Embrace the virtues of patience and perseverance, knowing that success in Hardcore mode often requires multiple attempts and learning from your mistakes. Stay determined and keep pushing forward, even in the face of adversity.",
|
||||
L"Develop a backup plan for emergencies, ensuring you have contingencies in place for unexpected situations such as running out of potions or finding yourself cornered by powerful enemies. Preparation is key to survival in Hardcore Ironman.",
|
||||
L"Coordinate your actions with your party members, leveraging each other's strengths and abilities to overcome challenges that would be insurmountable alone. In Hardcore mode, teamwork can mean the difference between life and death.",
|
||||
L"Remain vigilant and alert at all times, keeping a watchful eye on your surroundings and being prepared to react swiftly to any threats or dangers that may arise. In Hardcore Ironman, constant vigilance is essential for survival.",
|
||||
|
||||
L"In Hardcore Ironman, survival is your top priority. Every decision you make, every action you take, should be with the singular goal of keeping your character alive in the unforgiving world of Diablo 2.",
|
||||
L"Before engaging enemies or venturing into unknown territory, take the time to thoroughly scout your surroundings. Look for potential threats, plan escape routes, and assess the level of danger you may face.",
|
||||
L"With town portals disabled, strategic planning becomes even more critical. Always have a backup plan in place for emergencies, whether it's knowing the location of the nearest waypoint or having a stash of emergency supplies hidden away.",
|
||||
L"Effective inventory management can mean the difference between life and death in Hardcore mode. Organize your inventory carefully, prioritize essential items such as potions and scrolls, and be mindful of your carrying capacity at all times.",
|
||||
L"When facing challenging foes or uncertain situations, don't hesitate to retreat and regroup if necessary. Survival in Hardcore Ironman requires patience, caution, and a willingness to make strategic withdrawals when the odds are against you.",
|
||||
L"Experiment with different skill builds and character setups to find what works best for your playstyle and the challenges you face. Adaptability and versatility are key attributes for success in Hardcore mode.",
|
||||
L"Stay vigilant and be constantly aware of your surroundings. Traps, ambushes, and environmental hazards can pose just as much of a threat as enemy attacks, so always proceed with caution and remain alert.",
|
||||
L"Equip gear that emphasizes defense and survivability over offensive power. Prioritize items with high resistances, damage reduction, and life-saving bonuses to maximize your chances of survival in Hardcore Ironman.",
|
||||
L"Your mercenary companion can be a valuable asset in Hardcore mode, providing additional firepower, support, and distraction in battle. Invest in their equipment and skills wisely to ensure they can effectively complement your own abilities.",
|
||||
L"In multiplayer games, effective communication and cooperation are essential for survival. Coordinate with your party members, share information about enemy locations and tactics, and work together to overcome challenges and dangers.",
|
||||
L"Stay informed about the latest updates, patches, and strategies in the Diablo 2 community. Knowledge is power in Hardcore mode, and staying up-to-date with the latest developments can give you a significant advantage.",
|
||||
L"Develop a contingency plan for emergencies. Whether it's having a reserve of emergency potions, escape routes planned out in advance, or backup characters ready to take over in case of death, always be prepared for the worst-case scenario.",
|
||||
L"Practice patience and resilience in the face of adversity. Setbacks and challenges are inevitable in Hardcore Ironman, but maintaining a positive mindset and persevering through tough times is key to ultimate success.",
|
||||
L"Build connections with other Hardcore players and join communities or forums where you can share tips, strategies, and experiences. Learning from the insights of others can help you improve your own Hardcore gameplay.",
|
||||
L"Trust your instincts and intuition when navigating the dangers of Hardcore mode. If something feels too risky or dangerous, don't hesitate to err on the side of caution and take a safer approach.",
|
||||
L"Embrace the thrill and challenge of Hardcore Ironman, and savor the adrenaline rush that comes with narrowly escaping death. The high stakes and permanent consequences make every victory all the more rewarding in Hardcore mode.",
|
||||
L"Maintain discipline and avoid taking unnecessary risks that could jeopardize your character's survival. Exercise caution in all your actions, and remember that one careless mistake could cost you dearly in Hardcore Ironman.",
|
||||
L"Keep a clear mind and remain focused, especially during intense or dangerous situations. Panic and anxiety can cloud your judgment and lead to fatal errors in Hardcore mode, so strive to stay calm and composed at all times.",
|
||||
L"Learn from your mistakes and use each death as an opportunity for growth and improvement. Analyze what went wrong, identify areas for improvement, and apply those lessons to future gameplay to become a stronger Hardcore player.",
|
||||
L"Be vigilant and attentive to your surroundings, as danger can lurk around every corner in Hardcore mode. Take nothing for granted, and always be prepared to react quickly to unexpected threats or challenges.",
|
||||
L"Prioritize defensive capabilities and survival skills when choosing gear and allocating skill points. A sturdy defense and reliable survivability are essential for weathering the dangers of Hardcore Ironman.",
|
||||
L"Stock up on essential supplies such as potions, scrolls, and emergency gear to ensure you're always prepared for whatever challenges may arise in Hardcore mode. It's better to have too much than too little when your life is on the line.",
|
||||
L"Plan your routes and engagements carefully, avoiding unnecessary risks and ensuring you always have a viable escape plan. Rushing headlong into danger is a surefire way to meet an untimely end in Hardcore Ironman.",
|
||||
L"Remain adaptable and flexible in your approach, adjusting your tactics and strategies as needed to overcome the ever-changing challenges of Hardcore mode. The ability to think on your feet and adapt to new situations is crucial for survival.",
|
||||
L"Communicate effectively with your party members in multiplayer games, coordinating your actions and sharing information to maximize your chances of success. Teamwork is essential for conquering the toughest challenges in Hardcore Ironman.",
|
||||
L"Exercise caution and prudence when exploring new areas, taking care to avoid potential traps, ambushes, and other hazards that could spell doom for your character. Proceed with caution and always be prepared for the unexpected.",
|
||||
L"Equip gear that emphasizes defensive bonuses and survivability over raw offensive power, prioritizing items that offer high resistances, damage reduction, and other life-saving properties. In Hardcore mode, staying alive is the ultimate goal.",
|
||||
L"Study the strengths and weaknesses of different enemy types, learning their attack patterns and behaviors to better anticipate and counter their threats. Knowledge is power in Hardcore Ironman, and understanding your foes is key to victory.",
|
||||
L"Embrace the virtues of patience and perseverance, knowing that success in Hardcore mode often requires multiple attempts and learning from your mistakes. Stay determined and keep pushing forward, even in the face of adversity.",
|
||||
L"Develop a backup plan for emergencies, ensuring you have contingencies in place for unexpected situations such as running out of potions or finding yourself cornered by powerful enemies. Preparation is key to survival in Hardcore Ironman.",
|
||||
L"Coordinate your actions with your party members, leveraging each other's strengths and abilities to overcome challenges that would be insurmountable alone. In Hardcore mode, teamwork can mean the difference between life and death.",
|
||||
L"Remain vigilant and alert at all times, keeping a watchful eye on your surroundings and being prepared to react swiftly to any threats or dangers that may arise. In Hardcore Ironman, constant vigilance is essential for survival.",
|
||||
L"Learn from your mistakes and use each death as an opportunity for growth and improvement. Analyze what went wrong, identify areas for improvement, and apply those lessons to your future gameplay to become a stronger and more resilient Hardcore player.",
|
||||
L"Stock up on essential supplies such as potions, scrolls, and emergency gear to ensure you're always prepared for whatever challenges may arise in Hardcore mode. It's better to have too much than too little when your life is on the line.",
|
||||
L"Plan your routes and engagements carefully, avoiding unnecessary risks and ensuring you always have a viable escape plan. Rushing headlong into danger is a surefire way to meet an untimely end in Hardcore Ironman.",
|
||||
L"Remain adaptable and flexible in your approach, adjusting your tactics and strategies as needed to overcome the ever-changing challenges of Hardcore mode. The ability to think on your feet and adapt to new situations is crucial for survival.",
|
||||
L"Communicate effectively with your party members in multiplayer games, coordinating your actions and sharing information to maximize your chances of success. Teamwork is essential for conquering the toughest challenges in Hardcore Ironman.",
|
||||
L"Exercise caution and prudence when exploring new areas, taking care to avoid potential traps, ambushes, and other hazards that could spell doom for your character. Proceed with caution and always be prepared for the unexpected.",
|
||||
L"Equip gear that emphasizes defensive bonuses and survivability over raw offensive power, prioritizing items that offer high resistances, damage reduction, and other life-saving properties. In Hardcore mode, staying alive is the ultimate goal.",
|
||||
L"Study the strengths and weaknesses of different enemy types, learning their attack patterns and behaviors to better anticipate and counter their threats. Knowledge is power in Hardcore Ironman, and understanding your foes is key to victory.",
|
||||
L"Embrace the virtues of patience and perseverance, knowing that success in Hardcore mode often requires multiple attempts and learning from your mistakes. Stay determined and keep pushing forward, even in the face of adversity.",
|
||||
L"Develop a backup plan for emergencies, ensuring you have contingencies in place for unexpected situations such as running out of potions or finding yourself cornered by powerful enemies. Preparation is key to survival in Hardcore Ironman.",
|
||||
L"Coordinate your actions with your party members, leveraging each other's strengths and abilities to overcome challenges that would be insurmountable alone. In Hardcore mode, teamwork can mean the difference between life and death.",
|
||||
L"Remain vigilant and alert at all times, keeping a watchful eye on your surroundings and being prepared to react swiftly to any threats or dangers that may arise. In Hardcore Ironman, constant vigilance is essential for survival."
|
||||
|
||||
L"In Hardcore Ironman, the safety of your character is paramount. Every action you take should be calculated to ensure survival in the unforgiving world of Diablo 2. Take the time to carefully assess your surroundings, anticipate potential threats, and plan your actions accordingly.",
|
||||
L"With town portals disabled, strategic planning becomes even more crucial. Always have an exit strategy in mind, whether it's knowing the location of the nearest waypoint or having a designated escape route planned out in advance.",
|
||||
L"Effective inventory management is essential for survival in Hardcore mode. Keep your inventory organized, prioritize essential items such as potions and scrolls, and be mindful of your carrying capacity at all times.",
|
||||
L"When facing tough enemies or uncertain situations, don't be afraid to retreat and regroup if necessary. Survival in Hardcore Ironman requires patience, caution, and a willingness to reassess your approach when the odds are against you.",
|
||||
L"Experiment with different skill builds, character setups, and equipment combinations to find what works best for your playstyle and the challenges you encounter. Adaptability and versatility are key attributes for success in Hardcore mode.",
|
||||
L"Stay vigilant and remain constantly aware of your surroundings. Traps, ambushes, and environmental hazards can be just as deadly as enemy attacks, so always proceed with caution and keep your senses sharp.",
|
||||
L"Equip gear that prioritizes defense and survivability over offensive power. Look for items with high resistances, damage reduction, and life-saving bonuses to increase your chances of surviving the dangers of Hardcore Ironman.",
|
||||
L"Your mercenary companion can provide valuable support in Hardcore mode, serving as an additional source of damage, crowd control, and distraction in battle. Invest in their equipment and skills to ensure they can effectively complement your own abilities.",
|
||||
L"In multiplayer games, effective communication and cooperation are crucial for success. Coordinate with your party members, share information about enemy locations and tactics, and work together to overcome challenges and dangers.",
|
||||
L"Stay informed about the latest developments and strategies in the Diablo 2 community. Knowledge is power in Hardcore mode, and staying up-to-date with the latest information can give you a significant advantage.",
|
||||
L"Develop contingency plans for emergencies. Whether it's having a stash of emergency potions, designated escape routes planned out in advance, or backup characters ready to take over in case of death, always be prepared for the worst-case scenario.",
|
||||
L"Practice patience and resilience in the face of adversity. Setbacks and challenges are inevitable in Hardcore Ironman, but maintaining a positive attitude and persevering through tough times is essential for ultimate success.",
|
||||
L"Build connections with other Hardcore players and participate in communities or forums where you can share tips, strategies, and experiences. Learning from the insights of others can help you improve your own Hardcore gameplay.",
|
||||
L"Trust your instincts and intuition when navigating the dangers of Hardcore mode. If something feels too risky or dangerous, don't hesitate to err on the side of caution and take a safer approach.",
|
||||
L"Embrace the excitement and challenge of Hardcore Ironman, and relish the adrenaline rush that comes with narrowly escaping death. The high stakes and permanent consequences make every victory all the more satisfying in Hardcore mode.",
|
||||
L"Maintain discipline and avoid taking unnecessary risks that could jeopardize your character's survival. Exercise caution in all your actions, and remember that one careless mistake could cost you dearly in Hardcore Ironman.",
|
||||
L"Keep a clear head and stay focused, especially during intense or dangerous situations. Panic and fear can cloud your judgment and lead to fatal errors in Hardcore mode, so strive to remain calm and composed at all times.",
|
||||
L"Learn from your mistakes and view each death as an opportunity for growth and improvement. Analyze what went wrong, identify areas for improvement, and apply those lessons to your future gameplay to become a stronger Hardcore player.",
|
||||
L"Be vigilant and observant of your surroundings, as danger can lurk around every corner in Hardcore mode. Take nothing for granted, and always be prepared to react swiftly to unexpected threats or challenges.",
|
||||
L"Prioritize defensive capabilities and survival skills when choosing gear and allocating skill points. A solid defense and reliable survivability are essential for withstanding the dangers of Hardcore Ironman.",
|
||||
L"Stock up on essential supplies such as potions, scrolls, and emergency gear to ensure you're always prepared for whatever challenges may arise in Hardcore mode. It's better to have too much than too little when your life is on the line.",
|
||||
L"Plan your routes and engagements carefully, avoiding unnecessary risks and ensuring you always have a viable escape plan. Charging headlong into danger is a surefire way to meet an untimely end in Hardcore Ironman.",
|
||||
L"Remain adaptable and flexible in your approach, adjusting your tactics and strategies as needed to overcome the ever-changing challenges of Hardcore mode. The ability to think on your feet and adapt to new situations is crucial for survival.",
|
||||
L"Communicate effectively with your party members in multiplayer games, coordinating your actions and sharing information to maximize your chances of success. Teamwork is essential for overcoming the toughest challenges in Hardcore Ironman.",
|
||||
L"Exercise caution and prudence when exploring new areas, taking care to avoid potential traps, ambushes, and other hazards that could spell doom for your character. Proceed with caution and always be prepared for the unexpected.",
|
||||
L"Equip gear that emphasizes defensive bonuses and survivability over raw offensive power, prioritizing items that offer high resistances, damage reduction, and other life-saving properties. In Hardcore mode, staying alive is paramount.",
|
||||
L"Study the strengths and weaknesses of different enemy types, familiarizing yourself with their attack patterns and behaviors to better anticipate and counter their threats. Knowledge is power in Hardcore Ironman, and understanding your foes is key to victory.",
|
||||
L"Embrace the virtues of patience and perseverance, recognizing that success in Hardcore mode often requires multiple attempts and learning from your mistakes. Stay determined and keep pushing forward, even when the odds seem stacked against you.",
|
||||
L"Develop backup plans for emergencies, ensuring you have contingencies in place for unexpected situations such as running out of potions or finding yourself cornered by powerful enemies. Preparation is key to survival in Hardcore Ironman.",
|
||||
L"Coordinate your actions with your party members, leveraging each other's strengths and abilities to overcome challenges that would be insurmountable alone. In Hardcore mode, teamwork can be the difference between life and death.",
|
||||
L"Remain vigilant and alert at all times, maintaining a keen awareness of your surroundings and being prepared to react swiftly to any threats or dangers that may arise. In Hardcore Ironman, constant vigilance is essential for survival.",
|
||||
L"Learn from your mistakes and view each death as an opportunity for growth and improvement. Reflect on what went wrong, identify areas for improvement, and apply those lessons to your future gameplay to become a more skilled Hardcore player.",
|
||||
L"Stock up on essential supplies such as potions, scrolls, and emergency gear to ensure you're always prepared for whatever challenges may arise in Hardcore mode. It's better to have too much than too little when your life is on the line.",
|
||||
L"Plan your routes and engagements carefully, avoiding unnecessary risks and ensuring you always have a viable escape plan. Charging headlong into danger is a surefire way to meet an untimely end in Hardcore Ironman.",
|
||||
L"Remain adaptable and flexible in your approach, adjusting your tactics and strategies as needed to overcome the ever-changing challenges of Hardcore mode. The ability to think on your feet and adapt to new situations is crucial for survival.",
|
||||
L"Communicate effectively with your party members in multiplayer games, coordinating your actions and sharing information to maximize your chances of success. Teamwork is essential for overcoming the toughest challenges in Hardcore Ironman.",
|
||||
L"Exercise caution and prudence when exploring new areas, taking care to avoid potential traps, ambushes, and other hazards that could spell doom for your character. Proceed with caution and always be prepared for the unexpected.",
|
||||
L"Equip gear that emphasizes defensive bonuses and survivability over raw offensive power, prioritizing items that offer high resistances, damage reduction, and other life-saving properties. In Hardcore mode, staying alive is paramount.",
|
||||
L"Study the strengths and weaknesses of different enemy types, familiarizing yourself with their attack patterns and behaviors to better anticipate and counter their threats. Knowledge is power in Hardcore Ironman, and understanding your foes is key to victory.",
|
||||
L"Embrace the virtues of patience and perseverance, recognizing that success in Hardcore mode often requires multiple attempts and learning from your mistakes. Stay determined and keep pushing forward, even when the odds seem stacked against you.",
|
||||
L"Develop backup plans for emergencies, ensuring you have contingencies in place for unexpected situations such as running out of potions or finding yourself cornered by powerful enemies. Preparation is key to survival in Hardcore Ironman.",
|
||||
L"Coordinate your actions with your party members, leveraging each other's strengths and abilities to overcome challenges that would be insurmountable alone. In Hardcore mode, teamwork can be the difference between life and death.",
|
||||
L"Remain vigilant and alert at all times, maintaining a keen awareness of your surroundings and being prepared to react swiftly to any threats or dangers that may arise. In Hardcore Ironman, constant vigilance is essential for survival.",
|
||||
|
||||
L"Discover the vast array of new sets introduced in the latest update, each offering unique bonuses and playstyles to explore. Experiment with different combinations to find the perfect set for your character's build and playstyle.",
|
||||
L"Explore the expansive collection of over 1400 new unique items, each with its own distinct attributes, affixes, and effects. From powerful weapons to protective armor, there's something for every type of character and playstyle.",
|
||||
L"Unlock the potential of hundreds of new runewords, each offering powerful bonuses and enhancements when socketed into your gear. Experiment with different combinations of runes to create the perfect runeword for your character's needs.",
|
||||
L"Delve into the world of gemwords, where combining multiple gems in your gear unlocks powerful bonuses and effects. With hundreds of gemwords to discover, there's endless potential for customization and optimization.",
|
||||
L"Discover the versatility of stonewords, which combine Diablo 3 gems with existing items to create powerful new gear with enhanced properties. Experiment with different gem combinations to find the perfect stoneword for your character.",
|
||||
L"Maximize the efficiency of your inventory management by utilizing the Magic Essence Harvester to extract essence from unwanted items. Convert magic, rare, set, or unique items into essence points, which can then be used to create new items and mods.",
|
||||
L"Utilize the Magic Essence Points obtained from the Harvester to create a wide variety of magic items and modifications. Whether you're enhancing existing gear or creating entirely new items, the possibilities are endless with Magic Essence Points.",
|
||||
L"Enhance your arsenal by using Rare Shards, Set Stones, or Unique Particles to create rare, set, and unique versions of items. Visit the NPC in town to access this feature and unlock the full potential of your gear.",
|
||||
L"Take advantage of Smithing Hammers, a new item type that drops in-game, to produce base item types for crafting custom gear. Use these base items as the foundation for creating powerful and unique equipment tailored to your character's needs.",
|
||||
L"Make use of the Item Salvager to break down white items and obtain valuable item parts for crafting. With a variety of salvaging options available, you can extract parts from different item qualities to fuel your crafting endeavors.",
|
||||
L"Explore the vast array of cube recipes added to the salvaging system, offering over 2,000 new combinations for extracting item parts and materials. Experiment with different recipes to discover the most efficient ways to salvage items and obtain resources.",
|
||||
L"Discover the excitement of Demon Souls and Spirits, which can be obtained from defeated demons. These unique drops offer valuable bonuses and enhancements, providing new opportunities for character customization and power-ups.",
|
||||
L"Organize your collection of gems and runes with Gem Bags and Rune Bags, which allow you to store and manage your precious resources more efficiently. With the ability to stack gems and runes up to 100 each, you'll have plenty of space for your collection.",
|
||||
L"Unlock the potential of full hireling inventory, allowing your hired companions to equip additional items such as belts, boots, gloves, rings, and amulets. Customize your hirelings to suit your needs and maximize their effectiveness in battle.",
|
||||
L"Access your stash from anywhere with the Remote Stash feature, which drops after achieving 10,000 kills. Enjoy the convenience of managing your inventory on the go, without the need to return to town or find a stash.",
|
||||
L"Increase your killcounter stat by slaying monsters and unlocking various bonuses and rewards based on your kill count. From healing potions to rare weapons and armor, there are plenty of incentives to keep pushing forward and defeating enemies.",
|
||||
L"Unlock Demon Chests and Keys by combining demon drops to receive random items of varying qualities. Experiment with different combinations to discover the treasures hidden within these mysterious chests.",
|
||||
L"Maximize the potential of your gear by socketing gems and runes into almost every item type, including helms, charms, boots, rings, amulets, shields, and belts. Customize your equipment to suit your playstyle and optimize your character's abilities.",
|
||||
L"Discover a wide range of magic, rare, and unique arrows and bolts, each offering unique properties and effects to enhance your ranged combat abilities. Experiment with different types to find the perfect ammunition for your character.",
|
||||
L"Unlock the power of magic, rare, and unique charms to bolster your character's stats and abilities. Whether you're seeking increased damage, resistance, or utility, there's a charm out there to suit your needs.",
|
||||
L"Explore the world of summoner doll charms, which offer unique bonuses and effects related to summoning and pet abilities. Enhance your summoner build with these specialized charms and unleash the full potential of your minions.",
|
||||
L"Experience the thrill of the Charmzone, where charms can only be utilized in the bottom four rows of your inventory. Strategically manage your charm inventory to optimize your character's performance in battle.",
|
||||
L"Collect monster body parts dropped by defeated enemies and use them to craft various items and enhancements. From resistance potions to elemental essences, there's a wide range of possibilities to explore with monster body parts.",
|
||||
L"Enhance your character's resistance capabilities with a variety of resistance potions, including fire, magic, poison, and lightning resistance. Stock up on these valuable consumables to bolster your defenses against elemental threats.",
|
||||
L"Dive into the Hardcore Ironman game mode, where survival is your top priority and every decision could mean life or death. With gold disabled and town portals replaced by waypoints, strategic gameplay and resource management are essential for success.",
|
||||
L"Experience the unique challenges of Hardcore Ironman, where underused skills become valuable and vitality is crucial for survival. Experiment with different weapons and strategies to overcome the dangers of this unforgiving game mode.",
|
||||
L"Prepare for the ultimate test of skill and strategy as you venture into Hardcore Ironman mode, where the stakes are high and the risks are greater than ever before. With gold rendered useless and town portals disabled, only the bravest adventurers will survive.",
|
||||
L"Master the art of survival in Hardcore Ironman mode, where every decision could mean the difference between life and death. With gold eliminated from the game and town portals disabled, strategic planning and careful resource management are essential for success.",
|
||||
L"Immerse yourself in the Hardcore Ironman experience, where the thrill of danger and the rush of victory await at every turn. With gold removed from the equation and town portals disabled, only the strongest and most resourceful adventurers will prevail.",
|
||||
L"Embark on a journey into the heart of darkness with Hardcore Ironman mode, where the challenges are greater, the risks are higher, and the rewards are more satisfying than ever before. Will you have what it takes to survive in this unforgiving world?",
|
||||
L"Test your skills and resilience in Hardcore Ironman mode, where every decision carries weight and every encounter could be your last. With gold no longer a factor and town portals disabled, only the most cunning and resourceful players will emerge victorious.",
|
||||
L"Challenge yourself to new heights of difficulty with Hardcore Ironman mode, where the stakes are higher, the dangers are greater, and the rewards are more satisfying than ever before. Can you overcome the ultimate test of skill and strategy?",
|
||||
L"Prepare for the ultimate test of survival in Hardcore Ironman mode, where every step could be your last and every decision could mean life or death. With gold out of the picture and town portals disabled, only the bravest adventurers will dare to venture forth.",
|
||||
L"Experience the adrenaline-fueled excitement of Hardcore Ironman mode, where danger lurks around every corner and death is always one misstep away. With gold rendered useless and town portals disabled, only the strongest and most resourceful heroes will prevail.",
|
||||
L"Dive into the heart of darkness with Hardcore Ironman mode, where the challenges are greater, the risks are higher, and the rewards are more satisfying than ever before. Will you have what it takes to conquer the perils that await?",
|
||||
L"Test your mettle in Hardcore Ironman mode, where survival is the ultimate goal and every decision could mean life or death. With gold eliminated from the game and town portals disabled, only the most skilled and determined adventurers will emerge victorious.",
|
||||
L"Prepare yourself for the ultimate challenge with Hardcore Ironman mode, where danger lurks around every corner and death is always a possibility. With gold removed from the equation and town portals disabled, only the bravest souls will dare to face the darkness.",
|
||||
L"Embark on an epic journey into the unknown with Hardcore Ironman mode, where the challenges are greater, the dangers are deadlier, and the rewards are more satisfying than ever before. Will you have what it takes to survive in this unforgiving world?",
|
||||
L"Test your limits in Hardcore Ironman mode, where every decision could mean life or death and every encounter is a battle for survival. With gold eliminated from the game and town portals disabled, only the strongest and most resourceful adventurers will prevail.",
|
||||
L"Experience the thrill of Hardcore Ironman mode, where danger lurks around every corner and death is always a possibility. With gold out of the picture and town portals disabled, only the bravest heroes will dare to venture forth into the unknown.",
|
||||
L"Dive into the heart of darkness with Hardcore Ironman mode, where the challenges are greater, the risks are higher, and the rewards are more satisfying than ever before. Will you have what it takes to overcome the perils that await?",
|
||||
L"Test your skills and resilience in Hardcore Ironman mode, where survival is the ultimate goal and every decision could mean life or death. With gold removed from the equation and town portals disabled, only the bravest adventurers will dare to venture forth.",
|
||||
L"Prepare for the ultimate test of survival in Hardcore Ironman mode, where danger lurks around every corner and death is always one misstep away. With gold rendered useless and town portals disabled, only the strongest and most resourceful heroes will prevail.",
|
||||
L"Experience the adrenaline-fueled excitement of Hardcore Ironman mode, where danger lurks around every corner and death is always a possibility. With gold eliminated from the game and town portals disabled, only the bravest souls will dare to face the darkness.",
|
||||
L"Dive into the heart of darkness with Hardcore Ironman mode, where the challenges are greater, the risks are higher, and the rewards are more satisfying than ever before. Will you have what it takes to survive in this unforgiving world?",
|
||||
L"Test your limits in Hardcore Ironman mode, where every decision could mean life or death and every encounter is a battle for survival. With gold out of the picture and town portals disabled, only the strongest and most resourceful adventurers will prevail.",
|
||||
|
||||
L"Upgrade your Runes by combining any 3 Runes up to Lem to create the next Rune type. Likewise, merge any 2 Runes from Pul up to advance to the next level of Rune power.",
|
||||
L"Transform your Magic Charms by combining 3 of the same type into a new Magic Charm of the same variety. Whether they're Small, Large, or Grand, gather 3 Magic Charms to reroll them into a fresh version at 100% of your character's level.",
|
||||
L"Enhance your Jewels by gathering 3 of the same type and converting them into a new Jewel of the same category. Whether they're Magic or Rare, merge 3 Jewels to reroll them into a more potent version, matching your character's level at 100%.",
|
||||
L"Craft new Rings by combining sets of 3 Rings. Combine 3 Magic Rings to reroll them into a new Magic Ring at 75% of your character's level, or gather 3 Rare Rings to reroll them at full power.",
|
||||
L"Create new Amulets by collecting sets of 3 Amulets. Combine 3 Magic Amulets to reroll them into a fresh Magic Amulet at 75% of your character's level, or gather 3 Rare Amulets to reroll them into new Rare Amulets at full strength.",
|
||||
L"Unleash the power of Unique Arrows & Bolts by combining them with specific Runes and Gems. Mix a Quiver of Arrows or Bolts with the right combination of Runes and Gems to create unique ammunition, or replenish your Arrow Stack by combining any Unique Arrows or Bolts with a Health Potion.",
|
||||
L"Prepare your Armor, Shields, and Weapons for powerful Runewords by socketing them appropriately. Use specific Runes to add sockets to your equipment, allowing for the insertion of powerful Runewords to enhance their capabilities.",
|
||||
L"Add sockets to your Armor, Shields, and Weapons to prepare them for powerful upgrades. Combine specific Runes with various types of equipment to add sockets, enabling you to further customize and enhance their effectiveness.",
|
||||
L"Enhance your Weapons with the power of Chipped Gems, upgrading their damage and attributes. Combine any Weapon with Chipped Gems to add elemental damage, increased attack rating, or additional durability, depending on the gem used and its level.",
|
||||
L"Elevate your Weapons with Flawed Gems, infusing them with greater power and versatility. Combine any Weapon with Flawed Gems to significantly increase their elemental damage, attack rating, or durability, based on the gem type and its level.",
|
||||
L"Augment your Weapons with Regular Gems, imbuing them with even greater potency and effectiveness. Combine any Weapon with Regular Gems to substantially boost their elemental damage, attack rating, or durability, depending on the gem used and its level.",
|
||||
L"Empower your Weapons with Flawless Gems, unlocking their full potential and making them formidable tools of destruction. Combine any Weapon with Flawless Gems to dramatically increase their elemental damage, attack rating, or durability, depending on the gem type and its level.",
|
||||
L"Enrich your Weapons with the supreme power of Perfect Gems, granting them unparalleled strength and capability. Combine any Weapon with Perfect Gems to unleash devastating elemental damage, vastly improve attack rating, or significantly enhance durability, depending on the gem used and its level.",
|
||||
L"Fortify your Armor with the durability of Perfect Diamonds, ensuring they withstand the toughest battles. Combine any Armor with Perfect Diamonds to add durability, granting increased resistance to wear and tear.",
|
||||
L"Reinforce your Armor with the defensive prowess of Perfect Diamonds, bolstering their resilience against enemy attacks. Combine any Armor with 3 Perfect Diamonds to enhance defense, providing greater protection in combat.",
|
||||
|
||||
|
||||
L"Boost the effectiveness of all Armor types by combining them with various Runes and Magic Jewels. Enhance your Armor's attributes such as light radius, resistance, damage reduction, faster hit recovery, and more, depending on the combination used and the level of the runes.",
|
||||
L"Strengthen any Body Armor (Torso) by infusing it with the power of Runes and Magic Jewels. Improve attributes like stamina drain, mana per kill, defense, mana regeneration, damage reduction, resistances, and more, based on the combination of runes and jewels used.",
|
||||
L"Empower Belts, Boots, Gloves, and Helms with the magical properties of Runes and Magic Jewels. Enhance attributes such as stamina drain, mana per kill, defense, mana regeneration, damage reduction, resistances, and more, depending on the combination of runes and jewels used.",
|
||||
|
||||
|
||||
L"Improve the defensive capabilities of any Torso Armor by combining it with various Runes and Magic Jewels. Enhance attributes such as stamina drain, mana per kill, defense, mana regeneration, damage reduction, resistances, and magic find, depending on the combination used.",
|
||||
L"Strengthen the properties of Belts, Boots, Gloves, and Helms by infusing them with the magical essence of Runes and Magic Jewels. Enhance attributes like stamina drain, mana per kill, defense, mana regeneration, damage reduction, resistances, and magic find, based on the combination of runes and jewels employed.",
|
||||
L"Empower Shields with the mystical energy of Runes and Magic Jewels to bolster their defensive capabilities. Enhance attributes such as light radius, block chance, mana per kill, defense, mana regeneration, damage reduction, faster block rate, resistances, and magic find, depending on the combination of runes and jewels utilized.",
|
||||
|
||||
|
||||
|
||||
L"Use a variety of weapons to exploit enemy vulnerabilities and resistances",
|
||||
L"Consume spirits like potions to increase Spirits Quaffed stat in character stat sheet page",
|
||||
L"Cube Souls with Energy Sphere to capture Soul Energy and use it to create powerful items. Recipes will come later",
|
||||
L"Collect Demon souls from demons and regular souls from monsters; Demon souls morph you into the demon whose soul you have",
|
||||
L"Spirits can be consumed like potions or put on as rings to add to Souls Consumed count",
|
||||
L"Cube underused magic, rare, set, unique items with Energy Sphere to collect their magic energy for creating new items",
|
||||
L"Cube white items with Energy Sphere to break down into simple item parts for creating base item types with smithing hammers",
|
||||
L"Use Rare Shard, Set Stone, or Unique Particle with smithing hammers and Energy Sphere to create rare, set, unique items",
|
||||
L"Acquire smithing hammers to create base item types, each requiring X number of collected item parts",
|
||||
L"Capture Talisman of Corruption and cube to corrupt items for new magical properties; a gamble with potential rewards",
|
||||
L"Use Experience Book for extra experience, Infinite Mana Elixir for massive mana regeneration, and Regeneration Elixir for life regeneration",
|
||||
L"Use Elixirs to permanently boost stats like Strength, Dexterity, Health, Stamina, Mana, and resistances",
|
||||
L"Equip Sling Stone for increased throwing potion damage, various elemental stones for resistance boosts, and Mastery Stones for skill damage boosts",
|
||||
L"Use Portable Shrines for temporary buffs like increased defense, damage, experience gained, mana regeneration, and skill levels",
|
||||
L"In Ironman, gold is nonexistent, town portals are disabled; rely on items, waypoints, and strategic gameplay to progress",
|
||||
L"Inventory management is critical; use items conservatively and intelligently switch gear based on monster types and situations",
|
||||
L"Hybrid character builds and creative weapon choices are encouraged in Ironman; experiment and adapt strategies accordingly",
|
||||
L"Protect hirelings actively as they are essential allies; they can be hired for 0 gold but lose items if they die",
|
||||
L"Coordinate with teammates in MultiPlayer; teamwork, resource sharing, and strategy are key to success in Ironman",
|
||||
L"In Hardcore Ironman, caution and careful planning are crucial; falling back, potion management, and adaptability are essential for survival",
|
||||
L"Utilize waypoints for inter-level travel in Ironman; waypoints become crucial for navigating the game world",
|
||||
L"Always have backup gear in your backpack in Ironman; switch out gear intelligently based on monster types and challenges",
|
||||
L"Experiment with different weapons and gear in Ironman; adapt your strategies to overcome various monster types and situations",
|
||||
L"Keep a close watch on your hirelings' health in Ironman; losing a hireling means losing their equipped items as well",
|
||||
L"Plan and communicate effectively in MultiPlayer Ironman games; teamwork and coordination are key to overcoming challenges",
|
||||
L"Be conservative with resources in Hardcore Ironman; strategic planning and careful execution are vital for survival",
|
||||
L"Craft rare, set, unique items using collected item parts and smithing hammers in Ironman; choose item types wisely for your build",
|
||||
L"Capture and corrupt items using Talisman of Corruption for new magical properties in Ironman; take calculated risks for potential rewards",
|
||||
L"Use Portable Shrines strategically in Ironman for temporary buffs; timing and placement of shrines can turn the tide of battle",
|
||||
L"Keep track of Souls Consumed and Spirits Quaffed stats in Ironman; they reflect your progress and resource utilization in the game",
|
||||
L"Enhance your character with Elixirs and Stones for permanent stat boosts and bonuses in Ironman; plan your upgrades wisely",
|
||||
L"Master the art of retreating and regrouping in Hardcore Ironman; strategic fallbacks can save your character's life in tough situations",
|
||||
L"Stay vigilant and adapt your strategies in MultiPlayer Ironman games; synergy and cooperation with teammates are essential for success",
|
||||
L"Experiment with different skill synergies and builds in Ironman; explore the full potential of your character's abilities",
|
||||
L"Craft and equip powerful unique items using collected Magic Essence Points and recipes in Ironman; customize your gear for optimal performance",
|
||||
L"Explore new areas and challenges in Ironman; discover hidden secrets and encounters by venturing off the beaten path",
|
||||
L"Combine different magic, rare, set, unique items with the Energy Sphere to collect their magic energy in Ironman",
|
||||
L"Cube white items with the Energy Sphere to break them down into simple item parts for crafting in Ironman",
|
||||
L"Use smithing hammers with the Energy Sphere to create base item types for crafting in Ironman",
|
||||
L"Combine Rare Shard, Set Stone, or Unique Particle with base item types and Magic Essence Points to create rare, set, unique items in Ironman",
|
||||
L"Cube Souls with the Energy Sphere to capture their energy and use it for creating more powerful items in Ironman",
|
||||
L"Capture Talisman of Corruption and cube it to corrupt items for new magical properties in Ironman; a gamble with potential rewards",
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
void OnLoad() {
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Function to break the tip into words
|
||||
vector<string> split(const string& s, char delim) {
|
||||
stringstream ss(s);
|
||||
string item;
|
||||
vector<string> tokens;
|
||||
while (getline(ss, item, delim)) {
|
||||
tokens.push_back(item);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
// Function to create sentences from words
|
||||
string makeSentence(vector<string> words, int start, int end) {
|
||||
stringstream ss;
|
||||
for (int i = start; i <= end; ++i) {
|
||||
ss << words[i] << " ";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// Function to convert string to wide string
|
||||
wstring stringToWstring(const string& s) {
|
||||
wstring ws;
|
||||
for (char c : s) {
|
||||
ws += (wchar_t)c;
|
||||
}
|
||||
return ws;
|
||||
}
|
||||
|
||||
// Your original code here
|
||||
|
||||
// Modified onDraw function
|
||||
//void onDraw() {
|
||||
// if (GetTickCount64() >= nEndTime) {
|
||||
// nEndTime = GetTickCount64() + DURATION;
|
||||
// nTip = rand() % diablo2Tips.size();
|
||||
// }
|
||||
|
||||
// // Convert wstring to string for manipulation
|
||||
// string strTip = string(diablo2Tips[nTip].begin(), diablo2Tips[nTip].end());
|
||||
// vector<string> words = split(strTip, ' ');
|
||||
|
||||
// // Calculate positions for multiple lines
|
||||
// int yPos = 65;
|
||||
// for (int i = 0; i < words.size(); i += 5) {
|
||||
// // Create a sentence from words and convert it back to wide string
|
||||
// string sentence = makeSentence(words, i, min(i + 4, (int)words.size() - 1));
|
||||
// wstring wSentence = stringToWstring(sentence);
|
||||
// D2PrintString(const_cast<LPWSTR>(wSentence.c_str()), 152, yPos, D2Color::WHITE, 0);
|
||||
// yPos += 14; // Move to the next line
|
||||
// }
|
||||
//}
|
||||
|
||||
// Helper function to justify a line of text
|
||||
void justifyLine(const vector<string>& words, int start, int end, int maxLineLength, int yPos) {
|
||||
// Handle the case when there is only one word in the line
|
||||
if (start == end) {
|
||||
wstring word = stringToWstring(words[start]);
|
||||
D2PrintString(const_cast<LPWSTR>(word.c_str()), 130, yPos, D2Color::WHITE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the total length of the line (excluding spaces)
|
||||
int lineLength = 0;
|
||||
for (int i = start; i <= end; i++) {
|
||||
lineLength += D2Win_GetTextWidth(const_cast<LPWSTR>(stringToWstring(words[i]).c_str())); // Get the actual width of the word
|
||||
|
||||
}
|
||||
|
||||
// Calculate the number of spaces to distribute
|
||||
int numSpaces = end - start;
|
||||
int extraSpaces = maxLineLength - lineLength;
|
||||
|
||||
// Distribute the extra spaces evenly
|
||||
int spaceWidth = 1;
|
||||
int extraSpacePerGap = extraSpaces / numSpaces;
|
||||
int remainingSpaces = extraSpaces % numSpaces;
|
||||
|
||||
// Build the justified line
|
||||
wstring wLine;
|
||||
int xPos = 152;
|
||||
for (int i = start; i <= end; i++) {
|
||||
wstring word = stringToWstring(words[i]);
|
||||
D2PrintString(const_cast<LPWSTR>(word.c_str()), xPos, yPos, D2Color::WHITE, 0);
|
||||
xPos += D2Win_GetTextWidth(const_cast<LPWSTR>(stringToWstring(words[i]).c_str())) + (spaceWidth + extraSpacePerGap);
|
||||
|
||||
if (remainingSpaces > 0) {
|
||||
xPos += 1; // Add an extra pixel for the remaining spaces
|
||||
remainingSpaces--;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Refactored onDraw function
|
||||
void onDraw() {
|
||||
if (GetTickCount64() >= nEndTime) {
|
||||
nEndTime = GetTickCount64() + DURATION;
|
||||
nTip = rand() % diablo2Tips.size();
|
||||
}
|
||||
|
||||
// Convert wstring to string for manipulation
|
||||
string strTip = string(diablo2Tips[nTip].begin(), diablo2Tips[nTip].end());
|
||||
vector<string> words = split(strTip, ' ');
|
||||
|
||||
// Calculate positions for multiple lines
|
||||
int yPos = 65;
|
||||
int lineStart = 0;
|
||||
int lineLength = 0;
|
||||
int maxLineLength = 580 - 152; // Maximum line length in pixels
|
||||
|
||||
for (int i = 0; i < words.size(); i++) {
|
||||
// Get the length of the current word
|
||||
// int wordLength = words[i].length() * 8; // Assuming a fixed-width font with 8 pixels per character
|
||||
int wordLength = D2Win_GetTextWidth(const_cast<LPWSTR>(stringToWstring(words[i]).c_str())); // Get the actual width of the word
|
||||
|
||||
// If adding the current word would exceed the maximum line length, print the current line
|
||||
if (lineLength + wordLength > maxLineLength) {
|
||||
// Justify the current line
|
||||
justifyLine(words, lineStart, i - 1, maxLineLength, yPos);
|
||||
|
||||
// Move to the next line
|
||||
yPos += 14;
|
||||
lineStart = i;
|
||||
lineLength = 0;
|
||||
}
|
||||
|
||||
// Add the current word to the line
|
||||
lineLength += wordLength + 8; // Add space length (8 pixels)
|
||||
}
|
||||
|
||||
// Print the last line if it exists
|
||||
if (lineStart < words.size()) {
|
||||
//justifyLine(words, lineStart, words.size() - 1, maxLineLength, yPos);
|
||||
wstring wLine = stringToWstring(makeSentence(words, lineStart, words.size() - 1));
|
||||
D2PrintString(const_cast<LPWSTR>(wLine.c_str()), 152, yPos, D2Color::WHITE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//// Refactored onDraw function
|
||||
//void onDraw() {
|
||||
// if (GetTickCount64() >= nEndTime) {
|
||||
// nEndTime = GetTickCount64() + DURATION;
|
||||
// nTip = rand() % diablo2Tips.size();
|
||||
// }
|
||||
//
|
||||
// // Convert wstring to string for manipulation
|
||||
// string strTip = string(diablo2Tips[nTip].begin(), diablo2Tips[nTip].end());
|
||||
// vector<string> words = split(strTip, ' ');
|
||||
//
|
||||
// // Calculate positions for multiple lines
|
||||
// int yPos = 65;
|
||||
// int lineStart = 0;
|
||||
// int lineLength = 0;
|
||||
// int maxLineLength = 590 - 158; // Maximum line length in pixels
|
||||
//
|
||||
// for (int i = 0; i < words.size(); i++) {
|
||||
// // Get the length of the current word
|
||||
// int wordLength = words[i].length() * 8; // Assuming a fixed-width font with 8 pixels per character
|
||||
//
|
||||
// // If adding the current word would exceed the maximum line length, print the current line
|
||||
// if (lineLength + wordLength > maxLineLength) {
|
||||
// // Print the current line
|
||||
// wstring wLine = stringToWstring(makeSentence(words, lineStart, i - 1));
|
||||
// D2PrintString(const_cast<LPWSTR>(wLine.c_str()), 130, yPos, D2Color::WHITE, 0);
|
||||
//
|
||||
// // Move to the next line
|
||||
// yPos += 14;
|
||||
// lineStart = i;
|
||||
// lineLength = 0;
|
||||
// }
|
||||
//
|
||||
// // Add the current word to the line
|
||||
// lineLength += wordLength + 8; // Add space length (8 pixels)
|
||||
// }
|
||||
//
|
||||
// // Print the last line
|
||||
// if (lineStart < words.size()) {
|
||||
// wstring wLine = stringToWstring(makeSentence(words, lineStart, words.size() - 1));
|
||||
// D2PrintString(const_cast<LPWSTR>(wLine.c_str()), 130, yPos, D2Color::WHITE, 0); //diablo2::d2_gfx::draw_filled_rect(130, 48, 640, 155, 5, 50);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color, DWORD bfalse)
|
||||
{
|
||||
if (onRealm || !D2isLODGame() )
|
||||
@ -355,10 +1030,9 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color,
|
||||
|
||||
WCHAR text[21];
|
||||
getCurrentStashName(text, 21, ptChar);
|
||||
|
||||
// Replace character # by number page.
|
||||
int j = 0;
|
||||
for (int i=0; text[i]; i++)
|
||||
for (int i = 0; text[i]; i++)
|
||||
{
|
||||
if (text[i] == L'#')
|
||||
{
|
||||
@ -368,7 +1042,7 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color,
|
||||
{
|
||||
nbDigits++;
|
||||
val /= 10;
|
||||
} while(val);
|
||||
} while (val);
|
||||
j += nbDigits;
|
||||
|
||||
val = currentId;
|
||||
@ -378,7 +1052,7 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color,
|
||||
nbDigits++;
|
||||
popupText[j - nbDigits] = (WCHAR)(val % 10 + 48);
|
||||
val /= 10;
|
||||
} while(val);
|
||||
} while (val);
|
||||
}
|
||||
else
|
||||
popupText[j++] = text[i];
|
||||
@ -388,7 +1062,7 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color,
|
||||
// Check text length vs field name length
|
||||
int pixelLen = D2GetPixelLen(popupText);
|
||||
int len = wcslen(popupText);
|
||||
while(len > 0 && pixelLen > posWStashNameField - 5)
|
||||
while (len > 0 && pixelLen > posWStashNameField - 5)
|
||||
{
|
||||
len--;
|
||||
popupText[len] = NULL;
|
||||
@ -396,24 +1070,40 @@ void FASTCALL printPageNumber(LPWSTR maxGoldText, DWORD x, DWORD y, DWORD color,
|
||||
}
|
||||
|
||||
DWORD color = isShared ? (isMainIndex ? SharedMainIndexPageColor : isIndex ? SharedIndexPageColor : SharedNormalPageColor) : (isMainIndex ? PersonalMainIndexPageColor : isIndex ? PersonalIndexPageColor : PersonalNormalPageColor);
|
||||
D2PrintString(popupText, x, y, color, bfalse);
|
||||
|
||||
if (isOnStashNameField(mx, my))
|
||||
{
|
||||
_snwprintf(popupText, 0x400, getLocalString(STR_PAGE_TYPE_CHANGE), currentId);
|
||||
D2PrintPopup(popupText, getXStashNameField() + posWStashNameField/2, getYStashNameField() - posHStashNameField - 2, WHITE, 1);
|
||||
}
|
||||
}
|
||||
// By HashCasper
|
||||
D2PrintString(popupText, 152, 605, color, bfalse);
|
||||
|
||||
// Mapping from int to ui_font_t
|
||||
//std::map<int, diablo2::ui_font_t> fontMap = {
|
||||
// {0, diablo2::ui_font_t::UI_FONT_8},
|
||||
// {1, diablo2::ui_font_t::UI_FONT_16},
|
||||
// {2, diablo2::ui_font_t::UI_FONT_30},
|
||||
// {3, diablo2::ui_font_t::UI_FONT_42},
|
||||
// {4, diablo2::ui_font_t::UI_FONT_FORMAL10},
|
||||
// {5, diablo2::ui_font_t::UI_FONT_FORMAL12},
|
||||
// {6, diablo2::ui_font_t::UI_FONT_6},
|
||||
// {7, diablo2::ui_font_t::UI_FONT_24},
|
||||
// {8, diablo2::ui_font_t::UI_FONT_FORMAL11},
|
||||
// {9, diablo2::ui_font_t::UI_FONT_EXOCET10},
|
||||
// {10, diablo2::ui_font_t::UI_FONT_RIDICULOUS},
|
||||
// {11, diablo2::ui_font_t::UI_FONT_EXOCET8},
|
||||
// {12, diablo2::ui_font_t::UI_FONT_REALLYTHELASTSUCKER},
|
||||
// {13, diablo2::ui_font_t::UI_FONT_INGAMECHAT}
|
||||
//};
|
||||
|
||||
|
||||
D2SetFont(2);
|
||||
WCHAR HashString[] = L"Ironman Mod by Hash";
|
||||
D2PrintString(HashString, 150, 35, color, bfalse);
|
||||
|
||||
// Print Random Tips
|
||||
D2SetFont(0);
|
||||
onDraw();
|
||||
|
||||
// Reset font after printing
|
||||
D2SetFont(8);
|
||||
|
||||
//printGoldMaxPopup
|
||||
if (isOnStashGoldField(mx, my))
|
||||
{
|
||||
if (active_sharedGold)
|
||||
{
|
||||
_snwprintf(popupText, 0x400, L"%s\n%s: %u", maxGoldText, getLocalString(STR_SHARED_GOLD_QUANTITY), PCPY->sharedGold);
|
||||
D2PrintPopup(popupText, getXStashGoldField() + posWStashGoldField/2, getYStashGoldField() - posHStashGoldField - 2, WHITE, 1);
|
||||
} else
|
||||
D2PrintPopup(maxGoldText, getXStashGoldField() + posWStashGoldField/2, getYStashGoldField() - posHStashGoldField - 2, WHITE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,7 +1315,11 @@ void Install_InterfaceStash()
|
||||
|
||||
// print page number
|
||||
mem_seek R8(D2Client, 3903C, 3903C, 3F375, B0FE3, 7DF63, B3633, 99A33, 9DE03, 8F2E5);
|
||||
|
||||
MEMJ_REF4( D2PrintString, printPageNumber);
|
||||
|
||||
|
||||
|
||||
//6FADF374 |. E8 3FCC0800 CALL <JMP.&D2Win.#10117>
|
||||
//6FB60FE2 |. E8 99C2F5FF CALL <JMP.&D2Win.#10020>
|
||||
//6FB2DF62 |. E8 19F3F8FF CALL <JMP.&D2Win.#10064>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
static struct
|
||||
{
|
||||
union{
|
||||
@ -35,6 +36,7 @@ static struct
|
||||
#define getYNextPageBtn() RY(D2GetResolution()?0x40:0x70)
|
||||
#define getHNextPageBtn() 32
|
||||
#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn())
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@ -49,7 +51,7 @@ void STDCALL printStatsPageBtns()
|
||||
sDrawImageInfo data;
|
||||
ZeroMemory(&data,sizeof(data));
|
||||
|
||||
if (printBackgroundOnMainPage && D2GetResolution())
|
||||
if (printBackgroundOnMainPage)
|
||||
{
|
||||
setImage(&data, statsBackgroundImages);
|
||||
setFrame(&data, 1);
|
||||
@ -57,16 +59,14 @@ void STDCALL printStatsPageBtns()
|
||||
}
|
||||
|
||||
setImage(&data, D2LoadBuySelBtn());
|
||||
if (D2GetResolution())
|
||||
{
|
||||
setFrame(&data, 12 + isDownBtn.previousPage);
|
||||
D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0);
|
||||
}
|
||||
setFrame(&data, 12 + isDownBtn.previousPage);
|
||||
D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0);
|
||||
|
||||
setFrame(&data, 14 + isDownBtn.nextPage);
|
||||
D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0);
|
||||
|
||||
D2SetFont(1);
|
||||
if (D2GetResolution() && isOnPreviousPageBtn(mx,my)) //print popup "previous page"
|
||||
if (isOnPreviousPageBtn(mx,my)) //print popup "previous page"
|
||||
{
|
||||
lpText = getLocalString(STR_PREVIOUS_PAGE);
|
||||
D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1);
|
||||
@ -84,6 +84,12 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg)
|
||||
|
||||
if (!active_newInterfaces || !D2isLODGame() ) return ptChar;
|
||||
|
||||
if (statsLeftDown(msg)) {
|
||||
freeMessage(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push down left button previous page\n");
|
||||
@ -100,6 +106,7 @@ Unit* STDCALL statsPageMouseDown(sWinMessage* msg)
|
||||
freeMessage(msg);
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
return ptChar;
|
||||
}
|
||||
|
||||
@ -110,6 +117,13 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg)
|
||||
|
||||
if (!active_newInterfaces || !D2isLODGame() ) return ptChar;
|
||||
|
||||
if (statsLeftUp(msg)) {
|
||||
isDownBtn.all=0;
|
||||
freeMessage(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
if (D2GetResolution() && isOnPreviousPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push up left button previous page\n");
|
||||
@ -134,6 +148,7 @@ Unit* STDCALL statsPageMouseUp(sWinMessage* msg)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
isDownBtn.all=0;
|
||||
return ptChar;
|
||||
|
@ -51,7 +51,7 @@ LPCWSTR getLocalTypeString(DWORD code)
|
||||
{
|
||||
if (sLocalizedTypeStrings[i].code == code)
|
||||
{
|
||||
log_msg("Code=%08X\n", code);
|
||||
//log_msg("Code=%08X\n", code);
|
||||
if (sLocalizedTypeStrings[i].itemStr)
|
||||
return StripGender(D2GetStringFromString(sLocalizedTypeStrings[i].itemStr));
|
||||
LPWSTR text = StripGender(sLocalizedTypeStrings[i].typeLocalizedString);
|
||||
@ -300,6 +300,8 @@ void loadLocalizedStrings(int language)
|
||||
LOAD(STR_SHARED_GOLD_QUANTITY);
|
||||
LOAD(STR_PREVIOUS_PAGE);
|
||||
LOAD(STR_NEXT_PAGE);
|
||||
LOAD(STR_PREVIOUS_RUNE);
|
||||
LOAD(STR_NEXT_RUNE);
|
||||
LOAD(STR_ITEM_LEVEL);
|
||||
LOAD(STR_PAGE_TYPE_CHANGE);
|
||||
|
||||
|
@ -37,6 +37,8 @@ enum eStringList
|
||||
STR_SHARED_GOLD_QUANTITY,
|
||||
STR_PREVIOUS_PAGE,
|
||||
STR_NEXT_PAGE,
|
||||
STR_PREVIOUS_RUNE,
|
||||
STR_NEXT_RUNE,
|
||||
STR_ITEM_LEVEL,
|
||||
STR_PAGE_TYPE_CHANGE,
|
||||
//
|
||||
|
@ -233,12 +233,6 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize)
|
||||
printInputItem(&curForm->input6, buf, len, &realNbInputs);
|
||||
printInputItem(&curForm->input7, buf, len, &realNbInputs);
|
||||
|
||||
if (realNbInputs != curForm->numinputs)
|
||||
{
|
||||
PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PRINT(BUF,L" => ");
|
||||
int realNbOutputs=0;
|
||||
|
||||
@ -269,6 +263,9 @@ DWORD print(CubeMainBIN* curForm, LPWSTR buf, LPINT len, DWORD)//maxsize)
|
||||
// if (curForm->version == 100)
|
||||
// sprintf(BUF, " [expansion only]");
|
||||
|
||||
if (realNbInputs != curForm->numinputs)
|
||||
PRINT(BUF, L" *** ERROR : numInputs(%d) != realNbInputs(%d) ***", curForm->numinputs, realNbInputs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#undef BUF
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
#define NB_RUNES_PER_PAGE 25
|
||||
|
||||
#define getXCloseBtn() 360
|
||||
@ -53,6 +54,7 @@ static struct
|
||||
};
|
||||
};
|
||||
} isDownBtn;
|
||||
*/
|
||||
|
||||
|
||||
void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
@ -64,7 +66,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
D2SetFont(6);
|
||||
DWORD nbPixel = D2GetPixelLen(lpText);
|
||||
DWORD x1 = (nbPixel >= 195) ? 0 : 195-nbPixel;
|
||||
D2PrintString(lpText, x1, 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel)
|
||||
D2PrintString(lpText, posXRunesList + RX(x1), posYRunesList + 10 + pos*20, GOLD, 0);//MILIEU(0x00,0x70,nbPixel)
|
||||
|
||||
typesList[0]=L'\0';
|
||||
DWORD numItype=0;
|
||||
@ -80,7 +82,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
}
|
||||
nbPixel = D2GetPixelLen(typesList);
|
||||
x1 = (nbPixel >= 195) ? 0 : 195-nbPixel;
|
||||
D2PrintString(typesList, x1, 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel)
|
||||
D2PrintString(typesList, posXRunesList + RX(x1), posYRunesList + 20 + pos*20, WHITE, 0);//MILIEU(0x70,0xA0,nbPixel)
|
||||
|
||||
runesList[0]=L'\0';
|
||||
DWORD numRune=0;
|
||||
@ -115,7 +117,7 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
}
|
||||
|
||||
// x1 = (nbPixel < 145) ? 155 : 300-nbPixel;
|
||||
D2PrintString(runesList, x1, y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel)
|
||||
D2PrintString(runesList, posXRunesList + RX(x1), posYRunesList + y1 + pos*20, WHITE, 0);//MILIEU(0xD0,0xA0,nbPixel)
|
||||
}
|
||||
|
||||
|
||||
@ -123,48 +125,58 @@ void printRuneword(RunesBIN* runesData, DWORD pos)
|
||||
//6FB21FAA
|
||||
void STDCALL printRunewordsPage()
|
||||
{
|
||||
if (!D2isLODGame() || !D2GetResolution()) return D2PrintStatsPage();
|
||||
if (!D2isLODGame()) return D2PrintStatsPage();
|
||||
|
||||
LPWSTR lpText;
|
||||
bDontPrintBorder = true;
|
||||
bDontPrintBorder = D2GetResolution()? true : false;
|
||||
|
||||
//Init data for print image
|
||||
sDrawImageInfo data;
|
||||
ZeroMemory(&data,sizeof(data));
|
||||
|
||||
//print background
|
||||
/* setImage(&data, newStatsInterfaceImages);
|
||||
fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5);
|
||||
setImage(&data, newStatsInterfaceImages);
|
||||
setFrame(&data, 0);
|
||||
D2PrintImage(&data, 0, 256, -1, 5, 0);
|
||||
D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 1);
|
||||
D2PrintImage(&data, 256,256, -1, 5, 0);
|
||||
D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 2);
|
||||
D2PrintImage(&data, 0, 512, -1, 5, 0);
|
||||
D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 3);
|
||||
D2PrintImage(&data, 256,512, -1, 5, 0);
|
||||
D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 4);
|
||||
D2PrintImage(&data, 0, 552, -1, 5, 0);
|
||||
D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0);
|
||||
setFrame(&data, 5);
|
||||
D2PrintImage(&data, 256,552, -1, 5, 0);
|
||||
*/
|
||||
fillRect(0,0,400,552,0,5);
|
||||
D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0);
|
||||
|
||||
if (printBackgroundOnMainPage)
|
||||
{
|
||||
setImage(&data, statsBackgroundImages);
|
||||
setFrame(&data, 1);
|
||||
D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0);
|
||||
D2PrintImage(&data, getXPrevRunesBtn()-7, getYPrevRunesBtn()+8, -1, 5, 0);
|
||||
}
|
||||
|
||||
//print button close
|
||||
setImage(&data, D2LoadBuySelBtn());
|
||||
setFrame(&data, 10 + isDownBtn.close);
|
||||
D2PrintImage(&data, getXCloseBtn(), getYCloseBtn(), -1, 5, 0);
|
||||
|
||||
//print previous page button
|
||||
setFrame(&data, 12 + isDownBtn.previousPage);
|
||||
D2PrintImage(&data, getXPreviousPageBtn(), getYPreviousPageBtn(), -1, 5, 0);
|
||||
|
||||
//print next page button
|
||||
setFrame(&data, isDownBtn.nextPage);
|
||||
setFrame(&data, 14 + isDownBtn.nextPage);
|
||||
D2PrintImage(&data, getXNextPageBtn(), getYNextPageBtn(), -1, 5, 0);
|
||||
|
||||
//print previous runes button
|
||||
setImage(&data, stashBtnsImages);
|
||||
setFrame(&data, isDownBtn.prevRunes);
|
||||
setFrame(&data, 12 + isDownBtn.prevRunes);
|
||||
D2PrintImage(&data, getXPrevRunesBtn(), getYPrevRunesBtn(), -1, 5, 0);
|
||||
|
||||
//print previous runes button
|
||||
setFrame(&data, 2 + isDownBtn.nextRunes);
|
||||
setFrame(&data, 14 + isDownBtn.nextRunes);
|
||||
D2PrintImage(&data, getXNextRunesBtn(), getYNextRunesBtn(), -1, 5, 0);
|
||||
|
||||
D2SetFont(6);
|
||||
@ -181,11 +193,11 @@ void STDCALL printRunewordsPage()
|
||||
{
|
||||
if (!runesData->Complete || runesData->Server) continue;
|
||||
nbRunesCompleted++;
|
||||
if ( (curRunesPage * NB_RUNES_PER_PAGE < nbRunesCompleted) &&
|
||||
(nbRunesCompleted <= (curRunesPage+1) * NB_RUNES_PER_PAGE) )
|
||||
if ( (curRunesPage * runesPerPage < nbRunesCompleted) &&
|
||||
(nbRunesCompleted <= (curRunesPage+1) * runesPerPage) )
|
||||
printRuneword(runesData, curNbRunes++);
|
||||
}
|
||||
maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / NB_RUNES_PER_PAGE : 0;
|
||||
maxRunesPage = nbRunesCompleted ? (nbRunesCompleted-1) / runesPerPage : 0;
|
||||
|
||||
|
||||
//////////////////// POPUP PRINTING ////////////////////
|
||||
@ -197,11 +209,26 @@ void STDCALL printRunewordsPage()
|
||||
{
|
||||
D2PrintPopup(D2GetStringFromIndex(0x1030), getXCloseBtn()+getLCloseBtn()/2, getYCloseBtn()-getHCloseBtn(), WHITE, 1);
|
||||
}
|
||||
else if (isOnPreviousPageBtn(x,y)) //print popup "previous page"
|
||||
{
|
||||
lpText = getLocalString(STR_PREVIOUS_PAGE);
|
||||
D2PrintPopup(lpText, getXPreviousPageBtn()+getLPreviousPageBtn()/2, getYPreviousPageBtn()-getHPreviousPageBtn(), WHITE, 1);
|
||||
}
|
||||
else if (isOnNextPageBtn(x,y)) // print popup "next page"
|
||||
{
|
||||
lpText = getLocalString(STR_NEXT_PAGE);
|
||||
D2PrintPopup(lpText, getXNextPageBtn()+getLNextPageBtn()/2, getYNextPageBtn()-getHNextPageBtn(), WHITE, 1);
|
||||
}
|
||||
else if (isOnPrevRunesBtn(x,y)) // print popup "previous rune"
|
||||
{
|
||||
lpText = getLocalString(STR_PREVIOUS_RUNE);
|
||||
D2PrintPopup(lpText, getXPrevRunesBtn()+getLPrevRunesBtn()/2, getYPrevRunesBtn()-getHPrevRunesBtn(), WHITE, 1);
|
||||
}
|
||||
else if (isOnNextRunesBtn(x,y)) // print popup "next rune"
|
||||
{
|
||||
lpText = getLocalString(STR_NEXT_RUNE);
|
||||
D2PrintPopup(lpText, getXNextRunesBtn()+getLNextRunesBtn()/2, getYNextRunesBtn()-getHNextRunesBtn(), WHITE, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
#define getXCloseBtn() 360
|
||||
#define getLCloseBtn() 32
|
||||
#define getYCloseBtn() (ResolutionY - 60)
|
||||
@ -92,6 +93,7 @@ void** ptD2AssignStatsPointsBtnImages = (void**)0x6FBB5BB4;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
static struct
|
||||
{
|
||||
union{
|
||||
@ -111,6 +113,7 @@ static struct
|
||||
};
|
||||
};
|
||||
} isDownBtn;
|
||||
*/
|
||||
|
||||
|
||||
void print2Lines(WORD id, LPWSTR lpText, DWORD x, DWORD l, DWORD y)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "common.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
#define getXCloseBtn() RX(0x110)
|
||||
#define getLCloseBtn() 32
|
||||
#define getYCloseBtn() RY(0x40)
|
||||
@ -29,11 +30,13 @@
|
||||
#define getYNextPageBtn() RY(0x40)
|
||||
#define getHNextPageBtn() 32
|
||||
#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn())
|
||||
*/
|
||||
|
||||
const char * STATS_INTERFACE_FILENAME = "PlugY\\statsinterface.txt";
|
||||
|
||||
#define BUFSIZE 0x400
|
||||
|
||||
/*
|
||||
static struct
|
||||
{
|
||||
union{
|
||||
@ -45,6 +48,7 @@ static struct
|
||||
};
|
||||
};
|
||||
} isDownBtn;
|
||||
*/
|
||||
|
||||
|
||||
struct statsInterfaceBIN
|
||||
@ -337,8 +341,7 @@ void STDCALL printNewStatsPageTwo(int currentPage)
|
||||
|
||||
WCHAR text[BUFSIZE];
|
||||
LPWSTR lpText;
|
||||
bDontPrintBorder = false;
|
||||
|
||||
bDontPrintBorder = D2GetResolution()? true : false;
|
||||
Unit* ptChar = D2GetClientPlayer();
|
||||
|
||||
d2_assert(!ptChar, "Printing stats page : no character selected",__FILE__,__LINE__);
|
||||
@ -349,16 +352,20 @@ void STDCALL printNewStatsPageTwo(int currentPage)
|
||||
ZeroMemory(&data,sizeof(data));
|
||||
|
||||
//print background
|
||||
fillRect(RX(0),RY(480),320,432,0,5);//552
|
||||
fillRect(RX(0), RY(ResolutionY), 512, 768, 0, 5);
|
||||
setImage(&data, newStatsInterfaceImages);
|
||||
setFrame(&data, 0);
|
||||
D2PrintImage(&data, RX(0), RY(224), -1, 5, 0);
|
||||
D2PrintImage(&data, RX(0), RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 1);
|
||||
D2PrintImage(&data, RX(256),RY(224), -1, 5, 0);//256
|
||||
D2PrintImage(&data, RX(256),RY(ResolutionY-256), -1, 5, 0);
|
||||
setFrame(&data, 2);
|
||||
D2PrintImage(&data, RX(0), RY(48), -1, 5, 0);//432
|
||||
D2PrintImage(&data, RX(0), RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 3);
|
||||
D2PrintImage(&data, RX(256),RY(48), -1, 5, 0);
|
||||
D2PrintImage(&data, RX(256),RY(ResolutionY-256*2), -1, 5, 0);
|
||||
setFrame(&data, 4);
|
||||
D2PrintImage(&data, RX(0), RY(ResolutionY-256*3), -1, 5, 0);
|
||||
setFrame(&data, 5);
|
||||
D2PrintImage(&data, RX(256),RY(ResolutionY-256*3), -1, 5, 0);
|
||||
|
||||
D2SetFont(1);
|
||||
for (int i=0; i<nbStatsInterface; i++)
|
||||
@ -392,10 +399,12 @@ void STDCALL printNewStatsPageTwo(int currentPage)
|
||||
D2PrintString(text, x, y, WHITE, 0);
|
||||
*/
|
||||
|
||||
//print background previous/next page buttons
|
||||
setImage(&data, statsBackgroundImages);
|
||||
setFrame(&data, D2GetResolution()?1:0);
|
||||
D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0);
|
||||
if (printBackgroundOnMainPage) {
|
||||
//print background previous/next page buttons
|
||||
setImage(&data, statsBackgroundImages);
|
||||
setFrame(&data, 1);
|
||||
D2PrintImage(&data, getXPreviousPageBtn()-7, getYPreviousPageBtn()+8, -1, 5, 0);
|
||||
}
|
||||
|
||||
//print button close
|
||||
setImage(&data, D2LoadBuySelBtn());
|
||||
|
@ -22,11 +22,39 @@ bool active_newInterfaces=false;
|
||||
bool selectMainPageOnOpenning=true;
|
||||
bool printBackgroundOnMainPage=true;
|
||||
|
||||
int posXNextPageBtn = -1;
|
||||
int posYNextPageBtn = -1;
|
||||
int posXPrevPageBtn = -1;
|
||||
int posYPrevPageBtn = -1;
|
||||
int posXClosePageBtn = -1;
|
||||
int posYClosePageBtn = -1;
|
||||
int posXNextRuneBtn = -1;
|
||||
int posYNextRuneBtn = -1;
|
||||
int posXPrevRuneBtn = -1;
|
||||
int posYPrevRuneBtn = -1;
|
||||
int posXRunesList = -1;
|
||||
int posYRunesList = -1;
|
||||
int runesPerPage = -1;
|
||||
|
||||
DWORD getXNextPageBtn() {return RX(posXNextPageBtn);}
|
||||
DWORD getYNextPageBtn() {return RY(posYNextPageBtn);}
|
||||
DWORD getXPreviousPageBtn() {return RX(posXPrevPageBtn);}
|
||||
DWORD getYPreviousPageBtn() {return RY(posYPrevPageBtn);}
|
||||
DWORD getXCloseBtn() {return RX(posXClosePageBtn);}
|
||||
DWORD getYCloseBtn() {return RY(posYClosePageBtn);}
|
||||
DWORD getXNextRunesBtn() {return RX(posXNextRuneBtn);}
|
||||
DWORD getYNextRunesBtn() {return RY(posYNextRuneBtn);}
|
||||
DWORD getXPrevRunesBtn() {return RX(posXPrevRuneBtn);}
|
||||
DWORD getYPrevRunesBtn() {return RY(posYPrevRuneBtn);}
|
||||
|
||||
DWORD bDontPrintBorder=false;
|
||||
|
||||
int selectedPage=0;
|
||||
int lastPage=0;
|
||||
int extraHiddenPage=0;
|
||||
int curRunesPage=0;
|
||||
int maxRunesPage=0xFFFF;
|
||||
BtnState isDownBtn={0};
|
||||
|
||||
void GoNextStatPage()
|
||||
{
|
||||
@ -44,8 +72,12 @@ void GoPreviousStatPage()
|
||||
|
||||
void GoStatPage(int page)
|
||||
{
|
||||
if ( (page >= 0) && (page <= lastPage + (D2GetResolution()? extraHiddenPage : 0)) )
|
||||
if ( (page >= 0) && (page <= (lastPage + extraHiddenPage)) )
|
||||
selectedPage = page;
|
||||
else if (page < 0)
|
||||
selectedPage = lastPage + extraHiddenPage;
|
||||
else
|
||||
selectedPage = 0;
|
||||
}
|
||||
|
||||
int GetCurrentPage()
|
||||
@ -83,6 +115,16 @@ DWORD STDCALL mouseCustomPageLeftDown(sWinMessage* msg)
|
||||
DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg)
|
||||
{
|
||||
if(onRealm) return -1;
|
||||
|
||||
if (selectedPage == 0) return -1;
|
||||
if (!isOnStatsPage(msg->x,msg->y)) return 1;
|
||||
statsLeftUp(msg);
|
||||
D2CleanStatMouseUp();
|
||||
freeMessage(msg);
|
||||
isDownBtn.all=0;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
if ( (selectedPage > 0) && (selectedPage <= lastPage) )
|
||||
return mouseNewStatsPageTwoLeftUp(msg);
|
||||
else if (selectedPage == lastPage+1)
|
||||
@ -91,6 +133,87 @@ DWORD STDCALL mouseCustomPageLeftUp(sWinMessage* msg)
|
||||
return mouseNewStatsPageLeftUp(msg);
|
||||
else
|
||||
return -1;
|
||||
*/
|
||||
}
|
||||
|
||||
DWORD STDCALL statsLeftDown(sWinMessage* msg)
|
||||
{
|
||||
if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0)
|
||||
{
|
||||
log_msg("push down left button close\n");
|
||||
isDownBtn.close = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnPreviousPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push down left button previous page\n");
|
||||
isDownBtn.previousPage = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnNextPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push down left button next page\n");
|
||||
isDownBtn.nextPage = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
{
|
||||
log_msg("push down left button prev runes\n");
|
||||
isDownBtn.prevRunes = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
{
|
||||
log_msg("push down left button next runes\n");
|
||||
isDownBtn.nextRunes = 1;
|
||||
D2PlaySound(4,0,0,0,0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD STDCALL statsLeftUp(sWinMessage* msg)
|
||||
{
|
||||
if (isOnCloseBtn(msg->x,msg->y) && selectedPage != 0)
|
||||
{
|
||||
log_msg("push up left button close\n");
|
||||
if (isDownBtn.close)
|
||||
D2TogglePage(2,1,0);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnPreviousPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push up left button previous page\n");
|
||||
if (isDownBtn.previousPage)
|
||||
GoStatPage(selectedPage-1);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnNextPageBtn(msg->x,msg->y))
|
||||
{
|
||||
log_msg("push up left button next page\n");
|
||||
if (isDownBtn.nextPage)
|
||||
GoStatPage(selectedPage+1);
|
||||
return 1;
|
||||
}
|
||||
else if (isOnPrevRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
{
|
||||
log_msg("push up left button prev runes\n");
|
||||
if (isDownBtn.prevRunes && curRunesPage)
|
||||
curRunesPage--;
|
||||
return 1;
|
||||
}
|
||||
else if (isOnNextRunesBtn(msg->x,msg->y) && selectedPage == (lastPage + extraHiddenPage))
|
||||
{
|
||||
log_msg("push up left button next runes\n");
|
||||
if (isDownBtn.nextRunes && (curRunesPage < maxRunesPage))
|
||||
curRunesPage++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FCT_ASM ( caller_DontPrintBorder_114 )
|
||||
@ -474,6 +597,7 @@ void Install_NewInterfaces()
|
||||
//00498636 |. 6A 48 PUSH 48
|
||||
//00498638 |. 8D45 B8 LEA EAX,DWORD PTR SS:[EBP-48]
|
||||
|
||||
/* Conflicts with D2ExpRes
|
||||
// Manage mouse down (Play sound)
|
||||
mem_seek R8(D2Client, 2A9DC, 2A9CC, 312A5, 82736, 891B6, 6B116, BCD36, BF4D6, A7731);
|
||||
memt_byte( 0x8D, 0xE8 ); // CALL
|
||||
@ -486,6 +610,7 @@ void Install_NewInterfaces()
|
||||
//6FB6CD36 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80]
|
||||
//6FB6F4D6 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80]
|
||||
//004A7731 . 8D88 80000000 LEA ECX,DWORD PTR DS:[EAX+80]
|
||||
*/
|
||||
|
||||
// Manage mouse up
|
||||
mem_seek R8(D2Client, 2ABBB, 2ABAB, 3148D, 836D9, 8A159, 6C0B9, BDCB9, C0459, A78DA);
|
||||
|
@ -58,6 +58,7 @@ const char* S_dllFilenames2 = "DllToLoad2";
|
||||
const char* S_active_Commands = "ActiveCommands";
|
||||
const char* S_active_CheckMemory = "ActiveCheckMemory";
|
||||
const char* S_active_othersFeatures = "ActiveAllOthersFeatures";
|
||||
const char* S_saveFileStackSize = "SaveFileStackSize";
|
||||
|
||||
const char* S_WINDOWED = "WINDOWED";
|
||||
const char* S_ActiveWindowed = "ActiveWindowed";
|
||||
@ -214,6 +215,19 @@ const char* S_INTERFACE = "INTERFACE";
|
||||
const char* S_active_newInterfaces = "ActiveNewStatsInterface";
|
||||
const char* S_selectMainPageOnOpenning = "SelectMainPageOnOpenning";
|
||||
const char* S_printBackgroundOnMainPage = "PrintButtonsBackgroundOnMainStatsPage";
|
||||
const char* S_posXNextPageBtn = "PosXNextPageBtn";
|
||||
const char* S_posYNextPageBtn = "PosYNextPageBtn";
|
||||
const char* S_posXPrevPageBtn = "PosXPrevPageBtn";
|
||||
const char* S_posYPrevPageBtn = "PosYPrevPageBtn";
|
||||
const char* S_posXClosePageBtn = "PosXClosePageBtn";
|
||||
const char* S_posYClosePageBtn = "PosYClosePageBtn";
|
||||
const char* S_posXNextRuneBtn = "PosXNextRuneBtn";
|
||||
const char* S_posYNextRuneBtn = "PosYNextRuneBtn";
|
||||
const char* S_posXPrevRuneBtn = "PosXPrevRuneBtn";
|
||||
const char* S_posYPrevRuneBtn = "PosYPrevRuneBtn";
|
||||
const char* S_posXRunesList = "PosXRunesList";
|
||||
const char* S_posYRunesList = "PosYRunesList";
|
||||
const char* S_runesPerPage = "RunesPerPage";
|
||||
|
||||
const char* S_EXTRA = "EXTRA";
|
||||
const char* S_active_RunLODs = "ActiveLaunchAnyNumberOfLOD";
|
||||
@ -316,6 +330,10 @@ void init_General(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDefaultFi
|
||||
active_othersFeatures = atoi(buffer) != 0;
|
||||
log_msg("active_othersFeatures\t\t= %u\n", active_othersFeatures);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_GENERAL, S_saveFileStackSize, "8192");
|
||||
saveFileStackSize = atoi(buffer);
|
||||
log_msg("SaveFileStackSize\t\t\t= %u\n", saveFileStackSize);
|
||||
|
||||
log_msg("\n");
|
||||
}
|
||||
|
||||
@ -1032,6 +1050,52 @@ void init_NewInterfaces(INIFile* iniFile, INIFile* iniFixedFile, INIFile* iniDef
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_printBackgroundOnMainPage, "1");
|
||||
printBackgroundOnMainPage = atoi(buffer) != 0;
|
||||
log_msg("printBackgroundOnMainPage\t= %u\n", printBackgroundOnMainPage);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextPageBtn, "161");
|
||||
posXNextPageBtn = atoi(buffer);
|
||||
log_msg("posXNextPageBtn\t= %d\n", posXNextPageBtn);
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextPageBtn, "64");
|
||||
posYNextPageBtn = atoi(buffer);
|
||||
log_msg("posYNextPageBtn\t= %d\n", posYNextPageBtn);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevPageBtn, "119");
|
||||
posXPrevPageBtn = atoi(buffer);
|
||||
log_msg("posXPrevPageBtn\t= %d\n", posXPrevPageBtn);
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevPageBtn, "64");
|
||||
posYPrevPageBtn = atoi(buffer);
|
||||
log_msg("posYPrevPageBtn\t= %d\n", posYPrevPageBtn);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXClosePageBtn, "360");
|
||||
posXClosePageBtn = atoi(buffer);
|
||||
log_msg("posXClosePageBtn\t= %d\n", posXClosePageBtn);
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYClosePageBtn, "64");
|
||||
posYClosePageBtn = atoi(buffer);
|
||||
log_msg("posYClosePageBtn\t= %d\n", posYClosePageBtn);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXNextRuneBtn, "302");
|
||||
posXNextRuneBtn = atoi(buffer);
|
||||
log_msg("posXNextRuneBtn\t= %d\n", posXNextRuneBtn);
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYNextRuneBtn, "64");
|
||||
posYNextRuneBtn = atoi(buffer);
|
||||
log_msg("posYNextRuneBtn\t= %d\n", posYNextRuneBtn);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXPrevRuneBtn, "260");
|
||||
posXPrevRuneBtn = atoi(buffer);
|
||||
log_msg("posXPrevRuneBtn\t= %d\n", posXPrevRuneBtn);
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYPrevRuneBtn, "64");
|
||||
posYPrevRuneBtn = atoi(buffer);
|
||||
log_msg("posYPrevRuneBtn\t= %d\n", posYPrevRuneBtn);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posXRunesList, "50");
|
||||
posXRunesList = atoi(buffer);
|
||||
log_msg("posXRunesList\t= %d\n", posXRunesList);
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_posYRunesList, "45");
|
||||
posYRunesList = atoi(buffer);
|
||||
log_msg("posYRunesList\t= %d\n", posYRunesList);
|
||||
|
||||
GET_PRIVATE_PROFILE_STRING(S_INTERFACE, S_runesPerPage, "30");
|
||||
runesPerPage = atoi(buffer);
|
||||
log_msg("runesPerPage\t= %d\n", runesPerPage);
|
||||
}
|
||||
log_msg("\n");
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ Unit* FASTCALL updateItem(Game* ptGame, DWORD type, DWORD itemNum, Unit* ptChar)
|
||||
if (ptGame->isLODGame && (D2ItemGetPage(ptItem) == 4))
|
||||
{
|
||||
Stash* ptStash = getStashFromItem(ptChar, ptItem);
|
||||
//log_msg("- updateItem PCPY->currentStash->id : %d // ptStash->id : %d\n", PCPY->currentStash?PCPY->currentStash->id:-1, ptStash?ptStash->id:-1);
|
||||
if (!ptStash) return NULL;
|
||||
selectStash(ptChar, ptStash, ptStash->id == 0);
|
||||
}
|
||||
|
BIN
PlugY/PlugY.aps
Normal file
BIN
PlugY/PlugY.aps
Normal file
Binary file not shown.
BIN
PlugY/PlugY.rc
BIN
PlugY/PlugY.rc
Binary file not shown.
@ -1,7 +1,9 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugY", "PlugY.vcproj", "{EB63DF4E-A019-4522-A140-9E8C7350B331}"
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32505.173
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PlugY", "PlugY.vcxproj", "{EB63DF4E-A019-4522-A140-9E8C7350B331}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -17,4 +19,7 @@ Global
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {83A1632A-5376-46CE-89D9-F2D4E74FFE31}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
BIN
PlugY/PlugY.suo
BIN
PlugY/PlugY.suo
Binary file not shown.
@ -18,6 +18,7 @@ extern bool active_sharedStash;
|
||||
extern bool active_sharedGold;
|
||||
extern bool separateHardSoftStash;
|
||||
extern char* sharedStashFilename;
|
||||
extern DWORD saveFileStackSize;
|
||||
|
||||
extern bool displaySharedSetItemNameInGreen;
|
||||
extern int posXPreviousBtn;
|
||||
|
@ -9,20 +9,94 @@
|
||||
#include "common.h"
|
||||
|
||||
#define MILIEU(X,L,N) (X + ((N<L)? (L-N)/2 : 0))
|
||||
#define isOnStatsPage(x,y) ((x<400) && (y<553))
|
||||
#define isOnStatsPage(x,y) (x<RX(512))
|
||||
|
||||
extern DWORD bDontPrintBorder;
|
||||
extern int selectedPage;
|
||||
extern int extraHiddenPage;
|
||||
extern int curRunesPage;
|
||||
extern int maxRunesPage;
|
||||
|
||||
void GoNextStatPage();
|
||||
void GoPreviousStatPage();
|
||||
void GoStatPage(int page);
|
||||
int GetCurrentPage();
|
||||
|
||||
struct BtnState
|
||||
{
|
||||
union{
|
||||
DWORD all;
|
||||
struct{
|
||||
DWORD AssSTR:1;
|
||||
DWORD AssDEX:1;
|
||||
DWORD AssVIT:1;
|
||||
DWORD AssENE:1;
|
||||
DWORD UnaSTR:1;
|
||||
DWORD UnaDEX:1;
|
||||
DWORD UnaVIT:1;
|
||||
DWORD UnaENE:1;
|
||||
DWORD close:1;
|
||||
DWORD previousPage:1;
|
||||
DWORD nextPage:1;
|
||||
DWORD prevRunes:1;
|
||||
DWORD nextRunes:1;
|
||||
};
|
||||
};
|
||||
};
|
||||
extern BtnState isDownBtn;
|
||||
|
||||
extern bool active_newInterfaces;
|
||||
extern bool selectMainPageOnOpenning;
|
||||
extern bool printBackgroundOnMainPage;
|
||||
|
||||
extern int posXNextPageBtn;
|
||||
extern int posYNextPageBtn;
|
||||
extern int posXPrevPageBtn;
|
||||
extern int posYPrevPageBtn;
|
||||
extern int posXClosePageBtn;
|
||||
extern int posYClosePageBtn;
|
||||
extern int posXNextRuneBtn;
|
||||
extern int posYNextRuneBtn;
|
||||
extern int posXPrevRuneBtn;
|
||||
extern int posYPrevRuneBtn;
|
||||
extern int posXRunesList;
|
||||
extern int posYRunesList;
|
||||
extern int runesPerPage;
|
||||
|
||||
DWORD getXNextPageBtn();
|
||||
DWORD getYNextPageBtn();
|
||||
DWORD getXPreviousPageBtn();
|
||||
DWORD getYPreviousPageBtn();
|
||||
DWORD getXCloseBtn();
|
||||
DWORD getYCloseBtn();
|
||||
DWORD getXNextRunesBtn();
|
||||
DWORD getYNextRunesBtn();
|
||||
DWORD getXPrevRunesBtn();
|
||||
DWORD getYPrevRunesBtn();
|
||||
|
||||
#define getLCloseBtn() 32
|
||||
#define getHCloseBtn() 32
|
||||
#define isOnCloseBtn(x,y) isOnRect(x, y, getXCloseBtn(), getYCloseBtn(), getLCloseBtn(), getHCloseBtn())
|
||||
|
||||
#define getLPreviousPageBtn() 32
|
||||
#define getHPreviousPageBtn() 32
|
||||
#define isOnPreviousPageBtn(x,y) isOnRect(x, y, getXPreviousPageBtn(), getYPreviousPageBtn(), getLPreviousPageBtn(), getHPreviousPageBtn())
|
||||
|
||||
#define getLNextPageBtn() 32
|
||||
#define getHNextPageBtn() 32
|
||||
#define isOnNextPageBtn(x,y) isOnRect(x, y, getXNextPageBtn(), getYNextPageBtn(), getLNextPageBtn(), getHNextPageBtn())
|
||||
|
||||
#define getLPrevRunesBtn() 32
|
||||
#define getHPrevRunesBtn() 32
|
||||
#define isOnPrevRunesBtn(x,y) isOnRect(x, y, getXPrevRunesBtn(), getYPrevRunesBtn(), getLPrevRunesBtn(), getHPrevRunesBtn())
|
||||
|
||||
#define getLNextRunesBtn() 32
|
||||
#define getHNextRunesBtn() 32
|
||||
#define isOnNextRunesBtn(x,y) isOnRect(x, y, getXNextRunesBtn(), getYNextRunesBtn(), getLNextRunesBtn(), getHNextRunesBtn())
|
||||
|
||||
DWORD STDCALL statsLeftDown(sWinMessage* msg);
|
||||
DWORD STDCALL statsLeftUp(sWinMessage* msg);
|
||||
|
||||
void Install_NewInterfaces();
|
||||
|
||||
/*================================= END OF FILE =================================*/
|
@ -6,7 +6,7 @@
|
||||
=================================================================*/
|
||||
#pragma once
|
||||
|
||||
#define PLUGY_VERSION "14.02"
|
||||
#define PLUGY_VERSION "14.03 HD"
|
||||
|
||||
enum TargetMod
|
||||
{
|
||||
|
@ -47,10 +47,10 @@ BEGIN
|
||||
VALUE "CompanyName", "Yohann Nicolas"
|
||||
VALUE "FileDescription", "PlugY patcher"
|
||||
VALUE "FileVersion", "1.0.6.0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2017"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "PlugYInstall.exe"
|
||||
VALUE "ProductName", "PlugY, The Survival Kit"
|
||||
VALUE "ProductVersion", "14.02"
|
||||
VALUE "ProductVersion", "14.03"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
Binary file not shown.
@ -5,7 +5,7 @@
|
||||
; ;
|
||||
; by Yohann Nicolas ;
|
||||
; ;
|
||||
; version 14.02 ;
|
||||
; version 14.03 ;
|
||||
; ;
|
||||
;--------------------------------------------------------------------------------------;
|
||||
|
||||
|
@ -3,7 +3,7 @@ Unicode True
|
||||
|
||||
!include "MUI2.nsh"
|
||||
|
||||
!define VERSION "v14.02"
|
||||
!define VERSION "v14.03"
|
||||
!define D2FILES "."
|
||||
!define NAME "PlugY, The Survival Kit"
|
||||
!define MOD_DIR "Mod PlugY"
|
||||
|
Binary file not shown.
@ -6,7 +6,7 @@
|
||||
; ;
|
||||
; by Yohann Nicolas ;
|
||||
; ;
|
||||
; version 14.02 ;
|
||||
; version 14.03 ;
|
||||
; ;
|
||||
;--------------------------------------------------------------------------------------;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
; ;
|
||||
; by Yohann Nicolas ;
|
||||
; ;
|
||||
; version 14.02 ;
|
||||
; version 14.03 ;
|
||||
; ;
|
||||
;--------------------------------------------------------------------------------------;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
; ;
|
||||
; von Yohann Nicolas ;
|
||||
; ;
|
||||
; version 14.02 ;
|
||||
; version 14.03 ;
|
||||
; ;
|
||||
;--------------------------------------------------------------------------------------;
|
||||
|
||||
@ -24,7 +24,7 @@ Jedes Feature kann via PlugY.ini an/ausgeschaltet werden (siehe "Kommentare aus
|
||||
- Battle.net LogIn via Hauptmenü deaktiviert.
|
||||
- Nahezu unbegrenzter Speicherplatz im Goldschatz.
|
||||
- Gemeinsam genutzter Speicherplatz im Goldschatz.
|
||||
- Die Ladder-Only Runenwörter können für den Singleplayer aktiviert werden.
|
||||
- Die Ladder-Only Runenwörter können für den Singleplayer aktiviert werden.
|
||||
- Lokales World Event und Überquest im Singleplayer und via TCP/IP
|
||||
- Das Portal zum Kuh-Level bleibt geöffnet, wenn der Kuhkönig in dieser Schwierigkeit getötet wurde.
|
||||
- Das Portal zu Nihlathak bleibt geöffnet, wenn der Wegpunkt in dieser Schwierigkeit aktiviert wurde.
|
||||
@ -75,8 +75,12 @@ Jedes Feature kann via PlugY.ini an/ausgeschaltet werden (siehe "Kommentare aus
|
||||
/listcube: (Beta) Erstellt eine "cube.txt" Datei im Savegame-Verzeichnis mit allen Würfelrezepten.
|
||||
/renamechar newname: (Beta) Speichert und benennt den Char um.
|
||||
|
||||
v14.03 Änderungen :
|
||||
- Behebung eines Fehlers bei der Anzeige von Gegenständen, wenn nur eine Stash-Seite gefüllt ist.
|
||||
- Koreanische Übersetzung hinzugefügt.
|
||||
|
||||
v14.02 Änderungen :
|
||||
- Behebt Fehler, durch den mehrere identische, einzigartige Charms im Inventar gespeichert werden können.
|
||||
- Behebt Fehler, durch den mehrere identische, einzigartige Charms im Inventar gespeichert werden können.
|
||||
|
||||
v14.01 Änderungen :
|
||||
- Fehler behoben, der das Löschen von Truhen-Items hervorgerufen hat, wenn der Character zum ersten Mal geladen wurde.
|
||||
@ -178,18 +182,18 @@ v7.01b Änderungen :
|
||||
- Behoben: Die Ladder-only Runenwort Features in den LoD-Versionen 1.11 und 1.10.
|
||||
- Behoben : Seltsame Zeichen in manchen Texten.
|
||||
|
||||
v7.01 Änderungen :
|
||||
- Die Ladder-Only Runenwörter können für den Singleplayer aktiviert werden.
|
||||
v7.01 Änderungen :
|
||||
- Die Ladder-Only Runenwörter können für den Singleplayer aktiviert werden.
|
||||
- Fehler bei der AI des Überbaals behoben
|
||||
- Die Parameter in der PlugY.ini standardmäßig entfernt (wie -w um im Fenster zu starten)
|
||||
- Die Basiswerte der Statuspunkte werden angezeigt (ohne magische Boni) auch wenn die Statneuverteilung deaktiviert ist
|
||||
- Die Parameter in der PlugY.ini standardmäßig entfernt (wie -w um im Fenster zu starten)
|
||||
- Die Basiswerte der Statuspunkte werden angezeigt (ohne magische Boni) auch wenn die Statneuverteilung deaktiviert ist
|
||||
- Eine eigene EXE wurde hinzugefügt um PlugY zu starten (es werden keine LoD-Dateien mehr verändert)
|
||||
- Spanische und Polnische Übersetzung hinzugefügt.
|
||||
|
||||
V7.00 Änderungen :
|
||||
- PlugY funktioniert nun auch mit LoD 1.11b Versionen.
|
||||
- Den Basiswert für jeden Stat im Mausübertext hinzugefügt.
|
||||
- Behoben: Unendliche Statuspunkte bei der Neuverteilung
|
||||
- Behoben: Unendliche Statuspunkte bei der Neuverteilung
|
||||
- Behoben: Einige Features blieben auch im Battle.net aktiviert
|
||||
- Italienische Übersetzung hinzugefügt.
|
||||
|
||||
@ -197,7 +201,7 @@ v6.01b Änderungen :
|
||||
- Fehler mit dem Popups der Statuspunktvergabe-Buttons behoben.
|
||||
|
||||
v6.01 Änderungen :
|
||||
- Behoben : unique carry1 items verschwinden nicht wenn sie in LoD 1.10 gecubt werden
|
||||
- Behoben : unique carry1 items verschwinden nicht wenn sie in LoD 1.10 gecubt werden
|
||||
- Schlüssel und Uber-Organe werden nicht mehr entfernt wenn man das rote Portal außerhalb von Harrogath öffnen wollte.
|
||||
- Fehler in der Versionsanzeige wegen einem Konflikt mit D2Mod behoben.
|
||||
|
||||
@ -220,7 +224,7 @@ v5.05 Änderungen :
|
||||
- Kommando "/DisplayLifeAndMana" ist nun "/DisplayLifeMana".
|
||||
- Möglichkeit die Namen von Setgegenständen in Grün bei Mouseover in der gemeinsamen Kiste anzuzeigen
|
||||
- Multiplayer Fehler behoben, indem der gesamte Prozess neu programmiert wurde
|
||||
|
||||
|
||||
v5.04 Änderungen :
|
||||
- Behoben : Status/Skill Punkte per Levelup bug.
|
||||
- Behoben : Multiplayer bugs.
|
||||
@ -274,11 +278,11 @@ v4.02b Änderungen :
|
||||
- Behoben : Alle Funktionen bleiben im offenen Battle.net eingeschaltet.
|
||||
|
||||
v4.02 Änderungen :
|
||||
- Behoben : Das vergessene "d" in "SeparateHardcoreStash=1" in der PlugY.ini ergänzt
|
||||
- Behoben: Standardmäßig wird die Sprache in der PlugY.ini nicht geändert.
|
||||
- Behoben : Item Level sollte nun in allen Konfigurationen von PlugY korrekt angezeigt werden.
|
||||
- Behoben : No more conflict with Battle.net (BigStash disabled on realms)
|
||||
- Weitere Daten auf der zusätzlichen Statusseite eingefügt.
|
||||
- Behoben : Das vergessene "d" in "SeparateHardcoreStash=1" in der PlugY.ini ergänzt
|
||||
- Behoben: Standardmäßig wird die Sprache in der PlugY.ini nicht geändert.
|
||||
- Behoben : Item Level sollte nun in allen Konfigurationen von PlugY korrekt angezeigt werden.
|
||||
- Behoben : No more conflict with Battle.net (BigStash disabled on realms)
|
||||
- Weitere Daten auf der zusätzlichen Statusseite eingefügt.
|
||||
|
||||
v4.01 Änderungen :
|
||||
- Behoben: NbPlayers Schalter stellte immer 8 Spieler ein.
|
||||
@ -344,7 +348,7 @@ v2.02 Änderungen :
|
||||
- Die Goldkistenerweiterung wird bei Realm Spielen automatisch abgeschaltet.
|
||||
- Index Button Fehler behoben.
|
||||
|
||||
v.2.01 Änderungen
|
||||
v.2.01 Änderungen
|
||||
- Fertigkeitsfehler beim LevelUp behoben.
|
||||
- Anzeigefehler im Hauptbildschirm behoben.
|
||||
|
||||
@ -374,13 +378,13 @@ v1.02 Änderungen :
|
||||
- Dateinamen geändert wegen eines Fehlers mit dem IE und ZIP-Files
|
||||
- Man kann die Versions-Information im Hauptbildschirm ändern (siehe Ini-Datei).
|
||||
|
||||
v1.01 Änderungen :
|
||||
- Französische Lokalisierung hinzugefügt (Französisches Liesmich.txt folgt)
|
||||
v1.01 Änderungen :
|
||||
- Französische Lokalisierung hinzugefügt (Französisches Liesmich.txt folgt)
|
||||
- Dateinamen von "PlugY, The Survival Kit.ini" in "PlugY,The_Survival_Kit" geändert.
|
||||
- Installationsbeispiele im Liesmich hinzugefügt.
|
||||
- Fehlerhafte Installation beim PlugY-Aufruf eingebaut.
|
||||
- Fehlerhafte Installation beim PlugY-Aufruf eingebaut.
|
||||
- Den Eintrag "[GENERAL]PlugYDirectory=PlugY\" aus der Ini-Datei entfernt
|
||||
(Man kann ihn weiterhin hinzufügen, sollte aber wissen, was man tut...)
|
||||
(Man kann ihn weiterhin hinzufügen, sollte aber wissen, was man tut...)
|
||||
- Paket von .rar auf .zip umgestellt
|
||||
|
||||
v1.00 Funktionen (es können alle einfach ein- und ausgeschaltet werden) :
|
||||
@ -418,17 +422,17 @@ v1.00 Funktionen (es können alle einfach ein- und ausgeschaltet werden) :
|
||||
|
||||
|
||||
******** INSTALLATION ********
|
||||
Installation :
|
||||
- Entpacke alle Dateien in dein Diablo Verzeichnis.
|
||||
- Kopiere die PlugY.ini und die PlugY.exe in das Verzeichnis in dem dein Mod ist.
|
||||
- Bearbeite die PlugY.ini um die gewünschten Features zu de/aktivieren (dazu weiter unten).
|
||||
- Run PlugY.exe and enjoy :-)
|
||||
Installation :
|
||||
- Entpacke alle Dateien in dein Diablo Verzeichnis.
|
||||
- Kopiere die PlugY.ini und die PlugY.exe in das Verzeichnis in dem dein Mod ist.
|
||||
- Bearbeite die PlugY.ini um die gewünschten Features zu de/aktivieren (dazu weiter unten).
|
||||
- Run PlugY.exe and enjoy :-)
|
||||
|
||||
Beispiel :
|
||||
Du hast LoD in folgendem Verzeichnis installiert : C:\Games\Diablo II\
|
||||
Der Mod und PlugY befindet sich hier : D:\D2Mod\MyMod\
|
||||
Beispiel :
|
||||
Du hast LoD in folgendem Verzeichnis installiert : C:\Games\Diablo II\
|
||||
Der Mod und PlugY befindet sich hier : D:\D2Mod\MyMod\
|
||||
And the second mod is in : D:\D2Mod\MyMod2\
|
||||
Dann müssen die Einstellungen wie folgt lauten :
|
||||
Dann müssen die Einstellungen wie folgt lauten :
|
||||
C:\Games\Diablo II\PlugY.dll
|
||||
D:\D2Mod\MyMod\PlugY\SharedGoldBtns.dc6
|
||||
D:\D2Mod\MyMod\PlugY\PlugYFixed.ini
|
||||
@ -462,7 +466,7 @@ Dann müssen die Einstellungen wie folgt lauten :
|
||||
Deinstallation : Einfach alle PlugY-Dateien löschen
|
||||
|
||||
|
||||
Wenn Probleme auftreten beim Ausführen der PlugY.exe benutze einfach die alte Installation (PlugY_Installer.exe).
|
||||
Wenn Probleme auftreten beim Ausführen der PlugY.exe benutze einfach die alte Installation (PlugY_Installer.exe).
|
||||
Wenn das Spiel unter Windows 2000 nicht startet nimm auch die alte Installation.
|
||||
1. Entpacke das Paket in einen temporären Ordner
|
||||
2. Entpacke das Manual_Installer.zip in das selbe Verzeichnis
|
||||
@ -476,16 +480,16 @@ Hinweis: Man kann ebenfalls die PlugY.dll in das Mod Verzeichnis installieren un
|
||||
|
||||
|
||||
******************** FAQ ******************
|
||||
Ich kann die PlugY.ini nicht finden ?
|
||||
Ich kann die PlugY.ini nicht finden ?
|
||||
Öffne im Explorer Extras/Ordneroptionen/Anzeige und nimm den Haken raus bei Erweiterung bekannter Dateien ausblenden
|
||||
Generell sehr sinnvoll, da man so leichter Viren identifiziert (zB virus.txt.exe da würde man sonst nur txt statt auch das exe sehen..) !
|
||||
|
||||
Wie kann ich gelegentlich im Battle.net spielen, wenn PlugY aktiviert ist ?
|
||||
2 Möglichkeiten:
|
||||
1) Starte PlugY_Uninstall.bat bevor Du Diablo2 startest und starte PlugY_Install.exe danach wenn Du wieder Einzelspieler spielen willst
|
||||
Wie kann ich gelegentlich im Battle.net spielen, wenn PlugY aktiviert ist ?
|
||||
2 Möglichkeiten:
|
||||
1) Starte PlugY_Uninstall.bat bevor Du Diablo2 startest und starte PlugY_Install.exe danach wenn Du wieder Einzelspieler spielen willst
|
||||
2) Nutze die klassische Installation. (Vergiss nicht die PlugY.ini im Diablo2 Verzeichnis zu entfernen)
|
||||
|
||||
Tips: Erzeuge eine Verknüpfung und füge -skiptobnet im "Ziel" Feld mit einem Leerzeichen hinter dem Anführungszeichen hinzu, um direkt ins Battle.Net zu gelangen ohne die Videos.
|
||||
Tips: Erzeuge eine Verknüpfung und füge -skiptobnet im "Ziel" Feld mit einem Leerzeichen hinter dem Anführungszeichen hinzu, um direkt ins Battle.Net zu gelangen ohne die Videos.
|
||||
|
||||
Was tun wenn man "Bad Generic File" mit einem neuen Charakter bekommt ?
|
||||
Dies passiert wenn man einen "schlechten" Gegenstand in der gemeinsamen Kiste hat
|
||||
@ -522,7 +526,7 @@ Ihr könnt die Version des D2Mod-System (v1.02 und Folgende) nutzen um PlugY zu
|
||||
- Startet PlugY_Uninstall.bat um alles zu deinstallieren
|
||||
- Fügt die Zeile "PlugY=PlugY.dll" in den [D2MOD] Abschnitt der D2Mod.ini ein.
|
||||
|
||||
Achtung,
|
||||
Achtung,
|
||||
- Gegenstände im Horadrim-Würfel werden immer im Spieler-Profil gespeichert. Wenn Ihr diese Gegenstände weitergeben wollt, müsst Ihr sie in den Goldschatz umpacken.
|
||||
|
||||
Warnung :
|
||||
@ -561,16 +565,16 @@ Anmerkung:
|
||||
|
||||
Modder können mich erreichen, wenn sie Hilfe brauchen oder mehr Details über das Konfigurations-System haben möchten.
|
||||
|
||||
WARNUNG : Vergesst nicht, dass wenn Konfigurations-System missbraucht wird werden die Benutzer auf alte PlugY Versionen zurückgreifen und ich werde kein andere Möglichkeit haben als es zu deaktivieren.
|
||||
WARNUNG : Vergesst nicht, dass wenn Konfigurations-System missbraucht wird werden die Benutzer auf alte PlugY Versionen zurückgreifen und ich werde kein andere Möglichkeit haben als es zu deaktivieren.
|
||||
|
||||
|
||||
******** Kommentare aus der Konfigurationsdatei ********
|
||||
Standardwerte bedeuten, das sie auch benutzt werden, wenn Ihr die Zeilen in der PlugY.ini löscht.
|
||||
Die Werte in der PlugY.ini (die dem ZIP beiliegt) sind ein Beispiel einer Konfiguration, nicht die Standardwerte.value.
|
||||
|
||||
[LAUNCHING]
|
||||
[LAUNCHING]
|
||||
Dieser Abschnitt beinhaltet Informationen für die PlugY.exe und funktioniert nicht in der PlugYDefault.ini und PlugYFixed.ini
|
||||
|
||||
|
||||
Füge Parameter hinzu um LoD mit der gewünschten Einstellung zu starten
|
||||
Parameter die der PlugY.exe hinzugefügt wurden werden auch an LoD weitergeleitet
|
||||
Standardmäßig werden keine Parameter ausgeführt
|
||||
@ -584,7 +588,7 @@ Param= {-direct -txt -w: Diese 3 Befehle werden an das Spiel
|
||||
Wähle die Dll aus die geladen werden soll.
|
||||
Das gewählte Verzeichnis wird von LoD benutzt (wie die "Ausführen in"-Zeile in einer Verknüpfung).
|
||||
Wenn keine Dll angegeben ist startet LoD ohne PlugY
|
||||
Library=PlugY.dll
|
||||
Library=PlugY.dll
|
||||
|
||||
|
||||
[GENERAL]
|
||||
@ -727,7 +731,7 @@ Es gibt zwei Goldschatzkisten mit Mehrfach-Seiten :
|
||||
- eine persönliche die nur der Spieler sieht ;
|
||||
- eine gemeinsame die jeder Spieler sieht.
|
||||
Benutzt den "Goldschatz"-Knopf um zwischen den beiden Kisten zu wechseln (unten links).
|
||||
Benutze die Pfeiltasten am unteren Rand der Kiste (und die Shift Taste) um zwischen den Seiten umzuschalten
|
||||
Benutze die Pfeiltasten am unteren Rand der Kiste (und die Shift Taste) um zwischen den Seiten umzuschalten
|
||||
Definition: Die letzte Seite, ist die letzte Seite die einen Gegenstand enthält
|
||||
Die Mehrfach-Seiten sind deaktiviert für Diablo2 Classic Charaktere.
|
||||
Startet NIEMALS mehrere Spiele auf einem PC die den gleichen Speicherort für den gemeinsamen Goldschatz benutzen und in Realm Spielen.
|
||||
@ -820,11 +824,11 @@ Beispiel :
|
||||
|
||||
|
||||
[WORLD EVENT]
|
||||
Aktiviert den lokalen World Event
|
||||
Aktiviert den lokalen World Event
|
||||
World Event kann nur in Hölle und nur einmal pro Spiel aktiviert werden.
|
||||
WorldEvent wird alle 75-125 verkauften SOJ aktivert
|
||||
Der Verkauf eines echten SOJ erhöht den Zähler um 100
|
||||
Bei Start eines D2 Spiels ist der SOJ Zähler zwischen 200-3000
|
||||
WorldEvent wird alle 75-125 verkauften SOJ aktivert
|
||||
Der Verkauf eines echten SOJ erhöht den Zähler um 100
|
||||
Bei Start eines D2 Spiels ist der SOJ Zähler zwischen 200-3000
|
||||
Der SOJ Zähler wird alle 10-20 Minuten um 1 erhöht, auch wenn man nicht in einem Spiel ist.
|
||||
When der World Event ausgelöst wird, und man nicht in einem Spiel ist, verliert man ihn.
|
||||
Hinweis 1: Es besteht eine Chance von 1/12 einen WE in der ersten Spielstunde zu erhalten
|
||||
@ -872,12 +876,12 @@ UberBaalChillingArmorTimer=6000 {6000:Timer between Uber Baal casting Chilling
|
||||
|
||||
[INTERFACE]
|
||||
Fügt eine zusätzliche Charakter Info Seite hinzu
|
||||
Man kann auswählen, ob die zuletzt angezeigte Seite erscheint, oder die Hauptseite
|
||||
Man kann auswählen, ob die zuletzt angezeigte Seite erscheint, oder die Hauptseite
|
||||
Die Eigenschaften die in den Extraseiten angezeigt werden können in der PlugY\statsinterface.txt verändert werden (Mit MS Excel öffnen)
|
||||
Es gibt kein Seitenlimit.
|
||||
Unterdrückt den Hintergrund von Schaltflächen, wenn der MOD diese bereits ändert
|
||||
Unterdrückt den Hintergrund von Schaltflächen, wenn der MOD diese bereits ändert
|
||||
- ActiveNewStatsInterface=0 {0:Deaktiviert ; 1: Aktiviert}
|
||||
- SelectMainPageOnOpenning=1 {0:Zuletzt ausgewählte Seite wird angezeigt; 1: Hauptseite wird angezeigt}
|
||||
- SelectMainPageOnOpenning=1 {0:Zuletzt ausgewählte Seite wird angezeigt; 1: Hauptseite wird angezeigt}
|
||||
- PrintButtonsBackgroundOnMainStatsPage=1 {0: Zeigt nicht den Hintergrund an ; 1: Zeigt ihn an }
|
||||
|
||||
|
||||
@ -885,7 +889,7 @@ Unterdrückt den Hintergrund von Schaltflächen, wenn der MOD diese bereits änd
|
||||
[EXTRA]
|
||||
Man kann LOD beliebig oft auf einem Computer starten.
|
||||
Zum Beispiel können Modder Multiplayer-Spiele auf einem PC testen.
|
||||
Warnung :
|
||||
Warnung :
|
||||
Startet keine Spiele mit dem gleichen Speicherort (SavePath), wenn Ihr den gemeinsamen Goldschatz aktiviert habt.
|
||||
Benutzt nicht zweimal den gleichen Charakter zur gleichen Zeit.
|
||||
- ActiveLaunchAnyNumberOfLOD=0 {0:Deaktiviert ; 1: Aktiviert}
|
||||
@ -906,7 +910,7 @@ Behebt den Bug der verhindert das von Microsoft Excel geöffnete Text-Dateien ni
|
||||
- EnabledTXTFilesWhenMSExcelOpenIt=0 {0:Deaktiviert; 1:Aktiviert}
|
||||
|
||||
Die Ladder-Only Runenwörter können für den Singleplayer aktiviert werden.
|
||||
Das wird ermöglicht indem die Spalte "Server" in der runes.txt deaktiviert wird.
|
||||
Das wird ermöglicht indem die Spalte "Server" in der runes.txt deaktiviert wird.
|
||||
Benutze diese Spalte also nicht in deinem Mod wenn diese Funktion aktiviert ist.
|
||||
- ActiveLadderRunewords=0 {0:Deaktiviert; 1:Aktiviert}
|
||||
|
||||
@ -963,5 +967,6 @@ Zur Korrektur der deutschen Übersetzung bitte eine eMail an ChaosEnergy@planetd
|
||||
* Polnisch: Serdel
|
||||
* Russisch: L'Autour
|
||||
* Chinesisch: Nagahaku
|
||||
* Koreanisch: Woodlac
|
||||
|
||||
;--------------------------------------------------------------------------------------;
|
@ -4,7 +4,7 @@
|
||||
; ;
|
||||
; par Yohann Nicolas ;
|
||||
; ;
|
||||
; version 14.02 ;
|
||||
; version 14.03 ;
|
||||
; ;
|
||||
;--------------------------------------------------------------------------------------;
|
||||
|
||||
@ -75,6 +75,10 @@ Toutes ces fonctions peuvent être activé/désactivé via PlugY.ini (voir "COMM
|
||||
/listcube : (beta) Crée un fichier "cube.txt" dans le répertoire de sauvegarde contenant toutes les formules du cube.
|
||||
/renamechar newname : (beta) Renomme la personnage et le sauvegarde.
|
||||
|
||||
Changements apportés par la v14.03 :
|
||||
- Corrige un bug d'affichage d'objects quand une seule page du coffre est remplit.
|
||||
- Ajout de la traduction en coréen.
|
||||
|
||||
Changements apportés par la v14.02 :
|
||||
- Corrige un bug permettant d'avoir plusieurs charmes uniques identiques dans l'inventaire.
|
||||
|
||||
@ -185,7 +189,7 @@ Changements apportés par la v7.01 :
|
||||
- Active les mots runiques du ladder en dehors des royaumes.
|
||||
- Corrige le bug avec l'IA de Uber Baal.
|
||||
- Retire les options de paramètres mis par defaut dans PlugY.ini (comme le mode fenêtré)
|
||||
- Affiche la valeur courante des caracs (sans les bonus magiques) même quand la désallocation des caracs est désactivée.
|
||||
- Affiche la valeur courante des caracs (sans les bonus magiques) même quand la désallocation des caracs est désactivée.
|
||||
- Ajout d'un exécutable pour lancer Plugy (plus aucun fichier de LoD modifié). (RAPPEL)
|
||||
- Traduction en espagnol et polonais.
|
||||
|
||||
@ -378,7 +382,7 @@ Installation normale :
|
||||
|
||||
note : Vous pouvez choisir le répertoire de "Diablo II" comme répertoire d'installation.
|
||||
|
||||
Installation dans un autre mod
|
||||
Installation dans un autre mod
|
||||
- Copier PlugY.ini, PlugY.exe et le répertoire PlugY\ (+son sontenu) dans le répertoire du mod ciblé.
|
||||
- Editer PlugY.ini pour configurer les options (voir section plus bas).
|
||||
- Lancer le jeu PlugY.exe.
|
||||
@ -435,7 +439,7 @@ Si vous avez des problème pour éxécuter PlugY.exe alors utiliser PatchD2File.
|
||||
|
||||
******************** FAQ ******************
|
||||
|
||||
=> Je ne trouve pas le fichier PlugY.ini, où est-il ?
|
||||
=> Je ne trouve pas le fichier PlugY.ini, où est-il ?
|
||||
Dans l'explorateur Windows, aller dans outils->Options des dossiers->affichage.
|
||||
Cocher "Afficher les fichiers et répertoires cachés"
|
||||
Décocher "Masquer les extensions des fichiers dont le type est connu".
|
||||
@ -451,7 +455,7 @@ Une cause possible est l'utilisation du même répertoire de sauvegarde pour des
|
||||
Si c'est le cas, il suffit de changer ce répertoire dans PlugY.ini.
|
||||
Vous pouvez aussi déplacer _LOD_SharedStashSave.sss et _LOD_HC_SharedStashSave.sss dans un autre répertoire.
|
||||
|
||||
=> IL y a "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" dans D2YYMMDD.txt, que dois-je faire ?
|
||||
=> IL y a "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" dans D2YYMMDD.txt, que dois-je faire ?
|
||||
Ceci est juste un avertissement sans conséquence sur le jeu.
|
||||
|
||||
|
||||
@ -500,7 +504,7 @@ Library= {PlugY.dll: Charger PlugY.dll}
|
||||
|
||||
[GENERAL]
|
||||
Active ou désactive PlugY
|
||||
Les dll des champs "DllToLoad" ne sont plus chargés quand ActivePlugin=0.
|
||||
Les dll des champs "DllToLoad" ne sont plus chargés quand ActivePlugin=0.
|
||||
Ci-dessous, les valeurs par défauts et entre {} des exemples avec leurs significations :
|
||||
- ActivePlugin=0 {0:Charge aucunes fonctions; 1:Plugin activé}
|
||||
|
||||
@ -838,5 +842,6 @@ Déplace Deckar Cain à coté du portail d'Harrogath.
|
||||
* Russe : L'Autour
|
||||
* Chinois (Traditionnel): Nagahaku
|
||||
* Japanase : CaiMiao
|
||||
* Coréen : Woodlac
|
||||
|
||||
;--------------------------------------------------------------------------------------;
|
@ -4,7 +4,7 @@
|
||||
; ;
|
||||
; by Yohann Nicolas ;
|
||||
; ;
|
||||
; version 14.02 ;
|
||||
; version 14.03 ;
|
||||
; ;
|
||||
;--------------------------------------------------------------------------------------;
|
||||
|
||||
@ -75,6 +75,10 @@ Each features can be turn on/off via PlugY.ini (see "COMMENTS ON THE CONFIGURATI
|
||||
/listcube : (beta) Create a "cube.txt" file in save directory containing all cube's receipts.
|
||||
/renamechar newname : (beta) Rename your character and save it.
|
||||
|
||||
v14.03 changes :
|
||||
- Fix a items diplay bug when only one stash page is filled.
|
||||
- Add Korean Translation.
|
||||
|
||||
v14.02 changes :
|
||||
- Fix a bug allowing multiple identical unique charms to be in inventory.
|
||||
|
||||
@ -120,7 +124,7 @@ v14.00 changes :
|
||||
- Update Chinese transalation. (Thanks to Nagahaku)
|
||||
- Fix some translations in different languages.
|
||||
|
||||
v12.00 changes :
|
||||
v12.00 changes :
|
||||
- Unofficial version supporting LOD 1.14d
|
||||
|
||||
v11.02 changes :
|
||||
@ -141,7 +145,7 @@ v11.01 changes :
|
||||
- Rename command /rename to /renamechar.
|
||||
- Remove unfinished command /reload.
|
||||
|
||||
v11.00 changes :
|
||||
v11.00 changes :
|
||||
- Unofficial version supporting LOD 1.13d
|
||||
|
||||
v10.01 changes :
|
||||
@ -283,7 +287,7 @@ v4.02 changes :
|
||||
- Added data in the extra stats page.
|
||||
|
||||
v4.01 changes :
|
||||
- Fixed : NbPlayers always set to 8 when active.
|
||||
- Fixed : NbPlayers always set to 8 when active.
|
||||
- Added data in the extra stats page.
|
||||
|
||||
v4.00b changes :
|
||||
@ -340,7 +344,7 @@ v2.03b changes :
|
||||
v2.03 changes :
|
||||
- Major fix : Correct and secure the saving procedure.
|
||||
- No more crash of the host game when a character is unable to enter the game.
|
||||
- Unassign stats points button greyed when base stat is above 255 fixed.
|
||||
- Unassign stats points button greyed when base stat is above 255 fixed.
|
||||
- Change version printing on main screen (change color & PlugY version in right corner)
|
||||
- Character without PlugY can join game host with PlugY enabled.
|
||||
|
||||
@ -384,14 +388,14 @@ v1.02 changes :
|
||||
- Re-changed name files due to an IE bug with colon in zip file.
|
||||
- Ability to change the version text print in the main menu (see ini file).
|
||||
|
||||
v1.01 changes :
|
||||
- Localized for french version (wait for an french readme.txt)
|
||||
- Changed filename from "PlugY, The Survival Kit.ini" to "PlugY,The_Survival_Kit".
|
||||
- Added example for installation in the readme.
|
||||
- Detection of bad installation on starting plugY.
|
||||
- Removed from the ini default file the [GENERAL]PlugYDirectory=PlugY\
|
||||
(you can add it if you want but need to know what are you doing...)
|
||||
- Released in .zip file instead of .rar
|
||||
v1.01 changes :
|
||||
- Localized for french version (wait for an french readme.txt)
|
||||
- Changed filename from "PlugY, The Survival Kit.ini" to "PlugY,The_Survival_Kit".
|
||||
- Added example for installation in the readme.
|
||||
- Detection of bad installation on starting plugY.
|
||||
- Removed from the ini default file the [GENERAL]PlugYDirectory=PlugY\
|
||||
(you can add it if you want but need to know what are you doing...)
|
||||
- Released in .zip file instead of .rar
|
||||
|
||||
v1.00 features (can all be easily enabled or disabled) :
|
||||
- You can change the save path directory.
|
||||
@ -478,7 +482,7 @@ So the new installation is :
|
||||
|
||||
Uninstallation : Use the uninstaller or simply remove all PlugY files.
|
||||
Note : You can also move PlugY.dll in the mod folder but you must remove any on in D2 folder.
|
||||
Note : PlugY directory and its contents can be put in a mpq.
|
||||
Note : PlugY directory and its contents can be put in a mpq.
|
||||
|
||||
------- D2File Patcher
|
||||
|
||||
@ -491,24 +495,24 @@ If you have problem when you run PlugY.exe then use PatchD2File.exe. (It happend
|
||||
|
||||
******************** FAQ ******************
|
||||
|
||||
=> I can't find PlugY.ini file, where is it ?
|
||||
=> I can't find PlugY.ini file, where is it ?
|
||||
In Windows Explorer, selecting Tools->Folder Options->View.
|
||||
Mark "Show Hidden files and Folders".
|
||||
Unmark "Hide extensions for know file types".
|
||||
Then you will for sure see the ini file.
|
||||
Then you will for sure see the ini file.
|
||||
|
||||
|
||||
=> How do I Play sometimes on Battle.net when PlugY is installed ?
|
||||
PlugY disable the connection to Battle.net.
|
||||
|
||||
=> What do I do if I have an error like "Bad Generic File" on loading a new Character ?
|
||||
This can appear when you have bad item in the shared stash file.
|
||||
=> What do I do if I have an error like "Bad Generic File" on loading a new Character ?
|
||||
This can appear when you have bad item in the shared stash file.
|
||||
A possible cause is to use same save folder for different mod.
|
||||
In this case, just change the save folder in PlugY.ini.
|
||||
In this case, just change the save folder in PlugY.ini.
|
||||
You can also move the _LOD_SharedStashSave.sss and _LOD_HC_SharedStashSave.sss to another directory.
|
||||
|
||||
=> I get "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" in D2YYMMDD.txt, what I should do ?
|
||||
It's just a warning, it causes no problem in game.
|
||||
=> I get "sUnitItemInsertItemInvGridBase failed at 1046 in C:\projects\D2\head\Diablo2\Source\D2Client\UNIT\Item.cpp" in D2YYMMDD.txt, what I should do ?
|
||||
It's just a warning, it causes no problem in game.
|
||||
|
||||
|
||||
******** CONFIGURATION ********
|
||||
@ -924,5 +928,6 @@ Move Cain near Harrogath waypoint.
|
||||
* Russian: L'Autour
|
||||
* Chinese (Traditional): Nagahaku
|
||||
* Japanase : CaiMiao
|
||||
* Korean : Woodlac
|
||||
|
||||
;--------------------------------------------------------------------------------------;
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user