diff --git a/AutoMark/scripts/mods/AutoMark/AutoMark.lua b/AutoMark/scripts/mods/AutoMark/AutoMark.lua index fc443d2..a462236 100644 --- a/AutoMark/scripts/mods/AutoMark/AutoMark.lua +++ b/AutoMark/scripts/mods/AutoMark/AutoMark.lua @@ -72,6 +72,8 @@ local mod_settings = { focus_target_switch_override_manual = mod:get("focus_target_switch_override_manual") or false, focus_target_switch_melee = mod:get("focus_target_switch_melee") or false, focus_target_switch_range = mod:get("focus_target_switch_range") or false, + omni_mark = mod:get("omni_mark") or false, + omni_mark_ignore_los = mod:get("omni_mark_ignore_los") or false, } mod.settings = mod_settings if mod:get("capacitance_retention_elite_threshold_negative_zero") then diff --git a/AutoMark/scripts/mods/AutoMark/AutoMark_data.lua b/AutoMark/scripts/mods/AutoMark/AutoMark_data.lua index 813f7dc..563189d 100644 --- a/AutoMark/scripts/mods/AutoMark/AutoMark_data.lua +++ b/AutoMark/scripts/mods/AutoMark/AutoMark_data.lua @@ -169,6 +169,18 @@ local widgets = { type = "checkbox", default_value = false }, + { + setting_id = "omni_mark", + type = "checkbox", + default_value = false, + sub_widgets = { + { + setting_id = "omni_mark_ignore_los", + type = "checkbox", + default_value = false, + }, + }, + }, } }, { diff --git a/AutoMark/scripts/mods/AutoMark/AutoMark_localization.lua b/AutoMark/scripts/mods/AutoMark/AutoMark_localization.lua index cc164d1..081cdcd 100644 --- a/AutoMark/scripts/mods/AutoMark/AutoMark_localization.lua +++ b/AutoMark/scripts/mods/AutoMark/AutoMark_localization.lua @@ -57,6 +57,26 @@ local localization = { ["zh-cn"] = "调试模式", ["zh-tw"] = "除錯模式", }, + omni_mark = { + en = "360° Marking", + ["zh-cn"] = "全向标记", + ["zh-tw"] = "全向標記", + }, + omni_mark_tooltip = { + en = "Find mark targets in all directions, including off-screen enemies behind you, instead of only under the crosshair.", + ["zh-cn"] = "向所有方向寻找标记目标,包括屏幕外和身后的敌人,而不再仅限准星下方。", + ["zh-tw"] = "向所有方向尋找標記目標,包括螢幕外和身後的敵人,而不再僅限準星下方。", + }, + omni_mark_ignore_los = { + en = "Ignore Line of Sight", + ["zh-cn"] = "忽略视线", + ["zh-tw"] = "忽略視線", + }, + omni_mark_ignore_los_tooltip = { + en = "Mark enemies even without a clear line of sight (through walls).", + ["zh-cn"] = "即使没有清晰视线也能标记敌人(穿墙)。", + ["zh-tw"] = "即使沒有清晰視線也能標記敵人(穿牆)。", + }, -- arbites settings adamant_settings = { en = "Arbites Settings", diff --git a/AutoMark/scripts/mods/AutoMark/targeting/custom_targeting.lua b/AutoMark/scripts/mods/AutoMark/targeting/custom_targeting.lua index 62a6144..e964137 100644 --- a/AutoMark/scripts/mods/AutoMark/targeting/custom_targeting.lua +++ b/AutoMark/scripts/mods/AutoMark/targeting/custom_targeting.lua @@ -53,13 +53,14 @@ local INDEX_NORMAL = 3 local INDEX_ACTOR = 4 local COLLISION_FILTER = "filter_player_ping_target_selection" local EMPTY_TABLE = {} -local MAX_VISIBILITY_CHECKS_PER_FRAME = 10 +local MAX_VISIBILITY_CHECKS_PER_FRAME = 16 local VIEW_CHECK_MIN_DISTANCE = 3 local VIEW_CHECK_MIN_DOT = 0.75 local AIM_CHECK_FILTER = "filter_player_ping_target_selection" local AIM_CHECK_MAX_HITS = 64 local AIM_CHECK_MIN_RADIUS = 1 local AIM_CHECK_RADIUS_PER_METER = 0.052 +local OMNI_MAX_HITS = 128 -- Params local visibility_raycast_object = nil @@ -524,7 +525,7 @@ function mod:is_target_pingable(target_unit) local forward = Vector3_flat(Quaternion_forward(first_person_component.rotation)) local dot = Vector3_dot(Vector3_normalize(forward), Vector3_normalize(to_target)) if dot < VIEW_CHECK_MIN_DOT then - return false + return mod_settings.omni_mark == true end local first_person_extension = ScriptUnit_extension(player_unit, "first_person_system") @@ -578,9 +579,16 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont return end - -- raycast for hit unit list + -- hit unit list: forward raycast, or full-sphere sweep when omni mark is enabled + local omni_mark = mod_settings.omni_mark local ray_origin, forward, right, up = smart_targeting_extension:_targeting_parameters() - local hits, num_hits = PhysicsWorld_raycast(smart_targeting_extension._physics_world, ray_origin, forward, max_range, "all", "collision_filter", COLLISION_FILTER) + local hits, num_hits, hits_use_actor + if omni_mark then + hits, num_hits = PhysicsWorld_linear_sphere_sweep(smart_targeting_extension._physics_world, ray_origin, ray_origin + forward * max_range, max_range, OMNI_MAX_HITS, "types", "both", "collision_filter", COLLISION_FILTER, "report_initial_overlap", true) + hits_use_actor = true + else + hits, num_hits = PhysicsWorld_raycast(smart_targeting_extension._physics_world, ray_origin, forward, max_range, "all", "collision_filter", COLLISION_FILTER) + end if not hits or num_hits <= 0 then return @@ -624,9 +632,11 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont local best_unit_is_dormant_daemonhost = false local best_unit_marked_by_execution_order = false local best_unit_is_sticky_targeting = false + local best_unit_distance = math.huge local marked_unit = marked_tag and marked_tag._target_unit if marked_unit then best_unit = marked_unit + best_unit_distance = Vector3_length(Unit_world_position(best_unit, 1) - ray_origin) local best_unit_data_extension = ScriptUnit_extension(best_unit, "unit_data_system") local best_unit_breed_data = best_unit_data_extension and best_unit_data_extension._breed best_unit_breed_name = best_unit_breed_data and best_unit_breed_data.name @@ -640,7 +650,7 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont for i = 1, num_hits do local hit = hits[i] - local hit_actor = hit[INDEX_ACTOR] + local hit_actor = hits_use_actor and hit.actor or hit[INDEX_ACTOR] if not hit_actor then goto continue end @@ -695,7 +705,7 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont best_unit_score = best_unit_score + (best_unit_is_attacking_player and 100 or 0) end - if hit_unit_score <= best_unit_score then + if hit_unit_score < best_unit_score then goto continue end @@ -707,6 +717,11 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont goto continue end + -- prefer the closer unit on score ties (hit order is arbitrary for the omni sweep) + if hit_unit_score == best_unit_score and distance >= best_unit_distance then + goto continue + end + local hit_unit_tag = smart_tag_system:unit_tag(hit_unit) if tag_name == TAG_NAMES.ENEMY_TAG then if hit_unit_tag then @@ -733,7 +748,9 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont end local visible - if tag_name == TAG_NAMES.SERVO_SKULL_TAG then + if omni_mark and mod_settings.omni_mark_ignore_los then + visible = true + elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then visible = is_servo_skull_target_visible(companion_position, hit_unit, fixed_frame) elseif tag_name == TAG_NAMES.COMPANION_TAG then local half_height = Breed_height(hit_unit, hit_unit_breed_data) * 0.5 @@ -755,6 +772,7 @@ function mod:find_auto_mark_target_unit(min_range, max_range, tag_name, tag_cont best_unit_is_dormant_daemonhost = hit_unit_is_dormant_daemonhost best_unit_marked_by_execution_order = hit_unit_marked_by_execution_order best_unit_is_sticky_targeting = false + best_unit_distance = distance ::continue:: end