mirror of
https://gitlab.com/hashborgir/d2tweaks-rnd2k.git
synced 2024-11-30 04:35:58 +00:00
Working on right click gem extraction
This commit is contained in:
parent
d7fab9d077
commit
74f1d9de01
@ -47,12 +47,12 @@
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>..\..\Diablo II\MODS\ironman-dev</OutDir>
|
||||
<OutDir>..\..\Diablo II\MODS\ironman-dev\</OutDir>
|
||||
<IntDir>$(SolutionDir)Build\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>..\..\Diablo II\MODS\ironman-dev</OutDir>
|
||||
<OutDir>..\..\Diablo II\MODS\ironman-dev\</OutDir>
|
||||
<IntDir>$(SolutionDir)Build\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
|
Binary file not shown.
@ -1,3 +1,2 @@
|
||||
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Microsoft\VC\v170\Microsoft.CppBuild.targets(517,5): warning MSB8004: Output Directory does not end with a trailing slash. This build instance will add the slash as it is required to allow proper evaluation of the Output Directory.
|
||||
ui_manager.cpp
|
||||
ui_manager.cpp
|
||||
D2tweaks.vcxproj -> D:\Diablo II\MODS\ironman-dev\D2tweaks.dll
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -28,6 +28,9 @@ extern int randStatBool;
|
||||
|
||||
extern bool m_stats_enabled;
|
||||
|
||||
extern bool m_help_enabled;
|
||||
|
||||
|
||||
namespace diablo2 {
|
||||
namespace structures {
|
||||
struct unit;
|
||||
|
@ -17,6 +17,7 @@ namespace d2_tweaks {
|
||||
class loot_filter_settings_toggle_menu final : public ui::menu, singleton<loot_filter_settings_toggle_menu> {
|
||||
ui::controls::button* m_toggle_filter_settings_btn;
|
||||
ui::controls::button* m_btn_toggle_stats;
|
||||
ui::controls::button* m_btn_toggle_help;
|
||||
menu* m_filter_settings_menu;
|
||||
bool m_show;
|
||||
public:
|
||||
@ -24,6 +25,7 @@ namespace d2_tweaks {
|
||||
|
||||
void toggle_filter_settings_click();
|
||||
void toggle_stats_settings_click();
|
||||
void toggle_help_click();
|
||||
|
||||
void draw() override;
|
||||
|
||||
|
@ -235,6 +235,7 @@ namespace d2_tweaks {
|
||||
|
||||
struct item_move_cs : packet_header {
|
||||
uint32_t item_guid;
|
||||
const char* item_code;
|
||||
uint8_t target_page;
|
||||
uint32_t bag_guid = 0;
|
||||
bool updateBag;
|
||||
|
@ -86,5 +86,10 @@ namespace diablo2 {
|
||||
static bool is_gamble_open();
|
||||
static uint8_t current_interact_menu();
|
||||
static void resync_vendor_inventory(structures::unit* ptNPC);
|
||||
|
||||
static int32_t send_to_server_9(BYTE type, DWORD num, DWORD unk1);
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
@ -47,5 +47,6 @@ namespace diablo2 {
|
||||
|
||||
static void update_inventory_items(structures::game* game, structures::unit* player);
|
||||
static uint32_t __fastcall diablo2::d2_game::transmogrify(diablo2::structures::game* game, diablo2::structures::unit* player);
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
|
||||
#include <d2tweaks/common/common.h>
|
||||
#include <d2tweaks/common/protocol.h>
|
||||
#include <d2tweaks/common/asset_manager.h>
|
||||
@ -20,7 +19,6 @@
|
||||
#include <diablo2/d2gfx.h>
|
||||
#include <diablo2/d2cmp.h>
|
||||
|
||||
|
||||
#include <diablo2/structures/unit.h>
|
||||
#include <diablo2/structures/inventory.h>
|
||||
#include <diablo2/structures/item_data.h>
|
||||
@ -45,10 +43,19 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
||||
#include <DllNotify.h>
|
||||
#include <D2Template.h>
|
||||
|
||||
#include <diablo2/d2gfx.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
MODULE_INIT(autosort)
|
||||
|
||||
enum ColorEnum {
|
||||
@ -88,7 +95,6 @@ std::map<int, diablo2::ui_font_t> fontMap = {
|
||||
{13, diablo2::ui_font_t::UI_FONT_INGAMECHAT}
|
||||
};
|
||||
|
||||
|
||||
class inventory_sort_menu : public d2_tweaks::ui::menu {
|
||||
d2_tweaks::common::asset* m_buttons_img;
|
||||
|
||||
@ -115,8 +121,6 @@ public:
|
||||
m_sort_cube_btn = get_button("m_sort_cube_btn", std::bind(&inventory_sort_menu::sort_cube_click, this));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function to find the Diablo II window handle
|
||||
HWND FindDiabloIIWindow() {
|
||||
return FindWindow(NULL, "Diablo II");
|
||||
@ -132,11 +136,81 @@ public:
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int statsFont = GetPrivateProfileIntA("Options", "statsFont", 0, "./d2tweaks.ini");
|
||||
|
||||
ULONGLONG lastSendTime = GetTickCount64();
|
||||
|
||||
|
||||
// Function to split a string into words
|
||||
std::vector<std::string> split(const std::string& s, char delim) {
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
std::vector<std::string> tokens;
|
||||
while (getline(ss, item, delim)) {
|
||||
tokens.push_back(item);
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
std::wstring stringToWstring(const std::string& str) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
return converter.from_bytes(str);
|
||||
}
|
||||
|
||||
// Function to justify a line of text
|
||||
void justifyLine(const std::vector<std::string>& words, int start, int end, int maxLineLength, int& xPos, int yPos, int padding) {
|
||||
int lineLength = 0;
|
||||
for (int i = start; i <= end; i++) {
|
||||
lineLength += words[i].length() * 8; // Assuming each character has a width of 8 pixels
|
||||
}
|
||||
|
||||
int numSpaces = end - start;
|
||||
int extraSpaces = maxLineLength - lineLength - padding * 2;
|
||||
|
||||
int spaceWidth = 8;
|
||||
int extraSpacePerGap = numSpaces > 0 ? extraSpaces / numSpaces : 0;
|
||||
int remainingSpaces = numSpaces > 0 ? extraSpaces % numSpaces : 0;
|
||||
|
||||
for (int i = start; i <= end; i++) {
|
||||
diablo2::d2_win::draw_boxed_text(const_cast<wchar_t*>(stringToWstring(words[i]).c_str()), xPos + padding, yPos, 0, 0, diablo2::UI_COLOR_WHITE); // Assuming paletteIndex, transTbl, and color are 0
|
||||
xPos += words[i].length() * 8 + spaceWidth + extraSpacePerGap + padding;
|
||||
|
||||
if (remainingSpaces > 0) {
|
||||
xPos += 1; // Add an extra pixel for the remaining spaces
|
||||
remainingSpaces--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to draw justified text inside a box with padding
|
||||
void drawJustifiedTextInBox(const std::string& text, int boxX, int boxY, int boxWidth, int boxHeight, int padding) {
|
||||
std::vector<std::string> words = split(text, ' ');
|
||||
int maxLineLength = boxWidth;
|
||||
int xPos = boxX + padding;
|
||||
int yPos = boxY + padding;
|
||||
|
||||
for (size_t i = 0; i < words.size(); ) {
|
||||
int start = i;
|
||||
int end = i;
|
||||
int lineLength = 0;
|
||||
|
||||
// Find the end index for the current line
|
||||
while (end < words.size() && lineLength + words[end].length() <= maxLineLength) {
|
||||
lineLength += words[end].length();
|
||||
if (end > start) {
|
||||
lineLength++; // Add space width
|
||||
}
|
||||
end++;
|
||||
}
|
||||
|
||||
justifyLine(words, start, end - 1, maxLineLength, xPos, yPos, padding);
|
||||
yPos += 16; // Assuming each line is 16 pixels tall
|
||||
xPos = boxX + padding;
|
||||
i = end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void draw() override {
|
||||
@ -157,16 +231,12 @@ public:
|
||||
// Initialize statValue
|
||||
int32_t statValue = 0;
|
||||
|
||||
|
||||
if (diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_STASH)) {
|
||||
diablo2::d2_gfx::draw_filled_rect(130, 48, 640, 155, 5, 50);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (m_stats_enabled) {
|
||||
for (const auto& stat : stats) {
|
||||
|
||||
double param = 6;
|
||||
|
||||
int32_t spirits = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(185), NULL);
|
||||
@ -175,7 +245,7 @@ public:
|
||||
switch (stat.stat) {
|
||||
// 2. (statValue <- this is probably op stat1 ? * baseValue <- this is probably op base ) / 2 ^ param
|
||||
|
||||
// (op stat1 value * base stat value) / (2 ^ param)
|
||||
// (op stat1 value * base stat value) / (2 ^ param)
|
||||
// let's try this fucking thing
|
||||
|
||||
case 190: {
|
||||
@ -229,7 +299,6 @@ public:
|
||||
// By default, get player stats
|
||||
statValue = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(stat.stat), NULL);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,7 +342,6 @@ public:
|
||||
diablo2::d2_common::set_stat(player, static_cast<diablo2::unit_stats_t>(randStat), 0, 0);
|
||||
diablo2::d2_common::set_stat(player, static_cast<diablo2::unit_stats_t>(randStatBool), 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
auto statValueStr = std::to_wstring(statValue);
|
||||
@ -301,175 +369,185 @@ public:
|
||||
&& !diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_HELP)
|
||||
&& !diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_MERC)
|
||||
&& !diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_SCROLL)) {
|
||||
|
||||
// Draw stats
|
||||
diablo2::d2_win::set_current_font(fontMap[statsFont]); // Set font to FONT16
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(statText.c_str()), stat.x1, stat.y1 + textOffset, stat.colorStat, 0);
|
||||
|
||||
diablo2::d2_win::set_current_font(fontMap[statsFont]); // Set font to FONT16
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(statValueStr.c_str()), stat.x2, stat.y2 + textOffset, stat.colorStatValue, 0);
|
||||
|
||||
|
||||
//diablo2::d2_win::draw_boxed_text(const_cast<wchar_t*>(statText.c_str()), stat.x1, stat.y1 + textOffset, 1, 0, stat.colorStat);
|
||||
//diablo2::d2_win::draw_boxed_text(const_cast<wchar_t*>(statValueStr.c_str()), stat.x2, stat.y2 + textOffset, 1, 4, stat.colorStatValue);
|
||||
|
||||
// diablo2::d2_win::set_current_font(diablo2::UI_FONT_16); // Set font to FONT16
|
||||
|
||||
|
||||
//diablo2::structures::d2_cmp::init_gfx_data(&g_gfxdata);
|
||||
|
||||
//diablo2::d2_gfx::draw_image(&g_gfxdata, 200, 200, 1, 5, 0);
|
||||
|
||||
// instead try to load direct jpg with gdi and insetad ofloading jpg file, specify it bb64 encoded and decode it.
|
||||
|
||||
diablo2::ui_color_t::UI_COLOR_WHITE;
|
||||
|
||||
|
||||
// print player health, mana, and stamina bars, lastexp, nextexp, and level
|
||||
// Get current HP, Mana, and Stamina along with their maximum values
|
||||
int statHP = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(6), NULL) / 256;
|
||||
int statMaxHP = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(7), NULL) / 256;
|
||||
int statMana = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(8), NULL) / 256;
|
||||
int statMaxMana = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(9), NULL) / 256;
|
||||
int statStamina = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(10), NULL) / 256;
|
||||
int statMaxStamina = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(11), NULL) / 256;
|
||||
|
||||
// Convert the integer values to wide character strings
|
||||
std::wstring strHP = std::to_wstring(statHP);
|
||||
std::wstring strMaxHP = std::to_wstring(statMaxHP);
|
||||
std::wstring strMana = std::to_wstring(statMana);
|
||||
std::wstring strMaxMana = std::to_wstring(statMaxMana);
|
||||
std::wstring strStamina = std::to_wstring(statStamina);
|
||||
std::wstring strMaxStamina = std::to_wstring(statMaxStamina);
|
||||
|
||||
diablo2::d2_win::set_current_font(diablo2::UI_FONT_16); // Set font to FONT16
|
||||
|
||||
// Calculate the percentages of current HP, Mana, and Stamina
|
||||
float healthPercentage = static_cast<float>(statHP) / static_cast<float>(statMaxHP);
|
||||
float manaPercentage = static_cast<float>(statMana) / static_cast<float>(statMaxMana);
|
||||
float staminaPercentage = static_cast<float>(statStamina) / static_cast<float>(statMaxStamina);
|
||||
|
||||
|
||||
|
||||
int sHeight = 768;
|
||||
int sWidth = 1280;
|
||||
|
||||
int sHCenter = sHeight / 2;
|
||||
int sWCenter = sWidth / 2;
|
||||
|
||||
//spdlog::info("healthPercentage: {}", healthPercentage);
|
||||
|
||||
|
||||
// Define default bar color
|
||||
DWORD barColor = 0;
|
||||
|
||||
// Determine bar color based on health percentage
|
||||
if (healthPercentage > .80) {
|
||||
barColor = 118;
|
||||
}
|
||||
else if (healthPercentage > .50) {
|
||||
barColor = 13;
|
||||
}
|
||||
else {
|
||||
barColor = 5;
|
||||
}
|
||||
|
||||
//spdlog::info("barColor: {}", barColor);
|
||||
|
||||
|
||||
|
||||
// Define the dimensions for the bars
|
||||
int barWidth = 200; // Width of the bars
|
||||
int barHeight = 16; // Height of the bars
|
||||
|
||||
// Define the coordinates for the bars
|
||||
int barX = sWCenter - 100; // Left coordinate of the bars
|
||||
int barY_HP = 654; // Top coordinate of the HP bar
|
||||
int barY_Mana = barY_HP + barHeight + 4; // Top coordinate of the Mana bar with separator
|
||||
int barY_Stamina = barY_Mana + barHeight + 4; // Top coordinate of the Stamina bar with separator
|
||||
|
||||
std::wstring life = L"L: " + strHP + L" / " + strMaxHP;
|
||||
std::wstring mana = L"M: " + strMana + L" / " + strMaxMana;
|
||||
std::wstring stamina = L"" + strStamina + L" / " + strMaxStamina;
|
||||
|
||||
int lifeWidth = diablo2::d2_win::get_text_pixel_width(const_cast<wchar_t*>(life.c_str()));
|
||||
int manaWidth = diablo2::d2_win::get_text_pixel_width(const_cast<wchar_t*>(mana.c_str()));
|
||||
int staminaWidth = diablo2::d2_win::get_text_pixel_width(const_cast<wchar_t*>(stamina.c_str()));
|
||||
|
||||
|
||||
// Calculate the filled widths of the bars
|
||||
int filledHPWidth = static_cast<int>(healthPercentage * barWidth);
|
||||
int filledManaWidth = static_cast<int>(manaPercentage * barWidth);
|
||||
int filledStaminaWidth = static_cast<int>(staminaPercentage * barWidth);
|
||||
|
||||
// at 345 we need to minus the width of the text
|
||||
sWCenter = barX + 100 - (diablo2::d2_win::get_text_pixel_width(const_cast<wchar_t*>(mana.c_str())) / 2);
|
||||
|
||||
HWND diabloIIWnd = FindDiabloIIWindow();
|
||||
|
||||
// Draw the filled HP bar
|
||||
diablo2::d2_gfx::draw_filled_rect(barX, barY_HP, barX + filledHPWidth, barY_HP + barHeight, barColor, 255);
|
||||
//DrawFilledRect(diabloIIWnd, barX, barY_HP, barX + filledHPWidth, barY_HP + barHeight, RGB(255, 0, 0)); // Red color for HP
|
||||
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(life.c_str()), sWCenter, barY_HP + 15, stat.colorStatValue, 0);
|
||||
|
||||
|
||||
|
||||
// Draw the filled Mana bar
|
||||
diablo2::d2_gfx::draw_filled_rect(barX, barY_Mana, barX + filledManaWidth, barY_Mana + barHeight, 140, 255);
|
||||
//DrawFilledRect(diabloIIWnd, barX, barY_Mana, barX + filledManaWidth, barY_Mana + barHeight, RGB(100, 100, 255)); // Blue color for Mana
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(mana.c_str()), sWCenter, barY_Mana + 15, stat.colorStatValue, 0);
|
||||
|
||||
/*
|
||||
// Define the number of separators
|
||||
int numColors = 256;
|
||||
int numColumns = 4;
|
||||
int colorsPerColumn = numColors / numColumns;
|
||||
int separatorHeight = 1; // Height of each separator
|
||||
int columnOffset = 200; // Offset for each column
|
||||
|
||||
// Iterate over each column
|
||||
for (int column = 0; column < numColumns; ++column) {
|
||||
// Calculate the starting X coordinate for this column
|
||||
int columnX = barX + (column * columnOffset);
|
||||
|
||||
// Draw the filled Mana bars for this column
|
||||
for (int i = 0; i < colorsPerColumn; ++i) {
|
||||
int colorIndex = column * colorsPerColumn + i;
|
||||
int separatorY = barY_Mana + barHeight + i * (separatorHeight + barHeight);
|
||||
|
||||
// Draw the filled Mana bar
|
||||
diablo2::d2_gfx::draw_filled_rect(columnX, separatorY, columnX + filledManaWidth, separatorY + barHeight, colorIndex, 255);
|
||||
|
||||
// Draw the index number at the same coordinates as the bar
|
||||
std::wstring indexStr = std::to_wstring(colorIndex);
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(indexStr.c_str()), columnX - 20, separatorY, diablo2::UI_COLOR_DARK_GOLD, 0);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Draw the filled Stamina bar
|
||||
// diablo2::d2_gfx::draw_filled_rect(barX, barY_Stamina, barX + filledStaminaWidth, barY_Stamina + barHeight, 12, 255);
|
||||
//DrawFilledRect(diabloIIWnd, barX, barY_Stamina, barX + filledStaminaWidth, barY_Stamina + barHeight, RGB(255, 255, 0)); // Green color for Stamina
|
||||
|
||||
int statLevel = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(12), NULL);
|
||||
int statLastExp = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(29), NULL);
|
||||
int statNextExp = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(30), NULL);
|
||||
|
||||
diablo2::d2_win::set_current_font(diablo2::UI_FONT_16); // Set font to FONT16
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//diablo2::d2_win::draw_boxed_text(const_cast<wchar_t*>(statText.c_str()), stat.x1, stat.y1 + textOffset, 1, 0, stat.colorStat);
|
||||
//diablo2::d2_win::draw_boxed_text(const_cast<wchar_t*>(statValueStr.c_str()), stat.x2, stat.y2 + textOffset, 1, 4, stat.colorStatValue);
|
||||
|
||||
// diablo2::d2_win::set_current_font(diablo2::UI_FONT_16); // Set font to FONT16
|
||||
|
||||
//diablo2::structures::d2_cmp::init_gfx_data(&g_gfxdata);
|
||||
|
||||
//diablo2::d2_gfx::draw_image(&g_gfxdata, 200, 200, 1, 5, 0);
|
||||
|
||||
// instead try to load direct jpg with gdi and insetad ofloading jpg file, specify it bb64 encoded and decode it.
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (m_help_enabled) {
|
||||
|
||||
const int windowWidth = 1280;
|
||||
const int windowHeight = 768;
|
||||
|
||||
const int boxWidth = 1000;
|
||||
const int boxHeight = 680;
|
||||
|
||||
const int boxX = (windowWidth - boxWidth) / 2;
|
||||
const int boxY = (windowHeight - boxHeight) / 2;
|
||||
|
||||
const std::string helpText = "This is a sample help screen! You can put help text in here!?";
|
||||
|
||||
// Draw filled background box
|
||||
diablo2::d2_gfx::draw_filled_rect(boxX, boxY, boxX + boxWidth, boxY + boxHeight, 0, 255);
|
||||
|
||||
|
||||
// Draw justified text inside the box with padding
|
||||
drawJustifiedTextInBox(helpText, boxX, boxY, boxWidth, boxHeight, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
diablo2::ui_color_t::UI_COLOR_WHITE;
|
||||
|
||||
// print player health, mana, and stamina bars, lastexp, nextexp, and level
|
||||
// Get current HP, Mana, and Stamina along with their maximum values
|
||||
int statHP = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(6), NULL) / 256;
|
||||
int statMaxHP = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(7), NULL) / 256;
|
||||
int statMana = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(8), NULL) / 256;
|
||||
int statMaxMana = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(9), NULL) / 256;
|
||||
int statStamina = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(10), NULL) / 256;
|
||||
int statMaxStamina = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(11), NULL) / 256;
|
||||
|
||||
// Convert the integer values to wide character strings
|
||||
std::wstring strHP = std::to_wstring(statHP);
|
||||
std::wstring strMaxHP = std::to_wstring(statMaxHP);
|
||||
std::wstring strMana = std::to_wstring(statMana);
|
||||
std::wstring strMaxMana = std::to_wstring(statMaxMana);
|
||||
std::wstring strStamina = std::to_wstring(statStamina);
|
||||
std::wstring strMaxStamina = std::to_wstring(statMaxStamina);
|
||||
|
||||
diablo2::d2_win::set_current_font(diablo2::UI_FONT_16); // Set font to FONT16
|
||||
|
||||
// Calculate the percentages of current HP, Mana, and Stamina
|
||||
float healthPercentage = static_cast<float>(statHP) / static_cast<float>(statMaxHP);
|
||||
float manaPercentage = static_cast<float>(statMana) / static_cast<float>(statMaxMana);
|
||||
float staminaPercentage = static_cast<float>(statStamina) / static_cast<float>(statMaxStamina);
|
||||
|
||||
int sHeight = 768;
|
||||
int sWidth = 1280;
|
||||
|
||||
int sHCenter = sHeight / 2;
|
||||
int sWCenter = sWidth / 2;
|
||||
|
||||
//spdlog::info("healthPercentage: {}", healthPercentage);
|
||||
|
||||
// Define default bar color
|
||||
DWORD barColor = 0;
|
||||
|
||||
// Determine bar color based on health percentage
|
||||
if (healthPercentage > .80) {
|
||||
barColor = 118;
|
||||
}
|
||||
else if (healthPercentage > .50) {
|
||||
barColor = 13;
|
||||
}
|
||||
else {
|
||||
barColor = 5;
|
||||
}
|
||||
|
||||
//spdlog::info("barColor: {}", barColor);
|
||||
|
||||
// Define the dimensions for the bars
|
||||
int barWidth = 200; // Width of the bars
|
||||
int barHeight = 16; // Height of the bars
|
||||
|
||||
// Define the coordinates for the bars
|
||||
int barX = 245; // Left coordinate of the bars
|
||||
int barY_HP = 728; // Top coordinate of the HP bar
|
||||
int barY_Mana = barY_HP + barHeight + 4; // Top coordinate of the Mana bar with separator
|
||||
int barY_Stamina = barY_Mana + barHeight + 4; // Top coordinate of the Stamina bar with separator
|
||||
|
||||
std::wstring life = strHP + L" / " + strMaxHP;
|
||||
std::wstring mana = strMana + L" / " + strMaxMana;
|
||||
std::wstring stamina = strStamina + L" / " + strMaxStamina;
|
||||
|
||||
// Calculate the filled widths of the bars
|
||||
int filledHPWidth = static_cast<int>(healthPercentage * barWidth);
|
||||
int filledManaWidth = static_cast<int>(manaPercentage * barWidth);
|
||||
int filledStaminaWidth = static_cast<int>(staminaPercentage * barWidth);
|
||||
|
||||
// at 345 we need to minus the width of the text
|
||||
sWCenter = barX + 100 - (diablo2::d2_win::get_text_pixel_width(const_cast<wchar_t*>(mana.c_str())) / 2);
|
||||
|
||||
HWND diabloIIWnd = FindDiabloIIWindow();
|
||||
|
||||
// Draw the filled HP bar
|
||||
diablo2::d2_gfx::draw_filled_rect(barX, barY_HP, barX + filledHPWidth, barY_HP + barHeight, barColor, 255);
|
||||
//DrawFilledRect(diabloIIWnd, barX, barY_HP, barX + filledHPWidth, barY_HP + barHeight, RGB(255, 0, 0)); // Red color for HP
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(life.c_str()), sWCenter, barY_HP + 15, diablo2::UI_COLOR_WHITE, 0);
|
||||
|
||||
// Draw the filled Mana bar
|
||||
diablo2::d2_gfx::draw_filled_rect(barX, barY_Mana, barX + filledManaWidth, barY_Mana + barHeight, 140, 255);
|
||||
//DrawFilledRect(diabloIIWnd, barX, barY_Mana, barX + filledManaWidth, barY_Mana + barHeight, RGB(100, 100, 255)); // Blue color for Mana
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(mana.c_str()), sWCenter, barY_Mana + 15, diablo2::UI_COLOR_WHITE, 0);
|
||||
|
||||
/*
|
||||
// Define the number of separators
|
||||
int numColors = 256;
|
||||
int numColumns = 4;
|
||||
int colorsPerColumn = numColors / numColumns;
|
||||
int separatorHeight = 1; // Height of each separator
|
||||
int columnOffset = 200; // Offset for each column
|
||||
|
||||
// Iterate over each column
|
||||
for (int column = 0; column < numColumns; ++column) {
|
||||
// Calculate the starting X coordinate for this column
|
||||
int columnX = barX + (column * columnOffset);
|
||||
|
||||
// Draw the filled Mana bars for this column
|
||||
for (int i = 0; i < colorsPerColumn; ++i) {
|
||||
int colorIndex = column * colorsPerColumn + i;
|
||||
int separatorY = barY_Mana + barHeight + i * (separatorHeight + barHeight);
|
||||
|
||||
// Draw the filled Mana bar
|
||||
diablo2::d2_gfx::draw_filled_rect(columnX, separatorY, columnX + filledManaWidth, separatorY + barHeight, colorIndex, 255);
|
||||
|
||||
// Draw the index number at the same coordinates as the bar
|
||||
std::wstring indexStr = std::to_wstring(colorIndex);
|
||||
diablo2::d2_win::draw_text(const_cast<wchar_t*>(indexStr.c_str()), columnX - 20, separatorY, diablo2::UI_COLOR_DARK_GOLD, 0);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw the filled Stamina bar
|
||||
// diablo2::d2_gfx::draw_filled_rect(barX, barY_Stamina, barX + filledStaminaWidth, barY_Stamina + barHeight, 12, 255);
|
||||
//DrawFilledRect(diabloIIWnd, barX, barY_Stamina, barX + filledStaminaWidth, barY_Stamina + barHeight, RGB(255, 255, 0)); // Green color for Stamina
|
||||
|
||||
int statLevel = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(12), NULL);
|
||||
int statLastExp = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(29), NULL);
|
||||
int statNextExp = diablo2::d2_common::get_stat(player, static_cast<diablo2::unit_stats_t>(30), NULL);
|
||||
|
||||
diablo2::d2_win::set_current_font(diablo2::UI_FONT_16); // Set font to FONT16
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (!should_draw()) {
|
||||
m_sort_inventory_btn->set_enabled(false);
|
||||
m_sort_inventory_btn->set_visible(false);
|
||||
@ -546,12 +624,9 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void d2_tweaks::client::modules::autosort::init_early() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void d2_tweaks::client::modules::autosort::init() {
|
||||
char acPathToIni[MAX_PATH] = { 0 };
|
||||
const char* pcIniFile = "\\d2tweaks.ini";
|
||||
@ -583,5 +658,4 @@ void d2_tweaks::client::modules::autosort::handle_packet(common::packet_header*
|
||||
|
||||
diablo2::d2_common::inv_add_item(player->inventory, item, inventorySort->tx, inventorySort->ty, inventoryIndex, true, item->item_data->page);
|
||||
diablo2::d2_common::inv_update_item(player->inventory, item, true);
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,24 @@
|
||||
#include <DllNotify.h>
|
||||
#include <D2Template.h>
|
||||
|
||||
|
||||
#include <diablo2/d2gfx.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <string>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
#include <cstdlib> // For system function
|
||||
|
||||
#include <shellapi.h> // For ShellExecute
|
||||
|
||||
using namespace d2_tweaks::client::modules;
|
||||
bool m_stats_enabled = false;
|
||||
bool m_help_enabled = false;
|
||||
|
||||
d2_tweaks::client::modules::loot_filter_settings_toggle_menu::loot_filter_settings_toggle_menu(token) {
|
||||
m_show = false;
|
||||
@ -39,6 +56,11 @@ d2_tweaks::client::modules::loot_filter_settings_toggle_menu::loot_filter_settin
|
||||
m_btn_toggle_stats->set_on_click(std::bind(&loot_filter_settings_toggle_menu::toggle_stats_settings_click, this));
|
||||
|
||||
|
||||
m_btn_toggle_help = static_cast<ui::controls::button*>(get_control("m_toggle_help"));
|
||||
m_btn_toggle_help->set_enabled(true);
|
||||
m_btn_toggle_help->set_visible(true);
|
||||
m_btn_toggle_help->set_on_click(std::bind(&loot_filter_settings_toggle_menu::toggle_help_click, this));
|
||||
|
||||
}
|
||||
|
||||
void d2_tweaks::client::modules::loot_filter_settings_toggle_menu::toggle_filter_settings_click() {
|
||||
@ -55,6 +77,23 @@ void d2_tweaks::client::modules::loot_filter_settings_toggle_menu::toggle_stats_
|
||||
m_stats_enabled = !m_stats_enabled;
|
||||
}
|
||||
|
||||
void d2_tweaks::client::modules::loot_filter_settings_toggle_menu::toggle_help_click() {
|
||||
//m_help_enabled = !m_help_enabled;
|
||||
// Open the default OS browser to the URL
|
||||
const std::string url = "https://im.stoned.io";
|
||||
#ifdef _WIN32
|
||||
// For Windows
|
||||
ShellExecute(nullptr, "open", url.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
|
||||
#elif defined __linux__ || defined __APPLE__
|
||||
// For Linux and macOS
|
||||
system(("xdg-open " + url).c_str());
|
||||
#else
|
||||
// Unsupported platform
|
||||
// You can add handling for other platforms here
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void d2_tweaks::client::modules::loot_filter_settings_toggle_menu::draw() {
|
||||
m_btn_toggle_stats->set_enabled(diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_INTERFACE));
|
||||
m_btn_toggle_stats->set_visible(diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_INTERFACE));
|
||||
|
@ -13,6 +13,64 @@
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <diablo2/d2client.h>
|
||||
|
||||
#include <iomanip> // For std::setw
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stdexcept> // For std::invalid_argument
|
||||
|
||||
#include <windows.h> // Include Windows API header for MessageBox
|
||||
|
||||
// Define your deserialization method for the item structure
|
||||
diablo2::structures::unit unserialize_item(const std::string& itemcode, std::ifstream& file) {
|
||||
// Read each line from the file
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
// Split the line into item code and serialized data
|
||||
std::istringstream iss(line);
|
||||
std::string code;
|
||||
std::getline(iss, code, ':');
|
||||
if (code == itemcode) {
|
||||
// Found matching item code, extract serialized data
|
||||
std::string serializedData;
|
||||
std::getline(iss, serializedData);
|
||||
// Convert serialized data from hexadecimal string to binary
|
||||
std::istringstream hexStream(serializedData);
|
||||
diablo2::structures::unit item;
|
||||
for (size_t i = 0; i < sizeof(item); ++i) {
|
||||
int byte;
|
||||
if (!(hexStream >> std::hex >> byte)) {
|
||||
throw std::invalid_argument("Error reading serialized data");
|
||||
}
|
||||
reinterpret_cast<char*>(&item)[i] = static_cast<char>(byte);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
// Item code not found
|
||||
throw std::invalid_argument("Item code not found");
|
||||
}
|
||||
|
||||
#include <iomanip> // For std::setw
|
||||
|
||||
void serialize_item(const std::string& itemcode, const diablo2::structures::unit& item, std::ofstream& file) {
|
||||
// Write item code
|
||||
file << itemcode << ":";
|
||||
|
||||
// Write serialized data
|
||||
for (size_t i = 0; i < sizeof(item); ++i) {
|
||||
file << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned>(reinterpret_cast<const char*>(&item)[i]);
|
||||
}
|
||||
|
||||
// Add a newline after each item
|
||||
file << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MODULE_INIT(item_move)
|
||||
|
||||
void d2_tweaks::server::modules::item_move::init() {
|
||||
@ -35,7 +93,13 @@ bool d2_tweaks::server::modules::item_move::handle_packet(diablo2::structures::g
|
||||
static auto& instance = singleton<server>::instance();
|
||||
|
||||
const auto itemMove = static_cast<common::item_move_cs*>(packet);
|
||||
const auto key = static_cast<common::item_move_cs*>(packet)->item_code;
|
||||
|
||||
// Display key in a message box
|
||||
MessageBox(NULL, key, "Item code", MB_OK | MB_ICONINFORMATION);
|
||||
|
||||
const auto item = instance.get_server_unit(game, itemMove->item_guid, diablo2::structures::unit_type_t::UNIT_TYPE_ITEM); //0x4 = item
|
||||
const char* itemcode = itemMove->item_code;
|
||||
const auto bag = instance.get_server_unit(game, itemMove->bag_guid, diablo2::structures::unit_type_t::UNIT_TYPE_ITEM); //0x4 = item
|
||||
|
||||
D2PropertyStrc itemProperty = {};
|
||||
@ -49,6 +113,9 @@ bool d2_tweaks::server::modules::item_move::handle_packet(diablo2::structures::g
|
||||
if (item == nullptr)
|
||||
return true; //block further packet processing
|
||||
|
||||
|
||||
|
||||
|
||||
const auto inventoryIndex = diablo2::d2_common::get_inventory_index(player, itemMove->target_page, game->item_format == 101);
|
||||
|
||||
uint32_t tx, ty;
|
||||
@ -75,6 +142,22 @@ bool d2_tweaks::server::modules::item_move::handle_packet(diablo2::structures::g
|
||||
|
||||
diablo2::d2_net::send_to_client(1, client->client_id, &resp, sizeof resp);
|
||||
|
||||
|
||||
if (itemMove->updateBag == 1) {
|
||||
|
||||
// Serialize item data into binary file
|
||||
std::string playerName = player->player_data->name;
|
||||
std::string fileName = "./Save/" + playerName + ".boh";
|
||||
std::ofstream outFile(fileName, std::ios::binary);
|
||||
if (!outFile) {
|
||||
std::cerr << "Error opening file: " << fileName << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
serialize_item(itemcode, *item, outFile);
|
||||
outFile.close();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,16 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include <iomanip> // For std::setw
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stdexcept> // For std::invalid_argument
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
diablo2::structures::unit* g_item1;
|
||||
|
||||
static LRESULT(__stdcall* g_wnd_proc_original)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
@ -127,6 +137,8 @@ struct D2InventoryGridInfoStrc
|
||||
WORD pad0x16; //0x16
|
||||
};
|
||||
|
||||
|
||||
|
||||
LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
static auto& instance = singleton<ui_manager>::instance();
|
||||
|
||||
@ -462,9 +474,10 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
|
||||
if (diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_STASH) || diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_CUBE) || diablo2::d2_client::get_ui_window_state(diablo2::UI_WINDOW_INVENTORY)) {
|
||||
for (const auto& gem : gemTypes) {
|
||||
// Accessing key and value
|
||||
const std::string& key = gem.first;
|
||||
const std::string& _key = gem.first;
|
||||
const char* key = gem.first.c_str();
|
||||
const GemType& value = gem.second;
|
||||
if (strncmp(normCode, key.c_str(), 3) == 0) {
|
||||
if (strncmp(normCode, key, 3) == 0) {
|
||||
D2PropertyStrc itemProperty = {};
|
||||
itemProperty.nProperty = value.rowID - 3;
|
||||
itemProperty.nLayer = 0;
|
||||
@ -475,12 +488,15 @@ LRESULT d2_tweaks::ui::ui_manager::wnd_proc(HWND hWnd, UINT msg, WPARAM wParam,
|
||||
|
||||
static d2_tweaks::common::item_move_cs packet;
|
||||
packet.item_guid = g_hoverItem->guid;
|
||||
packet.item_code = key;
|
||||
packet.bag_guid = gemBagGuid;
|
||||
packet.updateBag = 1;
|
||||
packet.prop = itemProperty.nProperty;
|
||||
packet.val = itemProperty.nMin;
|
||||
packet.target_page = 99;
|
||||
diablo2::d2_client::send_to_server(&packet, sizeof packet);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,13 @@ int32_t diablo2::d2_client::send_to_server_7(BYTE type, DWORD num, DWORD unk1, D
|
||||
return send_to_server_7(type, num, unk1, unk2);
|
||||
}
|
||||
|
||||
//D2FUNC(D2CLIENT, SendToServer9, void, __fastcall, (BYTE type, DWORD num, DWORD unk1), 0xDA40) // Interact
|
||||
|
||||
int32_t diablo2::d2_client::send_to_server_9(BYTE type, DWORD num, DWORD unk1) {
|
||||
static wrap_func_fast<int32_t(BYTE type, DWORD num, DWORD unk1)> send_to_server_9(0xDA40, get_base());
|
||||
return send_to_server_9(type, num, unk1);
|
||||
}
|
||||
|
||||
uint32_t diablo2::d2_client::screen_height() {
|
||||
return *reinterpret_cast<uint32_t*>(get_base() + 0xD40F0);
|
||||
}
|
||||
|
@ -15,3 +15,4 @@ int32_t diablo2::d2_net::send_to_client(int32_t queue, int32_t clientId, void* p
|
||||
static wrap_func_std_import<int32_t(int32_t, int32_t, void*, size_t)> send_to_client(10006, get_base());
|
||||
return send_to_client(queue, clientId, packet, size);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user