From 2cabef76614938d3c48117f66f31bbd636c91a8b Mon Sep 17 00:00:00 2001 From: michael Date: Sat, 3 Oct 2026 14:43:21 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20omni=20auto-hack=20picks=20target=20its?= =?UTF-8?q?elf=20(measured:=20game's=20=5Fcontextual=5Ftag=5Ftemplate=5Fna?= =?UTF-8?q?me=20is=20forward-LOS=20gated=20=E2=80=94=20hackable=3D0=20all?= =?UTF-8?q?=20session=20even=20under=20crosshair);=20nearest=20filtered=20?= =?UTF-8?q?enemy=20breed=20within=2045m,=20direct=20set=5Ftag,=2030s=20per?= =?UTF-8?q?-unit=20retry=20blacklist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mods/AutoMark/mark/servo_skull_mark.lua | 78 ++++++++----------- 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/AutoMark/scripts/mods/AutoMark/mark/servo_skull_mark.lua b/AutoMark/scripts/mods/AutoMark/mark/servo_skull_mark.lua index 719aa41..a67b9d0 100644 --- a/AutoMark/scripts/mods/AutoMark/mark/servo_skull_mark.lua +++ b/AutoMark/scripts/mods/AutoMark/mark/servo_skull_mark.lua @@ -12,6 +12,7 @@ local SpecialRulesSettings = require("scripts/settings/ability/spec local CompanionServoSkullSettings = require("scripts/settings/companion/companion_servo_skull_settings") local Hud = require("scripts/utilities/ui/hud") local Health = require("scripts/utilities/health") +local Breed = require("scripts/utilities/breed") local special_rules = SpecialRulesSettings.special_rules local servo_skull_states = CompanionServoSkullSettings.STATES @@ -217,6 +218,14 @@ local find_hackable_target_unit = function() return selected_marker_unit, selected_marker_distance end +local OMNI_HACK_RANGE = 45 +local HACK_RETRY_DELAY = 30 +mod._hack_blacklist = mod._hack_blacklist or {} + +-- NOTE: the game's _contextual_tag_template_name() is forward-LOS gated (measured in live play: +-- hackable=0 all session for all 15 nearby smart-taggable units, even under the crosshair), +-- so we pick the target ourselves with the same enemy filter the marking path uses and let +-- auto_hack()'s set_tag() do the actual tagging - same call in-game smart tagging performs. local function find_hackable_target_unit_omni() local smart_tag_system = context.smart_tag_system local player = context.player @@ -225,58 +234,22 @@ local function find_hackable_target_unit_omni() return end - if mod_settings.debug_mode and not mod.omni_hack_template_logged then - mod.omni_hack_template_logged = true - local templates = smart_tag_system._templates or smart_tag_system._tag_templates - if templates and type(templates) == "table" then - local tpl = templates[HACK_TAG_NAME] - if type(tpl) == "table" then - local parts = {} - for k, v in pairs(tpl) do - local vs - if type(v) == "table" then - local inner = {} - for k2, v2 in pairs(v) do - inner[#inner + 1] = tostring(k2) .. "=" .. tostring(v2) - end - vs = "{" .. table.concat(inner, ",") .. "}" - else - vs = tostring(v) - end - parts[#parts + 1] = tostring(k) .. "=" .. vs - end - mod:diag("OMNI-HACK-DIAG template: " .. table.concat(parts, " ")) - else - mod:diag("OMNI-HACK-DIAG template missing: " .. tostring(tpl)) - end - else - local keys = {} - for k in pairs(smart_tag_system) do - keys[#keys + 1] = tostring(k) - end - table.sort(keys) - mod:diag("OMNI-HACK-DIAG no templates table, system keys: " .. table.concat(keys, ",")) - end - end - local player_position = Unit_world_position(player_unit, 1) local selected_unit, selected_distance - local diag_total, diag_hackable + local diag_total if mod_settings.debug_mode then - diag_total, diag_hackable = 0, 0 + diag_total = 0 end for unit, target_extension in pairs(smart_tag_system._unit_extension_data) do - if unit ~= player_unit and HEALTH_ALIVE[unit] and target_extension._target_type == "breed" then - local template_name = target_extension:_contextual_tag_template_name(player_unit, "companion_order") - if diag_total then - diag_total = diag_total + 1 - if template_name == HACK_TAG_NAME then - diag_hackable = diag_hackable + 1 + if unit ~= player_unit and HEALTH_ALIVE[unit] and target_extension._target_type == "breed" and not mod._hack_blacklist[unit] then + local unit_data_extension = ScriptUnit_extension(unit, "unit_data_system") + local breed_data = unit_data_extension and unit_data_extension._breed + if breed_data and Breed.is_minion(breed_data) and breed_data.unit_template_name == "minion" and breed_data.faction_name ~= "imperium" and not breed_data.is_boss then + if diag_total then + diag_total = diag_total + 1 end - end - if template_name == HACK_TAG_NAME then local distance = Vector3_distance(Unit_world_position(unit, 1), player_position) - if not selected_distance or distance < selected_distance then + if distance <= OMNI_HACK_RANGE and (not selected_distance or distance < selected_distance) then selected_unit, selected_distance = unit, distance end end @@ -285,9 +258,13 @@ local function find_hackable_target_unit_omni() if diag_total then mod.omni_hack_diag_counter = (mod.omni_hack_diag_counter or 0) + 1 if mod.omni_hack_diag_counter % 10 == 1 then - mod:diag(string.format("OMNI-HACK-DIAG breed_units=%d hackable=%d selected=%s dist=%s", diag_total, diag_hackable, tostring(selected_unit), tostring(selected_distance))) + mod:diag(string.format("OMNI-HACK-DIAG enemies=%d selected=%s dist=%s", diag_total, tostring(selected_unit), tostring(selected_distance))) end end + if selected_unit then + -- don't retarget the same unit forever if the game refuses to accept the tag + mod._hack_blacklist[selected_unit] = HACK_RETRY_DELAY + end return selected_unit, selected_distance end @@ -302,6 +279,15 @@ function mod:auto_hack(dt, t, fixed_frame) return end + for unit, remaining in pairs(mod._hack_blacklist) do + local age = remaining - dt + if age <= 0 then + mod._hack_blacklist[unit] = nil + else + mod._hack_blacklist[unit] = age + end + end + if mod:is_servo_skull_hacking() then return end