From 0dc7e655f2d47d86bd4146504e7ac77a752190c2 Mon Sep 17 00:00:00 2001 From: Azrub Date: Fri, 11 Jul 2025 23:02:59 +0200 Subject: [PATCH] Release v1.0.0-beta.3 Environment damage support, advanced settings settings, UI improvements, clean up --- GolemHelper/dllmain.cpp | 247 +++++++++++++++++++++++++++++++--------- 1 file changed, 194 insertions(+), 53 deletions(-) diff --git a/GolemHelper/dllmain.cpp b/GolemHelper/dllmain.cpp index 6eeb615..79ac140 100644 --- a/GolemHelper/dllmain.cpp +++ b/GolemHelper/dllmain.cpp @@ -10,17 +10,34 @@ AddonAPI* g_api = nullptr; NexusLinkData* NexusLink = nullptr; +enum HitboxType { + HITBOX_SMALL = 0, + HITBOX_MEDIUM = 1, + HITBOX_BIG = 2 +}; + +enum EnvironmentDamageLevel { + ENV_MILD = 0, + ENV_MODERATE = 1, + ENV_EXTREME = 2 +}; + struct { bool enabled = false; bool boonsEnabled = true; bool golemEnabled = true; bool isQuickDps = false; bool isAlacDps = false; - bool isChronomancer = false; - bool isMediumHitbox = false; + bool environmentDamage = false; + EnvironmentDamageLevel envDamageLevel = ENV_MILD; + bool skipSlow = false; + bool skipBurning = false; + bool fiveBleedingStacks = false; + HitboxType hitboxType = HITBOX_SMALL; bool debugMode = false; bool showUI = false; bool useCustomDelays = false; + bool showAdvanced = false; int debugCounter = 0; int stepDelay = 290; @@ -57,13 +74,11 @@ bool ShouldSkipBoonStep(int stepIndex); bool ShouldSkipGolemStep(int stepIndex); void HandleBoonKeybind(const char* id, bool release); void HandleGolemKeybind(const char* id, bool release); +void HandleQuickDpsKeybind(const char* id, bool release); +void HandleAlacDpsKeybind(const char* id, bool release); void HandleToggleKeybind(const char* id, bool release); void HandleUIToggleKeybind(const char* id, bool release); void HandleDebugKeybind(const char* id, bool release); -void HandleQuickDpsKeybind(const char* id, bool release); -void HandleAlacDpsKeybind(const char* id, bool release); -void HandleChronomancerKeybind(const char* id, bool release); -void HandleMediumHitboxKeybind(const char* id, bool release); void Load(AddonAPI* aApi); void Unload(); @@ -75,7 +90,7 @@ void RenderUI() { if (ImGui::Begin("GolemHelper Control Panel", &g_state.showUI, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::TextColored(ImVec4(0.2f, 0.8f, 1.0f, 1.0f), "GolemHelper v1.0.0-beta.2"); + ImGui::TextColored(ImVec4(0.2f, 0.8f, 1.0f, 1.0f), "GolemHelper v1.0.0-beta.3"); ImGui::Separator(); ImGui::Text("Status:"); @@ -120,6 +135,25 @@ void RenderUI() { g_state.isAlacDps = true; } + ImGui::Spacing(); + ImGui::Text("Healer Bench:"); + + ImGui::Checkbox("Environment Damage", &g_state.environmentDamage); + + if (g_state.environmentDamage) { + if (ImGui::RadioButton("Mild", g_state.envDamageLevel == ENV_MILD)) { + g_state.envDamageLevel = ENV_MILD; + } + + if (ImGui::RadioButton("Moderate", g_state.envDamageLevel == ENV_MODERATE)) { + g_state.envDamageLevel = ENV_MODERATE; + } + + if (ImGui::RadioButton("Extreme", g_state.envDamageLevel == ENV_EXTREME)) { + g_state.envDamageLevel = ENV_EXTREME; + } + } + ImGui::Spacing(); ImGui::Separator(); @@ -132,16 +166,29 @@ void RenderUI() { } } - ImGui::Checkbox("Medium Hitbox (Default is Small)", &g_state.isMediumHitbox); + ImGui::Text("Golem Hitbox:"); - ImGui::Checkbox("Chronomancer Mode (Skip Slow)", &g_state.isChronomancer); + if (ImGui::RadioButton("Small (Benchmark Default)", g_state.hitboxType == HITBOX_SMALL)) { + g_state.hitboxType = HITBOX_SMALL; + } + + if (ImGui::RadioButton("Medium", g_state.hitboxType == HITBOX_MEDIUM)) { + g_state.hitboxType = HITBOX_MEDIUM; + } + + if (ImGui::RadioButton("Big", g_state.hitboxType == HITBOX_BIG)) { + g_state.hitboxType = HITBOX_BIG; + } ImGui::Spacing(); - ImGui::Separator(); + ImGui::Text("Advanced:"); - ImGui::Text("Settings"); + ImGui::Checkbox("Condition Settings", &g_state.showAdvanced); - if (ImGui::Button("Configure Hotkeys", ImVec2(150, 0))) { + if (g_state.showAdvanced) { + ImGui::Checkbox("Skip Slow", &g_state.skipSlow); + ImGui::Checkbox("Skip Burning", &g_state.skipBurning); + ImGui::Checkbox("5 Bleeding Stacks", &g_state.fiveBleedingStacks); } if (g_state.debugMode) { @@ -196,9 +243,14 @@ void RenderOptions() { if (ImGui::Button("Reset all settings")) { g_state.isQuickDps = false; g_state.isAlacDps = false; - g_state.isChronomancer = false; - g_state.isMediumHitbox = false; + g_state.environmentDamage = false; + g_state.envDamageLevel = ENV_MILD; + g_state.skipSlow = false; + g_state.skipBurning = false; + g_state.fiveBleedingStacks = false; + g_state.hitboxType = HITBOX_SMALL; g_state.useCustomDelays = false; + g_state.showAdvanced = false; g_state.stepDelay = 290; g_state.boonsEnabled = true; g_state.golemEnabled = true; @@ -206,9 +258,40 @@ void RenderOptions() { ImGui::Spacing(); ImGui::Text("Current Modes:"); - ImGui::Text("- Boons: %s", g_state.isQuickDps ? "Quick DPS" : g_state.isAlacDps ? "Alac DPS" : "Normal"); - ImGui::Text("- Golem: %s", g_state.isChronomancer ? "Chronomancer" : "Normal"); - ImGui::Text("- Hitbox: %s", g_state.isMediumHitbox ? "Medium" : "Small"); + + std::string boonMode = "Normal"; + if (g_state.isQuickDps) { + boonMode = "Quick DPS"; + } + else if (g_state.isAlacDps) { + boonMode = "Alac DPS"; + } + + if (g_state.environmentDamage) { + boonMode += " + Env "; + switch (g_state.envDamageLevel) { + case ENV_MILD: boonMode += "Mild"; break; + case ENV_MODERATE: boonMode += "Moderate"; break; + case ENV_EXTREME: boonMode += "Extreme"; break; + } + } + + ImGui::Text("- Boons: %s", boonMode.c_str()); + + std::string golemMods = "Normal"; + if (g_state.showAdvanced && (g_state.skipSlow || g_state.skipBurning || g_state.fiveBleedingStacks)) { + golemMods = ""; + if (g_state.skipSlow) golemMods += "Skip Slow "; + if (g_state.skipBurning) golemMods += "Skip Burning "; + if (g_state.fiveBleedingStacks) golemMods += "5 Bleeding "; + if (!golemMods.empty()) golemMods.pop_back(); + } + ImGui::Text("- Golem: %s", golemMods.c_str()); + + const char* hitboxName = g_state.hitboxType == HITBOX_SMALL ? "Small" : + g_state.hitboxType == HITBOX_MEDIUM ? "Medium" : "Big"; + ImGui::Text("- Hitbox: %s", hitboxName); + ImGui::Text("- Timing: %s", g_state.useCustomDelays ? "Custom" : "Default"); } @@ -325,7 +408,15 @@ bool ShouldSkipBoonStep(int stepIndex) { } bool ShouldSkipGolemStep(int stepIndex) { - if (g_state.isChronomancer && stepIndex == 17) { + if (!g_state.showAdvanced) { + return false; + } + + if (g_state.skipSlow && stepIndex == 17) { + return true; + } + + if (g_state.skipBurning && stepIndex == 7) { return true; } @@ -340,11 +431,25 @@ void ApplyAllBoons() { g_state.showUI = false; } - const char* mode = g_state.isQuickDps ? "Quick DPS" : - g_state.isAlacDps ? "Alac DPS" : "Normal"; + std::string mode = "Normal"; + if (g_state.isQuickDps) { + mode = "Quick DPS"; + } + else if (g_state.isAlacDps) { + mode = "Alac DPS"; + } - char startBuffer[200]; - sprintf_s(startBuffer, "Starting boon sequence (20 steps) - Mode: %s", mode); + if (g_state.environmentDamage) { + mode += " + Environment "; + switch (g_state.envDamageLevel) { + case ENV_MILD: mode += "Mild"; break; + case ENV_MODERATE: mode += "Moderate"; break; + case ENV_EXTREME: mode += "Extreme"; break; + } + } + + char startBuffer[300]; + sprintf_s(startBuffer, "Starting boon sequence (20 steps) - Mode: %s", mode.c_str()); g_api->Log(ELogLevel_INFO, "GolemHelper", startBuffer); try { @@ -352,7 +457,9 @@ void ApplyAllBoons() { int initialDelay = g_state.useCustomDelays ? g_state.stepDelay : 390; Sleep(initialDelay); - for (int i = 0; i < 20; i++) { + int maxSteps = g_state.environmentDamage ? 19 : 20; + + for (int i = 0; i < maxSteps; i++) { if (g_coords.boonStepX[i] == 0 && g_coords.boonStepY[i] == 0) { continue; } @@ -361,10 +468,33 @@ void ApplyAllBoons() { continue; } - int delay = (i == 19) ? 50 : (g_state.useCustomDelays ? g_state.stepDelay : 290); + int delay = (i == maxSteps - 1) ? 50 : (g_state.useCustomDelays ? g_state.stepDelay : 290); ClickAtScaled(g_coords.boonStepX[i], g_coords.boonStepY[i], delay); } + + if (g_state.environmentDamage) { + g_api->Log(ELogLevel_INFO, "GolemHelper", "Applying Environment Damage sequence"); + + int delay = g_state.useCustomDelays ? g_state.stepDelay : 290; + + Sleep(delay); + ClickAtScaled(830, 500, delay); + ClickAtScaled(830, 454, delay); + ClickAtScaled(830, 454, delay); + ClickAtScaled(830, 306, delay); + ClickAtScaled(830, 257, delay); + + int finalY; + switch (g_state.envDamageLevel) { + case ENV_MILD: finalY = 352; break; + case ENV_MODERATE: finalY = 306; break; + case ENV_EXTREME: finalY = 257; break; + default: finalY = 352; break; + } + + ClickAtScaled(830, finalY, 50); + } } catch (...) { g_api->Log(ELogLevel_WARNING, "GolemHelper", "Exception during boon sequence"); @@ -385,10 +515,20 @@ void ApplyGolemSettings() { g_state.showUI = false; } - const char* mode = g_state.isChronomancer ? "Chronomancer" : "Normal"; - const char* hitbox = g_state.isMediumHitbox ? "Medium Hitbox" : "Small Hitbox"; - char startBuffer[300]; - sprintf_s(startBuffer, "Starting golem settings sequence (25 steps) - Mode: %s, Hitbox: %s", mode, hitbox); + const char* hitbox = g_state.hitboxType == HITBOX_SMALL ? "Small Hitbox" : + g_state.hitboxType == HITBOX_MEDIUM ? "Medium Hitbox" : "Big Hitbox"; + + std::string modifiers = "Normal"; + if (g_state.showAdvanced && (g_state.skipSlow || g_state.skipBurning || g_state.fiveBleedingStacks)) { + modifiers = ""; + if (g_state.skipSlow) modifiers += "Skip Slow "; + if (g_state.skipBurning) modifiers += "Skip Burning "; + if (g_state.fiveBleedingStacks) modifiers += "5 Bleeding "; + if (!modifiers.empty()) modifiers.pop_back(); + } + + char startBuffer[400]; + sprintf_s(startBuffer, "Starting golem settings sequence (25 steps) - Modifiers: %s, Hitbox: %s", modifiers.c_str(), hitbox); g_api->Log(ELogLevel_INFO, "GolemHelper", startBuffer); try { @@ -408,13 +548,32 @@ void ApplyGolemSettings() { int currentX = g_coords.golemStepX[i]; int currentY = g_coords.golemStepY[i]; - if (g_state.isMediumHitbox && i == 1) { - currentY = 305; + if (i == 1) { + switch (g_state.hitboxType) { + case HITBOX_SMALL: + currentY = 260; + break; + case HITBOX_MEDIUM: + currentY = 305; + break; + case HITBOX_BIG: + currentY = 352; + break; + } } int delay = (i == 24) ? 50 : (g_state.useCustomDelays ? g_state.stepDelay : 290); ClickAtScaled(currentX, currentY, delay); + + if (g_state.showAdvanced && g_state.fiveBleedingStacks && i == 6) { + g_api->Log(ELogLevel_INFO, "GolemHelper", "5 Bleeding Stacks - repeating 7th step 4 more times"); + + for (int repeat = 0; repeat < 4; repeat++) { + int repeatDelay = g_state.useCustomDelays ? g_state.stepDelay : 290; + ClickAtScaled(currentX, currentY, repeatDelay); + } + } } } catch (...) { @@ -477,20 +636,6 @@ void HandleAlacDpsKeybind(const char* id, bool release) { } } -void HandleChronomancerKeybind(const char* id, bool release) { - if (!release) { - g_state.isChronomancer = !g_state.isChronomancer; - g_api->UI.SendAlert(g_state.isChronomancer ? "Chronomancer mode enabled" : "Chronomancer mode disabled"); - } -} - -void HandleMediumHitboxKeybind(const char* id, bool release) { - if (!release) { - g_state.isMediumHitbox = !g_state.isMediumHitbox; - g_api->UI.SendAlert(g_state.isMediumHitbox ? "Medium Hitbox enabled" : "Medium Hitbox disabled"); - } -} - void Load(AddonAPI* aApi) { g_api = aApi; @@ -509,13 +654,11 @@ void Load(AddonAPI* aApi) { g_api->InputBinds.RegisterWithStruct("GolemHelper.ApplyGolem", HandleGolemKeybind, kb_empty); g_api->InputBinds.RegisterWithStruct("GolemHelper.QuickDPS", HandleQuickDpsKeybind, kb_empty); g_api->InputBinds.RegisterWithStruct("GolemHelper.AlacDPS", HandleAlacDpsKeybind, kb_empty); - g_api->InputBinds.RegisterWithStruct("GolemHelper.Chronomancer", HandleChronomancerKeybind, kb_empty); - g_api->InputBinds.RegisterWithStruct("GolemHelper.MediumHitbox", HandleMediumHitboxKeybind, kb_empty); g_api->InputBinds.RegisterWithStruct("GolemHelper.Toggle", HandleToggleKeybind, kb_empty); - g_api->InputBinds.RegisterWithStruct("GolemHelper.DebugMouse", HandleDebugKeybind, kb_empty); g_api->InputBinds.RegisterWithStruct("GolemHelper.ToggleUI", HandleUIToggleKeybind, kb_empty); + g_api->InputBinds.RegisterWithStruct("GolemHelper.DebugMouse", HandleDebugKeybind, kb_empty); - g_api->Log(ELogLevel_INFO, "GolemHelper", "=== GolemHelper v1.0.0-beta.2 Loaded ==="); + g_api->Log(ELogLevel_INFO, "GolemHelper", "=== GolemHelper v1.0.0-beta.3 Loaded ==="); g_api->Log(ELogLevel_INFO, "GolemHelper", "GolemHelper addon loaded successfully!"); } @@ -527,11 +670,9 @@ void Unload() { g_api->InputBinds.Deregister("GolemHelper.ApplyGolem"); g_api->InputBinds.Deregister("GolemHelper.QuickDPS"); g_api->InputBinds.Deregister("GolemHelper.AlacDPS"); - g_api->InputBinds.Deregister("GolemHelper.Chronomancer"); - g_api->InputBinds.Deregister("GolemHelper.MediumHitbox"); g_api->InputBinds.Deregister("GolemHelper.Toggle"); - g_api->InputBinds.Deregister("GolemHelper.DebugMouse"); g_api->InputBinds.Deregister("GolemHelper.ToggleUI"); + g_api->InputBinds.Deregister("GolemHelper.DebugMouse"); } g_api->Log(ELogLevel_INFO, "GolemHelper", "GolemHelper signing off, it was an honor commander."); @@ -545,9 +686,9 @@ extern "C" __declspec(dllexport) AddonDefinition* GetAddonDef() { def.Signature = -424248; def.APIVersion = NEXUS_API_VERSION; def.Name = "GolemHelper"; - def.Version = { 1, 0, 0, 2 }; + def.Version = { 1, 0, 0, 3 }; def.Author = "Azrub"; - def.Description = "Automatically applies boons and configures golems in the training area"; + def.Description = "Automatically applies boons and golem settings in the training area"; def.Load = Load; def.Unload = Unload; def.Flags = EAddonFlags_None;