mirror of
https://gitlab.com/hashborgir/d2tweaks-rnd2k.git
synced 2025-09-19 01:52:08 +00:00
Working on right click gem extraction
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user