feat: spoof _contextual_tag_template_name for the flagged auto-hack target — tagcheck proved the game silently rejects off-LOS set_tag (27/29 tag_applied=false); the game re-validates tags through this forward-LOS check, so flagging the chosen unit's extension makes its own validation accept the order
This commit is contained in:
@@ -29,6 +29,29 @@ local Vector3_distance = Vector3.distance
|
|||||||
local HACK_TAG_NAME = "hacking_over_here_companion"
|
local HACK_TAG_NAME = "hacking_over_here_companion"
|
||||||
local CANCEL_INTERVAL = 0.5
|
local CANCEL_INTERVAL = 0.5
|
||||||
|
|
||||||
|
-- set_tag() for off-LOS units is silently rejected because the game re-validates the tag
|
||||||
|
-- through the target extension's forward-LOS _contextual_tag_template_name(); flag the single
|
||||||
|
-- auto-hack target on its extension so the game's own validation accepts the order.
|
||||||
|
if not mod.omni_hack_spoof_hooked then
|
||||||
|
local spoof_class, spoof_class_name
|
||||||
|
for name, cls in pairs(CLASS) do
|
||||||
|
if type(cls) == "table" and rawget(cls, "_contextual_tag_template_name") ~= nil then
|
||||||
|
spoof_class, spoof_class_name = cls, name
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if spoof_class then
|
||||||
|
mod.omni_hack_spoof_hooked = true
|
||||||
|
mod.omni_hack_spoof_class = spoof_class_name
|
||||||
|
mod:hook(spoof_class, "_contextual_tag_template_name", function(previous_hook, self, player_unit, tag_name)
|
||||||
|
if tag_name == "companion_order" and self._automark_hack_order then
|
||||||
|
return HACK_TAG_NAME
|
||||||
|
end
|
||||||
|
return previous_hook(self, player_unit, tag_name)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function servo_skull_mark_callback()
|
local function servo_skull_mark_callback()
|
||||||
local smart_tag_system = context.smart_tag_system
|
local smart_tag_system = context.smart_tag_system
|
||||||
if not smart_tag_system then
|
if not smart_tag_system then
|
||||||
@@ -235,7 +258,7 @@ local function find_hackable_target_unit_omni()
|
|||||||
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, selected_name
|
local selected_unit, selected_distance, selected_name, selected_extension
|
||||||
local diag_total
|
local diag_total
|
||||||
if mod_settings.debug_mode then
|
if mod_settings.debug_mode then
|
||||||
diag_total = 0
|
diag_total = 0
|
||||||
@@ -255,6 +278,7 @@ local function find_hackable_target_unit_omni()
|
|||||||
end
|
end
|
||||||
if distance <= OMNI_HACK_RANGE and (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
|
||||||
|
selected_extension = target_extension
|
||||||
if diag_samples then
|
if diag_samples then
|
||||||
selected_name = breed_data.name
|
selected_name = breed_data.name
|
||||||
end
|
end
|
||||||
@@ -273,7 +297,10 @@ local function find_hackable_target_unit_omni()
|
|||||||
end
|
end
|
||||||
if selected_unit then
|
if selected_unit then
|
||||||
-- don't retarget the same unit forever if the game refuses to accept the tag
|
-- don't retarget the same unit forever if the game refuses to accept the tag
|
||||||
mod._hack_blacklist[selected_unit] = { t = HACK_RETRY_DELAY, n = selected_name }
|
mod._hack_blacklist[selected_unit] = { t = HACK_RETRY_DELAY, n = selected_name, ext = selected_extension }
|
||||||
|
if selected_extension then
|
||||||
|
selected_extension._automark_hack_order = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return selected_unit, selected_distance
|
return selected_unit, selected_distance
|
||||||
end
|
end
|
||||||
@@ -288,6 +315,9 @@ function mod:auto_hack(dt, t, fixed_frame)
|
|||||||
for unit, entry in pairs(mod._hack_blacklist) do
|
for unit, entry in pairs(mod._hack_blacklist) do
|
||||||
entry.t = entry.t - dt
|
entry.t = entry.t - dt
|
||||||
if entry.t <= 0 then
|
if entry.t <= 0 then
|
||||||
|
if entry.ext then
|
||||||
|
entry.ext._automark_hack_order = nil
|
||||||
|
end
|
||||||
mod._hack_blacklist[unit] = nil
|
mod._hack_blacklist[unit] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -297,7 +327,7 @@ function mod:auto_hack(dt, t, fixed_frame)
|
|||||||
if hack_check.ttl <= 0 then
|
if hack_check.ttl <= 0 then
|
||||||
if mod_settings.debug_mode then
|
if mod_settings.debug_mode then
|
||||||
local smart_tag_system = context.smart_tag_system
|
local smart_tag_system = context.smart_tag_system
|
||||||
mod:diag(string.format("OMNI-HACK-DIAG tagcheck %s alive=%s tag_applied=%s skull_hacking=%s", tostring(hack_check.n), tostring(HEALTH_ALIVE[hack_check.unit] == true), tostring(smart_tag_system and smart_tag_system:unit_tag(hack_check.unit) ~= nil), tostring(mod:is_servo_skull_hacking())))
|
mod:diag(string.format("OMNI-HACK-DIAG tagcheck %s alive=%s tag_applied=%s skull_hacking=%s spoof=%s", tostring(hack_check.n), tostring(HEALTH_ALIVE[hack_check.unit] == true), tostring(smart_tag_system and smart_tag_system:unit_tag(hack_check.unit) ~= nil), tostring(mod:is_servo_skull_hacking()), tostring(mod.omni_hack_spoof_class)))
|
||||||
end
|
end
|
||||||
hack_check = nil
|
hack_check = nil
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user