review: prod-readiness fix pass (3-agent code review + 2 self-found)

HIGH:
- rpc shadow dropped tagger_game_object_id and target_location (wrong vararg capture,
  args shifted); now forwards all varargs verbatim via unpack
- rpc shadow could NEVER install: ensure() read context.smart_tag_system (client-side
  instance) instead of the updating self; now armed per-instance, client shadow still
  pinned to the context instance only
- on_setting_changed debug_mode branch returned before the snapshot write: Debug Mode
  toggles were dead mid-session and the ON-notify read the stale value (AGENTS.md trap
  again, in my own fix); debug_chat/debug_hud now update the snapshot live too
- capacitance retention unit bug: widget relabel to charges (-10..10) left the legacy
  /100 in load + change handler + breed menu round-trip (*100) + breed setter (/100),
  making every retention threshold 100x too small; removed all four conversions
  (health-threshold percent semantics untouched)

MEDIUM:
- TARGETS capture was observer-non-neutral: MARKED candidate fell through into full
  re-evaluation (burned shared visibility budget); now skips like vanilla
- omni_diag_counter was an implicit global incremented in the prod hot path; now a
  file-local, only touched under debug_mode
- hack skull/check/blacklist state survived mission end (stale unit handles + stamped
  _automark_hack_order flags); mod:reset_servo_skull_local_state() runs on state exit,
  which also clears omni_last/omni_candidates/last_skull_confirm/banners

