Release v1.7.0.0
New Features: - Added Coordinate Calibration - manually calibrate click positions for unsupported resolutions, UI scales, or custom Windows DPI settings via addon options - Calibration values are saved persistently and applied globally to all click sequences UI Improvements: - Moved "Current template" indicator inside the Templates tab - also resolves window stretching on certain resolutions - Added hint below delay settings to suggest calibration if clicks miss Technical Changes: - Fixed implicit size_t to int conversion warning in template list rendering
This commit is contained in:
parent
a334cadd83
commit
d035d14587
6 changed files with 203 additions and 46 deletions
|
|
@ -2,10 +2,17 @@
|
|||
#include <string>
|
||||
#include "CoordinateUtils.h"
|
||||
#include "../Common/Globals.h"
|
||||
#include "../Config/ConfigManager.h"
|
||||
|
||||
void CoordinateUtils::GetScaledCoordinates(int baseX, int baseY, int* scaledX, int* scaledY) {
|
||||
if (!g_api) return;
|
||||
|
||||
if (g_state.hasCalibration) {
|
||||
*scaledX = (int)(baseX * g_state.calibratedScaleX);
|
||||
*scaledY = (int)(baseY * g_state.calibratedScaleY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_nexusLink && g_nexusLink->Width > 0 && g_nexusLink->Height > 0) {
|
||||
float uiScale = g_nexusLink->Scaling;
|
||||
float dpiScaleX, dpiScaleY;
|
||||
|
|
@ -173,4 +180,74 @@ void CoordinateUtils::ClickAtScaled(int baseX, int baseY, int delay) {
|
|||
Sleep(10);
|
||||
SendMessage(gameWindow, WM_LBUTTONUP, 0, lParam);
|
||||
Sleep(delay);
|
||||
}
|
||||
|
||||
void CoordinateUtils::StartCalibration() {
|
||||
g_state.calibrationMode = true;
|
||||
g_state.showUI = false;
|
||||
|
||||
if (g_api) {
|
||||
g_api->Log(ELogLevel_INFO, "GolemHelper",
|
||||
"Calibration started - interact with the Boon Console and click 'Adjust Self'");
|
||||
}
|
||||
}
|
||||
|
||||
void CoordinateUtils::CaptureCalibrationPoint() {
|
||||
POINT mousePos;
|
||||
GetCursorPos(&mousePos);
|
||||
|
||||
const float REF_BASE_X = 830.0f;
|
||||
const float REF_BASE_Y = 262.0f;
|
||||
|
||||
g_state.calibratedScaleX = mousePos.x / REF_BASE_X;
|
||||
g_state.calibratedScaleY = mousePos.y / REF_BASE_Y;
|
||||
g_state.hasCalibration = true;
|
||||
g_state.calibrationMode = false;
|
||||
|
||||
ConfigManager::SaveCustomDelaySettings();
|
||||
|
||||
if (g_api) {
|
||||
char buffer[256];
|
||||
sprintf_s(buffer,
|
||||
"Calibration saved: click=(%ld, %ld) scaleX=%.4f scaleY=%.4f",
|
||||
mousePos.x, mousePos.y,
|
||||
g_state.calibratedScaleX, g_state.calibratedScaleY);
|
||||
g_api->Log(ELogLevel_INFO, "GolemHelper", buffer);
|
||||
g_api->UI.SendAlert("Calibration saved!");
|
||||
}
|
||||
}
|
||||
|
||||
void CoordinateUtils::ResetCalibration() {
|
||||
g_state.hasCalibration = false;
|
||||
g_state.calibrationMode = false;
|
||||
g_state.calibratedScaleX = 1.0f;
|
||||
g_state.calibratedScaleY = 1.0f;
|
||||
|
||||
ConfigManager::SaveCustomDelaySettings();
|
||||
|
||||
if (g_api) {
|
||||
g_api->Log(ELogLevel_INFO, "GolemHelper", "Calibration reset - back to auto-scaling");
|
||||
g_api->UI.SendAlert("Calibration reset to default");
|
||||
}
|
||||
}
|
||||
|
||||
void CoordinateUtils::UpdateCalibrationCapture() {
|
||||
if (!g_state.calibrationMode) return;
|
||||
|
||||
if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
|
||||
g_state.calibrationMode = false;
|
||||
if (g_api) g_api->UI.SendAlert("Calibration cancelled");
|
||||
return;
|
||||
}
|
||||
|
||||
static bool s_wasPressed = false;
|
||||
bool isPressed = (GetAsyncKeyState(VK_LBUTTON) & 0x8000) != 0;
|
||||
|
||||
if (isPressed && !s_wasPressed) {
|
||||
if (g_mumbleData && g_mumbleData->Context.IsGameFocused) {
|
||||
CaptureCalibrationPoint();
|
||||
}
|
||||
}
|
||||
|
||||
s_wasPressed = isPressed;
|
||||
}
|
||||
|
|
@ -5,4 +5,9 @@ public:
|
|||
static void GetScaledCoordinates(int baseX, int baseY, int* scaledX, int* scaledY);
|
||||
static void DebugMousePosition();
|
||||
static void ClickAtScaled(int baseX, int baseY, int delay = 25);
|
||||
|
||||
static void StartCalibration();
|
||||
static void CaptureCalibrationPoint();
|
||||
static void ResetCalibration();
|
||||
static void UpdateCalibrationCapture();
|
||||
};
|
||||
|
|
@ -155,6 +155,12 @@ struct GolemHelperState {
|
|||
bool quickAccessVisible = false;
|
||||
unsigned int lastMapID = 0;
|
||||
|
||||
// Calibration
|
||||
bool calibrationMode = false;
|
||||
bool hasCalibration = false;
|
||||
float calibratedScaleX = 1.0f;
|
||||
float calibratedScaleY = 1.0f;
|
||||
|
||||
std::vector<GolemTemplate> templates;
|
||||
int selectedTemplateIndex = -1;
|
||||
int lastUserTemplateIndex = -1;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ void ConfigManager::SaveCustomDelaySettings() {
|
|||
configFile << "alwaysHideIcon=" << (g_state.alwaysHideIcon ? "1" : "0") << std::endl;
|
||||
configFile << "autoShowHideUI=" << (g_state.autoShowHideUI ? "1" : "0") << std::endl;
|
||||
configFile << "alwaysLoadLastSettings=" << (g_state.alwaysLoadLastSettings ? "1" : "0") << std::endl;
|
||||
configFile << "hasCalibration=" << (g_state.hasCalibration ? "1" : "0") << std::endl;
|
||||
configFile << "calibratedScaleX=" << g_state.calibratedScaleX << std::endl;
|
||||
configFile << "calibratedScaleY=" << g_state.calibratedScaleY << std::endl;
|
||||
|
||||
configFile.close();
|
||||
|
||||
|
|
@ -84,6 +87,23 @@ void ConfigManager::LoadCustomDelaySettings() {
|
|||
else if (key == "alwaysLoadLastSettings") {
|
||||
g_state.alwaysLoadLastSettings = (value == "1");
|
||||
}
|
||||
else if (key == "hasCalibration") {
|
||||
g_state.hasCalibration = (value == "1");
|
||||
}
|
||||
else if (key == "calibratedScaleX") {
|
||||
try {
|
||||
float v = std::stof(value);
|
||||
if (v > 0.1f && v < 10.0f) g_state.calibratedScaleX = v;
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
else if (key == "calibratedScaleY") {
|
||||
try {
|
||||
float v = std::stof(value);
|
||||
if (v > 0.1f && v < 10.0f) g_state.calibratedScaleY = v;
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
configFile.close();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ void Load(AddonAPI* aApi) {
|
|||
|
||||
MapUtils::UpdateQuickAccessVisibility();
|
||||
|
||||
g_api->Log(ELogLevel_INFO, "GolemHelper", "=== GolemHelper v1.6.0.0 Loaded ===");
|
||||
g_api->Log(ELogLevel_INFO, "GolemHelper", "=== GolemHelper v1.7.0.0 Loaded ===");
|
||||
g_api->Log(ELogLevel_INFO, "GolemHelper", "<c=#00ff00>GolemHelper addon</c> loaded successfully!");
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ extern "C" __declspec(dllexport) AddonDefinition* GetAddonDef() {
|
|||
def.Signature = -424248;
|
||||
def.APIVersion = NEXUS_API_VERSION;
|
||||
def.Name = "GolemHelper";
|
||||
def.Version = { 1, 6, 0, 0 };
|
||||
def.Version = { 1, 7, 0, 0 };
|
||||
def.Author = "Azrub";
|
||||
def.Description = "Automates the process of setting optimal boon and golem configurations in the training area";
|
||||
def.Load = Load;
|
||||
|
|
|
|||
|
|
@ -5,11 +5,14 @@
|
|||
#include "../Config/ConfigManager.h"
|
||||
#include "../Utils/MapUtils.h"
|
||||
#include "../Config/TemplateManager.h"
|
||||
#include "../Automation/CoordinateUtils.h"
|
||||
#include "../Dependencies/imgui/imgui.h"
|
||||
|
||||
void UIManager::RenderUI() {
|
||||
MapUtils::UpdateQuickAccessVisibility();
|
||||
|
||||
CoordinateUtils::UpdateCalibrationCapture();
|
||||
|
||||
if (!g_state.showUI) return;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(450, 600), ImGuiCond_FirstUseEver);
|
||||
|
|
@ -17,7 +20,7 @@ void UIManager::RenderUI() {
|
|||
|
||||
if (ImGui::Begin("GolemHelper", &g_state.showUI, ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
|
||||
ImGui::TextColored(ImVec4(0.2f, 0.8f, 1.0f, 1.0f), "GolemHelper v1.6.0.0");
|
||||
ImGui::TextColored(ImVec4(0.2f, 0.8f, 1.0f, 1.0f), "GolemHelper v1.7.0.0");
|
||||
ImGui::Separator();
|
||||
|
||||
if (ImGui::BeginTabBar("GolemHelperTabs", ImGuiTabBarFlags_None)) {
|
||||
|
|
@ -28,46 +31,6 @@ void UIManager::RenderUI() {
|
|||
}
|
||||
|
||||
if (ImGui::BeginTabItem("Templates")) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 130);
|
||||
|
||||
std::string currentTemplateName = "None";
|
||||
bool foundMatchingTemplate = false;
|
||||
|
||||
for (const auto& temp : g_state.templates) {
|
||||
if (temp.isQuickDps == g_state.isQuickDps &&
|
||||
temp.isAlacDps == g_state.isAlacDps &&
|
||||
temp.environmentDamage == g_state.environmentDamage &&
|
||||
temp.envDamageLevel == g_state.envDamageLevel &&
|
||||
temp.skipBurning == g_state.skipBurning &&
|
||||
temp.skipConfusion == g_state.skipConfusion &&
|
||||
temp.skipSlow == g_state.skipSlow &&
|
||||
temp.addImmobilize == g_state.addImmobilize &&
|
||||
temp.addBlind == g_state.addBlind &&
|
||||
temp.fiveBleedingStacks == g_state.fiveBleedingStacks &&
|
||||
temp.hitboxType == g_state.hitboxType &&
|
||||
temp.addResistance == g_state.addResistance &&
|
||||
temp.addStability == g_state.addStability &&
|
||||
temp.skipAegis == g_state.skipAegis) {
|
||||
currentTemplateName = temp.name;
|
||||
foundMatchingTemplate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text("Current: ");
|
||||
ImGui::SameLine();
|
||||
if (foundMatchingTemplate) {
|
||||
std::string truncatedName = currentTemplateName;
|
||||
if (truncatedName.length() > 8) {
|
||||
truncatedName = truncatedName.substr(0, 6) + "..";
|
||||
}
|
||||
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "%s", truncatedName.c_str());
|
||||
}
|
||||
else {
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "None");
|
||||
}
|
||||
|
||||
RenderTemplatesTab();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
|
@ -264,6 +227,7 @@ void UIManager::RenderSettingsTab() {
|
|||
|
||||
ImGui::Spacing();
|
||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.2f, 1.0f), "Increase delays if clicks fail");
|
||||
ImGui::TextColored(ImVec4(0.8f, 0.8f, 0.2f, 1.0f), "or calibrate in Options");
|
||||
|
||||
if (oldStepDelay != g_state.stepDelay || oldInitialDelay != g_state.initialDelay) {
|
||||
ConfigManager::SaveCustomDelaySettings();
|
||||
|
|
@ -329,6 +293,41 @@ void UIManager::RenderSettingsTab() {
|
|||
}
|
||||
|
||||
void UIManager::RenderTemplatesTab() {
|
||||
|
||||
std::string currentTemplateName = "None";
|
||||
bool foundMatchingTemplate = false;
|
||||
|
||||
for (const auto& temp : g_state.templates) {
|
||||
if (temp.isQuickDps == g_state.isQuickDps &&
|
||||
temp.isAlacDps == g_state.isAlacDps &&
|
||||
temp.environmentDamage == g_state.environmentDamage &&
|
||||
temp.envDamageLevel == g_state.envDamageLevel &&
|
||||
temp.skipBurning == g_state.skipBurning &&
|
||||
temp.skipConfusion == g_state.skipConfusion &&
|
||||
temp.skipSlow == g_state.skipSlow &&
|
||||
temp.addImmobilize == g_state.addImmobilize &&
|
||||
temp.addBlind == g_state.addBlind &&
|
||||
temp.fiveBleedingStacks == g_state.fiveBleedingStacks &&
|
||||
temp.hitboxType == g_state.hitboxType &&
|
||||
temp.addResistance == g_state.addResistance &&
|
||||
temp.addStability == g_state.addStability &&
|
||||
temp.skipAegis == g_state.skipAegis) {
|
||||
currentTemplateName = temp.name;
|
||||
foundMatchingTemplate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Current: ");
|
||||
ImGui::SameLine();
|
||||
if (foundMatchingTemplate) {
|
||||
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "%s", currentTemplateName.c_str());
|
||||
}
|
||||
else {
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "None");
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Apply Boons", ImVec2(110, 0))) {
|
||||
|
|
@ -407,7 +406,7 @@ void UIManager::RenderTemplatesTab() {
|
|||
}
|
||||
|
||||
ImGui::SetNextItemWidth(170);
|
||||
if (ImGui::Combo("##templateList", ¤tUserIndex, userTemplateNames.data(), userTemplateNames.size())) {
|
||||
if (ImGui::Combo("##templateList", ¤tUserIndex, userTemplateNames.data(), (int)userTemplateNames.size())) {
|
||||
g_state.selectedTemplateIndex = userTemplateIndices[currentUserIndex];
|
||||
g_state.lastUserTemplateIndex = userTemplateIndices[currentUserIndex];
|
||||
}
|
||||
|
|
@ -535,7 +534,7 @@ void UIManager::RenderTemplatesTab() {
|
|||
TemplateManager::LoadTemplate(templateIndex);
|
||||
g_state.selectedTemplateIndex = -1;
|
||||
}
|
||||
if (i < 2) ImGui::SameLine(0, 5);;
|
||||
if (i < 2) ImGui::SameLine(0, 5);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -556,7 +555,7 @@ void UIManager::RenderTemplatesTab() {
|
|||
TemplateManager::LoadTemplate(templateIndex);
|
||||
g_state.selectedTemplateIndex = -1;
|
||||
}
|
||||
if (i == 3) ImGui::SameLine(0, 5);;
|
||||
if (i == 3) ImGui::SameLine(0, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -588,4 +587,54 @@ void UIManager::RenderOptions() {
|
|||
}
|
||||
|
||||
ImGui::Checkbox("Enable debug mode", &g_state.debugMode);
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.3f, 0.5f, 0.7f, 0.8f));
|
||||
if (ImGui::CollapsingHeader("Coordinate Calibration")) {
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (g_state.calibrationMode) {
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.85f, 0.0f, 1.0f), "! Calibration active !");
|
||||
ImGui::Spacing();
|
||||
ImGui::TextWrapped("1. Interact with the Boon Console (press F)");
|
||||
ImGui::TextWrapped("2. Hover your mouse over the middle of \"Adjust Self\" and click.");
|
||||
ImGui::Spacing();
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "The addon window is hidden.");
|
||||
ImGui::TextColored(ImVec4(0.7f, 0.7f, 0.7f, 1.0f), "Press ESC to cancel.");
|
||||
}
|
||||
else {
|
||||
if (g_state.hasCalibration) {
|
||||
ImGui::TextColored(ImVec4(0.2f, 1.0f, 0.4f, 1.0f), "Status: Calibrated");
|
||||
ImGui::Text("scaleX: %.4f scaleY: %.4f",
|
||||
g_state.calibratedScaleX, g_state.calibratedScaleY);
|
||||
}
|
||||
else {
|
||||
ImGui::TextColored(ImVec4(0.75f, 0.75f, 0.75f, 1.0f), "Status: Auto-scaling (default)");
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
||||
if (ImGui::Button("Calibrate", ImVec2(120, 0))) {
|
||||
CoordinateUtils::StartCalibration();
|
||||
}
|
||||
|
||||
if (g_state.hasCalibration) {
|
||||
ImGui::SameLine(0, 6);
|
||||
if (ImGui::Button("Reset to Default", ImVec2(120, 0))) {
|
||||
CoordinateUtils::ResetCalibration();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::TextDisabled("Interact with the Boon Console, then hover over");
|
||||
ImGui::TextDisabled("the middle of \"Adjust Self\" and click.");
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
}
|
||||
ImGui::PopStyleColor(2);
|
||||
}
|
||||
Loading…
Reference in a new issue