feat: omni auto-hack picks target itself (measured: game's _contextual_tag_template_name is forward-LOS gated — hackable=0 all session even under crosshair); nearest filtered enemy breed within 45m, direct set_tag, 30s per-unit retry blacklist
This commit is contained in:
@@ -12,6 +12,7 @@ local SpecialRulesSettings = require("scripts/settings/ability/spec
|
|||||||
local CompanionServoSkullSettings = require("scripts/settings/companion/companion_servo_skull_settings")
|
local CompanionServoSkullSettings = require("scripts/settings/companion/companion_servo_skull_settings")
|
||||||
local Hud = require("scripts/utilities/ui/hud")
|
local Hud = require("scripts/utilities/ui/hud")
|
||||||
local Health = require("scripts/utilities/health")
|
local Health = require("scripts/utilities/health")
|
||||||
|
local Breed = require("scripts/utilities/breed")
|
||||||
local special_rules = SpecialRulesSettings.special_rules
|
local special_rules = SpecialRulesSettings.special_rules
|
||||||
local servo_skull_states = CompanionServoSkullSettings.STATES
|
local servo_skull_states = CompanionServoSkullSettings.STATES
|
||||||
|
|
||||||
@@ -217,6 +218,14 @@ local find_hackable_target_unit = function()
|
|||||||
return selected_marker_unit, selected_marker_distance
|
return selected_marker_unit, selected_marker_distance
|
||||||
end
|
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 function find_hackable_target_unit_omni()
|
||||||
local smart_tag_system = context.smart_tag_system
|
local smart_tag_system = context.smart_tag_system
|
||||||
local player = context.player
|
local player = context.player
|
||||||
@@ -225,58 +234,22 @@ local function find_hackable_target_unit_omni()
|
|||||||
return
|
return
|
||||||
end
|
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 player_position = Unit_world_position(player_unit, 1)
|
||||||
local selected_unit, selected_distance
|
local selected_unit, selected_distance
|
||||||
local diag_total, diag_hackable
|
local diag_total
|
||||||
if mod_settings.debug_mode then
|
if mod_settings.debug_mode then
|
||||||
diag_total, diag_hackable = 0, 0
|
diag_total = 0
|
||||||
end
|
end
|
||||||
for unit, target_extension in pairs(smart_tag_system._unit_extension_data) do
|
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
|
if unit ~= player_unit and HEALTH_ALIVE[unit] and target_extension._target_type == "breed" and not mod._hack_blacklist[unit] then
|
||||||
local template_name = target_extension:_contextual_tag_template_name(player_unit, "companion_order")
|
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
|
if diag_total then
|
||||||
diag_total = diag_total + 1
|
diag_total = diag_total + 1
|
||||||
if template_name == HACK_TAG_NAME then
|
|
||||||
diag_hackable = diag_hackable + 1
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if template_name == HACK_TAG_NAME then
|
|
||||||
local distance = Vector3_distance(Unit_world_position(unit, 1), player_position)
|
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
|
selected_unit, selected_distance = unit, distance
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -285,9 +258,13 @@ local function find_hackable_target_unit_omni()
|
|||||||
if diag_total then
|
if diag_total then
|
||||||
mod.omni_hack_diag_counter = (mod.omni_hack_diag_counter or 0) + 1
|
mod.omni_hack_diag_counter = (mod.omni_hack_diag_counter or 0) + 1
|
||||||
if mod.omni_hack_diag_counter % 10 == 1 then
|
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
|
||||||
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
|
return selected_unit, selected_distance
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -302,6 +279,15 @@ function mod:auto_hack(dt, t, fixed_frame)
|
|||||||
return
|
return
|
||||||
end
|
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
|
if mod:is_servo_skull_hacking() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user