LOW: dead-tag release now honors per-class reset_cooldown; SERVO_SKULL gate checks class
before doing GameSession reads; mod:diag hard-gated on debug_mode internally (diag_log.txt
is never created for normal users anymore; un-gates OMNI-BOOT/banner/load probes); hits[]
pooled per call; early no-candidates return no longer dangles omni_rejects/omni_hud_units;
omni_last allocation gated on hud_capture; omni_hud_cur reset at entry and per-iteration
before actor resolution (no cross-candidate leakage); builder runs only while a level
world exists (no menu-side pcall spam); debug_hud_y fallback 24->0 matches default;
px unit_text localization added; six new widgets had orphan *_tooltip loc keys - DMF
only shows tooltips via an explicit tooltip field, added
This commit is contained in:
2026-10-04 11:18:23 -04:00
parent e9aebb2247
commit a18194519b
8 changed files with 129 additions and 41 deletions
+26 -13
View File
@@ -59,9 +59,9 @@ local mod_settings = {
noospheric_command_boost_special = mod:get("noospheric_command_boost_special") or false, noospheric_command_boost_special = mod:get("noospheric_command_boost_special") or false,
noospheric_command_boost_boss = mod:get("noospheric_command_boost_boss") or false, noospheric_command_boost_boss = mod:get("noospheric_command_boost_boss") or false,
capacitance_retention = mod:get("capacitance_retention") or false, capacitance_retention = mod:get("capacitance_retention") or false,
capacitance_retention_elite_threshold = (mod:get("capacitance_retention_elite_threshold") or 0) / 100, capacitance_retention_elite_threshold = mod:get("capacitance_retention_elite_threshold") or 0,
capacitance_retention_special_threshold = (mod:get("capacitance_retention_special_threshold") or 0) / 100, capacitance_retention_special_threshold = mod:get("capacitance_retention_special_threshold") or 0,
capacitance_retention_boss_threshold = (mod:get("capacitance_retention_boss_threshold") or 0) / 100, capacitance_retention_boss_threshold = mod:get("capacitance_retention_boss_threshold") or 0,
servo_skull_mark_sticky_targeting = mod:get("servo_skull_mark_sticky_targeting") or false, servo_skull_mark_sticky_targeting = mod:get("servo_skull_mark_sticky_targeting") or false,
servo_skull_mark_sticky_targeting_elite = mod:get("servo_skull_mark_sticky_targeting_elite") or false, servo_skull_mark_sticky_targeting_elite = mod:get("servo_skull_mark_sticky_targeting_elite") or false,
servo_skull_mark_sticky_targeting_special = mod:get("servo_skull_mark_sticky_targeting_special") or false, servo_skull_mark_sticky_targeting_special = mod:get("servo_skull_mark_sticky_targeting_special") or false,
@@ -372,21 +372,31 @@ mod.on_game_state_changed = function(status, state_name)
context.game_mode_valid = false context.game_mode_valid = false
-- menu mark info rest -- menu mark info rest
reset_context() reset_context()
if mod.reset_servo_skull_local_state then
mod:reset_servo_skull_local_state()
end
mod.omni_candidates = nil
mod.omni_candidates_pass = nil
mod.omni_last = nil
mod.last_skull_confirm = nil
mod.omni_gates_banner_done = nil
end end
end end
end end
-- Mod Setting Change -- Mod Setting Change
mod.on_setting_changed = function(setting_id) mod.on_setting_changed = function(setting_id)
if setting_id == "debug_mode" then if setting_id == "debug_mode" or setting_id == "debug_chat" or setting_id == "debug_hud" then
local value = mod:get(setting_id)
mod_settings[setting_id] = value
if mod_settings.debug_mode then if mod_settings.debug_mode then
mod:diag("OMNI-HUD setting changed:", setting_id, "=", tostring(value))
end
if setting_id == "debug_mode" and value then
mod:notify("AutoMark DEBUG ON: silent file diagnostics now write to mods/AutoMark/diag_log.txt and keep growing - remember to turn Debug Mode off when you are done!") mod:notify("AutoMark DEBUG ON: silent file diagnostics now write to mods/AutoMark/diag_log.txt and keep growing - remember to turn Debug Mode off when you are done!")
end end
return return
end end
if setting_id == "debug_hud" or setting_id == "debug_chat" then
mod:diag("OMNI-HUD setting changed:", setting_id, "=", tostring(mod_settings[setting_id]))
end
local result = mod:get(setting_id) local result = mod:get(setting_id)
local class_name = mod:get("class_selection") local class_name = mod:get("class_selection")
-- Normal Mod Settings -- Normal Mod Settings
@@ -394,7 +404,6 @@ mod.on_setting_changed = function(setting_id)
if setting_id == "companion_health_threshold" or setting_id == "servo_skull_cancel_mark_health_threshold" then if setting_id == "companion_health_threshold" or setting_id == "servo_skull_cancel_mark_health_threshold" then
result = result / 100 result = result / 100
elseif setting_id == "capacitance_retention_elite_threshold" or setting_id == "capacitance_retention_special_threshold" or setting_id == "capacitance_retention_boss_threshold" then elseif setting_id == "capacitance_retention_elite_threshold" or setting_id == "capacitance_retention_special_threshold" or setting_id == "capacitance_retention_boss_threshold" then
result = result / 100
if result == -0 and 1 / result < 0 then if result == -0 and 1 / result < 0 then
mod:set(setting_id .. "_negative_zero", true, false) mod:set(setting_id .. "_negative_zero", true, false)
else else
@@ -492,16 +501,18 @@ local function is_tag_valid(tag_name)
elseif tag_name == TAG_NAMES.ENEMY_TAG then elseif tag_name == TAG_NAMES.ENEMY_TAG then
return context.class_name ~= "veteran" or not context.has_focus_target return context.class_name ~= "veteran" or not context.has_focus_target
elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
local tg = is_training_grounds() if context.class_name ~= "cryptic" or not context.has_servo_skull then
return false
end
local state_ok = mod:is_servo_skull_ready_to_shoot() local state_ok = mod:is_servo_skull_ready_to_shoot()
local charge_ok = tg or can_noospheric_command_boost() local charge_ok = is_training_grounds() or can_noospheric_command_boost()
if not (state_ok and charge_ok) and mod_settings.debug_mode then if not (state_ok and charge_ok) and mod_settings.debug_mode then
mod.omni_gate_diag_counter = (mod.omni_gate_diag_counter or 0) + 1 mod.omni_gate_diag_counter = (mod.omni_gate_diag_counter or 0) + 1
if mod.omni_gate_diag_counter % 15 == 1 then if mod.omni_gate_diag_counter % 15 == 1 then
mod:diag(string.format("OMNI-GATE closed counter=%d state=%s state_ok=%s charge_ok=%s", mod.omni_gate_diag_counter, mod:debug_servo_skull_state(), tostring(state_ok), tostring(charge_ok))) mod:diag(string.format("OMNI-GATE closed counter=%d state=%s state_ok=%s charge_ok=%s", mod.omni_gate_diag_counter, mod:debug_servo_skull_state(), tostring(state_ok), tostring(charge_ok)))
end end
end end
return context.class_name == "cryptic" and context.has_servo_skull and state_ok and charge_ok return state_ok and charge_ok
end end
return false return false
end end
@@ -533,7 +544,9 @@ local function auto_mark_by_tag(tag_name, t, fixed_frame)
mod:print_debug("Auto Mark target dead, releasing tag") mod:print_debug("Auto Mark target dead, releasing tag")
smart_tag_system:cancel_tag(marked_tag._id, player_unit, true) smart_tag_system:cancel_tag(marked_tag._id, player_unit, true)
marked_tag = nil marked_tag = nil
tag_context.cooldown = 0 if mod:get_class_settings(tag_name).reset_cooldown then
tag_context.cooldown = 0
end
end end
end end
end end
@@ -719,7 +732,7 @@ mod:hook_safe(CLASS.PlayerUnitSmartTargetingExtension, "fixed_update",
return return
end end
if not mod.omni_gates_banner_done then if not mod.omni_gates_banner_done and mod_settings.debug_mode then
mod.omni_gates_banner_done = true mod.omni_gates_banner_done = true
local game_mode_manager = Managers.state.game_mode local game_mode_manager = Managers.state.game_mode
mod:diag(string.format("OMNI-GATES class=%s companion=%s skull=%s mode=%s valid=%s toggle=%s debug=%s", tostring(context.class_name), tostring(context.has_companion), tostring(context.has_servo_skull), game_mode_manager and tostring(game_mode_manager:game_mode_name()) or "nil", tostring(context.game_mode_valid), tostring(mod_settings.toggle_mod), tostring(mod_settings.debug_mode))) mod:diag(string.format("OMNI-GATES class=%s companion=%s skull=%s mode=%s valid=%s toggle=%s debug=%s", tostring(context.class_name), tostring(context.has_companion), tostring(context.has_servo_skull), game_mode_manager and tostring(game_mode_manager:game_mode_name()) or "nil", tostring(context.game_mode_valid), tostring(mod_settings.toggle_mod), tostring(mod_settings.debug_mode)))
@@ -173,14 +173,17 @@ local widgets = {
setting_id = "debug_chat", setting_id = "debug_chat",
type = "checkbox", type = "checkbox",
default_value = false, default_value = false,
tooltip = "debug_chat_tooltip",
}, },
{ {
setting_id = "debug_hud", setting_id = "debug_hud",
type = "checkbox", type = "checkbox",
default_value = false, default_value = false,
tooltip = "debug_hud_tooltip",
sub_widgets = { sub_widgets = {
{ {
setting_id = "debug_hud_x", setting_id = "debug_hud_x",
tooltip = "debug_hud_x_tooltip",
type = "numeric", type = "numeric",
default_value = 25, default_value = 25,
range = { 0, 3440 }, range = { 0, 3440 },
@@ -189,6 +192,7 @@ local widgets = {
}, },
{ {
setting_id = "debug_hud_y", setting_id = "debug_hud_y",
tooltip = "debug_hud_y_tooltip",
type = "numeric", type = "numeric",
default_value = 0, default_value = 0,
range = { -1440, 1440 }, range = { -1440, 1440 },
@@ -203,11 +207,13 @@ local widgets = {
setting_id = "omni_mark", setting_id = "omni_mark",
type = "checkbox", type = "checkbox",
default_value = false, default_value = false,
tooltip = "omni_mark_tooltip",
sub_widgets = { sub_widgets = {
{ {
setting_id = "omni_mark_ignore_los", setting_id = "omni_mark_ignore_los",
type = "checkbox", type = "checkbox",
default_value = false, default_value = false,
tooltip = "omni_mark_ignore_los_tooltip",
}, },
}, },
}, },
@@ -900,6 +900,11 @@ local localization = {
percent = { percent = {
en = "%%", en = "%%",
}, },
px = {
en = "px",
["zh-cn"] = "像素",
["zh-tw"] = "像素",
},
charges = { charges = {
en = "charge(s)", en = "charge(s)",
["zh-cn"] = "层充能", ["zh-cn"] = "层充能",
@@ -34,8 +34,13 @@ local CANCEL_INTERVAL = 0.5
-- metatable.__index) never land on this instance's call path — so we rawset an instance-level -- metatable.__index) never land on this instance's call path — so we rawset an instance-level
-- shadow that beats every lookup chain. It replicates set_tag's host accept-branch -- shadow that beats every lookup chain. It replicates set_tag's host accept-branch
-- (_generate_tag_id -> _create_tag_locally -> group limit -> rpc to clients) minus the gate. -- (_generate_tag_id -> _create_tag_locally -> group limit -> rpc to clients) minus the gate.
local function ensure_automark_tag_hook() local function ensure_automark_tag_hook(instance)
local smart_tag_system = context.smart_tag_system local smart_tag_system = context.smart_tag_system
if instance and instance._is_server then
-- the embedded-server-side system (host players only): context holds the CLIENT-side
-- instance, so the incoming RPC shadow must be armed on the updating instance itself
smart_tag_system = instance
end
if not smart_tag_system then if not smart_tag_system then
return return
end end
@@ -60,16 +65,17 @@ local function ensure_automark_tag_hook()
mod.omni_rpc_shadow_fired = true mod.omni_rpc_shadow_fired = true
mod:diag("OMNI-RPC-SHADOW FIRE (server-side testify window)") mod:diag("OMNI-RPC-SHADOW FIRE (server-side testify window)")
end end
local target_game_object_id, target_level_index, target_location = ... -- forward EVERYTHING verbatim: real signature is
-- (self, channel_id, template_name_id, tagger_game_object_id, target_game_object_id, target_level_index, target_location)
local args = { ... }
local saved_testify = GameParameters.testify local saved_testify = GameParameters.testify
GameParameters.testify = true GameParameters.testify = true
local ok = pcall(function() local ok = pcall(function()
orig_rpc(self, channel_id, template_name_id, target_game_object_id, target_level_index, target_location) orig_rpc(self, channel_id, template_name_id, unpack(args))
end) end)
GameParameters.testify = saved_testify GameParameters.testify = saved_testify
if not ok and mod_settings.debug_mode and not mod.omni_rpc_shadow_err_logged then if not ok then
mod.omni_rpc_shadow_err_logged = true mod:diag("OMNI-RPC-SHADOW orig handler threw, template=", tostring(template_name_id))
mod:diag("OMNI-RPC-SHADOW orig handler threw")
end end
end end
rawset(smart_tag_system, "rpc_request_set_smart_tag", patched_rpc) rawset(smart_tag_system, "rpc_request_set_smart_tag", patched_rpc)
@@ -77,6 +83,9 @@ local function ensure_automark_tag_hook()
mod:diag("OMNI-RPC-SHADOW INSTALLED on server-state system") mod:diag("OMNI-RPC-SHADOW INSTALLED on server-state system")
return return
end end
if smart_tag_system ~= context.smart_tag_system then
return
end
if mod.omni_hack_patched_sys == smart_tag_system then if mod.omni_hack_patched_sys == smart_tag_system then
return return
end end
@@ -146,7 +155,7 @@ mod:hook_safe(CLASS.SmartTagSystem, "update",
mod.omni_update_hook_seen = true mod.omni_update_hook_seen = true
mod:diag("OMNI-BOOT smart_tag_system:update seen, is_server=", tostring(self._is_server), " ctx_same=", tostring(self == context.smart_tag_system)) mod:diag("OMNI-BOOT smart_tag_system:update seen, is_server=", tostring(self._is_server), " ctx_same=", tostring(self == context.smart_tag_system))
end end
ensure_automark_tag_hook() ensure_automark_tag_hook(self)
end) end)
local function servo_skull_mark_callback() local function servo_skull_mark_callback()
@@ -256,7 +265,11 @@ function mod:is_servo_skull_hacking()
return false return false
end end
local game_session = Managers.state.game_session:game_session() local game_session_manager = Managers.state.game_session
local game_session = game_session_manager and game_session_manager:game_session()
if not game_session then
return false
end
local game_object_id = Managers.state.unit_spawner:game_object_id(companion_unit) local game_object_id = Managers.state.unit_spawner:game_object_id(companion_unit)
local state = get_game_object_field(game_session, game_object_id, "state") local state = get_game_object_field(game_session, game_object_id, "state")
return state == servo_skull_states.hacking return state == servo_skull_states.hacking
@@ -269,7 +282,11 @@ function mod:is_servo_skull_ready_to_shoot()
return false return false
end end
local game_session = Managers.state.game_session:game_session() local game_session_manager = Managers.state.game_session
local game_session = game_session_manager and game_session_manager:game_session()
if not game_session then
return false
end
local game_object_id = Managers.state.unit_spawner:game_object_id(companion_unit) local game_object_id = Managers.state.unit_spawner:game_object_id(companion_unit)
local state = get_game_object_field(game_session, game_object_id, "state") local state = get_game_object_field(game_session, game_object_id, "state")
return state == servo_skull_states.following or state == servo_skull_states.following_shooting or state == servo_skull_states.following_shooting_ability return state == servo_skull_states.following or state == servo_skull_states.following_shooting or state == servo_skull_states.following_shooting_ability
@@ -282,7 +299,11 @@ function mod:debug_servo_skull_state()
return "no_unit" return "no_unit"
end end
local game_session = Managers.state.game_session:game_session() local game_session_manager = Managers.state.game_session
local game_session = game_session_manager and game_session_manager:game_session()
if not game_session then
return "no_unit"
end
local game_object_id = Managers.state.unit_spawner:game_object_id(companion_unit) local game_object_id = Managers.state.unit_spawner:game_object_id(companion_unit)
return tostring(get_game_object_field(game_session, game_object_id, "state")) return tostring(get_game_object_field(game_session, game_object_id, "state"))
end end
@@ -587,3 +608,16 @@ function mod:auto_cancel_servo_skull_mark(dt, t, fixed_frame)
end end
end end
end end
function mod:reset_servo_skull_local_state()
hack_check = nil
skull_mark_check = nil
hack_interval = 0
cancel_interval = 0
for unit, entry in pairs(mod._hack_blacklist) do
if entry.ext then
entry.ext._automark_hack_order = nil
end
mod._hack_blacklist[unit] = nil
end
end
@@ -21,7 +21,7 @@ function mod:set_menu_servo_skull_breed_settings(breed_name)
mod:set("noospheric_command_boost_breed_override", breed_settings and breed_settings.override or false, false) mod:set("noospheric_command_boost_breed_override", breed_settings and breed_settings.override or false, false)
mod:set("servo_skull_range_limitation_breed", breed_settings and breed_settings.range_limitation or 0, false) mod:set("servo_skull_range_limitation_breed", breed_settings and breed_settings.range_limitation or 0, false)
mod:set("noospheric_command_boost_breed_toggle", breed_settings and breed_settings.toggle or false, false) mod:set("noospheric_command_boost_breed_toggle", breed_settings and breed_settings.toggle or false, false)
mod:set("capacitance_retention_breed_threshold", (breed_settings and breed_settings.threshold or 0) * 100, false) mod:set("capacitance_retention_breed_threshold", breed_settings and breed_settings.threshold or 0, false)
mod:set("servo_skull_mark_sticky_targeting_breed", breed_settings and breed_settings.sticky_targeting or false, false) mod:set("servo_skull_mark_sticky_targeting_breed", breed_settings and breed_settings.sticky_targeting or false, false)
mod:set("servo_skull_cancel_mark_breed_time_threshold", breed_settings and breed_settings.time_threshold or 0, false) mod:set("servo_skull_cancel_mark_breed_time_threshold", breed_settings and breed_settings.time_threshold or 0, false)
mod:set("servo_skull_cancel_mark_breed_health_threshold", (breed_settings and breed_settings.health_threshold or 0) * 100, false) mod:set("servo_skull_cancel_mark_breed_health_threshold", (breed_settings and breed_settings.health_threshold or 0) * 100, false)
@@ -38,7 +38,7 @@ function mod:set_servo_skull_breed_setting(breed_name, setting_id, value)
elseif setting_id == "noospheric_command_boost_breed_toggle" then elseif setting_id == "noospheric_command_boost_breed_toggle" then
noospheric_command_breed_settings[breed_name].toggle = value noospheric_command_breed_settings[breed_name].toggle = value
elseif setting_id == "capacitance_retention_breed_threshold" then elseif setting_id == "capacitance_retention_breed_threshold" then
noospheric_command_breed_settings[breed_name].threshold = value / 100 noospheric_command_breed_settings[breed_name].threshold = value
if value == -0 and 1 / value < 0 then if value == -0 and 1 / value < 0 then
noospheric_command_breed_settings[breed_name].threshold_negative_zero = true noospheric_command_breed_settings[breed_name].threshold_negative_zero = true
else else
@@ -61,6 +61,8 @@ local AIM_CHECK_MAX_HITS = 64
local AIM_CHECK_MIN_RADIUS = 1 local AIM_CHECK_MIN_RADIUS = 1
local AIM_CHECK_RADIUS_PER_METER = 0.052 local AIM_CHECK_RADIUS_PER_METER = 0.052
local omni_rejects = nil local omni_rejects = nil
local omni_diag_counter = 0
local omni_hits_pool = {}
local omni_hud_units = nil local omni_hud_units = nil
local omni_hud_cur = nil local omni_hud_cur = nil
local function omni_reject(reason) local function omni_reject(reason)
@@ -599,13 +601,17 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont
local hits, num_hits, hits_are_units local hits, num_hits, hits_are_units
local hud_capture = mod_settings.debug_hud or mod_settings.debug_mode local hud_capture = mod_settings.debug_hud or mod_settings.debug_mode
omni_hud_units = nil omni_hud_units = nil
omni_hud_cur = nil
if hud_capture then if hud_capture then
omni_hud_units = {} omni_hud_units = {}
mod.omni_candidates = nil mod.omni_candidates = nil
else
mod.omni_candidates = nil
mod.omni_candidates_pass = nil
end end
if omni_mark then if omni_mark then
-- enumerate smart-taggable units directly; physics sphere sweeps get swamped by world geometry actors -- enumerate smart-taggable units directly; physics sphere sweeps get swamped by world geometry actors
hits = {} hits = omni_hits_pool
num_hits = 0 num_hits = 0
local unit_extension_data = smart_tag_system._unit_extension_data local unit_extension_data = smart_tag_system._unit_extension_data
local max_range_squared = max_range * max_range local max_range_squared = max_range * max_range
@@ -616,7 +622,13 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont
local dist_squared = Vector3_distance_squared(position, ray_origin) local dist_squared = Vector3_distance_squared(position, ray_origin)
if dist_squared <= max_range_squared then if dist_squared <= max_range_squared then
num_hits = num_hits + 1 num_hits = num_hits + 1
hits[num_hits] = { unit = unit, position = position } local hit_entry = hits[num_hits]
if not hit_entry then
hit_entry = {}
hits[num_hits] = hit_entry
end
hit_entry.unit = unit
hit_entry.position = position
if omni_hud_units then if omni_hud_units then
local unit_data_extension = ScriptUnit_extension(unit, "unit_data_system") local unit_data_extension = ScriptUnit_extension(unit, "unit_data_system")
local breed = unit_data_extension and unit_data_extension._breed local breed = unit_data_extension and unit_data_extension._breed
@@ -629,9 +641,18 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont
end end
end end
end end
for i = num_hits + 1, #hits do
local stale = hits[i]
stale.unit = nil
stale.position = nil
end
hits_are_units = true hits_are_units = true
omni_diag_counter = (omni_diag_counter or 0) + 1 if mod_settings.debug_mode then
omni_rejects = mod_settings.debug_mode and omni_diag_counter % 10 == 1 and {} or nil omni_diag_counter = omni_diag_counter + 1
omni_rejects = omni_diag_counter % 10 == 1 and {} or nil
else
omni_rejects = nil
end
if omni_rejects then if omni_rejects then
local counts, ordered_names = {}, {} local counts, ordered_names = {}, {}
for i = 1, num_hits do for i = 1, num_hits do
@@ -655,6 +676,8 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont
end end
if not hits or num_hits <= 0 then if not hits or num_hits <= 0 then
omni_rejects = nil
omni_hud_units = nil
if hud_capture then if hud_capture then
mod.omni_candidates = mod.omni_candidates or {} mod.omni_candidates = mod.omni_candidates or {}
mod.omni_candidates_pass = tag_name mod.omni_candidates_pass = tag_name
@@ -719,6 +742,7 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont
for i = 1, num_hits do for i = 1, num_hits do
local hit = hits[i] local hit = hits[i]
local hit_unit, hit_unit_center_pos local hit_unit, hit_unit_center_pos
omni_hud_cur = nil
if hits_are_units then if hits_are_units then
hit_unit = hit.unit hit_unit = hit.unit
hit_unit_center_pos = hit.position hit_unit_center_pos = hit.position
@@ -733,6 +757,7 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont
omni_hud_cur = omni_hud_units and omni_hud_units[hit_unit] omni_hud_cur = omni_hud_units and omni_hud_units[hit_unit]
if omni_hud_cur and hit_unit == marked_unit then if omni_hud_cur and hit_unit == marked_unit then
omni_hud_cur.res = "MARKED" omni_hud_cur.res = "MARKED"
goto continue
elseif hit_unit == player_unit or hit_unit == marked_unit or canceled_units[hit_unit] or not HEALTH_ALIVE[hit_unit] then elseif hit_unit == player_unit or hit_unit == marked_unit or canceled_units[hit_unit] or not HEALTH_ALIVE[hit_unit] then
omni_reject("skip_player_dead") omni_reject("skip_player_dead")
goto continue goto continue
@@ -903,8 +928,10 @@ elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
omni_rejects = nil omni_rejects = nil
end end
mod.omni_last = { tag_name = tag_name, best = best_unit_breed_name, cands = num_hits } if hud_capture then
mod.omni_candidates_pass = tag_name mod.omni_last = { tag_name = tag_name, best = best_unit_breed_name, cands = num_hits }
mod.omni_candidates_pass = tag_name
end
if best_unit ~= marked_unit then if best_unit ~= marked_unit then
return best_unit, best_unit_tag, best_unit_is_dormant_daemonhost return best_unit, best_unit_tag, best_unit_is_dormant_daemonhost
+10 -10
View File
@@ -170,6 +170,15 @@ local function draw_inner(dt)
return return
end end
rebuild_acc = rebuild_acc + dt
if rebuild_acc >= REBUILD_INTERVAL then
rebuild_acc = 0
local ok, err = pcall(mod.build_debug_hud_lines, mod)
if not ok then
mod:diag("OMNI-HUD builder error:", tostring(err))
end
end
local buf = mod.debug_hud_last local buf = mod.debug_hud_last
local n = #buf local n = #buf
if n == 0 then if n == 0 then
@@ -185,7 +194,7 @@ local function draw_inner(dt)
local pad = math.floor(6 * scale + 0.5) local pad = math.floor(6 * scale + 0.5)
local margin_x = math.floor((mod_settings.debug_hud_x or 25) * scale + 0.5) local margin_x = math.floor((mod_settings.debug_hud_x or 25) * scale + 0.5)
local margin_y = math.floor((mod_settings.debug_hud_y or 24) * scale + 0.5) local margin_y = math.floor((mod_settings.debug_hud_y or 0) * scale + 0.5)
local maxw = 0 local maxw = 0
for i = 1, n do for i = 1, n do
@@ -247,14 +256,5 @@ mod.update = function (dt)
return return
end end
rebuild_acc = rebuild_acc + dt
if rebuild_acc >= REBUILD_INTERVAL then
rebuild_acc = 0
local ok, err = pcall(mod.build_debug_hud_lines, mod)
if not ok then
mod:diag("OMNI-HUD builder error:", tostring(err))
end
end
draw(dt) draw(dt)
end end
@@ -96,6 +96,9 @@ end
-- sandbox has no printf, so append to a plain text file instead (Mods.lua.io again). -- sandbox has no printf, so append to a plain text file instead (Mods.lua.io again).
-- never call unguarded: mod:diag swallows its own failures. -- never call unguarded: mod:diag swallows its own failures.
function mod:diag(...) function mod:diag(...)
if not mod_settings.debug_mode then
return
end
local args = { ... } local args = { ... }
local ok_diag, err_diag = pcall(function() local ok_diag, err_diag = pcall(function()
local file = Mods.lua.io.open("./../mods/AutoMark/diag_log.txt", "a") local file = Mods.lua.io.open("./../mods/AutoMark/diag_log.txt", "a")