Upstream AutoMark v2.5.3 (Shui Yu, Nexus #736) baseline
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
return {
|
||||
run = function()
|
||||
fassert(rawget(_G, "new_mod"), "`AutoMark` encountered an error loading the Darktide Mod Framework.")
|
||||
|
||||
new_mod("AutoMark", {
|
||||
mod_script = "AutoMark/scripts/mods/AutoMark/AutoMark",
|
||||
mod_data = "AutoMark/scripts/mods/AutoMark/AutoMark_data",
|
||||
mod_localization = "AutoMark/scripts/mods/AutoMark/AutoMark_localization",
|
||||
})
|
||||
end,
|
||||
packages = {},
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Auto Mark",
|
||||
"description": "Enhance your marking experience",
|
||||
"version": "2.5.3",
|
||||
"author": "Shui Yu",
|
||||
"homepage": "https://www.nexusmods.com/warhammer40kdarktide/mods/736",
|
||||
"source": "",
|
||||
"funding": {
|
||||
"kofi": "",
|
||||
"patreon": ""
|
||||
},
|
||||
"load_order": {
|
||||
"requirements": [],
|
||||
"load_after": [],
|
||||
"load_before": [
|
||||
"Muzzle"
|
||||
]
|
||||
},
|
||||
"localization": {}
|
||||
}
|
||||
@@ -0,0 +1,683 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local breeds = require("scripts/settings/breed/breeds")
|
||||
local Breed = require("scripts/utilities/breed")
|
||||
|
||||
-- Global Cache
|
||||
local CLASS = CLASS
|
||||
local ScriptUnit_extension = ScriptUnit.extension
|
||||
local table_clear = table.clear
|
||||
|
||||
-- Smart Tag Names
|
||||
---@class AutoMarkTagNames
|
||||
local TAG_NAMES = {
|
||||
ENEMY_TAG = "enemy_over_here",
|
||||
VETERAN_TAG = "enemy_over_here_veteran",
|
||||
COMPANION_TAG = "enemy_companion_target",
|
||||
SERVO_SKULL_TAG = "servo_skull_enemy_companion_target",
|
||||
}
|
||||
mod.TAG_NAMES = TAG_NAMES
|
||||
|
||||
-- Mod Settings
|
||||
---@class AutoMarkModSettings
|
||||
local mod_settings = {
|
||||
toggle_mod = mod:get("toggle_mod") or false,
|
||||
toggle_mod_keybind = mod:get("toggle_mod_keybind") or {},
|
||||
toggle_mod_notify = mod:get("toggle_mod_notify") or false,
|
||||
debug_mode = mod:get("debug_mode") or false,
|
||||
companion_mark_keybind = mod:get("companion_mark_keybind") or {},
|
||||
companion_mark_ignore_unaggroed = mod:get("companion_mark_ignore_unaggroed") or false,
|
||||
companion_range_limitation = mod:get("companion_range_limitation") or 0,
|
||||
companion_mark_max_distance = mod:get("companion_mark_max_distance") or 0,
|
||||
companion_mark_threat_priority = mod:get("companion_mark_threat_priority") or false,
|
||||
execution_order_priority = mod:get("execution_order_priority") or false,
|
||||
execution_order_force_mark = mod:get("execution_order_force_mark") or false,
|
||||
companion_mark_tagged_always_visible = mod:get("companion_mark_tagged_always_visible") or false,
|
||||
companion_mark_sticky_targeting = mod:get("companion_mark_sticky_targeting") or false,
|
||||
companion_mark_sticky_targeting_elite = mod:get("companion_mark_sticky_targeting_elite") or false,
|
||||
companion_mark_sticky_targeting_special = mod:get("companion_mark_sticky_targeting_special") or false,
|
||||
companion_mark_sticky_targeting_boss = mod:get("companion_mark_sticky_targeting_boss") or false,
|
||||
companion_cancel_mark = mod:get("companion_cancel_mark") or false,
|
||||
companion_cancel_mark_human = mod:get("companion_cancel_mark_human") or false,
|
||||
companion_cancel_mark_non_human = mod:get("companion_cancel_mark_non_human") or false,
|
||||
companion_health_threshold = (mod:get("companion_health_threshold") or 0) / 100,
|
||||
companion_time_threshold = mod:get("companion_time_threshold") or 0,
|
||||
companion_distance_threshold = mod:get("companion_distance_threshold") or 0,
|
||||
servo_skull_mark_keybind = mod:get("servo_skull_mark_keybind") or {},
|
||||
servo_skull_mark_ignore_unaggroed = mod:get("servo_skull_mark_ignore_unaggroed") or false,
|
||||
servo_skull_range_limitation = mod:get("servo_skull_range_limitation") or 0,
|
||||
servo_skull_mark_threat_priority = mod:get("servo_skull_mark_threat_priority") or false,
|
||||
hack_mark_keybind = mod:get("hack_mark_keybind") or {},
|
||||
auto_hack = mod:get("auto_hack") or false,
|
||||
disable_auto_hack_for_noospheric_command = mod:get("disable_auto_hack_for_noospheric_command") or false,
|
||||
noospheric_command_boost = mod:get("noospheric_command_boost") or false,
|
||||
noospheric_command_boost_elite = mod:get("noospheric_command_boost_elite") 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,
|
||||
capacitance_retention = mod:get("capacitance_retention") or false,
|
||||
capacitance_retention_elite_threshold = (mod:get("capacitance_retention_elite_threshold") or 0) / 100,
|
||||
capacitance_retention_special_threshold = (mod:get("capacitance_retention_special_threshold") or 0) / 100,
|
||||
capacitance_retention_boss_threshold = (mod:get("capacitance_retention_boss_threshold") or 0) / 100,
|
||||
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_special = mod:get("servo_skull_mark_sticky_targeting_special") or false,
|
||||
servo_skull_mark_sticky_targeting_boss = mod:get("servo_skull_mark_sticky_targeting_boss") or false,
|
||||
servo_skull_cancel_mark = mod:get("servo_skull_cancel_mark") or false,
|
||||
servo_skull_cancel_mark_time_threshold = mod:get("servo_skull_cancel_mark_time_threshold") or 0,
|
||||
servo_skull_cancel_mark_health_threshold = (mod:get("servo_skull_cancel_mark_health_threshold") or 0) / 100,
|
||||
focus_target_overwrite = mod:get("focus_target_overwrite") or false,
|
||||
focus_target_overwrite_delta = mod:get("focus_target_overwrite_delta") or 5,
|
||||
focus_target_ignore_unaggroed = mod:get("focus_target_ignore_unaggroed") or false,
|
||||
focus_target_switch = mod:get("focus_target_switch") or false,
|
||||
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,
|
||||
}
|
||||
mod.settings = mod_settings
|
||||
if mod:get("capacitance_retention_elite_threshold_negative_zero") then
|
||||
mod_settings.capacitance_retention_elite_threshold = -0
|
||||
mod:set("capacitance_retention_elite_threshold", -0, false)
|
||||
end
|
||||
if mod:get("capacitance_retention_special_threshold_negative_zero") then
|
||||
mod_settings.capacitance_retention_special_threshold = -0
|
||||
mod:set("capacitance_retention_special_threshold", -0, false)
|
||||
end
|
||||
if mod:get("capacitance_retention_boss_threshold_negative_zero") then
|
||||
mod_settings.capacitance_retention_boss_threshold = -0
|
||||
mod:set("capacitance_retention_boss_threshold", -0, false)
|
||||
end
|
||||
|
||||
local noospheric_command_breed_settings = mod:get("noospheric_command_breed_settings") or {}
|
||||
mod.noospheric_command_breed_settings = noospheric_command_breed_settings
|
||||
for _, breed_settings in pairs(noospheric_command_breed_settings) do
|
||||
if breed_settings.threshold_negative_zero then
|
||||
breed_settings.threshold = -0
|
||||
end
|
||||
end
|
||||
|
||||
local companion_cancel_mark_breed_settings = mod:get("companion_cancel_mark_breed_settings") or {}
|
||||
mod.companion_cancel_mark_breed_settings = companion_cancel_mark_breed_settings
|
||||
|
||||
-- Default Class Settings
|
||||
---@class AutoMarkDefaultClassSettings
|
||||
local DEFAULT_CLASS_SETTINGS = {
|
||||
toggle_class = true,
|
||||
cooldown = 25,
|
||||
reset_cooldown = true,
|
||||
interval = 1,
|
||||
mark_limit = true,
|
||||
min_range = 0,
|
||||
max_range = 100,
|
||||
override_manual = false,
|
||||
priority_switch = false,
|
||||
toggle_elite = true,
|
||||
toggle_special = true,
|
||||
toggle_boss = true,
|
||||
toggle_other = true,
|
||||
breed_priorities = {},
|
||||
}
|
||||
for breed_name, breed_data in pairs(breeds) do
|
||||
if Breed.is_minion(breed_data) and breed_data.unit_template_name == "minion" and breed_data.smart_tag_target_type == "breed" and breed_data.faction_name ~= "imperium" then
|
||||
if breed_data.tags.elite then
|
||||
DEFAULT_CLASS_SETTINGS.breed_priorities[breed_name] = 0
|
||||
elseif breed_data.tags.special then
|
||||
DEFAULT_CLASS_SETTINGS.breed_priorities[breed_name] = 1
|
||||
elseif breed_data.is_boss then
|
||||
DEFAULT_CLASS_SETTINGS.breed_priorities[breed_name] = 1
|
||||
if breed_data.tags.witch then
|
||||
DEFAULT_CLASS_SETTINGS.breed_priorities[breed_name .. "_passive"] = 1
|
||||
end
|
||||
else
|
||||
DEFAULT_CLASS_SETTINGS.breed_priorities[breed_name] = 1
|
||||
end
|
||||
end
|
||||
end
|
||||
mod.DEFAULT_CLASS_SETTINGS = DEFAULT_CLASS_SETTINGS
|
||||
|
||||
-- Context
|
||||
---@class AutoMarkContext
|
||||
local context = {
|
||||
mod_enabled = false,
|
||||
game_mode_valid = false,
|
||||
player = nil,
|
||||
class_name = nil,
|
||||
talent_resource_component = nil,
|
||||
disabled_character_state_component = nil,
|
||||
locomotion_component = nil,
|
||||
has_companion = false,
|
||||
has_execution_order = false,
|
||||
has_focus_target = false,
|
||||
focus_target_max_stacks = 0,
|
||||
has_servo_skull = false,
|
||||
has_noospheric_command = false,
|
||||
smart_targeting_extension = nil,
|
||||
companion_spawner_extension = nil,
|
||||
player_ability_extension = nil,
|
||||
smart_tag_system = nil,
|
||||
outline_system = nil,
|
||||
smoke_fog_system = nil,
|
||||
force_field_system = nil,
|
||||
broadphase_system = nil,
|
||||
side_system = nil,
|
||||
hud_element_smart_tagging = nil,
|
||||
companion_command_tap = "double"
|
||||
}
|
||||
mod.context = context
|
||||
|
||||
-- Auto Mark Settings
|
||||
local auto_mark_settings = mod:get("auto_mark_settings") or {}
|
||||
mod.auto_mark_settings = auto_mark_settings
|
||||
|
||||
-- Mark States
|
||||
---@class AutoMarkMarkContext
|
||||
local mark_context = {
|
||||
auto_mark_interval = 0,
|
||||
execution_order_units = setmetatable({}, { __mode = "k" }),
|
||||
[TAG_NAMES.ENEMY_TAG] = {
|
||||
tag = nil,
|
||||
cooldown = 0,
|
||||
priority_switch_cooldown = 0,
|
||||
delay = 0,
|
||||
delay_times = 0,
|
||||
interval = 0,
|
||||
manual_unit = nil,
|
||||
manual_unit_expired_time = nil,
|
||||
is_manual = false,
|
||||
},
|
||||
[TAG_NAMES.VETERAN_TAG] = {
|
||||
tag = nil,
|
||||
cooldown = 0,
|
||||
priority_switch_cooldown = 0,
|
||||
delay = 0,
|
||||
delay_times = 0,
|
||||
interval = 0,
|
||||
manual_unit = nil,
|
||||
manual_unit_expired_time = nil,
|
||||
is_manual = false,
|
||||
switch_melee_unit = nil,
|
||||
switch_range_unit = nil,
|
||||
switch_unit_expired_time = nil,
|
||||
is_switch_melee = false,
|
||||
is_switch_range = false,
|
||||
removed_units = setmetatable({}, { __mode = "k" }),
|
||||
},
|
||||
[TAG_NAMES.COMPANION_TAG] = {
|
||||
tag = nil,
|
||||
cooldown = 0,
|
||||
priority_switch_cooldown = 0,
|
||||
delay = 0,
|
||||
delay_times = 0,
|
||||
interval = 0,
|
||||
manual_unit = nil,
|
||||
manual_unit_expired_time = nil,
|
||||
is_manual = false,
|
||||
pounce_start_time = nil,
|
||||
is_cancelable = false,
|
||||
canceled_units = setmetatable({}, { __mode = "k" }),
|
||||
removed_units = setmetatable({}, { __mode = "k" }),
|
||||
},
|
||||
[TAG_NAMES.SERVO_SKULL_TAG] = {
|
||||
tag = nil,
|
||||
cooldown = 0,
|
||||
priority_switch_cooldown = 0,
|
||||
delay = 0,
|
||||
delay_times = 0,
|
||||
interval = 0,
|
||||
manual_unit = nil,
|
||||
manual_unit_expired_time = nil,
|
||||
is_manual = false,
|
||||
shoot_start_time = nil,
|
||||
noospheric_command_next_time = math.huge,
|
||||
servo_skull_lose_sight_time = nil,
|
||||
canceled_units = setmetatable({}, { __mode = "k" }),
|
||||
removed_units = setmetatable({}, { __mode = "k" }),
|
||||
},
|
||||
}
|
||||
mod.mark_context = mark_context
|
||||
|
||||
-- Enemy Visbility Check
|
||||
local visibility_cache = setmetatable({}, { __mode = "k" })
|
||||
local visibility_check_frame = setmetatable({}, { __mode = "k" })
|
||||
mod.visibility_cache = visibility_cache
|
||||
mod.visibility_check_frame = visibility_check_frame
|
||||
local servo_skull_visibility_cache = setmetatable({}, { __mode = "k" })
|
||||
local servo_skull_visibility_check_frame = setmetatable({}, { __mode = "k" })
|
||||
mod.servo_skull_visibility_cache = servo_skull_visibility_cache
|
||||
mod.servo_skull_visibility_check_frame = servo_skull_visibility_check_frame
|
||||
mod.num_visibility_checks_this_frame = 0
|
||||
|
||||
---@class AutoMarkDisablingTypes
|
||||
local DISABLING_TYPES = {
|
||||
-- netted = true,
|
||||
pounced = true,
|
||||
warp_grabbed = true,
|
||||
mutant_charged = true,
|
||||
consumed = true,
|
||||
grabbed = true,
|
||||
}
|
||||
mod.DISABLING_TYPES = DISABLING_TYPES
|
||||
|
||||
-- Reset all params
|
||||
local function reset_context()
|
||||
-- Reset Mark Params
|
||||
mark_context.auto_mark_interval = 0
|
||||
table_clear(mark_context.execution_order_units)
|
||||
table_clear(visibility_cache)
|
||||
table_clear(visibility_check_frame)
|
||||
table_clear(servo_skull_visibility_cache)
|
||||
table_clear(servo_skull_visibility_check_frame)
|
||||
for _, tag_name in pairs(TAG_NAMES) do
|
||||
local tag_context = mark_context[tag_name]
|
||||
tag_context.tag = nil
|
||||
tag_context.cooldown = 0
|
||||
tag_context.priority_switch_cooldown = 0
|
||||
tag_context.delay = 0
|
||||
tag_context.delay_times = 0
|
||||
tag_context.interval = 0
|
||||
tag_context.manual_unit = nil
|
||||
tag_context.manual_unit_expired_time = nil
|
||||
tag_context.is_manual = false
|
||||
end
|
||||
local veteran_tag_context = mark_context[TAG_NAMES.VETERAN_TAG]
|
||||
veteran_tag_context.switch_melee_unit = nil
|
||||
veteran_tag_context.switch_range_unit = nil
|
||||
veteran_tag_context.switch_unit_expired_time = nil
|
||||
veteran_tag_context.is_switch_melee = false
|
||||
veteran_tag_context.is_switch_range = false
|
||||
table_clear(veteran_tag_context.removed_units)
|
||||
local companion_tag_context = mark_context[TAG_NAMES.COMPANION_TAG]
|
||||
companion_tag_context.pounce_start_time = nil
|
||||
companion_tag_context.is_cancelable = false
|
||||
table_clear(companion_tag_context.canceled_units)
|
||||
table_clear(companion_tag_context.removed_units)
|
||||
local servo_skull_tag_context = mark_context[TAG_NAMES.SERVO_SKULL_TAG]
|
||||
servo_skull_tag_context.shoot_start_time = nil
|
||||
servo_skull_tag_context.noospheric_command_next_time = math.huge
|
||||
servo_skull_tag_context.servo_skull_lose_sight_time = nil
|
||||
table_clear(servo_skull_tag_context.canceled_units)
|
||||
table_clear(servo_skull_tag_context.removed_units)
|
||||
end
|
||||
|
||||
local function destroy_references()
|
||||
context.player = nil
|
||||
context.talent_resource_component = nil
|
||||
context.disabled_character_state_component = nil
|
||||
context.locomotion_component = nil
|
||||
context.smart_targeting_extension = nil
|
||||
context.companion_spawner_extension = nil
|
||||
context.player_ability_extension = nil
|
||||
context.smart_tag_system = nil
|
||||
context.outline_system = nil
|
||||
context.smoke_fog_system = nil
|
||||
context.force_field_system = nil
|
||||
context.broadphase_system = nil
|
||||
context.side_system = nil
|
||||
context.hud_element_smart_tagging = nil
|
||||
mod:destroy_visibility_raycast_objects()
|
||||
end
|
||||
|
||||
-- Load Other Files
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/utils/utils")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/context/context")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/setting/class_setting")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/setting/cyber_mastiff_setting")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/setting/servo_skull_setting")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/targeting/targeting")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/targeting/custom_targeting")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/mark/base_mark")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/mark/companion_mark")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/mark/focus_target_mark")
|
||||
mod:io_dofile("AutoMark/scripts/mods/AutoMark/mark/servo_skull_mark")
|
||||
|
||||
-- Mod Enabled
|
||||
mod.on_enabled = function(initial_call)
|
||||
context.mod_enabled = true
|
||||
mod:check_game_mode()
|
||||
mod:init_auto_mark_settings()
|
||||
-- init cache after mod enabled since all hooks were disabled
|
||||
mod:init_context()
|
||||
mod:init_execution_order_units()
|
||||
mod:init_visibility_raycast_objects()
|
||||
mod:set_menu_class_settings(mod:get_menu_class_name())
|
||||
mod:set_menu_servo_skull_breed_settings(mod:get("noospheric_command_boost_breed_name"))
|
||||
mod:set_menu_cyber_mastiff_breed_settings(mod:get("companion_cancel_mark_breed_name"))
|
||||
end
|
||||
|
||||
-- Mod Disabled
|
||||
mod.on_disabled = function(initial_call)
|
||||
context.mod_enabled = false
|
||||
-- mark info rest
|
||||
reset_context()
|
||||
destroy_references()
|
||||
end
|
||||
|
||||
-- Enter/Exit GameplayStateRun
|
||||
mod.on_game_state_changed = function(status, state_name)
|
||||
if state_name == "GameplayStateRun" then
|
||||
if status == "enter" then
|
||||
mod:check_game_mode()
|
||||
-- game settings cache
|
||||
mod:init_game_settings()
|
||||
-- display
|
||||
mod:set_menu_class_settings(mod:get_menu_class_name())
|
||||
elseif status == "exit" then
|
||||
context.game_mode_valid = false
|
||||
-- menu mark info rest
|
||||
reset_context()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Mod Setting Change
|
||||
mod.on_setting_changed = function(setting_id)
|
||||
local result = mod:get(setting_id)
|
||||
local class_name = mod:get("class_selection")
|
||||
-- Normal Mod Settings
|
||||
if mod_settings[setting_id] ~= nil then
|
||||
if setting_id == "companion_health_threshold" or setting_id == "servo_skull_cancel_mark_health_threshold" then
|
||||
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
|
||||
result = result / 100
|
||||
if result == -0 and 1 / result < 0 then
|
||||
mod:set(setting_id .. "_negative_zero", true, false)
|
||||
else
|
||||
mod:set(setting_id .. "_negative_zero", false, false)
|
||||
end
|
||||
end
|
||||
mod_settings[setting_id] = result
|
||||
-- Apply Class Settings to Other Classes
|
||||
elseif setting_id == "apply_button" then
|
||||
if result == "apply_to_all" then
|
||||
mod:apply_to_all_classes(class_name)
|
||||
elseif result == "apply_to_normal" then
|
||||
mod:apply_to_normal_tag(class_name)
|
||||
end
|
||||
mod:set("apply_button", "blank", false)
|
||||
-- Reset Class Settings
|
||||
elseif setting_id == "reset_button" then
|
||||
if result == "reset_all" then
|
||||
mod:reset_auto_mark_settings()
|
||||
elseif result == "reset_current" then
|
||||
mod:reset_class_settings(class_name)
|
||||
end
|
||||
mod:set_menu_class_settings(class_name)
|
||||
mod:set("reset_button", "blank", false)
|
||||
-- Select Noospheric Command Breed Name
|
||||
elseif setting_id == "noospheric_command_boost_breed_name" then
|
||||
mod:set_menu_servo_skull_breed_settings(result)
|
||||
-- Set Noospheric Command Breed Settings
|
||||
elseif mod:is_servo_skull_breed_setting_id(setting_id) then
|
||||
local breed_name = mod:get("noospheric_command_boost_breed_name")
|
||||
mod:set_servo_skull_breed_setting(breed_name, setting_id, result)
|
||||
-- Select Companion Cancel Mark Breed Name
|
||||
elseif setting_id == "companion_cancel_mark_breed_name" then
|
||||
mod:set_menu_cyber_mastiff_breed_settings(result)
|
||||
-- Set Companion Cancel Mark Breed Settings
|
||||
elseif mod:is_cyber_mastiff_breed_setting_id(setting_id) then
|
||||
local breed_name = mod:get("companion_cancel_mark_breed_name")
|
||||
mod:set_cyber_mastiff_breed_setting(breed_name, setting_id, result)
|
||||
-- Set Class Name
|
||||
elseif setting_id == "class_selection" then
|
||||
mod:set_menu_class_settings(result)
|
||||
-- Set Class Settings
|
||||
else
|
||||
local class_settings = auto_mark_settings[class_name]
|
||||
if DEFAULT_CLASS_SETTINGS[setting_id] ~= nil then
|
||||
class_settings[setting_id] = result
|
||||
elseif DEFAULT_CLASS_SETTINGS.breed_priorities[setting_id] ~= nil then
|
||||
if (class_name == "adamant_companion" or class_name == "cryptic_servo_skull") and setting_id == "chaos_poxwalker_bomber" then
|
||||
class_settings.breed_priorities[setting_id] = 0
|
||||
mod:set_menu_class_settings(class_name)
|
||||
else
|
||||
class_settings.breed_priorities[setting_id] = result
|
||||
end
|
||||
end
|
||||
mod:set("auto_mark_settings", auto_mark_settings, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggle Mod Enabled/Disabled
|
||||
mod.toggle_mod = function()
|
||||
if mod_settings.toggle_mod_notify then
|
||||
mod:notify("Auto Mark " .. (not mod_settings.toggle_mod and "Enabled" or "Disabled"))
|
||||
end
|
||||
mod:set("toggle_mod", not mod_settings.toggle_mod, true)
|
||||
end
|
||||
|
||||
local talent_settings = require("scripts/settings/talent/talent_settings")
|
||||
local cryptic_talent_settings = talent_settings.cryptic
|
||||
local function can_noospheric_command_boost()
|
||||
local player_ability_extension = context.player_ability_extension
|
||||
if not player_ability_extension then
|
||||
return false
|
||||
end
|
||||
|
||||
return player_ability_extension:has_enough_ability_charge_percentage("combat_ability", cryptic_talent_settings.servo_skull_shooting_tagging.minimum_capacitance)
|
||||
end
|
||||
|
||||
local function is_player_in_platform()
|
||||
local locomotion_component = context.locomotion_component
|
||||
local locomotion_parent_unit = locomotion_component and locomotion_component.parent_unit
|
||||
|
||||
return locomotion_parent_unit and ScriptUnit_extension(locomotion_parent_unit, "moveable_platform_system")
|
||||
end
|
||||
|
||||
-- Check if Tag is Valid for Current Class
|
||||
local function is_tag_valid(tag_name)
|
||||
if tag_name == TAG_NAMES.COMPANION_TAG then
|
||||
return context.class_name == "adamant" and context.has_companion and not is_player_in_platform()
|
||||
elseif tag_name == TAG_NAMES.VETERAN_TAG then
|
||||
return context.class_name == "veteran" and context.has_focus_target
|
||||
elseif tag_name == TAG_NAMES.ENEMY_TAG then
|
||||
return context.class_name ~= "veteran" or not context.has_focus_target
|
||||
elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
return context.class_name == "cryptic" and context.has_servo_skull and not mod:is_servo_skull_hacking()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Auto-Mark Target Unit with the Tag
|
||||
local function auto_mark_by_tag(tag_name, t, fixed_frame)
|
||||
if not is_tag_valid(tag_name) then
|
||||
return false
|
||||
end
|
||||
|
||||
local tag_context = mark_context[tag_name]
|
||||
if tag_context.interval > 0 then
|
||||
return false
|
||||
end
|
||||
|
||||
local marked_tag = tag_context.tag
|
||||
local marked_tag_is_manual = tag_context.is_manual
|
||||
local disabled_character_state_component = context.disabled_character_state_component
|
||||
local is_character_disabled = disabled_character_state_component and disabled_character_state_component.is_disabled and DISABLING_TYPES[disabled_character_state_component.disabling_type]
|
||||
local target_unit, target_tag, target_is_dormant_daemonhost
|
||||
if is_character_disabled and (tag_name == TAG_NAMES.COMPANION_TAG or tag_name == TAG_NAMES.SERVO_SKULL_TAG) then
|
||||
local disabling_unit = disabled_character_state_component and disabled_character_state_component.disabling_unit
|
||||
if disabling_unit and (not marked_tag or marked_tag._target_unit ~= disabling_unit) then
|
||||
mod:print_debug("Auto Mark Disabling Unit")
|
||||
target_unit = disabling_unit
|
||||
end
|
||||
else
|
||||
local class_settings = mod:get_class_settings(tag_name)
|
||||
-- mark when cooldown is zero
|
||||
local is_cooldown_ready = tag_context.cooldown <= 0 and (not class_settings.mark_limit or not marked_tag)
|
||||
-- mark when priority switch is on
|
||||
local is_priority_switch = tag_context.priority_switch_cooldown <= 0 and class_settings.priority_switch and marked_tag
|
||||
if class_settings.toggle_class and (class_settings.override_manual or not marked_tag_is_manual) then
|
||||
if is_cooldown_ready then
|
||||
target_unit, target_tag, target_is_dormant_daemonhost = mod:find_auto_mark_target_unit(class_settings.min_range, class_settings.max_range, tag_name, tag_context, class_settings)
|
||||
elseif is_priority_switch then
|
||||
target_unit, target_tag, target_is_dormant_daemonhost = mod:find_auto_mark_target_unit(class_settings.min_range, class_settings.max_range, tag_name, tag_context, class_settings, marked_tag)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if target_unit then
|
||||
if tag_name == TAG_NAMES.VETERAN_TAG and target_is_dormant_daemonhost then
|
||||
mod:set_auto_mark(TAG_NAMES.ENEMY_TAG, target_unit, target_tag)
|
||||
else
|
||||
mod:set_auto_mark(tag_name, target_unit, target_tag)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if tag_name == TAG_NAMES.VETERAN_TAG then
|
||||
if mod_settings.focus_target_overwrite and marked_tag then
|
||||
local marked_unit = marked_tag._target_unit
|
||||
if not mod:is_dormant_daemonhost(marked_unit) and mod:can_focus_target_overwrite(marked_unit, marked_tag) and mod:is_target_pingable(marked_unit) then
|
||||
mod:print_debug("Focus Target Overwrite")
|
||||
if tag_context.is_switch_melee then
|
||||
tag_context.switch_melee_unit = marked_unit
|
||||
elseif tag_context.is_switch_range then
|
||||
tag_context.switch_range_unit = marked_unit
|
||||
end
|
||||
if marked_tag_is_manual then
|
||||
mod:on_manual_mark(tag_context, marked_unit)
|
||||
end
|
||||
mod:set_auto_mark(tag_name, marked_unit, target_tag)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
if mod_settings.noospheric_command_boost and context.has_noospheric_command and marked_tag and t >= tag_context.noospheric_command_next_time and can_noospheric_command_boost() then
|
||||
local marked_unit = marked_tag._target_unit
|
||||
if is_character_disabled
|
||||
or not mod:is_dormant_daemonhost(marked_unit)
|
||||
and mod:is_noospheric_command_boost_breed_valid(marked_unit)
|
||||
and mod:has_enough_capacitance(marked_unit)
|
||||
and mod:is_servo_skull_target_visible(marked_unit, fixed_frame, true)
|
||||
and mod:is_target_pingable(marked_unit)
|
||||
then
|
||||
mod:print_debug("Noospheric Command Boost")
|
||||
if marked_tag_is_manual then
|
||||
mod:on_manual_mark(tag_context, marked_unit)
|
||||
end
|
||||
mod:set_auto_mark(tag_name, marked_unit, target_tag)
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Auto-Mark
|
||||
local function auto_mark(dt, t, fixed_frame)
|
||||
-- calculate interval
|
||||
if mark_context.auto_mark_interval > 0 then
|
||||
mark_context.auto_mark_interval = mark_context.auto_mark_interval - dt
|
||||
end
|
||||
-- calculate cooldown and delay for all tags
|
||||
local skip = false
|
||||
for _, tag_name in pairs(TAG_NAMES) do
|
||||
local tag_context = mark_context[tag_name]
|
||||
if tag_context.delay > 0 then
|
||||
tag_context.delay = tag_context.delay - dt
|
||||
if tag_context.delay <= 0 then
|
||||
tag_context.delay = 0
|
||||
tag_context.delay_times = 0
|
||||
else
|
||||
skip = true
|
||||
end
|
||||
end
|
||||
if tag_context.interval > 0 then
|
||||
tag_context.interval = tag_context.interval - dt
|
||||
end
|
||||
if tag_context.cooldown > 0 then
|
||||
tag_context.cooldown = tag_context.cooldown - dt
|
||||
end
|
||||
if tag_context.priority_switch_cooldown > 0 then
|
||||
tag_context.priority_switch_cooldown = tag_context.priority_switch_cooldown - dt
|
||||
end
|
||||
end
|
||||
-- pause auto mark for a period of time after it is executed.
|
||||
if mark_context.auto_mark_interval > 0 or skip then
|
||||
return
|
||||
end
|
||||
-- all kinds of tag to mark
|
||||
if auto_mark_by_tag(TAG_NAMES.COMPANION_TAG, t, fixed_frame) then
|
||||
return
|
||||
end
|
||||
|
||||
if auto_mark_by_tag(TAG_NAMES.SERVO_SKULL_TAG, t, fixed_frame) then
|
||||
return
|
||||
end
|
||||
|
||||
if auto_mark_by_tag(TAG_NAMES.VETERAN_TAG, t, fixed_frame) then
|
||||
return
|
||||
end
|
||||
|
||||
if auto_mark_by_tag(TAG_NAMES.ENEMY_TAG, t, fixed_frame) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function clean_visibility_cache(fixed_frame)
|
||||
if fixed_frame % 20 == 0 then
|
||||
local frame_threshold = fixed_frame - 5
|
||||
for cached_unit, check_frame in pairs(visibility_check_frame) do
|
||||
if check_frame < frame_threshold then
|
||||
visibility_cache[cached_unit] = nil
|
||||
visibility_check_frame[cached_unit] = nil
|
||||
end
|
||||
end
|
||||
for cached_unit, check_frame in pairs(servo_skull_visibility_check_frame) do
|
||||
if check_frame < frame_threshold then
|
||||
servo_skull_visibility_cache[cached_unit] = nil
|
||||
servo_skull_visibility_check_frame[cached_unit] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function clean_expired_units(t)
|
||||
for _, tag_name in pairs(TAG_NAMES) do
|
||||
local tag_context = mark_context[tag_name]
|
||||
if tag_context.manual_unit_expired_time and t >= tag_context.manual_unit_expired_time then
|
||||
tag_context.manual_unit = nil
|
||||
tag_context.manual_unit_expired_time = nil
|
||||
end
|
||||
if tag_context.switch_unit_expired_time and t >= tag_context.switch_unit_expired_time then
|
||||
tag_context.switch_melee_unit = nil
|
||||
tag_context.switch_range_unit = nil
|
||||
tag_context.switch_unit_expired_time = nil
|
||||
end
|
||||
local canceled_units = tag_context.canceled_units
|
||||
if canceled_units then
|
||||
for unit, expired_time in pairs(canceled_units) do
|
||||
if t >= expired_time then
|
||||
canceled_units[unit] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
local removed_units = tag_context.removed_units
|
||||
if removed_units then
|
||||
for unit, expired_time in pairs(removed_units) do
|
||||
if t >= expired_time then
|
||||
removed_units[unit] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Main Entry For Auto Mark
|
||||
mod:hook_safe(CLASS.PlayerUnitSmartTargetingExtension, "fixed_update",
|
||||
function(self, unit, dt, t, fixed_frame)
|
||||
if self._player.viewport_name ~= "player1" then
|
||||
return
|
||||
end
|
||||
|
||||
if mod_settings.toggle_mod and context.game_mode_valid then
|
||||
mod.num_visibility_checks_this_frame = 0
|
||||
clean_expired_units(t)
|
||||
clean_visibility_cache(fixed_frame)
|
||||
mod:auto_cancel_companion_mark(dt, t)
|
||||
mod:auto_cancel_servo_skull_mark(dt, t, fixed_frame)
|
||||
mod:auto_hack(dt, t, fixed_frame)
|
||||
auto_mark(dt, t, fixed_frame)
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,812 @@
|
||||
local mod = get_mod("AutoMark")
|
||||
local Breed = require("scripts/utilities/breed")
|
||||
local Breeds = require("scripts/settings/breed/breeds")
|
||||
local Archetypes = require("scripts/settings/archetype/archetypes")
|
||||
|
||||
local elite_widget = {
|
||||
setting_id = "toggle_elite",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
sub_widgets = {},
|
||||
}
|
||||
|
||||
local special_widget = {
|
||||
setting_id = "toggle_special",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
sub_widgets = {},
|
||||
}
|
||||
|
||||
local boss_widget = {
|
||||
setting_id = "toggle_boss",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
sub_widgets = {},
|
||||
}
|
||||
|
||||
local other_widget = {
|
||||
setting_id = "toggle_other",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
sub_widgets = {},
|
||||
}
|
||||
|
||||
local function create_breed_priority_dropdown(breed_name, default_value)
|
||||
local breed_priority_setting = {
|
||||
setting_id = breed_name,
|
||||
type = "numeric",
|
||||
default_value = breed_name == "chaos_poxwalker_bomber" and 0 or default_value,
|
||||
range = { 0, 30 },
|
||||
tooltip = "tooltip_breed_priority",
|
||||
}
|
||||
return breed_priority_setting
|
||||
end
|
||||
|
||||
local elite_priority_dropdown = {}
|
||||
local special_priority_dropdown = {}
|
||||
local boss_priority_dropdown = {}
|
||||
local other_priority_dropdown = {}
|
||||
|
||||
for breed_name, breed_data in pairs(Breeds) do
|
||||
if Breed.is_minion(breed_data) and breed_data.unit_template_name == "minion" and breed_data.smart_tag_target_type == "breed" and breed_data.faction_name ~= "imperium" then
|
||||
if breed_data.tags.elite then
|
||||
elite_priority_dropdown[#elite_priority_dropdown + 1] = create_breed_priority_dropdown(breed_name, 0)
|
||||
elseif breed_data.tags.special then
|
||||
special_priority_dropdown[#special_priority_dropdown + 1] = create_breed_priority_dropdown(breed_name, 1)
|
||||
elseif breed_data.is_boss then
|
||||
boss_priority_dropdown[#boss_priority_dropdown + 1] = create_breed_priority_dropdown(breed_name, 1)
|
||||
if breed_data.tags.witch then
|
||||
boss_priority_dropdown[#boss_priority_dropdown + 1] = create_breed_priority_dropdown(breed_name .. "_passive", 1)
|
||||
end
|
||||
else
|
||||
other_priority_dropdown[#other_priority_dropdown + 1] = create_breed_priority_dropdown(breed_name, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local get_breed_sort = function(breed_name)
|
||||
return mod:localize(breed_name)
|
||||
end
|
||||
|
||||
local compare_breed_name = function(a, b)
|
||||
return get_breed_sort(a.setting_id) < get_breed_sort(b.setting_id)
|
||||
end
|
||||
|
||||
table.sort(elite_priority_dropdown, compare_breed_name)
|
||||
table.sort(special_priority_dropdown, compare_breed_name)
|
||||
table.sort(boss_priority_dropdown, compare_breed_name)
|
||||
table.sort(other_priority_dropdown, compare_breed_name)
|
||||
|
||||
elite_widget.sub_widgets = elite_priority_dropdown
|
||||
special_widget.sub_widgets = special_priority_dropdown
|
||||
boss_widget.sub_widgets = boss_priority_dropdown
|
||||
other_widget.sub_widgets = other_priority_dropdown
|
||||
|
||||
local class_options = {
|
||||
{ text = "adamant_companion", value = "adamant_companion" },
|
||||
{ text = "veteran_focus_target", value = "veteran_focus_target" },
|
||||
{ text = "cryptic_servo_skull", value = "cryptic_servo_skull" },
|
||||
}
|
||||
|
||||
for class_name, _ in pairs(Archetypes) do
|
||||
class_options[#class_options + 1] = { text = class_name, value = class_name }
|
||||
end
|
||||
|
||||
table.sort(class_options, function(a, b) return a.text < b.text end)
|
||||
|
||||
local breed_name_options = {}
|
||||
local elite_breed_names = {}
|
||||
local special_breed_names = {}
|
||||
local boss_breed_names = {}
|
||||
local captain_breed_names = {}
|
||||
local other_breed_names = {}
|
||||
for breed_name, breed_data in pairs(Breeds) do
|
||||
if Breed.is_minion(breed_data) and breed_data.unit_template_name == "minion" and breed_data.smart_tag_target_type == "breed" and breed_data.faction_name ~= "imperium" then
|
||||
if breed_data.tags.elite then
|
||||
elite_breed_names[#elite_breed_names + 1] = breed_name
|
||||
elseif breed_data.tags.special then
|
||||
special_breed_names[#special_breed_names + 1] = breed_name
|
||||
elseif breed_data.is_boss then
|
||||
if breed_data.tags.captain or breed_data.tags.cultist_captain then
|
||||
captain_breed_names[#captain_breed_names + 1] = breed_name
|
||||
else
|
||||
boss_breed_names[#boss_breed_names + 1] = breed_name
|
||||
end
|
||||
else
|
||||
other_breed_names[#other_breed_names + 1] = breed_name
|
||||
end
|
||||
end
|
||||
end
|
||||
table.sort(elite_breed_names, function(a, b) return get_breed_sort(a) < get_breed_sort(b) end)
|
||||
table.sort(special_breed_names, function(a, b) return get_breed_sort(a) < get_breed_sort(b) end)
|
||||
table.sort(boss_breed_names, function(a, b) return get_breed_sort(a) < get_breed_sort(b) end)
|
||||
table.sort(captain_breed_names, function(a, b) return get_breed_sort(a) < get_breed_sort(b) end)
|
||||
table.sort(other_breed_names, function(a, b) return get_breed_sort(a) < get_breed_sort(b) end)
|
||||
|
||||
for _, breed_name in ipairs(elite_breed_names) do
|
||||
breed_name_options[#breed_name_options + 1] = { text = breed_name, value = breed_name }
|
||||
end
|
||||
for _, breed_name in ipairs(special_breed_names) do
|
||||
breed_name_options[#breed_name_options + 1] = { text = breed_name, value = breed_name }
|
||||
end
|
||||
for _, breed_name in ipairs(boss_breed_names) do
|
||||
breed_name_options[#breed_name_options + 1] = { text = breed_name, value = breed_name }
|
||||
end
|
||||
for _, breed_name in ipairs(captain_breed_names) do
|
||||
breed_name_options[#breed_name_options + 1] = { text = breed_name, value = breed_name }
|
||||
end
|
||||
for _, breed_name in ipairs(other_breed_names) do
|
||||
breed_name_options[#breed_name_options + 1] = { text = breed_name, value = breed_name }
|
||||
end
|
||||
|
||||
-- Manual settings
|
||||
local widgets = {
|
||||
{
|
||||
setting_id = "mod_settings",
|
||||
type = "group",
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "toggle_mod",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
},
|
||||
{
|
||||
setting_id = "toggle_mod_keybind",
|
||||
type = "keybind",
|
||||
default_value = {},
|
||||
keybind_global = false,
|
||||
keybind_trigger = "pressed",
|
||||
keybind_type = "function_call",
|
||||
function_name = "toggle_mod",
|
||||
},
|
||||
{
|
||||
setting_id = "toggle_mod_notify",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
},
|
||||
{
|
||||
setting_id = "debug_mode",
|
||||
type = "checkbox",
|
||||
default_value = false
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "adamant_settings",
|
||||
type = "group",
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "companion_mark_keybind",
|
||||
type = "keybind",
|
||||
default_value = {},
|
||||
keybind_global = false,
|
||||
keybind_trigger = "pressed",
|
||||
keybind_type = "function_call",
|
||||
function_name = "companion_mark",
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_ignore_unaggroed",
|
||||
title = "ignore_unaggroed",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_range_limitation",
|
||||
type = "numeric",
|
||||
title = "companion_range_limitation",
|
||||
tooltip = "companion_range_limitation_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_max_distance",
|
||||
type = "numeric",
|
||||
title = "companion_mark_max_distance",
|
||||
tooltip = "companion_mark_max_distance_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_tagged_always_visible",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_threat_priority",
|
||||
title = "threat_priority",
|
||||
tooltip = "threat_priority_tooltip",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "execution_order_priority",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "execution_order_force_mark",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_sticky_targeting",
|
||||
type = "checkbox",
|
||||
title = "sticky_targeting",
|
||||
tooltip = "sticky_targeting_tooltip",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "companion_mark_sticky_targeting_elite",
|
||||
type = "checkbox",
|
||||
title = "elite",
|
||||
tooltip = "elite_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_sticky_targeting_special",
|
||||
type = "checkbox",
|
||||
title = "special",
|
||||
tooltip = "special_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_sticky_targeting_boss",
|
||||
type = "checkbox",
|
||||
title = "boss",
|
||||
tooltip = "boss_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "companion_cancel_mark_human",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark_non_human",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_health_threshold",
|
||||
type = "numeric",
|
||||
title = "health_threshold",
|
||||
tooltip = "companion_health_threshold_tooltip",
|
||||
default_value = 0,
|
||||
unit_text = "percent",
|
||||
range = { 0, 100 },
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "companion_time_threshold",
|
||||
type = "numeric",
|
||||
title = "time_threshold",
|
||||
tooltip = "companion_time_threshold_tooltip",
|
||||
default_value = 0,
|
||||
unit_text = "second",
|
||||
range = { 0, 25 },
|
||||
decimals_number = 1
|
||||
},
|
||||
{
|
||||
setting_id = "companion_distance_threshold",
|
||||
type = "numeric",
|
||||
title = "distance_threshold",
|
||||
tooltip = "companion_distance_threshold_tooltip",
|
||||
default_value = 0,
|
||||
unit_text = "meter",
|
||||
range = { 0, 100 },
|
||||
decimals_number = 0
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark_breed_name",
|
||||
type = "dropdown",
|
||||
title = "enemy_settings",
|
||||
tooltip = "enemy_settings_tooltip",
|
||||
default_value = breed_name_options[1].value,
|
||||
options = table.clone(breed_name_options),
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "reset_all_cyber_mastiff_breed_settings",
|
||||
type = "button",
|
||||
title = "enemy_settings_reset",
|
||||
tooltip = "enemy_settings_reset_tooltip",
|
||||
button_text = "hold_to_reset",
|
||||
button_trigger = "held",
|
||||
button_hold_duration = 1.5,
|
||||
function_name = "reset_all_cyber_mastiff_breed_settings",
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark_breed_override",
|
||||
type = "checkbox",
|
||||
title = "enemy_settings_override",
|
||||
tooltip = "enemy_settings_override_tooltip",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "companion_range_limitation_breed",
|
||||
type = "numeric",
|
||||
title = "companion_range_limitation",
|
||||
tooltip = "companion_range_limitation_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_max_distance_breed",
|
||||
type = "numeric",
|
||||
title = "companion_mark_max_distance",
|
||||
tooltip = "companion_mark_max_distance_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "companion_mark_sticky_targeting_breed",
|
||||
type = "checkbox",
|
||||
title = "sticky_targeting",
|
||||
tooltip = "sticky_targeting_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark_breed_health_threshold",
|
||||
type = "numeric",
|
||||
title = "health_threshold",
|
||||
tooltip = "companion_health_threshold_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark_breed_time_threshold",
|
||||
type = "numeric",
|
||||
title = "time_threshold",
|
||||
tooltip = "companion_time_threshold_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 25 },
|
||||
unit_text = "second",
|
||||
decimals_number = 1
|
||||
},
|
||||
{
|
||||
setting_id = "companion_cancel_mark_breed_distance_threshold",
|
||||
type = "numeric",
|
||||
title = "distance_threshold",
|
||||
tooltip = "companion_distance_threshold_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "cryptic_settings",
|
||||
type = "group",
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "servo_skull_mark_keybind",
|
||||
type = "keybind",
|
||||
default_value = {},
|
||||
keybind_global = false,
|
||||
keybind_trigger = "pressed",
|
||||
keybind_type = "function_call",
|
||||
function_name = "servo_skull_mark",
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_mark_ignore_unaggroed",
|
||||
type = "checkbox",
|
||||
title = "ignore_unaggroed",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_range_limitation",
|
||||
type = "numeric",
|
||||
title = "companion_range_limitation",
|
||||
tooltip = "companion_range_limitation_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_mark_threat_priority",
|
||||
type = "checkbox",
|
||||
title = "threat_priority",
|
||||
tooltip = "threat_priority_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "hack_mark_keybind",
|
||||
type = "keybind",
|
||||
default_value = {},
|
||||
keybind_global = false,
|
||||
keybind_trigger = "pressed",
|
||||
keybind_type = "function_call",
|
||||
function_name = "hack_mark",
|
||||
},
|
||||
{
|
||||
setting_id = "auto_hack",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "disable_auto_hack_for_noospheric_command",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "noospheric_command_boost",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "noospheric_command_boost_elite",
|
||||
type = "checkbox",
|
||||
title = "elite",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "noospheric_command_boost_special",
|
||||
type = "checkbox",
|
||||
title = "special",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "noospheric_command_boost_boss",
|
||||
type = "checkbox",
|
||||
title = "boss",
|
||||
default_value = false,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "capacitance_retention",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "capacitance_retention_elite_threshold",
|
||||
type = "numeric",
|
||||
title = "elite",
|
||||
default_value = 0,
|
||||
range = { -1000, 1000 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0,
|
||||
},
|
||||
{
|
||||
setting_id = "capacitance_retention_special_threshold",
|
||||
type = "numeric",
|
||||
title = "special",
|
||||
default_value = 0,
|
||||
range = { -1000, 1000 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0,
|
||||
},
|
||||
{
|
||||
setting_id = "capacitance_retention_boss_threshold",
|
||||
type = "numeric",
|
||||
title = "boss",
|
||||
default_value = 0,
|
||||
range = { -1000, 1000 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_mark_sticky_targeting",
|
||||
type = "checkbox",
|
||||
title = "sticky_targeting",
|
||||
tooltip = "sticky_targeting_tooltip",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "servo_skull_mark_sticky_targeting_elite",
|
||||
type = "checkbox",
|
||||
title = "elite",
|
||||
tooltip = "elite_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_mark_sticky_targeting_special",
|
||||
type = "checkbox",
|
||||
title = "special",
|
||||
tooltip = "special_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_mark_sticky_targeting_boss",
|
||||
type = "checkbox",
|
||||
title = "boss",
|
||||
tooltip = "boss_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_cancel_mark",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "servo_skull_cancel_mark_time_threshold",
|
||||
type = "numeric",
|
||||
title = "servo_skull_lose_sight_tolerance",
|
||||
tooltip = "servo_skull_lose_sight_tolerance_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 25 },
|
||||
unit_text = "second",
|
||||
decimals_number = 1
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_cancel_mark_health_threshold",
|
||||
type = "numeric",
|
||||
title = "health_threshold",
|
||||
tooltip = "servo_skull_health_threshold_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "noospheric_command_boost_breed_name",
|
||||
type = "dropdown",
|
||||
title = "enemy_settings",
|
||||
tooltip = "enemy_settings_tooltip",
|
||||
default_value = breed_name_options[1].value,
|
||||
options = table.clone(breed_name_options),
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "reset_all_servo_skull_breed_settings",
|
||||
type = "button",
|
||||
title = "enemy_settings_reset",
|
||||
tooltip = "enemy_settings_reset_tooltip",
|
||||
button_text = "hold_to_reset",
|
||||
button_trigger = "held",
|
||||
button_hold_duration = 1.5,
|
||||
function_name = "reset_all_servo_skull_breed_settings",
|
||||
},
|
||||
{
|
||||
setting_id = "noospheric_command_boost_breed_override",
|
||||
type = "checkbox",
|
||||
title = "enemy_settings_override",
|
||||
tooltip = "enemy_settings_override_tooltip",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "servo_skull_range_limitation_breed",
|
||||
type = "numeric",
|
||||
title = "companion_range_limitation",
|
||||
tooltip = "companion_range_limitation_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "noospheric_command_boost_breed_toggle",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "capacitance_retention_breed_threshold",
|
||||
type = "numeric",
|
||||
default_value = 0,
|
||||
range = { -1000, 1000 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0,
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_mark_sticky_targeting_breed",
|
||||
type = "checkbox",
|
||||
title = "sticky_targeting",
|
||||
tooltip = "sticky_targeting_tooltip",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_cancel_mark_breed_time_threshold",
|
||||
type = "numeric",
|
||||
title = "servo_skull_lose_sight_tolerance",
|
||||
tooltip = "servo_skull_lose_sight_tolerance_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 25 },
|
||||
unit_text = "second",
|
||||
decimals_number = 1
|
||||
},
|
||||
{
|
||||
setting_id = "servo_skull_cancel_mark_breed_health_threshold",
|
||||
type = "numeric",
|
||||
title = "health_threshold",
|
||||
tooltip = "servo_skull_health_threshold_tooltip",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "percent",
|
||||
decimals_number = 0
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "veteran_settings",
|
||||
type = "group",
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "focus_target_ignore_unaggroed",
|
||||
type = "checkbox",
|
||||
title = "ignore_unaggroed",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "focus_target_overwrite",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "focus_target_overwrite_delta",
|
||||
type = "numeric",
|
||||
default_value = 5,
|
||||
range = { 1, 10 },
|
||||
unit_text = "stack",
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "focus_target_switch",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "focus_target_switch_override_manual",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "focus_target_switch_melee",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
{
|
||||
setting_id = "focus_target_switch_range",
|
||||
type = "checkbox",
|
||||
default_value = false,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "auto_mark_settings",
|
||||
type = "group",
|
||||
sub_widgets = {
|
||||
{
|
||||
setting_id = "class_selection",
|
||||
type = "dropdown",
|
||||
default_value = "adamant",
|
||||
options = class_options,
|
||||
},
|
||||
{
|
||||
setting_id = "apply_button",
|
||||
type = "dropdown",
|
||||
default_value = "blank",
|
||||
options = {
|
||||
{ text = "apply_to_normal", value = "apply_to_normal" },
|
||||
{ text = "apply_to_all", value = "apply_to_all" },
|
||||
{ text = "blank", value = "blank" },
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "reset_button",
|
||||
type = "dropdown",
|
||||
default_value = "blank",
|
||||
options = {
|
||||
{ text = "reset_current", value = "reset_current" },
|
||||
{ text = "reset_all", value = "reset_all" },
|
||||
{ text = "blank", value = "blank" },
|
||||
}
|
||||
},
|
||||
{
|
||||
setting_id = "toggle_class",
|
||||
type = "checkbox",
|
||||
default_value = true,
|
||||
},
|
||||
{
|
||||
setting_id = "interval",
|
||||
type = "numeric",
|
||||
default_value = 1,
|
||||
range = { 0, 50 },
|
||||
unit_text = "second",
|
||||
decimals_number = 1
|
||||
},
|
||||
{
|
||||
setting_id = "cooldown",
|
||||
type = "numeric",
|
||||
default_value = 25,
|
||||
range = { 10, 50 },
|
||||
unit_text = "second",
|
||||
decimals_number = 1
|
||||
},
|
||||
{
|
||||
setting_id = "reset_cooldown",
|
||||
type = "checkbox",
|
||||
default_value = true
|
||||
},
|
||||
{
|
||||
setting_id = "mark_limit",
|
||||
type = "checkbox",
|
||||
default_value = true
|
||||
},
|
||||
{
|
||||
setting_id = "min_range",
|
||||
type = "numeric",
|
||||
default_value = 0,
|
||||
range = { 0, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
{
|
||||
setting_id = "max_range",
|
||||
type = "numeric",
|
||||
default_value = 100,
|
||||
range = { 1, 100 },
|
||||
unit_text = "meter",
|
||||
decimals_number = 0
|
||||
},
|
||||
-- {
|
||||
-- setting_id = "max_angle",
|
||||
-- type = "numeric",
|
||||
-- default_value = 0,
|
||||
-- range = { 0, 180 },
|
||||
-- unit_text = "degree",
|
||||
-- decimals_number = 0
|
||||
-- },
|
||||
{
|
||||
setting_id = "override_manual",
|
||||
type = "checkbox",
|
||||
default_value = false
|
||||
},
|
||||
{
|
||||
setting_id = "priority_switch",
|
||||
type = "checkbox",
|
||||
default_value = false
|
||||
},
|
||||
elite_widget,
|
||||
special_widget,
|
||||
boss_widget,
|
||||
other_widget,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
name = mod:localize("mod_name"),
|
||||
description = mod:localize("mod_description"),
|
||||
is_togglable = true,
|
||||
options = {
|
||||
widgets = widgets
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,915 @@
|
||||
local Breed = require("scripts/utilities/breed")
|
||||
local Breeds = require("scripts/settings/breed/breeds")
|
||||
local Archetypes = require("scripts/settings/archetype/archetypes")
|
||||
local InputUtils = require("scripts/managers/input/input_utils")
|
||||
|
||||
local function color_text(text, color_name)
|
||||
local color = Color[color_name](255, true)
|
||||
return InputUtils.apply_color_to_input_text(text, color)
|
||||
end
|
||||
|
||||
local function highlight(text)
|
||||
return color_text(text, "terminal_text_warning_light")
|
||||
end
|
||||
|
||||
-- ###############################################################################################################
|
||||
-- zh-tw Localization maintenance note:
|
||||
-- For zh-tw updates, use the latest translation glossary as the source of truth:
|
||||
-- https://github.com/SyuanTsai/Warhammer-40-000-DARKTIDE-Mods/blob/main/Referneces/Translation.md
|
||||
-- Preserve existing context-specific translations when the glossary contains multiple valid terms.
|
||||
-- ###############################################################################################################
|
||||
|
||||
local localization = {
|
||||
-- mod_name
|
||||
mod_name = {
|
||||
en = "Auto Mark",
|
||||
["zh-cn"] = "智能标记",
|
||||
["zh-tw"] = "智慧標記",
|
||||
},
|
||||
mod_description = {
|
||||
en = "Enhance your marking experience",
|
||||
["zh-cn"] = "增强你的标记体验",
|
||||
["zh-tw"] = "增強你的標記體驗",
|
||||
},
|
||||
-- mod_settings
|
||||
mod_settings = {
|
||||
en = "Mod Settings",
|
||||
["zh-cn"] = "模组设置",
|
||||
["zh-tw"] = "模組設定",
|
||||
},
|
||||
toggle_mod = {
|
||||
en = "Toggle Mod",
|
||||
["zh-cn"] = "模组开关",
|
||||
["zh-tw"] = "模組開關",
|
||||
},
|
||||
toggle_mod_keybind = {
|
||||
en = "Toggle Keybind",
|
||||
["zh-cn"] = "模组开关按键",
|
||||
["zh-tw"] = "模組開關按鍵",
|
||||
},
|
||||
toggle_mod_notify = {
|
||||
en = "Toggle Notification",
|
||||
["zh-cn"] = "模组开关通知",
|
||||
["zh-tw"] = "模組開關通知",
|
||||
},
|
||||
debug_mode = {
|
||||
en = "Debug Mode",
|
||||
["zh-cn"] = "调试模式",
|
||||
["zh-tw"] = "除錯模式",
|
||||
},
|
||||
-- arbites settings
|
||||
adamant_settings = {
|
||||
en = "Arbites Settings",
|
||||
["zh-cn"] = "法务官设置",
|
||||
["zh-tw"] = "法務官設定",
|
||||
},
|
||||
companion_mark_keybind = {
|
||||
en = "Cyber-Mastiff Mark Keybind",
|
||||
["zh-cn"] = "智能獒犬标记按键",
|
||||
["zh-tw"] = "電子獒犬標記按鍵",
|
||||
},
|
||||
companion_mark_keybind_description = {
|
||||
en = "Dedicated key for Cyber-Mastiff Mark. As Arbites, you can now use both normal enemy mark and Cyber-Mastiff mark at the same time.\n\n" ..
|
||||
"When " .. highlight("Companion Target Tag") ..
|
||||
" is set to " .. highlight("Press Once") ..
|
||||
", this function becomes a normal enemy mark.",
|
||||
["zh-cn"] = "智能獒犬标记专用按键,现在你可以作为法务官,同时使用普通敌人标记和智能獒犬标记了。\n\n" ..
|
||||
"当" .. highlight("伙伴目标标记") ..
|
||||
"设置为" .. highlight("按一次") ..
|
||||
"时,此功能变为普通敌人标记。",
|
||||
["zh-tw"] = "電子獒犬標記專用按鍵,身為法務官,你現在可同時使用一般敵人標記與電子獒犬標記。\n\n" ..
|
||||
"當" .. highlight("同伴目標標記方式") ..
|
||||
"設為" .. highlight("按一次") ..
|
||||
"時,此功能會變為一般敵人標記。",
|
||||
},
|
||||
ignore_unaggroed = {
|
||||
en = "Ignore Unalerted Enemies",
|
||||
["zh-cn"] = "忽略未警觉的敌人",
|
||||
["zh-tw"] = "忽略未觸發警戒的敵人",
|
||||
},
|
||||
companion_mark_ignore_unaggroed_description = {
|
||||
en = "When enabled, Cyber-Mastiff Auto-Mark will not mark enemies that are not alerted.",
|
||||
["zh-cn"] = "当启用时,智能獒犬自动标记将不会标记未警觉的敌人。",
|
||||
["zh-tw"] = "當啟用時,電子獒犬自動標記將不會標記未觸發警戒的敵人。",
|
||||
},
|
||||
companion_mark_tagged_always_visible = {
|
||||
en = "Hunt Them Down",
|
||||
["zh-cn"] = "追踪到底",
|
||||
["zh-tw"] = "追蹤到底",
|
||||
},
|
||||
companion_mark_tagged_always_visible_description = {
|
||||
en = "When enabled, targets marked by any mark or chosen by Execution Order are always treated as visible by Cyber-Mastiff AUTO-MARK.",
|
||||
["zh-cn"] = "开启后,被任意标记或处决指令选中的目标,智能獒犬自动标记将始终视其为可见。",
|
||||
["zh-tw"] = "開啟後,被任意標記或處決指令選中的目標,智慧獒犬自動標記將始終視其為可見。",
|
||||
},
|
||||
threat_priority = {
|
||||
en = "Threat Priority",
|
||||
["zh-cn"] = "威胁优先",
|
||||
["zh-tw"] = "威脅優先",
|
||||
},
|
||||
threat_priority_tooltip = {
|
||||
en = "When enabled, Companion Auto-Mark prioritizes enemies targeting the player.",
|
||||
["zh-cn"] = "开启后,伙伴自动标记将优先标记以玩家为攻击目标的敌人。",
|
||||
["zh-tw"] = "開啟後,同伴自動標記將優先標記以玩家為攻擊目標的敵人。",
|
||||
},
|
||||
execution_order_priority = {
|
||||
en = "Execution Order Priority",
|
||||
["zh-cn"] = "遵从处决指令",
|
||||
["zh-tw"] = "遵從處決指令",
|
||||
},
|
||||
execution_order_priority_description = {
|
||||
en = "Arbites Cyber-Mastiff Auto-Mark prioritizes enemies chosen by Execution Order.",
|
||||
["zh-cn"] = "遵从处决指令的选择,法务官智能獒犬自动标记将优先标记已被处决指令选中的敌人。",
|
||||
["zh-tw"] = "遵從處決指令的選擇,法務官電子獒犬自動標記將優先標記已被處決指令選中的敵人。",
|
||||
},
|
||||
execution_order_force_mark = {
|
||||
en = "Execution Order Force Mark",
|
||||
["zh-cn"] = "处决指令强制标记",
|
||||
["zh-tw"] = "處決指令強制標記",
|
||||
},
|
||||
execution_order_force_mark_description = {
|
||||
en = "When enabled, targets chosen by Execution Order can be auto marked by Cyber-Mastiff even if their enemy type is set to ignored in priority settings.",
|
||||
["zh-cn"] = "开启后,处决指令选中的目标,即便其敌人类型在优先级设置中被设为忽略,仍可被智能獒犬自动标记。",
|
||||
["zh-tw"] = "開啟後,處決指令選中的目標,即便其敵人類型在優先度設定中被設為忽略,仍可被電子獒犬自動標記。",
|
||||
},
|
||||
companion_range_limitation = {
|
||||
en = "Companion Range Limitation",
|
||||
["zh-cn"] = "伙伴范围限制",
|
||||
["zh-tw"] = "伙伴範圍限制",
|
||||
},
|
||||
companion_range_limitation_tooltip = {
|
||||
en = "Restrict the maximum distance between your " .. highlight("companion") .. " and a target that can be marked by the Companion Auto-Mark.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.",
|
||||
["zh-cn"] = "限制伙伴自动标记系统可标记的目标与你的" .. highlight("伙伴") .. "之间的最大距离。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。",
|
||||
["zh-tw"] = "限制同伴自動標記系統可標記的目標與你的" .. highlight("同伴") .. "之間的最大距離。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用",
|
||||
},
|
||||
companion_cancel_mark = {
|
||||
en = "Auto Cancel Cyber-Mastiff Mark",
|
||||
["zh-cn"] = "自动取消智能獒犬标记",
|
||||
["zh-tw"] = "自動取消電子獒犬標記",
|
||||
},
|
||||
companion_cancel_mark_human = {
|
||||
en = "Human",
|
||||
["zh-cn"] = "人类",
|
||||
["zh-tw"] = "人類",
|
||||
},
|
||||
companion_cancel_mark_human_description = {
|
||||
en = "Enable for human-sized enemies that can be pounced by your Cyber-Mastiff.",
|
||||
["zh-cn"] = "在人类体型的敌人上启用,这些敌人可以被你的智能獒犬扑倒。",
|
||||
["zh-tw"] = "對可被你的電子獒犬撲倒的人型敵人啟用。",
|
||||
},
|
||||
companion_cancel_mark_non_human = {
|
||||
en = "Non-Human",
|
||||
["zh-cn"] = "非人类",
|
||||
["zh-tw"] = "非人類",
|
||||
},
|
||||
companion_cancel_mark_non_human_description = {
|
||||
en = "Enable for non-human-sized enemies that cannot be pounced by your Cyber-Mastiff.",
|
||||
["zh-cn"] = "在非人类体型的敌人上启用,这些敌人不能被你的智能獒犬扑倒。",
|
||||
["zh-tw"] = "對無法被你的電子獒犬撲倒的非人型敵人啟用。",
|
||||
},
|
||||
health_threshold = {
|
||||
en = "Health Threshold",
|
||||
["zh-cn"] = "生命阈值",
|
||||
["zh-tw"] = "生命值門檻",
|
||||
},
|
||||
companion_health_threshold_tooltip = {
|
||||
en = "Cancel the Cyber-Mastiff mark when the health of your Cyber-Mastiff's current attack target falls below your selected health percentage.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "当你的智能獒犬的攻击目标的血量低于所选百分比时,取消该目标的智能獒犬标记。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "當你的電子獒犬目前攻擊目標的生命值低於設定百分比時,取消該目標的電子獒犬標記。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
time_threshold = {
|
||||
en = "Time Threshold",
|
||||
["zh-cn"] = "时间阈值",
|
||||
["zh-tw"] = "時間門檻",
|
||||
},
|
||||
companion_time_threshold_tooltip = {
|
||||
en = "Cancel the Cyber-Mastiff mark when your Cyber-Mastiff has been attacking its current target for longer than your selected duration (in seconds).\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "当你的智能獒犬攻击当前目标的持续时间超过所选时长(单位:秒)时,取消该目标的智能獒犬标记。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "當你的電子獒犬攻擊目前目標超過設定秒數時,取消該目標的電子獒犬標記。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
distance_threshold = {
|
||||
en = "Distance Threshold",
|
||||
["zh-cn"] = "距离阈值",
|
||||
["zh-tw"] = "距離門檻",
|
||||
},
|
||||
companion_distance_threshold_tooltip = {
|
||||
en = "Cancel the Cyber-Mastiff mark when the distance between you and your Cyber-Mastiff exceeds your selected distance (in meters).\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "当你与你的智能獒犬之间的距离超过所选距离(单位:米)时,取消智能獒犬标记。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "當你與你的電子獒犬之間的距離超過設定公尺時,取消電子獒犬標記。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
enemy_settings = {
|
||||
en = "Enemy Settings Override",
|
||||
["zh-cn"] = "敌人设置覆盖",
|
||||
["zh-tw"] = "敵人設定覆蓋",
|
||||
},
|
||||
enemy_settings_tooltip = {
|
||||
en = "Select an enemy to configure its individual settings, which override the settings above, except for the master toggles.",
|
||||
["zh-cn"] = "选择一种敌人,为其配置其独立的设置,这些设置将覆盖上方的设置,除了总开关。",
|
||||
["zh-tw"] = "選擇一種敵人以設定其個別設定。除了總開關外,個別設定會覆蓋上方的一般設定。",
|
||||
},
|
||||
enemy_settings_reset = {
|
||||
en = "Reset to Defaults",
|
||||
["zh-cn"] = "重置为默认值",
|
||||
["zh-tw"] = "重設為預設值",
|
||||
},
|
||||
enemy_settings_reset_tooltip = {
|
||||
en = "Reset all per-enemy individual settings to their default values.",
|
||||
["zh-cn"] = "重置所有敌人的设置为默认值。",
|
||||
["zh-tw"] = "將所有敵人的個別設定重設為預設值。",
|
||||
},
|
||||
enemy_settings_override = {
|
||||
en = "Override",
|
||||
["zh-cn"] = "启用覆盖",
|
||||
["zh-tw"] = "啟用覆蓋",
|
||||
},
|
||||
enemy_settings_override_tooltip = {
|
||||
en = "Apply dedicated settings for this enemy, which take priority over the general settings above, except for the master toggles.",
|
||||
["zh-cn"] = "为这种敌人应用专用设置,这些设置将优先于上方的设置,除了总开关。",
|
||||
["zh-tw"] = "為此敵人套用專用設定。除了總開關外,專用設定優先於上方的一般設定。",
|
||||
},
|
||||
companion_cancel_mark_breed_health_threshold_description = {
|
||||
en = "Set Auto Cancel Cyber-Mastiff Mark Health Threshold for this enemy.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "为所选敌人设置自动取消智能獒犬标记生命阈值。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "設定此敵人的自動取消電子獒犬標記生命值門檻。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
companion_cancel_mark_breed_time_threshold_description = {
|
||||
en = "Set Auto Cancel Cyber-Mastiff Mark Time Threshold for this enemy.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "为所选敌人设置自动取消智能獒犬标记时间阈值。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "設定此敵人的自動取消電子獒犬標記時間門檻。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
companion_cancel_mark_breed_distance_threshold_description = {
|
||||
en = "Set Auto Cancel Cyber-Mastiff Mark Distance Threshold for this enemy.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "为所选敌人设置自动取消智能獒犬标记距离阈值。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "設定此敵人的自動取消電子獒犬標記距離門檻。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
companion_mark_max_distance = {
|
||||
en = "Player Max Distance",
|
||||
["zh-cn"] = "玩家最大距离",
|
||||
["zh-tw"] = "玩家最大距離",
|
||||
},
|
||||
companion_mark_max_distance_tooltip = {
|
||||
en = "Restrict the maximum distance between " .. highlight("player") .. " and a target that can be marked by the Companion Auto-Mark.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.",
|
||||
["zh-cn"] = "限制伙伴自动标记系统可标记的目标与" .. highlight("玩家") .. "之间的最大距离。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。",
|
||||
["zh-tw"] = "限制同伴自動標記系統可標記的目標與" .. highlight("玩家") .. "之間的最大距離。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用",
|
||||
},
|
||||
-- cryptic settings
|
||||
cryptic_settings = {
|
||||
en = "Skitarii Settings",
|
||||
["zh-cn"] = "护教军设置",
|
||||
["zh-tw"] = "護教軍設定",
|
||||
},
|
||||
servo_skull_mark_keybind = {
|
||||
en = "Servo-Skull Mark Keybind",
|
||||
["zh-cn"] = "伺服颅骨标记按键",
|
||||
["zh-tw"] = "伺服顱骨標記按鍵",
|
||||
},
|
||||
servo_skull_mark_keybind_description = {
|
||||
en = "Dedicated key for Servo-Skull Mark. As Skitarii, you can now use both normal enemy mark and Servo-Skull mark at the same time.\n\n" ..
|
||||
"When " .. highlight("Companion Target Tag") .. " is set to " .. highlight("Press Once") .. ", this function becomes a normal enemy mark.",
|
||||
["zh-cn"] = "伺服颅骨标记专用按键,现在你可以作为护教军,同时使用普通敌人标记和伺服颅骨标记了。\n\n" ..
|
||||
"当" .. highlight("伙伴目标标记") .. "设置为" .. highlight("按一次") .. "时,此功能变为普通敌人标记。",
|
||||
["zh-tw"] = "伺服顱骨標記專用按鍵。身為護教軍,你現在可同時使用一般敵人標記與伺服顱骨標記。\n\n" ..
|
||||
"當" .. highlight("同伴目標標記方式") .. "設為" .. highlight("按一次") .. "時,此功能會變為一般敵人標記。",
|
||||
},
|
||||
servo_skull_mark_ignore_unaggroed_description = {
|
||||
en = "When enabled, Servo-Skull Auto-Mark will not mark enemies that are not alerted.",
|
||||
["zh-cn"] = "当启用时,伺服颅骨自动标记将不会标记未警觉的敌人。",
|
||||
["zh-tw"] = "當啟用時,伺服顱骨自動標記將不會標記未觸發警戒的敵人。",
|
||||
},
|
||||
servo_skull_lose_sight_tolerance = {
|
||||
en = "Out of Sight Tolerance",
|
||||
["zh-cn"] = "视野丢失容忍时间",
|
||||
["zh-tw"] = "視野丟失容忍時間",
|
||||
},
|
||||
servo_skull_lose_sight_tolerance_tooltip = {
|
||||
en = "Cancel Servo-Skull marks when your Servo-Skull loses sight of the target for longer than your selected time (in seconds).\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "当你的伺服颅骨失去目标视野超过所选时间(单位:秒)时,取消伺服颅骨标记。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "當你的伺服顱骨失去目標視野超過設定秒數時,取消伺服顱骨標記。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
hack_mark_keybind = {
|
||||
en = "Data Interrogation Keybind",
|
||||
["zh-cn"] = "数据查询按键",
|
||||
["zh-tw"] = "資料查詢按鍵",
|
||||
},
|
||||
hack_mark_keybind_description = {
|
||||
en = "Dedicated key for Sending the Servo-Skull to hack the minigame.",
|
||||
["zh-cn"] = "用于指派伺服颅骨黑入数据查询小游戏的专用按键。",
|
||||
["zh-tw"] = "用於指派伺服顱骨黑入資料查詢小遊戲的專用按鍵。",
|
||||
},
|
||||
auto_hack = {
|
||||
en = "Auto Data Interrogation",
|
||||
["zh-cn"] = "自动数据查询",
|
||||
["zh-tw"] = "自動資料查詢",
|
||||
},
|
||||
auto_hack_description = {
|
||||
en = "Automatically sends your Servo-Skull to hack the minigame when you aim at a hackable objective",
|
||||
["zh-cn"] = "当你瞄准一个数据查询小游戏时,自动派遣伺服颅骨前去黑入。",
|
||||
["zh-tw"] = "當你瞄準一個資料查詢小遊戲時,自動派遣伺服顱骨前去黑入。",
|
||||
},
|
||||
disable_auto_hack_for_noospheric_command = {
|
||||
en = "Disable Auto Data Interrogation When Noospheric Command Talent is Equiped",
|
||||
["zh-cn"] = "当装备星语指令时禁用自动数据查询",
|
||||
["zh-tw"] = "當裝備心智網指令時停用自動資料查詢",
|
||||
},
|
||||
capacitance_retention = {
|
||||
en = "Capacitance Retention",
|
||||
["zh-cn"] = "电容保留",
|
||||
["zh-tw"] = "電容量保留",
|
||||
},
|
||||
capacitance_retention_description = {
|
||||
en = "While the Noospheric Command talent is active, all Servo-Skull Auto-Mark features (including Noospheric Command Boost) are disabled when remaining capacitance drops below the configured threshold.\n\n" ..
|
||||
"This threshold supports negative values (including -0):\n" ..
|
||||
"Non-negative values are checked directly against remaining capacitance.\n" ..
|
||||
"For negative values, the actual threshold equals maximum ability charges plus the configured value.\n\n" ..
|
||||
"Remaining capacitance is calculated as ability charge count plus current capacitance percentage.",
|
||||
["zh-cn"] = "当装备星语指令天赋时,若剩余电容低于所选阈值,将禁用所有伺服颅骨自动标记功能,包括星语指令增强。\n\n" ..
|
||||
"本阈值支持设置为负值(含-0):\n" ..
|
||||
"阈值为非负数时,直接以剩余电容数值判定。\n" ..
|
||||
"阈值为负数时,实际阈值等于技能最大充能次数加上设定值。\n\n" ..
|
||||
"剩余电容等于技能充能次数加上当前电容百分比。",
|
||||
["zh-tw"] = "當啟用心智網指令時,若剩餘電容量低於所選門檻,將停用所有伺服顱骨自動標記功能,包含心智網指令強化。\n\n" ..
|
||||
"本門檻支援設定為負值(含-0):\n" ..
|
||||
"門檻為非負數時,直接以剩餘電容量數值判定。\n" ..
|
||||
"門檻為負數時,實際門檻等於技能最大充能次數加上設定值。\n\n" ..
|
||||
"剩餘電容量等於技能充能次數加上當前電容量百分比。",
|
||||
},
|
||||
capacitance_retention_elite_threshold_description = {
|
||||
en = "Set Capacitance Retention Threshold for elites.",
|
||||
["zh-cn"] = "为精英敌人设置电容保留阈值。",
|
||||
["zh-tw"] = "設定精英敵人的電容保留門檻。",
|
||||
},
|
||||
capacitance_retention_special_threshold_description = {
|
||||
en = "Set Capacitance Retention Threshold for specialists.",
|
||||
["zh-cn"] = "为专家敌人设置电容保留阈值。",
|
||||
["zh-tw"] = "針對專家敵人的電容量,設定保留門檻。",
|
||||
},
|
||||
capacitance_retention_boss_threshold_description = {
|
||||
en = "Set Capacitance Retention Threshold for bosses.",
|
||||
["zh-cn"] = "为Boss设置电容保留阈值。",
|
||||
["zh-tw"] = "針對Boss的電容量,設定保留門檻。",
|
||||
},
|
||||
capacitance_retention_breed_threshold = {
|
||||
en = "Capacitance Retention",
|
||||
["zh-cn"] = "电容保留",
|
||||
["zh-tw"] = "電容量門檻",
|
||||
},
|
||||
capacitance_retention_breed_threshold_description = {
|
||||
en = "Set Capacitance Retention Threshold for this enemy.",
|
||||
["zh-cn"] = "为所选敌人设置电容保留阈值。",
|
||||
["zh-tw"] = "設定此敵人的電容保留門檻。",
|
||||
},
|
||||
noospheric_command_boost = {
|
||||
en = "Noospheric Command Boost",
|
||||
["zh-cn"] = "星语指令增强",
|
||||
["zh-tw"] = "心智網指令強化",
|
||||
},
|
||||
noospheric_command_boost_description = {
|
||||
en = "Automatically re-marks marked targets to extend the Noospheric Command effect.\n\n" ..
|
||||
"Re-marking occurs at intervals equal to the effect's duration, and only triggers when the target is within the Servo-Skull's line of sight.",
|
||||
["zh-cn"] = "自动对已标记目标进行重复标记,以延长星语指令的效果。\n\n" ..
|
||||
"重复标记间隔为星语指令的持续时间,只有当目标在伺服颅骨视野内时才会进行标记。",
|
||||
["zh-tw"] = "自動重新標記已標記目標,以延長心智網指令效果。\n\n" ..
|
||||
"重新標記間隔等同於效果持續時間,且僅在目標位於伺服顱骨視線內時觸發。",
|
||||
},
|
||||
noospheric_command_boost_elite_description = {
|
||||
en = "Enable Noospheric Command Boost for elites.",
|
||||
["zh-cn"] = "为精英敌人启用星语指令增强",
|
||||
["zh-tw"] = "為精英敵人啟用心智網指令強化。",
|
||||
},
|
||||
noospheric_command_boost_special_description = {
|
||||
en = "Enable Noospheric Command Boost for specialists.",
|
||||
["zh-cn"] = "为专家敌人启用星语指令增强",
|
||||
["zh-tw"] = "為專家敵人啟用心智網指令強化。",
|
||||
},
|
||||
noospheric_command_boost_boss_description = {
|
||||
en = "Enable Noospheric Command Boost for bosses.",
|
||||
["zh-cn"] = "为Boss启用星语指令增强",
|
||||
["zh-tw"] = "為Boss啟用心智網指令強化。",
|
||||
},
|
||||
noospheric_command_boost_breed_toggle = {
|
||||
en = "Noospheric Command",
|
||||
["zh-cn"] = "星语指令",
|
||||
["zh-tw"] = "心智網指令",
|
||||
},
|
||||
noospheric_command_boost_breed_toggle_description = {
|
||||
en = "Enable/Disable Noospheric Command Boost for this enemy.",
|
||||
["zh-cn"] = "为所选敌人启用/禁用星语指令增强。",
|
||||
["zh-tw"] = "為所選敵人啟用/停用心智網指令強化。",
|
||||
},
|
||||
-- veteran settings
|
||||
veteran_settings = {
|
||||
en = "Veteran Settings",
|
||||
["zh-cn"] = "老兵设置",
|
||||
["zh-tw"] = "老兵設定",
|
||||
},
|
||||
focus_target_overwrite = {
|
||||
en = "Focus Target Overwrite",
|
||||
["zh-cn"] = "聚焦目标覆盖",
|
||||
["zh-tw"] = "專注目標覆蓋",
|
||||
},
|
||||
focus_target_overwrite_description = {
|
||||
en = highlight("Off") .. ": Enemie marked by Focus Target will not be re-marked.\n" ..
|
||||
highlight("On") .. ": If the player's Focus Target stacks exceed those applied to the enemy, and the stack difference is greater than or equal to the option 'Focus Target Overwrite Delta' or the stacks are at max, the Focus Target mark will be reapplied.",
|
||||
["zh-cn"] = highlight("关闭") .. ":已被聚焦目标标记的敌人,不会再次被标记。\n" ..
|
||||
highlight("开启") .. ":当玩家自身聚焦目标层数高于敌人已被施加的层数,且层数差大于等于下方选项「聚焦目标覆盖最小层数差」或自身层数已满时,将重新施加聚焦目标标记。",
|
||||
["zh-tw"] = highlight("關閉") .. ":已被專注目標標記的敵人,不會再次被標記。\n" ..
|
||||
highlight("開啟") .. ":當玩家自身專注目標層數高於敵人已被施加的層數,且層數差大於等於下方選項「專注目標覆蓋最小層數差」或自身層數已滿時,將重新施加專注目標標記。",
|
||||
},
|
||||
focus_target_overwrite_delta = {
|
||||
en = "Focus Target Overwrite Delta",
|
||||
["zh-cn"] = "聚焦目标覆盖最小层数差",
|
||||
["zh-tw"] = "專注目標覆蓋最小層數差",
|
||||
},
|
||||
focus_target_ignore_unaggroed_description = {
|
||||
en = "When enabled, Focus Target will not mark enemies that are not alerted.",
|
||||
["zh-cn"] = "当启用时,聚焦目标将不会标记未警觉的敌人。",
|
||||
["zh-tw"] = "當啟用時,專注目標將不會標記未觸發警戒的敵人。",
|
||||
},
|
||||
focus_target_switch = {
|
||||
en = "Switch Target on Attack",
|
||||
["zh-cn"] = "攻击时切换目标",
|
||||
["zh-tw"] = "攻擊時切換目標",
|
||||
},
|
||||
focus_target_switch_description = {
|
||||
en = "When the player is attacking, the focus target mark will switch to the aimed target.",
|
||||
["zh-cn"] = "当进行攻击时,聚焦目标将标记当前瞄准的敌人。",
|
||||
["zh-tw"] = "進行攻擊時,專注目標將標記當前瞄準的敵人。",
|
||||
},
|
||||
focus_target_switch_override_manual = {
|
||||
en = "Override Manual",
|
||||
["zh-cn"] = "覆盖手动标记",
|
||||
["zh-tw"] = "覆蓋手動標記",
|
||||
},
|
||||
focus_target_switch_override_manual_description = {
|
||||
en = highlight("Off") .. ": Switch-Target stops when a manual mark is present.\n" ..
|
||||
highlight("On") .. ": Switch-Target continues to find new targets even when a manual mark is present.",
|
||||
["zh-cn"] = highlight("关闭") .. ":手动标记存在时,切换目标将停止。\n" ..
|
||||
highlight("开启") .. ":即使当前标记为手动标记,切换目标也会继续寻找新的目标。",
|
||||
["zh-tw"] = highlight("關閉") .. ":當存在手動標記時,切換目標會停止。\n" ..
|
||||
highlight("開啟") .. ":即使目前有手動標記,切換目標仍會持續尋找新目標。",
|
||||
},
|
||||
focus_target_switch_melee = {
|
||||
en = "Melee Weapon",
|
||||
["zh-cn"] = "近战武器",
|
||||
["zh-tw"] = "近戰武器",
|
||||
},
|
||||
focus_target_switch_range = {
|
||||
en = "Ranged Weapon",
|
||||
["zh-cn"] = "远程武器",
|
||||
["zh-tw"] = "遠程武器",
|
||||
},
|
||||
-- class settings
|
||||
auto_mark_settings = {
|
||||
en = "Auto Mark Settings",
|
||||
["zh-cn"] = "自动标记设置",
|
||||
["zh-tw"] = "自動標記設定",
|
||||
},
|
||||
class_selection = {
|
||||
en = "Class",
|
||||
["zh-cn"] = "职业",
|
||||
["zh-tw"] = "職業",
|
||||
},
|
||||
class_selection_description = {
|
||||
en = "Normal enemy marks for all classes, plus special marks for certain classes (Cyber-Mastiff, Servo-Skull, Focus Target).",
|
||||
["zh-cn"] = "所有职业的普通敌人标记,以及某些职业的特殊标记(智能獒犬、伺服颅骨、聚焦目标)。",
|
||||
["zh-tw"] = "所有職業的一般敵人標記,以及特定職業的特殊標記(電子獒犬、伺服顱骨、專注目標)。",
|
||||
},
|
||||
toggle_class = {
|
||||
en = "Toggle",
|
||||
["zh-cn"] = "开关",
|
||||
["zh-tw"] = "開關",
|
||||
},
|
||||
toggle_class_description = {
|
||||
en = "Toggle Auto-Mark for the selected mark type.",
|
||||
["zh-cn"] = "开启/关闭所选标记类型的自动标记功能。",
|
||||
["zh-tw"] = "啟用或停用所選標記類型的自動標記功能。",
|
||||
},
|
||||
interval = {
|
||||
en = "Interval",
|
||||
["zh-cn"] = "间隔时间",
|
||||
["zh-tw"] = "間隔時間",
|
||||
},
|
||||
interval_description = {
|
||||
en = "Minimum interval after a mark expires before Auto-Mark marks the next target.\n\nUnit: seconds.",
|
||||
["zh-cn"] = "设置标记消失后,执行下一次标记的最短时间间隔。\n\n单位:秒。",
|
||||
["zh-tw"] = "設定標記消失後,執行下一次標記的最短時間間隔。\n\n單位:秒。",
|
||||
},
|
||||
cooldown = {
|
||||
en = "Cooldown",
|
||||
["zh-cn"] = "冷却时间",
|
||||
["zh-tw"] = "冷卻時間",
|
||||
},
|
||||
cooldown_description = {
|
||||
en = "Cooldown after a mark is applied before Auto-Mark marks the next target.\n\nUnit: seconds.",
|
||||
["zh-cn"] = "设置标记生成后,自动标记下一个目标前的冷却时间。\n\n单位:秒。",
|
||||
["zh-tw"] = "設定標記生成後,自動標記下一個目標前的冷卻時間。\n\n單位:秒。",
|
||||
},
|
||||
reset_cooldown = {
|
||||
en = "Reset Cooldown",
|
||||
["zh-cn"] = "刷新冷却",
|
||||
["zh-tw"] = "重置冷卻",
|
||||
},
|
||||
reset_cooldown_description = {
|
||||
en = "Resets Auto-Mark cooldown when the last mark disappears.",
|
||||
["zh-cn"] = "当上个标记消失时,刷新自动标记冷却时间。",
|
||||
["zh-tw"] = "當上個標記消失時,重置自動標記冷卻時間。",
|
||||
},
|
||||
mark_limit = {
|
||||
en = "Mark Limit",
|
||||
["zh-cn"] = "标记限制",
|
||||
["zh-tw"] = "標記限制",
|
||||
},
|
||||
mark_limit_description = {
|
||||
en = "Stops Auto-Mark when the last mark is present.",
|
||||
["zh-cn"] = "当上个标记存在时,停止自动标记。",
|
||||
["zh-tw"] = "當上個標記存在時,停止自動標記。",
|
||||
},
|
||||
min_range = {
|
||||
en = "Min Range",
|
||||
["zh-cn"] = "最小范围",
|
||||
["zh-tw"] = "最小範圍",
|
||||
},
|
||||
min_range_description = {
|
||||
en = "Unit: Meters",
|
||||
["zh-cn"] = "单位:米",
|
||||
["zh-tw"] = "單位:公尺",
|
||||
},
|
||||
max_range = {
|
||||
en = "Max Range",
|
||||
["zh-cn"] = "最大范围",
|
||||
["zh-tw"] = "最大範圍",
|
||||
},
|
||||
max_range_description = {
|
||||
en = "Unit: Meters",
|
||||
["zh-cn"] = "单位:米",
|
||||
["zh-tw"] = "單位:公尺",
|
||||
},
|
||||
max_angle = {
|
||||
en = "Max Angle",
|
||||
["zh-cn"] = "最大角度",
|
||||
["zh-tw"] = "最大角度",
|
||||
},
|
||||
max_angle_description = {
|
||||
en = "Maximum angle in degrees between your crosshair and markable enemies. \n\nSet to " .. highlight("0") .. " to use vanilla raycast detection.",
|
||||
["zh-cn"] = "可标记敌人与准星间的最大角度。\n\n设置为" .. highlight("0") .. "时将使用游戏原版射线检测。",
|
||||
["zh-tw"] = "可標記敵人與準星間的最大角度。\n\n設為" .. highlight("0") .. "時將使用遊戲原版射線偵測。",
|
||||
},
|
||||
override_manual = {
|
||||
en = "Override Manual",
|
||||
["zh-cn"] = "覆盖手动标记",
|
||||
["zh-tw"] = "覆蓋手動標記",
|
||||
},
|
||||
override_manual_description = {
|
||||
en = highlight("Off") .. ": Auto-mark stops when a manual mark is present.\n" ..
|
||||
highlight("On") .. ": Auto-mark continues to find new targets even when a manual mark is present.",
|
||||
["zh-cn"] = highlight("关闭") .. ":手动标记存在时,自动标记将停止。\n" ..
|
||||
highlight("开启") .. ":即使当前标记为手动标记,自动标记也会继续寻找新的目标。",
|
||||
["zh-tw"] = highlight("關閉") .. ":當存在手動標記時,自動標記會停止。\n" ..
|
||||
highlight("開啟") .. ":即使目前有手動標記,自動標記仍會持續尋找新目標。",
|
||||
},
|
||||
priority_switch = {
|
||||
en = "Priority Switch",
|
||||
["zh-cn"] = "优先级切换",
|
||||
["zh-tw"] = "優先順序切換",
|
||||
},
|
||||
priority_switch_description = {
|
||||
en = "Switches to the aimed target if it has higher priority than the current marked target.",
|
||||
["zh-cn"] = "当正在瞄准的目标优先级高于已被标记的目标时,切换至瞄准的目标。",
|
||||
["zh-tw"] = "當正在瞄準的目標優先順序高於已標記的目標時,切換至瞄準的目標。",
|
||||
},
|
||||
toggle_elite = {
|
||||
en = "Toggle Elite",
|
||||
["zh-cn"] = "精英开关",
|
||||
["zh-tw"] = "精英開關",
|
||||
},
|
||||
toggle_elite_description = {
|
||||
en = "Enable/Disable Auto-Mark for elites.",
|
||||
["zh-cn"] = "为精英敌人启用/禁用自动标记功能。",
|
||||
["zh-tw"] = "啟用或停用精英敵人的自動標記功能。",
|
||||
},
|
||||
toggle_special = {
|
||||
en = "Toggle Specialist",
|
||||
["zh-cn"] = "专家开关",
|
||||
["zh-tw"] = "專家開關",
|
||||
},
|
||||
toggle_special_description = {
|
||||
en = "Enable/Disable Auto-Mark for specialists.",
|
||||
["zh-cn"] = "为专家敌人启用/禁用自动标记功能。",
|
||||
["zh-tw"] = "啟用或停用專家敵人的自動標記功能。",
|
||||
},
|
||||
toggle_boss = {
|
||||
en = "Toggle Boss",
|
||||
["zh-cn"] = "Boss开关",
|
||||
["zh-tw"] = "Boss開關",
|
||||
},
|
||||
toggle_boss_description = {
|
||||
en = "Enable/Disable Auto-Mark for bosses.",
|
||||
["zh-cn"] = "为Boss启用/禁用自动标记功能。",
|
||||
["zh-tw"] = "為Boss啟用或停用自動標記功能。",
|
||||
},
|
||||
toggle_other = {
|
||||
en = "Toggle Other",
|
||||
["zh-cn"] = "其他开关",
|
||||
["zh-tw"] = "其他開關",
|
||||
},
|
||||
toggle_other_description = {
|
||||
en = "Enable/Disable Auto-Mark for other enemies.",
|
||||
["zh-cn"] = "为其他敌人启用/禁用自动标记功能。",
|
||||
["zh-tw"] = "啟用或停用其他敵人的自動標記功能。",
|
||||
},
|
||||
priority_off = {
|
||||
en = "Off",
|
||||
["zh-cn"] = "关闭",
|
||||
["zh-tw"] = "關閉",
|
||||
},
|
||||
priority_lowest = {
|
||||
en = "Priority Lowest",
|
||||
["zh-cn"] = "最低优先级",
|
||||
["zh-tw"] = "最低優先",
|
||||
},
|
||||
priority_low = {
|
||||
en = "Priority Low",
|
||||
["zh-cn"] = "低优先级",
|
||||
["zh-tw"] = "低優先",
|
||||
},
|
||||
priority_medium = {
|
||||
en = "Priority Medium",
|
||||
["zh-cn"] = "中优先级",
|
||||
["zh-tw"] = "中優先",
|
||||
},
|
||||
priority_high = {
|
||||
en = "Priority High",
|
||||
["zh-cn"] = "高优先级",
|
||||
["zh-tw"] = "高優先",
|
||||
},
|
||||
priority_highest = {
|
||||
en = "Priority Highest",
|
||||
["zh-cn"] = "最高优先级",
|
||||
["zh-tw"] = "最高優先",
|
||||
},
|
||||
adamant_companion = {
|
||||
en = "Arbitrator Cyber-Mastiff",
|
||||
["zh-cn"] = "法务官 智能獒犬",
|
||||
["zh-tw"] = "法務官 電子獒犬",
|
||||
},
|
||||
veteran_focus_target = {
|
||||
en = "Veteran Focus Target",
|
||||
["zh-cn"] = "老兵聚焦目标",
|
||||
["zh-tw"] = "老兵專注目標",
|
||||
},
|
||||
cryptic_servo_skull = {
|
||||
en = "Skitarius Servo-Skull",
|
||||
["zh-cn"] = "护教军士兵 伺服颅骨",
|
||||
["zh-tw"] = "護教軍 伺服顱骨",
|
||||
},
|
||||
apply_to_all_classes = {
|
||||
en = "Apply to All Classes",
|
||||
["zh-cn"] = "应用于所有职业",
|
||||
["zh-tw"] = "套用至所有職業",
|
||||
},
|
||||
apply_button = {
|
||||
en = "Apply to All",
|
||||
["zh-cn"] = "应用于所有职业",
|
||||
["zh-tw"] = "套用至全部",
|
||||
},
|
||||
apply_button_description = {
|
||||
en =
|
||||
"Apply settings from the selected mark type to either all mark types or only normal enemy marks across all classes.",
|
||||
["zh-cn"] = "将所选标记类型的设置应用于所有标记类型或者只应用于所有职业的普通敌人标记。",
|
||||
["zh-tw"] = "將所選標記類型的設定套用到所有標記類型,或僅套用到所有職業的一般敵人標記。",
|
||||
},
|
||||
reset_auto_mark_settings = {
|
||||
en = "Reset Auto Mark Settings",
|
||||
["zh-cn"] = "重置自动标记设置",
|
||||
["zh-tw"] = "重置自動標記設定",
|
||||
},
|
||||
reset_button = {
|
||||
en = "Reset to Defaults",
|
||||
["zh-cn"] = "重置为默认值",
|
||||
["zh-tw"] = "重設為預設值",
|
||||
},
|
||||
reset_button_description = {
|
||||
en = "Reset mark settings to defaults for all mark types or the selected mark type.",
|
||||
["zh-cn"] = "将所有标记类型或所选标记类型的设置重置为默认值。",
|
||||
["zh-tw"] = "將所有標記類型或所選標記類型的設定重設為預設值。",
|
||||
},
|
||||
blank = {
|
||||
en = " ",
|
||||
["zh-cn"] = " ",
|
||||
["zh-tw"] = " ",
|
||||
},
|
||||
reset = {
|
||||
en = "Reset",
|
||||
["zh-cn"] = "重置",
|
||||
["zh-tw"] = "重設",
|
||||
},
|
||||
apply_to_normal = {
|
||||
en = "Apply to Normal Enemy Marks",
|
||||
["zh-cn"] = "应用于普通敌人标记",
|
||||
["zh-tw"] = "套用到一般敵人標記",
|
||||
},
|
||||
apply_to_all = {
|
||||
en = "Apply to All Mark Types",
|
||||
["zh-cn"] = "应用于所有标记类型",
|
||||
["zh-tw"] = "套用到所有標記類型",
|
||||
},
|
||||
reset_current = {
|
||||
en = "Reset Selected Mark Settings",
|
||||
["zh-cn"] = "重置所选标记设置",
|
||||
["zh-tw"] = "重設所選標記設定",
|
||||
},
|
||||
reset_all = {
|
||||
en = "Reset All Mark Settings",
|
||||
["zh-cn"] = "重置所有标记设置",
|
||||
["zh-tw"] = "重設所有標記設定",
|
||||
},
|
||||
tooltip_breed_priority = {
|
||||
en = "Set the marking priority for this enemy type. Auto-Mark prioritizes targets with higher priority values.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to ignore this enemy type.",
|
||||
["zh-cn"] = "设置该类敌人的标记优先级。自动标记将优先标记优先级更高的目标。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以忽略此类敌人。",
|
||||
["zh-tw"] = "設定該類敵人的標記優先度。自動標記將優先標記優先度較高的目標。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可忽略此類敵人。",
|
||||
},
|
||||
elite = {
|
||||
en = "Elite",
|
||||
["zh-cn"] = "精英",
|
||||
["zh-tw"] = "精英",
|
||||
},
|
||||
elite_tooltip = {
|
||||
en = "Enable for elites.",
|
||||
["zh-cn"] = "为精英敌人启用。",
|
||||
["zh-tw"] = "為精英敵人啟用。",
|
||||
},
|
||||
special = {
|
||||
en = "Specialist",
|
||||
["zh-cn"] = "专家",
|
||||
["zh-tw"] = "專家",
|
||||
},
|
||||
special_tooltip = {
|
||||
en = "Enable for specialists.",
|
||||
["zh-cn"] = "为专家敌人启用。",
|
||||
["zh-tw"] = "為專家敵人啟用。",
|
||||
},
|
||||
boss = {
|
||||
en = "Boss",
|
||||
["zh-cn"] = "Boss",
|
||||
["zh-tw"] = "Boss",
|
||||
},
|
||||
boss_tooltip = {
|
||||
en = "Enable for bosses.",
|
||||
["zh-cn"] = "为Boss敌人启用。",
|
||||
["zh-tw"] = "為Boss敵人啟用。",
|
||||
},
|
||||
sticky_targeting = {
|
||||
en = "Mark Stickiness",
|
||||
["zh-cn"] = "标记粘滞",
|
||||
["zh-tw"] = "標記黏滯",
|
||||
},
|
||||
sticky_targeting_tooltip = {
|
||||
en = "Enable for the selected enemy type. If a marked enemy has Mark Stickiness enabled, AUTO-MARK will pause target switching caused by priority switch.",
|
||||
["zh-cn"] = "为所选敌人类型启用标记粘滞。如果被标记的敌人开启了标记粘滞功能,自动标记会暂停因优先级切换导致的切换目标行为。",
|
||||
["zh-tw"] = "為所選敵人類型啟用標記黏滯。如果被標記的敵人開啟了標記黏滯功能,自動標記會暫停因優先順序切換導致的切換目標行為。",
|
||||
},
|
||||
servo_skull_cancel_mark = {
|
||||
en = "Auto Cancel Servo-Skull Mark",
|
||||
["zh-cn"] = "自动取消伺服颅骨标记",
|
||||
["zh-tw"] = "自動取消伺服顱骨標記",
|
||||
},
|
||||
servo_skull_health_threshold_tooltip = {
|
||||
en = "Cancel the Servo-Skull mark when the health of your Servo-Skull's current attack target falls below your selected health percentage.\n\n" ..
|
||||
"Set to " .. highlight("0") .. " to disable.\n" ..
|
||||
"Does not affect " .. highlight("manual") .. " marks.",
|
||||
["zh-cn"] = "当你的伺服颅骨的攻击目标的血量低于所选百分比时,取消该目标的伺服颅骨标记。\n\n" ..
|
||||
"设置为" .. highlight("0") .. "以禁用。\n" ..
|
||||
"对" .. highlight("手动") .. "标记无效。",
|
||||
["zh-tw"] = "當你的伺服顱骨目前攻擊目標的生命值低於設定百分比時,取消該目標的伺服顱骨標記。\n\n" ..
|
||||
"設為" .. highlight("0") .. "可停用。\n" ..
|
||||
"不影響" .. highlight("手動") .. "標記。",
|
||||
},
|
||||
meter = {
|
||||
en = "m",
|
||||
["zh-cn"] = "米",
|
||||
["zh-tw"] = "公尺",
|
||||
},
|
||||
percent = {
|
||||
en = "%%",
|
||||
},
|
||||
degree = {
|
||||
en = "°",
|
||||
},
|
||||
stack = {
|
||||
en = "stack",
|
||||
["zh-cn"] = "层",
|
||||
["zh-tw"] = "层",
|
||||
},
|
||||
second = {
|
||||
en = "s",
|
||||
["zh-cn"] = "秒",
|
||||
["zh-tw"] = "秒",
|
||||
},
|
||||
hold_to_reset = {
|
||||
en = "to Reset",
|
||||
["zh-cn"] = "重置",
|
||||
["zh-tw"] = "重設",
|
||||
},
|
||||
}
|
||||
|
||||
local function is_localization_valid(text)
|
||||
return not string.find(text, "unlocalized")
|
||||
end
|
||||
|
||||
local function add_breed_localization(breed_name, breed_data, is_passive)
|
||||
local text = Localize(breed_data.is_boss and type(breed_data.boss_display_name) == "string" and breed_data.boss_display_name or breed_data.display_name)
|
||||
if is_localization_valid(text) then
|
||||
if is_passive then
|
||||
localization[breed_name .. "_passive"] = {
|
||||
en = text .. " (Dormant)",
|
||||
["zh-cn"] = text .. "(休眠)",
|
||||
["zh-tw"] = text .. "(休眠)",
|
||||
}
|
||||
elseif breed_name == "chaos_mutator_ritualist" then
|
||||
localization[breed_name] = {
|
||||
en = "Hexbound " .. text,
|
||||
["zh-cn"] = "咒缚" .. text,
|
||||
["zh-tw"] = "魔縛" .. text,
|
||||
}
|
||||
elseif breed_name ~= "chaos_mutator_daemonhost" and string.find(breed_name, "mutator") then
|
||||
localization[breed_name] = {
|
||||
en = text .. " (Mutator)",
|
||||
["zh-cn"] = text .. "(变异体)",
|
||||
["zh-tw"] = text .. "(變異體)",
|
||||
}
|
||||
else
|
||||
localization[breed_name] = { en = text }
|
||||
end
|
||||
else
|
||||
localization[breed_name] = { en = breed_name }
|
||||
end
|
||||
end
|
||||
|
||||
for breed_name, breed_data in pairs(Breeds) do
|
||||
if Breed.is_minion(breed_data) and breed_data.unit_template_name == "minion" and breed_data.smart_tag_target_type == "breed" and breed_data.faction_name ~= "imperium" then
|
||||
add_breed_localization(breed_name, breed_data)
|
||||
if breed_data.tags.witch then
|
||||
add_breed_localization(breed_name, breed_data, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for class_name, archetype in pairs(Archetypes) do
|
||||
local text = Localize(archetype.archetype_name)
|
||||
localization[class_name] = {
|
||||
en = text
|
||||
}
|
||||
end
|
||||
|
||||
return localization
|
||||
@@ -0,0 +1,410 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local context = mod.context
|
||||
|
||||
-- Global Cache
|
||||
local CLASS = CLASS
|
||||
local ScriptUnit = ScriptUnit
|
||||
local Managers = Managers
|
||||
|
||||
-- Get Extensions
|
||||
local function get_player_talent_extension()
|
||||
local player = Managers.player:local_player_safe(1)
|
||||
return player and ScriptUnit.extension(player.player_unit, "talent_system")
|
||||
end
|
||||
|
||||
local function get_player_data_extension()
|
||||
local player = Managers.player:local_player_safe(1)
|
||||
return player and ScriptUnit.extension(player.player_unit, "unit_data_system")
|
||||
end
|
||||
|
||||
local function get_smart_targeting_extension()
|
||||
local player = Managers.player:local_player_safe(1)
|
||||
return player and ScriptUnit.extension(player.player_unit, "smart_targeting_system")
|
||||
end
|
||||
|
||||
local function get_companion_spawner_extension()
|
||||
local player = Managers.player:local_player_safe(1)
|
||||
return player and ScriptUnit.extension(player.player_unit, "companion_spawner_system")
|
||||
end
|
||||
|
||||
local function get_player_ability_extension()
|
||||
local player = Managers.player:local_player_safe(1)
|
||||
return player and ScriptUnit.extension(player.player_unit, "ability_system")
|
||||
end
|
||||
|
||||
-- Track Player
|
||||
local function init_player()
|
||||
local player = Managers.player:local_player_safe(1)
|
||||
if player then
|
||||
context.player = player
|
||||
end
|
||||
local class_name = player and player:archetype_name()
|
||||
if class_name then
|
||||
context.class_name = class_name
|
||||
end
|
||||
end
|
||||
|
||||
-- Track Player Components
|
||||
local function init_player_components(player_data_extension)
|
||||
player_data_extension = player_data_extension or get_player_data_extension()
|
||||
if not player_data_extension then
|
||||
return
|
||||
end
|
||||
|
||||
context.talent_resource_component = player_data_extension:read_component("talent_resource")
|
||||
context.disabled_character_state_component = player_data_extension:read_component("disabled_character_state")
|
||||
context.locomotion_component = player_data_extension:read_component("locomotion")
|
||||
mod:print_debug("Init talent_resource_component")
|
||||
end
|
||||
|
||||
local function destroy_player_components()
|
||||
context.talent_resource_component = nil
|
||||
context.disabled_character_state_component = nil
|
||||
context.locomotion_component = nil
|
||||
end
|
||||
|
||||
-- Track Player Extensions
|
||||
local function init_player_extensions()
|
||||
local smart_targeting_extension = get_smart_targeting_extension()
|
||||
if smart_targeting_extension then
|
||||
context.smart_targeting_extension = smart_targeting_extension
|
||||
end
|
||||
local companion_spawner_extension = get_companion_spawner_extension()
|
||||
if companion_spawner_extension then
|
||||
context.companion_spawner_extension = companion_spawner_extension
|
||||
end
|
||||
local player_ability_extension = get_player_ability_extension()
|
||||
if player_ability_extension then
|
||||
context.player_ability_extension = player_ability_extension
|
||||
end
|
||||
end
|
||||
|
||||
local function init_hud_elements()
|
||||
local hud = Managers.ui:get_hud()
|
||||
local hud_element_smart_tagging = hud and hud:element("HudElementSmartTagging")
|
||||
if hud_element_smart_tagging then
|
||||
context.hud_element_smart_tagging = hud_element_smart_tagging
|
||||
end
|
||||
end
|
||||
|
||||
-- Talent Names
|
||||
local TALENT_NAMES = {
|
||||
LONE_WOLF = "adamant_disable_companion",
|
||||
EXECUTION_ORDER = "adamant_execution_order",
|
||||
FOCUS_TARGET = "veteran_improved_tag",
|
||||
FOCUSED_FIRE = "veteran_improved_tag_more_damage",
|
||||
FORCE_FIELD = "cryptic_grenade_ability_force_field",
|
||||
ARC_GRENADE = "cryptic_grenade_ability_arc_grenade",
|
||||
NOOSPHERIC_COMMAND = "cryptic_servo_skull_improved_tagging",
|
||||
}
|
||||
-- Talent Settings
|
||||
local talent_settings = require("scripts/settings/talent/talent_settings")
|
||||
local veteran_talent_settings = talent_settings.veteran
|
||||
local veteran_tag_max_stacks = veteran_talent_settings.veteran_tag.max_stacks
|
||||
local veteran_tag_max_stacks_talent = veteran_talent_settings.veteran_tag.max_stacks_talent
|
||||
-- Track Player Talent Status
|
||||
local function init_player_talent_status(player_talent_extension)
|
||||
player_talent_extension = player_talent_extension or get_player_talent_extension()
|
||||
if not player_talent_extension then
|
||||
return
|
||||
end
|
||||
|
||||
local talents = player_talent_extension._talents
|
||||
-- has companion
|
||||
context.has_companion = context.class_name == "adamant" and not talents[TALENT_NAMES.LONE_WOLF]
|
||||
-- has execution order
|
||||
context.has_execution_order = context.class_name == "adamant" and not not talents[TALENT_NAMES.EXECUTION_ORDER]
|
||||
-- has focus target
|
||||
context.has_focus_target = context.class_name == "veteran" and not not talents[TALENT_NAMES.FOCUS_TARGET]
|
||||
-- has focused fire
|
||||
local has_focused_fire = not not talents[TALENT_NAMES.FOCUSED_FIRE]
|
||||
-- focus target max stacks
|
||||
context.focus_target_max_stacks = context.class_name == "veteran" and context.has_focus_target and (has_focused_fire and veteran_tag_max_stacks_talent or veteran_tag_max_stacks) or 0
|
||||
|
||||
context.has_servo_skull = context.class_name == "cryptic" and not talents[TALENT_NAMES.FORCE_FIELD] and not talents[TALENT_NAMES.ARC_GRENADE]
|
||||
|
||||
context.has_noospheric_command = context.class_name == "cryptic" and not not talents[TALENT_NAMES.NOOSPHERIC_COMMAND]
|
||||
|
||||
mod:print_debug("has companion", context.has_companion)
|
||||
mod:print_debug("has execution order", context.has_execution_order)
|
||||
mod:print_debug("has focus target", context.has_focus_target)
|
||||
mod:print_debug("focus target max stacks", context.focus_target_max_stacks)
|
||||
mod:print_debug("has servo skull", context.has_servo_skull)
|
||||
mod:print_debug("has noospheric command", context.has_noospheric_command)
|
||||
end
|
||||
|
||||
-- Track Systems
|
||||
local function init_systems()
|
||||
local smart_tag_system = Managers.state.extension and Managers.state.extension:system("smart_tag_system")
|
||||
if smart_tag_system then
|
||||
context.smart_tag_system = smart_tag_system
|
||||
end
|
||||
local outline_system = Managers.state.extension and Managers.state.extension:system("outline_system")
|
||||
if outline_system then
|
||||
context.outline_system = outline_system
|
||||
end
|
||||
local smoke_fog_system = Managers.state.extension and Managers.state.extension:system("smoke_fog_system")
|
||||
if smoke_fog_system then
|
||||
context.smoke_fog_system = smoke_fog_system
|
||||
end
|
||||
local force_field_system = Managers.state.extension and Managers.state.extension:system("force_field_system")
|
||||
if force_field_system then
|
||||
context.force_field_system = force_field_system
|
||||
end
|
||||
local broadphase_system = Managers.state.extension and Managers.state.extension:system("broadphase_system")
|
||||
if broadphase_system then
|
||||
context.broadphase_system = broadphase_system
|
||||
end
|
||||
local side_system = Managers.state.extension and Managers.state.extension:system("side_system")
|
||||
if side_system then
|
||||
context.side_system = side_system
|
||||
end
|
||||
end
|
||||
|
||||
-- Track Game Settings
|
||||
local function init_game_settings()
|
||||
context.companion_command_tap = Managers.save:account_data().input_settings.companion_command_tap
|
||||
end
|
||||
|
||||
function mod:init_game_settings()
|
||||
init_game_settings()
|
||||
end
|
||||
|
||||
local INVALID_MODE_NAMES = {
|
||||
training_grounds = true,
|
||||
hub = true,
|
||||
prologue_hub = true,
|
||||
}
|
||||
-- Check if player is in hub
|
||||
function mod:check_game_mode()
|
||||
local game_mode_manager = Managers.state.game_mode
|
||||
local game_mode_name = game_mode_manager and game_mode_manager:game_mode_name()
|
||||
if game_mode_name and not INVALID_MODE_NAMES[game_mode_name] then
|
||||
context.game_mode_valid = true
|
||||
end
|
||||
mod:print_debug("Game mode:", game_mode_name, context.game_mode_valid and "valid" or "invalid")
|
||||
end
|
||||
|
||||
-- Init all params
|
||||
function mod:init_context()
|
||||
-- Init Player
|
||||
init_player()
|
||||
-- Init Player Components
|
||||
init_player_components()
|
||||
-- Init Extensions
|
||||
init_player_extensions()
|
||||
-- Init HUD Elements
|
||||
init_hud_elements()
|
||||
-- Init Talents Status
|
||||
init_player_talent_status()
|
||||
-- Init Systems
|
||||
init_systems()
|
||||
-- Init Game Settings
|
||||
init_game_settings()
|
||||
end
|
||||
|
||||
-- Cache Player
|
||||
mod:hook_safe(CLASS.HumanPlayer, "init",
|
||||
function(self)
|
||||
if self.viewport_name == "player1" then
|
||||
mod:print_debug("Init HumanPlayer")
|
||||
context.player = self
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.HumanPlayer, "destroy",
|
||||
function(self)
|
||||
if self.viewport_name == "player1" then
|
||||
mod:print_debug("Destroy HumanPlayer")
|
||||
context.player = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Get Archetype Name When Player Set Profile
|
||||
mod:hook_safe(CLASS.HumanPlayer, "set_profile",
|
||||
function(self)
|
||||
if self.viewport_name == "player1" then
|
||||
context.class_name = self:archetype_name()
|
||||
mod:print_debug("Class name", context.class_name)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Player Unit Data Hook for Components
|
||||
mod:hook_safe(CLASS.PlayerUnitDataExtension, "init",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
mod:print_debug("Init PlayerUnitDataExtension")
|
||||
init_player_components(self)
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.PlayerUnitDataExtension, "destroy",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
mod:print_debug("Destroy PlayerUnitDataExtension")
|
||||
destroy_player_components()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Hook Extensions for Cache
|
||||
mod:hook_safe(CLASS.PlayerUnitSmartTargetingExtension, "init",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
mod:print_debug("Init PlayerUnitSmartTargetingExtension")
|
||||
context.smart_targeting_extension = self
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.PlayerUnitSmartTargetingExtension, "delete",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
mod:print_debug("Delete PlayerUnitSmartTargetingExtension")
|
||||
context.smart_targeting_extension = nil
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.CompanionSpawnerExtension, "init",
|
||||
function(self)
|
||||
if self._owner_player.viewport_name == "player1" then
|
||||
mod:print_debug("Init CompanionSpawnerExtension")
|
||||
context.companion_spawner_extension = self
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.CompanionSpawnerExtension, "destroy",
|
||||
function(self)
|
||||
if self._owner_player.viewport_name == "player1" then
|
||||
mod:print_debug("Destroy CompanionSpawnerExtension")
|
||||
context.companion_spawner_extension = nil
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.PlayerUnitAbilityExtension, "init",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
mod:print_debug("Init PlayerUnitAbilityExtension")
|
||||
context.player_ability_extension = self
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.PlayerUnitAbilityExtension, "delete",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
mod:print_debug("Delete PlayerUnitAbilityExtension")
|
||||
context.player_ability_extension = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Cache HUD Elements
|
||||
mod:hook_safe(CLASS.HudElementSmartTagging, "init",
|
||||
function(self, parent, draw_layer, start_scale)
|
||||
if self._parent._player_viewport_name == "player1" then
|
||||
mod:print_debug("Init HudElementSmartTagging")
|
||||
context.hud_element_smart_tagging = self
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.HudElementSmartTagging, "destroy",
|
||||
function(self, ui_renderer)
|
||||
if self._parent._player_viewport_name == "player1" then
|
||||
mod:print_debug("Destroy HudElementSmartTagging")
|
||||
context.hud_element_smart_tagging = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Update Talent Status
|
||||
mod:hook_safe(CLASS.PlayerUnitTalentExtension, "_apply_talents",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
init_player_talent_status(self)
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.PlayerHuskTalentExtension, "_update_talents",
|
||||
function(self)
|
||||
if self._player.viewport_name == "player1" then
|
||||
init_player_talent_status(self)
|
||||
end
|
||||
end)
|
||||
|
||||
-- System Cache Hook
|
||||
mod:hook_safe(CLASS.SmartTagSystem, "init",
|
||||
function(self)
|
||||
mod:print_debug("Init SmartTagSystem")
|
||||
context.smart_tag_system = self
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.SmartTagSystem, "destroy",
|
||||
function()
|
||||
mod:print_debug("Destroy SmartTagSystem")
|
||||
context.smart_tag_system = nil
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.OutlineSystem, "init",
|
||||
function(self)
|
||||
mod:print_debug("Init OutlineSystem")
|
||||
context.outline_system = self
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.OutlineSystem, "destroy",
|
||||
function()
|
||||
mod:print_debug("Destroy OutlineSystem")
|
||||
context.outline_system = nil
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.SmokeFogSystem, "init",
|
||||
function(self)
|
||||
mod:print_debug("Init SmokeFogSystem")
|
||||
context.smoke_fog_system = self
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.SmokeFogSystem, "destroy",
|
||||
function()
|
||||
mod:print_debug("Destroy SmokeFogSystem")
|
||||
context.smoke_fog_system = nil
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.ForceFieldSystem, "init",
|
||||
function(self)
|
||||
mod:print_debug("Init ForceFieldSystem")
|
||||
context.force_field_system = self
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.ForceFieldSystem, "destroy",
|
||||
function()
|
||||
mod:print_debug("Destroy ForceFieldSystem")
|
||||
context.force_field_system = nil
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.BroadphaseSystem, "init",
|
||||
function(self)
|
||||
mod:print_debug("Init BroadphaseSystem")
|
||||
context.broadphase_system = self
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.BroadphaseSystem, "destroy",
|
||||
function()
|
||||
mod:print_debug("Destroy BroadphaseSystem")
|
||||
context.broadphase_system = nil
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.SideSystem, "init",
|
||||
function(self)
|
||||
mod:print_debug("Init SideSystem")
|
||||
context.side_system = self
|
||||
end)
|
||||
|
||||
mod:hook_safe(CLASS.SideSystem, "destroy",
|
||||
function()
|
||||
mod:print_debug("Destroy SideSystem")
|
||||
context.side_system = nil
|
||||
end)
|
||||
|
||||
-- Update settings when input settings changed
|
||||
mod:hook_safe(CLASS.EventManager, "trigger", function(self, event_name)
|
||||
if event_name == "event_on_input_settings_changed" then
|
||||
mod:print_debug("input settings changed")
|
||||
init_game_settings()
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,319 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local context = mod.context
|
||||
local mark_context = mod.mark_context
|
||||
local TAG_NAMES = mod.TAG_NAMES
|
||||
local mod_settings = mod.settings
|
||||
local companion_cancel_mark_breed_settings = mod.companion_cancel_mark_breed_settings
|
||||
|
||||
-- Imports
|
||||
local TalentSettings = require("scripts/settings/talent/talent_settings")
|
||||
local NetworkLookup = require("scripts/network_lookup/network_lookup")
|
||||
local cryptic_talent_settings = TalentSettings.cryptic
|
||||
local noospheric_command_duration = cryptic_talent_settings.servo_skull_shooting_tagging.duration
|
||||
|
||||
-- Global Cache
|
||||
local CLASS = CLASS
|
||||
local ScriptUnit = ScriptUnit
|
||||
local Managers = Managers
|
||||
|
||||
-- Delay for Server Latency, Interval for Auto Mark
|
||||
local AUTO_MARK_DELAY = 0.5
|
||||
local AUTO_MARK_INTERVAL = 0.2
|
||||
local ENEMY_TAG_DELAY = 3
|
||||
local PRIORITY_SWITCH_COOLDOWN = 0.3
|
||||
local FOCUS_TARGET_DELAY = 1.5
|
||||
|
||||
-- set delay and interval for auto mark
|
||||
local function on_set_tag(tag_context)
|
||||
-- mark_context.auto_mark_interval = AUTO_MARK_INTERVAL
|
||||
tag_context.delay = AUTO_MARK_DELAY
|
||||
tag_context.delay_times = tag_context.delay_times + 1
|
||||
end
|
||||
|
||||
-- record manual marked unit
|
||||
function mod:on_manual_mark(tag_context, target_unit)
|
||||
mod:print_debug("manual mark unit:", target_unit)
|
||||
tag_context.manual_unit = target_unit
|
||||
tag_context.manual_unit_expired_time = mod:get_latest_fixed_time() + 1
|
||||
end
|
||||
|
||||
-- cancel mark by tag id
|
||||
function mod:cancel_mark(tag_id)
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
if not player_unit then
|
||||
return
|
||||
end
|
||||
|
||||
smart_tag_system:cancel_tag(tag_id, player_unit)
|
||||
end
|
||||
|
||||
-- mark target unit with tag
|
||||
function mod:set_auto_mark(tag_name, target_unit, target_tag)
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
local tag_context = mark_context[tag_name]
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not player_unit or not target_unit or not tag_context or not smart_tag_system
|
||||
then
|
||||
return
|
||||
end
|
||||
|
||||
local player_unit_id = Managers.state.unit_spawner:game_object_id(player_unit)
|
||||
if not player_unit_id then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit_id = Managers.state.unit_spawner:game_object_id(target_unit)
|
||||
if not target_unit_id then
|
||||
return
|
||||
end
|
||||
|
||||
if target_tag then
|
||||
if tag_name == TAG_NAMES.COMPANION_TAG or tag_name == TAG_NAMES.VETERAN_TAG or tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
local template = target_tag._template
|
||||
local is_enemy_mark = template and template.name == TAG_NAMES.ENEMY_TAG
|
||||
if is_enemy_mark then
|
||||
local tagger_player = target_tag._tagger_player
|
||||
local tagger_player_unit = tagger_player and tagger_player.player_unit
|
||||
if tagger_player_unit then
|
||||
smart_tag_system:cancel_tag(target_tag._id, tagger_player_unit, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mod:print_debug("Auto Mark", tag_name, target_unit)
|
||||
on_set_tag(tag_context)
|
||||
local template_name_id = NetworkLookup.smart_tag_templates[tag_name]
|
||||
if smart_tag_system._is_server then
|
||||
local tag_id = smart_tag_system:_generate_tag_id()
|
||||
local tag = smart_tag_system:_create_tag_locally(tag_id, tag_name, player_unit, target_unit)
|
||||
smart_tag_system:_server_check_tag_group_limit(player_unit, tag:group())
|
||||
Managers.state.game_session:send_rpc_clients("rpc_set_smart_tag", tag_id, template_name_id, player_unit_id, target_unit_id)
|
||||
else
|
||||
Managers.state.game_session:send_rpc_server("rpc_request_set_smart_tag", template_name_id, player_unit_id, target_unit_id)
|
||||
end
|
||||
end
|
||||
|
||||
function mod:set_manual_mark(tag_name, target_unit, target_tag)
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not player_unit or not target_unit or not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
if target_tag then
|
||||
if tag_name == TAG_NAMES.COMPANION_TAG or tag_name == TAG_NAMES.VETERAN_TAG or tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
local template = target_tag._template
|
||||
local is_enemy_mark = template and template.name == TAG_NAMES.ENEMY_TAG
|
||||
if is_enemy_mark then
|
||||
local tagger_player = target_tag._tagger_player
|
||||
local tagger_player_unit = tagger_player and tagger_player.player_unit
|
||||
if tagger_player_unit then
|
||||
smart_tag_system:cancel_tag(target_tag._id, tagger_player_unit, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
smart_tag_system:set_tag(tag_name, player_unit, target_unit)
|
||||
end
|
||||
|
||||
mod:hook(CLASS.SmartTagSystem, "set_tag",
|
||||
function(func, self, template_name, tagger_unit, target_unit, ...)
|
||||
local player = context.player
|
||||
if player and tagger_unit == player.player_unit then
|
||||
local tag_context = mark_context[template_name]
|
||||
if tag_context then
|
||||
-- the unit is marked manually
|
||||
mod:on_manual_mark(tag_context, target_unit)
|
||||
-- set delay and interval for auto mark
|
||||
on_set_tag(tag_context)
|
||||
end
|
||||
end
|
||||
return func(self, template_name, tagger_unit, target_unit, ...)
|
||||
end)
|
||||
|
||||
local function delay_normal_tag()
|
||||
local tag_context = mark_context[TAG_NAMES.ENEMY_TAG]
|
||||
if tag_context.cooldown < ENEMY_TAG_DELAY then
|
||||
tag_context.cooldown = ENEMY_TAG_DELAY
|
||||
end
|
||||
if tag_context.priority_switch_cooldown < ENEMY_TAG_DELAY then
|
||||
tag_context.priority_switch_cooldown = ENEMY_TAG_DELAY
|
||||
end
|
||||
end
|
||||
|
||||
-- Smart Tag Hook
|
||||
mod:hook_safe(CLASS.SmartTag, "init",
|
||||
function(self, tag_id, template, tagger_unit, target_unit, target_location, replies, is_server)
|
||||
local tagger_player = self._tagger_player
|
||||
if not tagger_player or tagger_player.viewport_name ~= "player1" then
|
||||
return
|
||||
end
|
||||
|
||||
local tag_name = template.name
|
||||
local tag_context = mark_context[tag_name]
|
||||
if not tag_context then
|
||||
return
|
||||
end
|
||||
|
||||
mod:print_debug("init smart tag", tag_name)
|
||||
mark_context.auto_mark_interval = AUTO_MARK_INTERVAL
|
||||
-- refresh delay and set cooldown
|
||||
tag_context.tag = self
|
||||
tag_context.interval = 0
|
||||
tag_context.cooldown = mod:get_class_settings(tag_name).cooldown
|
||||
tag_context.priority_switch_cooldown = PRIORITY_SWITCH_COOLDOWN
|
||||
-- reset delay
|
||||
tag_context.delay_times = tag_context.delay_times - 1
|
||||
if tag_context.delay_times <= 0 then
|
||||
tag_context.delay = 0
|
||||
tag_context.delay_times = 0
|
||||
end
|
||||
-- check if the tag is manual
|
||||
tag_context.is_manual = tag_context.manual_unit == target_unit
|
||||
tag_context.manual_unit = nil
|
||||
|
||||
if tag_name == TAG_NAMES.COMPANION_TAG then
|
||||
tag_context.pounce_start_time = nil
|
||||
local target_data_extension = ScriptUnit.extension(target_unit, "unit_data_system")
|
||||
local target_breed_data = target_data_extension and target_data_extension._breed
|
||||
local breed_name = target_breed_data and target_breed_data.name
|
||||
local breed_settings = companion_cancel_mark_breed_settings[breed_name]
|
||||
if breed_settings and breed_settings.override then
|
||||
tag_context.is_cancelable = true
|
||||
else
|
||||
local pounce_setting = target_breed_data and target_breed_data.companion_pounce_setting
|
||||
local pounce_action = pounce_setting and pounce_setting.companion_pounce_action
|
||||
if pounce_action == "human" then
|
||||
tag_context.is_cancelable = mod_settings.companion_cancel_mark_human
|
||||
else
|
||||
tag_context.is_cancelable = mod_settings.companion_cancel_mark_non_human
|
||||
end
|
||||
end
|
||||
delay_normal_tag()
|
||||
elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
tag_context.shoot_start_time = nil
|
||||
if context.has_noospheric_command then
|
||||
tag_context.noospheric_command_next_time = mod:get_latest_fixed_time() + noospheric_command_duration
|
||||
else
|
||||
tag_context.noospheric_command_next_time = math.huge
|
||||
end
|
||||
delay_normal_tag()
|
||||
elseif tag_name == TAG_NAMES.VETERAN_TAG then
|
||||
if tag_context.switch_melee_unit == target_unit then
|
||||
tag_context.is_switch_melee = true
|
||||
tag_context.is_switch_range = false
|
||||
elseif tag_context.switch_range_unit == target_unit then
|
||||
tag_context.is_switch_melee = false
|
||||
tag_context.is_switch_range = true
|
||||
else
|
||||
tag_context.is_switch_melee = false
|
||||
tag_context.is_switch_range = false
|
||||
end
|
||||
tag_context.switch_melee_unit = nil
|
||||
tag_context.switch_range_unit = nil
|
||||
elseif tag_name == TAG_NAMES.ENEMY_TAG then
|
||||
if context.class_name == "veteran" and context.has_focus_target then
|
||||
local veteran_tag_context = mark_context[TAG_NAMES.VETERAN_TAG]
|
||||
veteran_tag_context.tag = self
|
||||
veteran_tag_context.interval = 0
|
||||
veteran_tag_context.cooldown = mod:get_class_settings(TAG_NAMES.VETERAN_TAG).cooldown
|
||||
veteran_tag_context.priority_switch_cooldown = PRIORITY_SWITCH_COOLDOWN
|
||||
veteran_tag_context.is_manual = tag_context.is_manual
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
mod:hook(CLASS.SmartTag, "destroy",
|
||||
function(func, self, ...)
|
||||
local tag_name = self._template.name
|
||||
local tag_context = mark_context[tag_name]
|
||||
if not tag_context then
|
||||
return func(self, ...)
|
||||
end
|
||||
|
||||
if tag_context.tag == self then
|
||||
mod:print_debug("destroy smart tag", tag_name)
|
||||
tag_context.tag = nil
|
||||
tag_context.is_manual = false
|
||||
local class_settings = mod:get_class_settings(tag_name)
|
||||
tag_context.interval = class_settings.interval
|
||||
if class_settings.reset_cooldown then
|
||||
tag_context.cooldown = 0
|
||||
end
|
||||
|
||||
if tag_name == TAG_NAMES.COMPANION_TAG then
|
||||
tag_context.removed_units[self._target_unit] = mod:get_latest_fixed_time() + 1.5
|
||||
tag_context.pounce_start_time = nil
|
||||
tag_context.is_cancelable = false
|
||||
delay_normal_tag()
|
||||
elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
tag_context.removed_units[self._target_unit] = mod:get_latest_fixed_time() + 1.5
|
||||
tag_context.shoot_start_time = nil
|
||||
tag_context.noospheric_command_next_time = math.huge
|
||||
delay_normal_tag()
|
||||
elseif tag_name == TAG_NAMES.VETERAN_TAG then
|
||||
tag_context.removed_units[self._target_unit] = mod:get_latest_fixed_time() + 1.5
|
||||
if tag_context.is_switch_melee and tag_context.cooldown < FOCUS_TARGET_DELAY then
|
||||
tag_context.cooldown = FOCUS_TARGET_DELAY
|
||||
end
|
||||
tag_context.is_switch_melee = false
|
||||
tag_context.is_switch_range = false
|
||||
elseif tag_name == TAG_NAMES.ENEMY_TAG then
|
||||
if context.class_name == "veteran" and context.has_focus_target then
|
||||
local veteran_tag_context = mark_context[TAG_NAMES.VETERAN_TAG]
|
||||
if veteran_tag_context.tag == self then
|
||||
veteran_tag_context.tag = nil
|
||||
veteran_tag_context.is_manual = false
|
||||
local veteran_class_settings = mod:get_class_settings(TAG_NAMES.VETERAN_TAG)
|
||||
veteran_tag_context.interval = veteran_class_settings.interval
|
||||
if veteran_class_settings.reset_cooldown then
|
||||
veteran_tag_context.cooldown = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return func(self, ...)
|
||||
end)
|
||||
|
||||
local SERVO_SKULL_DAMAGE_PROFILE_NAMES = {
|
||||
default_companion_servo_skull_lasgun_killshot = true,
|
||||
improved_companion_servo_skull_lasgun_killshot = true,
|
||||
}
|
||||
-- Hook for Companion Dog Attack Info
|
||||
mod:hook_safe(CLASS.AttackReportManager, "add_attack_result",
|
||||
function(self, damage_profile, attacked_unit, attacking_unit, attack_direction, hit_world_position, hit_weakspot, damage, attack_result, attack_type, damage_efficiency, is_critical_strike)
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
if not player_unit or attacking_unit ~= player_unit then
|
||||
return
|
||||
end
|
||||
|
||||
if attack_type == "companion_dog" then
|
||||
local tag_context = mark_context[TAG_NAMES.COMPANION_TAG]
|
||||
local marked_tag = tag_context.tag
|
||||
if marked_tag and marked_tag._target_unit == attacked_unit and not tag_context.pounce_start_time then
|
||||
tag_context.pounce_start_time = mod:get_latest_fixed_time()
|
||||
mod:print_debug("pounce start time:", tag_context.pounce_start_time)
|
||||
end
|
||||
elseif SERVO_SKULL_DAMAGE_PROFILE_NAMES[damage_profile.name] then
|
||||
local tag_context = mark_context[TAG_NAMES.SERVO_SKULL_TAG]
|
||||
local marked_tag = tag_context.tag
|
||||
if marked_tag and marked_tag._target_unit == attacked_unit and not tag_context.shoot_start_time then
|
||||
tag_context.shoot_start_time = mod:get_latest_fixed_time()
|
||||
mod:print_debug("shoot start time:", tag_context.shoot_start_time)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,247 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local context = mod.context
|
||||
local mod_settings = mod.settings
|
||||
local mark_context = mod.mark_context
|
||||
local TAG_NAMES = mod.TAG_NAMES
|
||||
local companion_cancel_mark_breed_settings = mod.companion_cancel_mark_breed_settings
|
||||
local DISABLING_TYPES = mod.DISABLING_TYPES
|
||||
|
||||
-- Imports
|
||||
local Health = require("scripts/utilities/health")
|
||||
|
||||
-- Global Cache
|
||||
local CLASS = CLASS
|
||||
local HEALTH_ALIVE = HEALTH_ALIVE
|
||||
local Managers = Managers
|
||||
local callback = callback
|
||||
local Unit_world_position = Unit.world_position
|
||||
local Vector3_distance_squared = Vector3.distance_squared
|
||||
local ScriptUnit_extension = ScriptUnit.extension
|
||||
|
||||
-- Outline Name For Execution Order Detection
|
||||
local EXECUTION_ORDER_OUTLINE_NAME = "adamant_mark_target"
|
||||
local CANCEL_INTERVAL = 0.5
|
||||
|
||||
-- Callback Function for Companion Mark
|
||||
local function companion_mark_callback()
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit = mod:find_target_unit()
|
||||
if not target_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_tag = smart_tag_system:unit_tag(target_unit)
|
||||
local tag_name = TAG_NAMES.COMPANION_TAG
|
||||
mod:set_manual_mark(tag_name, target_unit, target_tag)
|
||||
end
|
||||
|
||||
-- Callback Function for Enemy Mark
|
||||
local function enemy_mark_callback()
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit = mod:find_target_unit()
|
||||
if not target_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_tag = smart_tag_system:unit_tag(target_unit)
|
||||
if target_tag then
|
||||
return
|
||||
end
|
||||
|
||||
local tag_name = TAG_NAMES.ENEMY_TAG
|
||||
mod:set_manual_mark(tag_name, target_unit, target_tag)
|
||||
end
|
||||
|
||||
-- Companion Mark Keybind Function
|
||||
mod.companion_mark = function()
|
||||
if not context.mod_enabled or not context.game_mode_valid or context.class_name ~= "adamant" or not context.has_companion then
|
||||
return
|
||||
end
|
||||
|
||||
local companion_command_tap = context.companion_command_tap
|
||||
if companion_command_tap == "double" then
|
||||
local cb = callback(companion_mark_callback)
|
||||
Managers.state.game_mode:register_physics_safe_callback(cb)
|
||||
elseif companion_command_tap == "single" then
|
||||
local cb = callback(enemy_mark_callback)
|
||||
Managers.state.game_mode:register_physics_safe_callback(cb)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check If Target Unit Is Marked by Execution Order
|
||||
local function is_marked_by_execution_order(unit)
|
||||
local outline_system = context.outline_system
|
||||
local extension = outline_system and outline_system._unit_extension_data[unit]
|
||||
local outlines = extension and extension.outlines
|
||||
if not outlines then
|
||||
return false
|
||||
end
|
||||
|
||||
for i = 1, #outlines do
|
||||
if outlines[i].name == EXECUTION_ORDER_OUTLINE_NAME then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Cache All Units Marked by Execution Order
|
||||
function mod:init_execution_order_units()
|
||||
if not context.has_execution_order then
|
||||
return
|
||||
end
|
||||
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local unit_extension_data = smart_tag_system._unit_extension_data
|
||||
if not unit_extension_data then
|
||||
return
|
||||
end
|
||||
|
||||
local execution_order_units = mark_context.execution_order_units
|
||||
for unit, smart_tag_extension in pairs(unit_extension_data) do
|
||||
if HEALTH_ALIVE[unit]
|
||||
and smart_tag_extension._target_type == "breed"
|
||||
and is_marked_by_execution_order(unit)
|
||||
then
|
||||
execution_order_units[unit] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local cancel_interval = 0
|
||||
function mod:auto_cancel_companion_mark(dt, t)
|
||||
if not mod_settings.companion_cancel_mark or context.class_name ~= "adamant" or not context.has_companion then
|
||||
return
|
||||
end
|
||||
|
||||
if cancel_interval > 0 then
|
||||
cancel_interval = cancel_interval - dt
|
||||
return
|
||||
end
|
||||
|
||||
local disabled_character_state_component = context.disabled_character_state_component
|
||||
if disabled_character_state_component and disabled_character_state_component.is_disabled and DISABLING_TYPES[disabled_character_state_component.disabling_type] then
|
||||
return
|
||||
end
|
||||
|
||||
local tag_context = mark_context[TAG_NAMES.COMPANION_TAG]
|
||||
local marked_tag = tag_context.tag
|
||||
local marked_unit = marked_tag and marked_tag._target_unit
|
||||
if not marked_tag or not marked_unit then
|
||||
return
|
||||
end
|
||||
|
||||
if tag_context.is_manual or not tag_context.is_cancelable then
|
||||
return
|
||||
end
|
||||
|
||||
if not tag_context.pounce_start_time then
|
||||
return
|
||||
end
|
||||
|
||||
local unit_data_extension = ScriptUnit_extension(marked_unit, "unit_data_system")
|
||||
local breed_data = unit_data_extension and unit_data_extension._breed
|
||||
local breed_name = breed_data and breed_data.name
|
||||
local breed_settings = companion_cancel_mark_breed_settings[breed_name]
|
||||
local health_threshold, time_threshold, distance_threshold
|
||||
if breed_settings and breed_settings.override then
|
||||
health_threshold = breed_settings.health_threshold or 0
|
||||
time_threshold = breed_settings.time_threshold or 0
|
||||
distance_threshold = breed_settings.distance_threshold or 0
|
||||
else
|
||||
health_threshold = mod_settings.companion_health_threshold
|
||||
time_threshold = mod_settings.companion_time_threshold
|
||||
distance_threshold = mod_settings.companion_distance_threshold
|
||||
end
|
||||
|
||||
if health_threshold > 0 then
|
||||
local health_percent = Health.current_health_percent(marked_unit)
|
||||
if health_percent < health_threshold then
|
||||
mod:print_debug("cancel companion mark due to health threshold, health_percent:", health_percent)
|
||||
tag_context.canceled_units[marked_unit] = t + 3
|
||||
cancel_interval = CANCEL_INTERVAL
|
||||
mod:cancel_mark(marked_tag._id)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if time_threshold > 0 then
|
||||
local elapsed_time = t - tag_context.pounce_start_time
|
||||
if elapsed_time > time_threshold then
|
||||
mod:print_debug("cancel companion mark due to time threshold, elapsed_time:", elapsed_time)
|
||||
tag_context.canceled_units[marked_unit] = t + 3
|
||||
cancel_interval = CANCEL_INTERVAL
|
||||
mod:cancel_mark(marked_tag._id)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if distance_threshold > 0 then
|
||||
local companion_spawner_extension = context.companion_spawner_extension
|
||||
local companion_units = companion_spawner_extension and companion_spawner_extension:companion_units()
|
||||
local companion_unit = companion_units and companion_units[1]
|
||||
if not companion_unit then
|
||||
goto exit
|
||||
end
|
||||
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
if not player_unit then
|
||||
goto exit
|
||||
end
|
||||
|
||||
local POSITION_LOOKUP = POSITION_LOOKUP
|
||||
local companion_position = POSITION_LOOKUP[companion_unit] or Unit_world_position(companion_unit, 1)
|
||||
local player_position = POSITION_LOOKUP[player_unit] or Unit_world_position(player_unit, 1)
|
||||
if not companion_position or not player_position then
|
||||
goto exit
|
||||
end
|
||||
|
||||
local distance_squared = Vector3_distance_squared(companion_position, player_position)
|
||||
if distance_squared > distance_threshold * distance_threshold then
|
||||
mod:print_debug("cancel companion mark due to distance threshold, distance squared:", distance_squared)
|
||||
tag_context.canceled_units[marked_unit] = t + 3
|
||||
cancel_interval = CANCEL_INTERVAL
|
||||
mod:cancel_mark(marked_tag._id)
|
||||
return
|
||||
end
|
||||
|
||||
::exit::
|
||||
end
|
||||
end
|
||||
|
||||
-- Cache Unit Marked by Execution Order
|
||||
mod:hook_safe(CLASS.OutlineSystem, "add_outline",
|
||||
function(self, unit, outline_name)
|
||||
if outline_name == EXECUTION_ORDER_OUTLINE_NAME then
|
||||
mark_context.execution_order_units[unit] = true
|
||||
end
|
||||
end)
|
||||
|
||||
-- Uncache Unit Unmarked by Execution Order
|
||||
mod:hook_safe(CLASS.OutlineSystem, "remove_outline",
|
||||
function(self, unit, outline_name)
|
||||
if outline_name == EXECUTION_ORDER_OUTLINE_NAME then
|
||||
mark_context.execution_order_units[unit] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Uncache Unit Dead
|
||||
mod:hook_safe(CLASS.OutlineSystem, "on_remove_extension",
|
||||
function(self, unit, extension_name)
|
||||
mark_context.execution_order_units[unit] = nil
|
||||
end)
|
||||
@@ -0,0 +1,84 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local context = mod.context
|
||||
local mod_settings = mod.settings
|
||||
local mark_context = mod.mark_context
|
||||
local TAG_NAMES = mod.TAG_NAMES
|
||||
|
||||
-- Global Cache
|
||||
local CLASS = CLASS
|
||||
|
||||
-- Constants
|
||||
local MELEE_RANGE = 5
|
||||
|
||||
local function focus_target_switch(is_melee)
|
||||
if not context.mod_enabled or not context.game_mode_valid or context.class_name ~= "veteran" or not context.has_focus_target then
|
||||
return
|
||||
end
|
||||
|
||||
local tag_name = TAG_NAMES.VETERAN_TAG
|
||||
local tag_context = mark_context[tag_name]
|
||||
if mark_context.auto_mark_interval > 0 or tag_context.delay > 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if not mod_settings.focus_target_switch_override_manual and tag_context.is_manual and not tag_context.is_switch_melee and not tag_context.is_switch_range then
|
||||
return
|
||||
end
|
||||
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit, target_tag
|
||||
if is_melee then
|
||||
target_unit, target_tag = mod:find_focus_target_switch_melee_target_unit(MELEE_RANGE)
|
||||
else
|
||||
target_unit = mod:find_target_unit(true)
|
||||
end
|
||||
|
||||
target_tag = target_tag or smart_tag_system:unit_tag(target_unit)
|
||||
if not target_unit or not mod:can_focus_target_overwrite(target_unit, target_tag) then
|
||||
return
|
||||
end
|
||||
|
||||
if is_melee then
|
||||
tag_context.switch_melee_unit = target_unit
|
||||
else
|
||||
tag_context.switch_range_unit = target_unit
|
||||
end
|
||||
tag_context.switch_unit_expired_time = mod:get_latest_fixed_time() + 1
|
||||
|
||||
mod:print_debug("Focus Target Switch", target_unit)
|
||||
mod:on_manual_mark(tag_context, target_unit)
|
||||
mod:set_auto_mark(tag_name, target_unit, target_tag)
|
||||
end
|
||||
|
||||
local MELEE_ACTION_KINDS = {
|
||||
-- windup = true,
|
||||
sweep = true,
|
||||
}
|
||||
local RANGED_ACTION_KINDS = {
|
||||
shoot_hit_scan = true,
|
||||
shoot_pellets = true,
|
||||
-- overload_charge = true,
|
||||
-- charge_ammo = true,
|
||||
}
|
||||
mod:hook_safe(CLASS.ActionHandler, "start_action",
|
||||
function(self, id, action_objects, action_name, action_params, action_settings, used_input, t, transition_type, condition_func_params, automatic_input, reset_combo_override)
|
||||
if self._unit_data_extension._player.viewport_name ~= 'player1' then
|
||||
return
|
||||
end
|
||||
|
||||
if id == "weapon_action" then
|
||||
if mod_settings.toggle_mod and mod_settings.focus_target_switch then
|
||||
local action_kind = action_settings.kind
|
||||
if mod_settings.focus_target_switch_melee and MELEE_ACTION_KINDS[action_kind] then
|
||||
focus_target_switch(true)
|
||||
elseif mod_settings.focus_target_switch_range and RANGED_ACTION_KINDS[action_kind] then
|
||||
focus_target_switch(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,324 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local context = mod.context
|
||||
local mark_context = mod.mark_context
|
||||
local TAG_NAMES = mod.TAG_NAMES
|
||||
local mod_settings = mod.settings
|
||||
local noospheric_command_breed_settings = mod.noospheric_command_breed_settings
|
||||
local DISABLING_TYPES = mod.DISABLING_TYPES
|
||||
|
||||
-- Imports
|
||||
local SpecialRulesSettings = require("scripts/settings/ability/special_rules_settings")
|
||||
local CompanionServoSkullSettings = require("scripts/settings/companion/companion_servo_skull_settings")
|
||||
local Hud = require("scripts/utilities/ui/hud")
|
||||
local Health = require("scripts/utilities/health")
|
||||
local special_rules = SpecialRulesSettings.special_rules
|
||||
local servo_skull_states = CompanionServoSkullSettings.STATES
|
||||
|
||||
-- Global Cache
|
||||
local RESOLUTION_LOOKUP = RESOLUTION_LOOKUP
|
||||
local Managers = Managers
|
||||
local callback = callback
|
||||
local get_game_object_field = GameSession.game_object_field
|
||||
local ScriptUnit_extension = ScriptUnit.extension
|
||||
|
||||
local HACK_TAG_NAME = "hacking_over_here_companion"
|
||||
local CANCEL_INTERVAL = 0.5
|
||||
|
||||
local function servo_skull_mark_callback()
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit = mod:find_target_unit()
|
||||
if not target_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_tag = smart_tag_system:unit_tag(target_unit)
|
||||
local tag_name = TAG_NAMES.SERVO_SKULL_TAG
|
||||
mod:set_manual_mark(tag_name, target_unit, target_tag)
|
||||
end
|
||||
|
||||
local function enemy_mark_callback()
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit = mod:find_target_unit()
|
||||
if not target_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_tag = smart_tag_system:unit_tag(target_unit)
|
||||
if target_tag then
|
||||
return
|
||||
end
|
||||
|
||||
local tag_name = TAG_NAMES.ENEMY_TAG
|
||||
mod:set_manual_mark(tag_name, target_unit, target_tag)
|
||||
end
|
||||
|
||||
mod.servo_skull_mark = function()
|
||||
if not context.mod_enabled or not context.game_mode_valid or context.class_name ~= "cryptic" or not context.has_servo_skull then
|
||||
return
|
||||
end
|
||||
|
||||
local companion_command_tap = context.companion_command_tap
|
||||
if companion_command_tap == "double" then
|
||||
local cb = callback(servo_skull_mark_callback)
|
||||
Managers.state.game_mode:register_physics_safe_callback(cb)
|
||||
elseif companion_command_tap == "single" then
|
||||
local cb = callback(enemy_mark_callback)
|
||||
Managers.state.game_mode:register_physics_safe_callback(cb)
|
||||
end
|
||||
end
|
||||
|
||||
local function hack_mark_callback()
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local hud_element_smart_tagging = context.hud_element_smart_tagging
|
||||
if not hud_element_smart_tagging then
|
||||
return
|
||||
end
|
||||
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
if not player_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_marker, _ = hud_element_smart_tagging:_find_world_marker_target()
|
||||
local target_unit = target_marker and target_marker.unit
|
||||
if not target_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_extension = smart_tag_system._unit_extension_data[target_unit]
|
||||
local template_name = target_extension and target_extension:_contextual_tag_template_name(player_unit, "companion_order")
|
||||
|
||||
if template_name ~= HACK_TAG_NAME then
|
||||
return
|
||||
end
|
||||
|
||||
local target_tag = smart_tag_system:unit_tag(target_unit)
|
||||
local tagger_player = target_tag and target_tag._tagger_player
|
||||
local tagger_player_unit = tagger_player and tagger_player.player_unit
|
||||
if tagger_player_unit then
|
||||
smart_tag_system:cancel_tag(target_tag._id, tagger_player_unit, true)
|
||||
end
|
||||
|
||||
smart_tag_system:set_tag(HACK_TAG_NAME, player_unit, target_unit)
|
||||
end
|
||||
|
||||
mod.hack_mark = function()
|
||||
if not context.mod_enabled or not context.game_mode_valid or context.class_name ~= "cryptic" or not context.has_servo_skull then
|
||||
return
|
||||
end
|
||||
|
||||
local cb = callback(hack_mark_callback)
|
||||
Managers.state.game_mode:register_physics_safe_callback(cb)
|
||||
end
|
||||
|
||||
function mod:is_servo_skull_hacking()
|
||||
local companion_spawner_extension = context.companion_spawner_extension
|
||||
local companion_unit = companion_spawner_extension and companion_spawner_extension:spawned_unit_lookup(special_rules.cryptic_servo_skull_hack)
|
||||
if not companion_unit then
|
||||
return false
|
||||
end
|
||||
|
||||
local game_session = Managers.state.game_session:game_session()
|
||||
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")
|
||||
return state == servo_skull_states.hacking
|
||||
end
|
||||
|
||||
function mod:is_noospheric_command_boost_breed_valid(target_unit)
|
||||
local unit_data_extension = ScriptUnit_extension(target_unit, "unit_data_system")
|
||||
local breed_data = unit_data_extension and unit_data_extension._breed
|
||||
if not breed_data then
|
||||
return false
|
||||
end
|
||||
|
||||
local breed_name = breed_data.name
|
||||
local breed_settings = noospheric_command_breed_settings[breed_name]
|
||||
if breed_settings and breed_settings.override then
|
||||
return breed_settings.toggle
|
||||
end
|
||||
|
||||
if breed_data.is_boss then
|
||||
return mod_settings.noospheric_command_boost_boss
|
||||
elseif breed_data.tags.special then
|
||||
return mod_settings.noospheric_command_boost_special
|
||||
else
|
||||
return mod_settings.noospheric_command_boost_elite
|
||||
end
|
||||
end
|
||||
|
||||
local find_hackable_target_unit = function()
|
||||
local hud_element_smart_tagging = context.hud_element_smart_tagging
|
||||
if not hud_element_smart_tagging then
|
||||
return
|
||||
end
|
||||
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
Managers.event:trigger("request_world_markers_list", callback(hud_element_smart_tagging, "_cb_world_markers_list_request"))
|
||||
local world_markers_list = hud_element_smart_tagging._world_markers_list
|
||||
local hud_scale = Hud.hud_scale()
|
||||
local selected_marker_distance = math.huge
|
||||
local selected_marker_unit
|
||||
local parent = hud_element_smart_tagging._parent
|
||||
local player = parent:player()
|
||||
local player_unit = player.player_unit
|
||||
local resolution_width, resolution_height = RESOLUTION_LOOKUP.width, RESOLUTION_LOOKUP.height
|
||||
local center_x, center_y = 0.5 * resolution_width, 0.5 * resolution_height
|
||||
local radius = resolution_height / 8 * 3
|
||||
local radius_squared = radius * radius
|
||||
|
||||
for i = 1, #world_markers_list do
|
||||
local marker = world_markers_list[i]
|
||||
local widget = marker.widget
|
||||
|
||||
if widget then
|
||||
local distance = widget.content.distance
|
||||
|
||||
if hud_element_smart_tagging:_is_marker_valid_for_tagging(player_unit, marker, distance) then
|
||||
local offset = widget.offset
|
||||
local x = offset[1] * hud_scale
|
||||
local y = offset[2] * hud_scale
|
||||
local dx = x - center_x
|
||||
local dy = y - center_y
|
||||
|
||||
if dx * dx + dy * dy <= radius_squared and distance < selected_marker_distance then
|
||||
local marker_unit = marker.unit
|
||||
local target_extension = smart_tag_system._unit_extension_data[marker_unit]
|
||||
local template_name = target_extension and target_extension:_contextual_tag_template_name(player_unit, "companion_order")
|
||||
if template_name == HACK_TAG_NAME then
|
||||
selected_marker_unit = marker_unit
|
||||
selected_marker_distance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return selected_marker_unit, selected_marker_distance
|
||||
end
|
||||
|
||||
local hack_interval = 0
|
||||
function mod:auto_hack(dt, t, fixed_frame)
|
||||
if not mod_settings.auto_hack or (mod_settings.disable_auto_hack_for_noospheric_command and context.has_noospheric_command) or context.class_name ~= "cryptic" or not context.has_servo_skull then
|
||||
return
|
||||
end
|
||||
|
||||
if hack_interval > 0 then
|
||||
hack_interval = hack_interval - dt
|
||||
return
|
||||
end
|
||||
|
||||
if mod:is_servo_skull_hacking() then
|
||||
return
|
||||
end
|
||||
|
||||
local smart_tag_system = context.smart_tag_system
|
||||
if not smart_tag_system then
|
||||
return
|
||||
end
|
||||
|
||||
local player = context.player
|
||||
local player_unit = player and player.player_unit
|
||||
if not player_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_unit, _ = find_hackable_target_unit()
|
||||
if not target_unit then
|
||||
return
|
||||
end
|
||||
|
||||
local target_tag = smart_tag_system:unit_tag(target_unit)
|
||||
local tagger_player = target_tag and target_tag._tagger_player
|
||||
local tagger_player_unit = tagger_player and tagger_player.player_unit
|
||||
if tagger_player_unit then
|
||||
smart_tag_system:cancel_tag(target_tag._id, tagger_player_unit, true)
|
||||
end
|
||||
|
||||
hack_interval = 1
|
||||
smart_tag_system:set_tag(HACK_TAG_NAME, player_unit, target_unit)
|
||||
end
|
||||
|
||||
local cancel_interval = 0
|
||||
function mod:auto_cancel_servo_skull_mark(dt, t, fixed_frame)
|
||||
if not mod_settings.servo_skull_cancel_mark or context.class_name ~= "cryptic" or not context.has_servo_skull then
|
||||
return
|
||||
end
|
||||
|
||||
if cancel_interval > 0 then
|
||||
cancel_interval = cancel_interval - dt
|
||||
return
|
||||
end
|
||||
|
||||
local disabled_character_state_component = context.disabled_character_state_component
|
||||
if disabled_character_state_component and disabled_character_state_component.is_disabled and DISABLING_TYPES[disabled_character_state_component.disabling_type] then
|
||||
return
|
||||
end
|
||||
|
||||
local tag_context = mark_context[TAG_NAMES.SERVO_SKULL_TAG]
|
||||
local marked_tag = tag_context.tag
|
||||
local marked_unit = marked_tag and marked_tag._target_unit
|
||||
if not marked_tag or not marked_unit then
|
||||
return
|
||||
end
|
||||
|
||||
if tag_context.is_manual then
|
||||
return
|
||||
end
|
||||
|
||||
local unit_data_extension = ScriptUnit_extension(marked_unit, "unit_data_system")
|
||||
local breed_data = unit_data_extension and unit_data_extension._breed
|
||||
local breed_name = breed_data and breed_data.name
|
||||
local breed_settings = noospheric_command_breed_settings[breed_name]
|
||||
local time_threshold, health_threshold
|
||||
if breed_settings and breed_settings.override then
|
||||
health_threshold = breed_settings.health_threshold or 0
|
||||
time_threshold = breed_settings.time_threshold or 0
|
||||
else
|
||||
time_threshold = mod_settings.servo_skull_cancel_mark_time_threshold
|
||||
health_threshold = mod_settings.servo_skull_cancel_mark_health_threshold
|
||||
end
|
||||
|
||||
if time_threshold > 0 then
|
||||
if mod:is_servo_skull_target_visible(marked_unit, fixed_frame, true) then
|
||||
tag_context.servo_skull_lose_sight_time = nil
|
||||
elseif not tag_context.servo_skull_lose_sight_time then
|
||||
tag_context.servo_skull_lose_sight_time = t
|
||||
end
|
||||
|
||||
if tag_context.servo_skull_lose_sight_time and t - tag_context.servo_skull_lose_sight_time > time_threshold then
|
||||
mod:print_debug("cancel servo skull mark due to time threshold")
|
||||
tag_context.canceled_units[marked_unit] = t + 0.3
|
||||
cancel_interval = CANCEL_INTERVAL
|
||||
mod:cancel_mark(marked_tag._id)
|
||||
end
|
||||
end
|
||||
|
||||
if health_threshold > 0 and tag_context.shoot_start_time then
|
||||
local health_percent = Health.current_health_percent(marked_unit)
|
||||
if health_percent < health_threshold then
|
||||
mod:print_debug("cancel servo skull mark due to health threshold, health_percent:", health_percent)
|
||||
tag_context.canceled_units[marked_unit] = t + 3
|
||||
cancel_interval = CANCEL_INTERVAL
|
||||
mod:cancel_mark(marked_tag._id)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,199 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local auto_mark_settings = mod.auto_mark_settings
|
||||
local context = mod.context
|
||||
local DEFAULT_CLASS_SETTINGS = mod.DEFAULT_CLASS_SETTINGS
|
||||
local TAG_NAMES = mod.TAG_NAMES
|
||||
|
||||
-- Imports
|
||||
local Archetypes = require("scripts/settings/archetype/archetypes")
|
||||
|
||||
-- Global Cache
|
||||
local table_clone = table.clone
|
||||
|
||||
-- Constants
|
||||
local BASE_CLASSES = {}
|
||||
for class_name, _ in pairs(Archetypes) do
|
||||
BASE_CLASSES[class_name] = true
|
||||
end
|
||||
-- Additional Class Name for Arbites and Veteran
|
||||
local ADAMANT_COMPANION = "adamant_companion"
|
||||
local CRYPTIC_SERVO_SKULL = "cryptic_servo_skull"
|
||||
local VETERAN_FOCUS_TARGET = "veteran_focus_target"
|
||||
-- Valid Class Names
|
||||
local VALID_CLASSES = {
|
||||
[ADAMANT_COMPANION] = true,
|
||||
[CRYPTIC_SERVO_SKULL] = true,
|
||||
[VETERAN_FOCUS_TARGET] = true,
|
||||
}
|
||||
for class_name, _ in pairs(Archetypes) do
|
||||
VALID_CLASSES[class_name] = true
|
||||
end
|
||||
|
||||
local ADAMANT_COMPANION_DEFAULT_CLASS_SETTINGS = table_clone(DEFAULT_CLASS_SETTINGS)
|
||||
ADAMANT_COMPANION_DEFAULT_CLASS_SETTINGS.interval = 0
|
||||
local adamant_companion_breed_priorities = ADAMANT_COMPANION_DEFAULT_CLASS_SETTINGS.breed_priorities
|
||||
adamant_companion_breed_priorities["chaos_daemonhost_passive"] = 0
|
||||
adamant_companion_breed_priorities["chaos_mutator_daemonhost_passive"] = 0
|
||||
adamant_companion_breed_priorities["chaos_daemonhost_torment_passive"] = 0
|
||||
adamant_companion_breed_priorities["chaos_ogryn_houndmaster"] = 0
|
||||
adamant_companion_breed_priorities["chaos_poxwalker_bomber"] = 0
|
||||
|
||||
local CRYPTIC_SERVO_SKULL_DEFAULT_CLASS_SETTINGS = table_clone(DEFAULT_CLASS_SETTINGS)
|
||||
CRYPTIC_SERVO_SKULL_DEFAULT_CLASS_SETTINGS.interval = 0
|
||||
local cryptic_servo_skull_breed_priorities = CRYPTIC_SERVO_SKULL_DEFAULT_CLASS_SETTINGS.breed_priorities
|
||||
cryptic_servo_skull_breed_priorities["chaos_daemonhost_passive"] = 0
|
||||
cryptic_servo_skull_breed_priorities["chaos_mutator_daemonhost_passive"] = 0
|
||||
cryptic_servo_skull_breed_priorities["chaos_daemonhost_torment_passive"] = 0
|
||||
cryptic_servo_skull_breed_priorities["chaos_poxwalker_bomber"] = 0
|
||||
|
||||
local VETERAN_FOCUS_TARGET_DEFAULT_CLASS_SETTINGS = table_clone(DEFAULT_CLASS_SETTINGS)
|
||||
VETERAN_FOCUS_TARGET_DEFAULT_CLASS_SETTINGS.interval = 0
|
||||
local veteran_focus_target_breed_priorities = VETERAN_FOCUS_TARGET_DEFAULT_CLASS_SETTINGS.breed_priorities
|
||||
-- veteran_focus_target_breed_priorities["chaos_daemonhost_passive"] = 0
|
||||
veteran_focus_target_breed_priorities["chaos_mutator_daemonhost_passive"] = 0
|
||||
|
||||
local function get_default_class_settings(class_name)
|
||||
if class_name == ADAMANT_COMPANION then
|
||||
return ADAMANT_COMPANION_DEFAULT_CLASS_SETTINGS
|
||||
elseif class_name == CRYPTIC_SERVO_SKULL then
|
||||
return CRYPTIC_SERVO_SKULL_DEFAULT_CLASS_SETTINGS
|
||||
elseif class_name == VETERAN_FOCUS_TARGET then
|
||||
return VETERAN_FOCUS_TARGET_DEFAULT_CLASS_SETTINGS
|
||||
end
|
||||
return DEFAULT_CLASS_SETTINGS
|
||||
end
|
||||
|
||||
local function init_table(dest, source)
|
||||
for key, value in pairs(source) do
|
||||
if type(value) == "table" then
|
||||
if type(dest[key]) == "table" then
|
||||
dest[key] = init_table(dest[key], value)
|
||||
else
|
||||
dest[key] = table_clone(value)
|
||||
end
|
||||
else
|
||||
if dest[key] == nil or type(dest[key]) ~= type(value) then
|
||||
dest[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for key, _ in pairs(dest) do
|
||||
if source[key] == nil then
|
||||
dest[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return dest
|
||||
end
|
||||
|
||||
-- Init Auto Mark Settings
|
||||
function mod:init_auto_mark_settings()
|
||||
for class_name, _ in pairs(VALID_CLASSES) do
|
||||
if auto_mark_settings[class_name] == nil then
|
||||
auto_mark_settings[class_name] = {}
|
||||
end
|
||||
local class_settings = auto_mark_settings[class_name]
|
||||
init_table(class_settings, get_default_class_settings(class_name))
|
||||
end
|
||||
|
||||
local cyber_mastiff_settings = auto_mark_settings[ADAMANT_COMPANION]
|
||||
local cyber_mastiff_breed_priorities = cyber_mastiff_settings.breed_priorities
|
||||
cyber_mastiff_breed_priorities["chaos_poxwalker_bomber"] = 0
|
||||
local servo_skull_settings = auto_mark_settings[CRYPTIC_SERVO_SKULL]
|
||||
local servo_skull_breed_priorities = servo_skull_settings.breed_priorities
|
||||
servo_skull_breed_priorities["chaos_poxwalker_bomber"] = 0
|
||||
|
||||
for class_name, _ in pairs(auto_mark_settings) do
|
||||
if not VALID_CLASSES[class_name] then
|
||||
auto_mark_settings[class_name] = nil
|
||||
end
|
||||
end
|
||||
|
||||
mod:set("auto_mark_settings", auto_mark_settings, false)
|
||||
end
|
||||
|
||||
-- Reset Auto Mark Settings to Default
|
||||
function mod:reset_auto_mark_settings()
|
||||
for class_name, _ in pairs(VALID_CLASSES) do
|
||||
auto_mark_settings[class_name] = table_clone(get_default_class_settings(class_name))
|
||||
end
|
||||
|
||||
mod:set("auto_mark_settings", auto_mark_settings, false)
|
||||
end
|
||||
|
||||
function mod:reset_class_settings(class_name)
|
||||
if not VALID_CLASSES[class_name] then
|
||||
return
|
||||
end
|
||||
|
||||
auto_mark_settings[class_name] = table_clone(get_default_class_settings(class_name))
|
||||
mod:set("auto_mark_settings", auto_mark_settings, false)
|
||||
end
|
||||
|
||||
-- Apply Settings to All Classes
|
||||
function mod:apply_to_all_classes(class_name)
|
||||
for other_class_name, _ in pairs(VALID_CLASSES) do
|
||||
if other_class_name ~= class_name then
|
||||
auto_mark_settings[other_class_name] = table_clone(auto_mark_settings[class_name])
|
||||
end
|
||||
end
|
||||
mod:set("auto_mark_settings", auto_mark_settings, false)
|
||||
end
|
||||
|
||||
-- Apply Settings to Normal Tag
|
||||
function mod:apply_to_normal_tag(class_name)
|
||||
for other_class_name, _ in pairs(BASE_CLASSES) do
|
||||
if other_class_name ~= class_name then
|
||||
auto_mark_settings[other_class_name] = table_clone(auto_mark_settings[class_name])
|
||||
end
|
||||
end
|
||||
mod:set("auto_mark_settings", auto_mark_settings, false)
|
||||
end
|
||||
|
||||
-- Set Menu for Display
|
||||
function mod:set_menu_class_settings(class_name)
|
||||
if not VALID_CLASSES[class_name] then
|
||||
return
|
||||
end
|
||||
|
||||
mod:set("class_selection", class_name, false)
|
||||
local class_settings = auto_mark_settings[class_name]
|
||||
for setting_name, default_setting in pairs(get_default_class_settings(class_name)) do
|
||||
if type(default_setting) == "table" then
|
||||
local breed_priorities = class_settings[setting_name]
|
||||
for breed_name, _ in pairs(default_setting) do
|
||||
mod:set(breed_name, breed_priorities[breed_name], false)
|
||||
end
|
||||
else
|
||||
mod:set(setting_name, class_settings[setting_name], false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get Class Settings by Tag Name
|
||||
function mod:get_class_settings(tag_name)
|
||||
if tag_name == TAG_NAMES.ENEMY_TAG then
|
||||
return auto_mark_settings[context.class_name]
|
||||
elseif tag_name == TAG_NAMES.VETERAN_TAG then
|
||||
return auto_mark_settings[VETERAN_FOCUS_TARGET]
|
||||
elseif tag_name == TAG_NAMES.COMPANION_TAG then
|
||||
return auto_mark_settings[ADAMANT_COMPANION]
|
||||
elseif tag_name == TAG_NAMES.SERVO_SKULL_TAG then
|
||||
return auto_mark_settings[CRYPTIC_SERVO_SKULL]
|
||||
end
|
||||
end
|
||||
|
||||
-- Get Class Name
|
||||
function mod:get_menu_class_name()
|
||||
if context.class_name == "adamant" and context.has_companion then
|
||||
return ADAMANT_COMPANION
|
||||
elseif context.class_name == "veteran" and context.has_focus_target then
|
||||
return VETERAN_FOCUS_TARGET
|
||||
elseif context.class_name == "cryptic" and context.has_servo_skull then
|
||||
return CRYPTIC_SERVO_SKULL
|
||||
else
|
||||
return context.class_name or "adamant"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local companion_cancel_mark_breed_settings = mod.companion_cancel_mark_breed_settings
|
||||
|
||||
local CYBER_MASTIFF_BREED_SETTING_IDS = {
|
||||
companion_cancel_mark_breed_override = true,
|
||||
companion_range_limitation_breed = true,
|
||||
companion_mark_max_distance_breed = true,
|
||||
companion_mark_sticky_targeting_breed = true,
|
||||
companion_cancel_mark_breed_health_threshold = true,
|
||||
companion_cancel_mark_breed_time_threshold = true,
|
||||
companion_cancel_mark_breed_distance_threshold = true,
|
||||
}
|
||||
|
||||
function mod:is_cyber_mastiff_breed_setting_id(setting_id)
|
||||
return CYBER_MASTIFF_BREED_SETTING_IDS[setting_id]
|
||||
end
|
||||
|
||||
function mod:set_menu_cyber_mastiff_breed_settings(breed_name)
|
||||
local breed_settings = companion_cancel_mark_breed_settings[breed_name]
|
||||
mod:set("companion_cancel_mark_breed_override", breed_settings and breed_settings.override or false, false)
|
||||
mod:set("companion_range_limitation_breed", breed_settings and breed_settings.range_limitation or 0, false)
|
||||
mod:set("companion_mark_max_distance_breed", breed_settings and breed_settings.max_distance or 0, false)
|
||||
mod:set("companion_mark_sticky_targeting_breed", breed_settings and breed_settings.sticky_targeting or false, false)
|
||||
mod:set("companion_cancel_mark_breed_health_threshold", (breed_settings and breed_settings.health_threshold or 0) * 100, false)
|
||||
mod:set("companion_cancel_mark_breed_time_threshold", breed_settings and breed_settings.time_threshold or 0, false)
|
||||
mod:set("companion_cancel_mark_breed_distance_threshold", breed_settings and breed_settings.distance_threshold or 0, false)
|
||||
end
|
||||
|
||||
function mod:set_cyber_mastiff_breed_setting(breed_name, setting_id, value)
|
||||
if companion_cancel_mark_breed_settings[breed_name] == nil then
|
||||
companion_cancel_mark_breed_settings[breed_name] = { override = false, range_limitation = 0, max_distance = 0, sticky_targeting = false, health_threshold = 0, time_threshold = 0, distance_threshold = 0 }
|
||||
end
|
||||
if setting_id == "companion_cancel_mark_breed_override" then
|
||||
companion_cancel_mark_breed_settings[breed_name].override = value
|
||||
elseif setting_id == "companion_range_limitation_breed" then
|
||||
companion_cancel_mark_breed_settings[breed_name].range_limitation = value
|
||||
elseif setting_id == "companion_mark_max_distance_breed" then
|
||||
companion_cancel_mark_breed_settings[breed_name].max_distance = value
|
||||
elseif setting_id == "companion_mark_sticky_targeting_breed" then
|
||||
companion_cancel_mark_breed_settings[breed_name].sticky_targeting = value
|
||||
elseif setting_id == "companion_cancel_mark_breed_health_threshold" then
|
||||
companion_cancel_mark_breed_settings[breed_name].health_threshold = value / 100
|
||||
elseif setting_id == "companion_cancel_mark_breed_time_threshold" then
|
||||
companion_cancel_mark_breed_settings[breed_name].time_threshold = value
|
||||
elseif setting_id == "companion_cancel_mark_breed_distance_threshold" then
|
||||
companion_cancel_mark_breed_settings[breed_name].distance_threshold = value
|
||||
end
|
||||
mod:set("companion_cancel_mark_breed_settings", companion_cancel_mark_breed_settings, false)
|
||||
end
|
||||
|
||||
mod.reset_all_cyber_mastiff_breed_settings = function()
|
||||
table.clear(companion_cancel_mark_breed_settings)
|
||||
mod:set("companion_cancel_mark_breed_settings", companion_cancel_mark_breed_settings, false)
|
||||
mod:set("companion_cancel_mark_breed_name", mod:get("companion_cancel_mark_breed_name"), true)
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local noospheric_command_breed_settings = mod.noospheric_command_breed_settings
|
||||
|
||||
local SERVO_SKULL_BREED_SETTING_IDS = {
|
||||
noospheric_command_boost_breed_override = true,
|
||||
servo_skull_range_limitation_breed = true,
|
||||
noospheric_command_boost_breed_toggle = true,
|
||||
capacitance_retention_breed_threshold = true,
|
||||
servo_skull_mark_sticky_targeting_breed = true,
|
||||
servo_skull_cancel_mark_breed_time_threshold = true,
|
||||
servo_skull_cancel_mark_breed_health_threshold = true,
|
||||
}
|
||||
|
||||
function mod:is_servo_skull_breed_setting_id(setting_id)
|
||||
return SERVO_SKULL_BREED_SETTING_IDS[setting_id]
|
||||
end
|
||||
|
||||
function mod:set_menu_servo_skull_breed_settings(breed_name)
|
||||
local breed_settings = noospheric_command_breed_settings[breed_name]
|
||||
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("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("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_health_threshold", (breed_settings and breed_settings.health_threshold or 0) * 100, false)
|
||||
end
|
||||
|
||||
function mod:set_servo_skull_breed_setting(breed_name, setting_id, value)
|
||||
if noospheric_command_breed_settings[breed_name] == nil then
|
||||
noospheric_command_breed_settings[breed_name] = { override = false, range_limitation = 0, toggle = false, threshold = 0, threshold_negative_zero = false, sticky_targeting = false, time_threshold = 0, health_threshold = 0 }
|
||||
end
|
||||
if setting_id == "noospheric_command_boost_breed_override" then
|
||||
noospheric_command_breed_settings[breed_name].override = value
|
||||
elseif setting_id == "servo_skull_range_limitation_breed" then
|
||||
noospheric_command_breed_settings[breed_name].range_limitation = value
|
||||
elseif setting_id == "noospheric_command_boost_breed_toggle" then
|
||||
noospheric_command_breed_settings[breed_name].toggle = value
|
||||
elseif setting_id == "capacitance_retention_breed_threshold" then
|
||||
noospheric_command_breed_settings[breed_name].threshold = value / 100
|
||||
if value == -0 and 1 / value < 0 then
|
||||
noospheric_command_breed_settings[breed_name].threshold_negative_zero = true
|
||||
else
|
||||
noospheric_command_breed_settings[breed_name].threshold_negative_zero = false
|
||||
end
|
||||
elseif setting_id == "servo_skull_mark_sticky_targeting_breed" then
|
||||
noospheric_command_breed_settings[breed_name].sticky_targeting = value
|
||||
elseif setting_id == "servo_skull_cancel_mark_breed_time_threshold" then
|
||||
noospheric_command_breed_settings[breed_name].time_threshold = value
|
||||
elseif setting_id == "servo_skull_cancel_mark_breed_health_threshold" then
|
||||
noospheric_command_breed_settings[breed_name].health_threshold = value / 100
|
||||
end
|
||||
mod:set("noospheric_command_breed_settings", noospheric_command_breed_settings, false)
|
||||
end
|
||||
|
||||
mod.reset_all_servo_skull_breed_settings = function()
|
||||
table.clear(noospheric_command_breed_settings)
|
||||
mod:set("noospheric_command_breed_settings", noospheric_command_breed_settings, false)
|
||||
mod:set("noospheric_command_boost_breed_name", mod:get("noospheric_command_boost_breed_name"), true)
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local context = mod.context
|
||||
|
||||
-- Global Cache
|
||||
local HEALTH_ALIVE = HEALTH_ALIVE
|
||||
|
||||
local SMART_TARGETING_TEMPLATE = {
|
||||
precision_target = {
|
||||
max_range = 100,
|
||||
min_range = 1,
|
||||
smart_tagging = true,
|
||||
},
|
||||
}
|
||||
|
||||
local SMART_TARGETING_PRECISION_TEMPLATE = {
|
||||
only_direct_hit = true,
|
||||
precision_target = {
|
||||
max_range = 100,
|
||||
min_range = 1,
|
||||
smart_tagging = true,
|
||||
},
|
||||
}
|
||||
|
||||
-- Find Target Unit For Mark System
|
||||
function mod:find_target_unit(only_direct_hit)
|
||||
local smart_targeting_extension = context.smart_targeting_extension
|
||||
if not smart_targeting_extension then
|
||||
return nil
|
||||
end
|
||||
|
||||
local ray_origin, forward, right, up = smart_targeting_extension:_targeting_parameters()
|
||||
smart_targeting_extension._precision_target_aim_assist:update_precision_target(
|
||||
smart_targeting_extension._unit,
|
||||
only_direct_hit and SMART_TARGETING_PRECISION_TEMPLATE or SMART_TARGETING_TEMPLATE,
|
||||
ray_origin, forward, right, up,
|
||||
smart_targeting_extension._smart_tag_targeting_data,
|
||||
smart_targeting_extension._latest_fixed_frame,
|
||||
smart_targeting_extension._visibility_cache,
|
||||
smart_targeting_extension._visibility_check_frame
|
||||
)
|
||||
local targeting_data = smart_targeting_extension:smart_tag_targeting_data()
|
||||
local target_unit = targeting_data and targeting_data.unit
|
||||
return HEALTH_ALIVE[target_unit] and target_unit
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
---@class AutoMarkMod:DMFMod
|
||||
local mod = get_mod("AutoMark")
|
||||
local mod_settings = mod.settings
|
||||
local FixedFrame = require("scripts/utilities/fixed_frame")
|
||||
|
||||
-- Global Cache
|
||||
local Managers = Managers
|
||||
|
||||
-- Debug Print
|
||||
function mod:print_debug(...)
|
||||
if mod_settings.debug_mode then
|
||||
local n = select("#", ...)
|
||||
if n == 0 then
|
||||
return
|
||||
end
|
||||
local result = tostring(select(1, ...))
|
||||
for i = 2, n do
|
||||
local value = select(i, ...)
|
||||
result = result .. " " .. tostring(value)
|
||||
end
|
||||
mod:echo(result)
|
||||
end
|
||||
end
|
||||
|
||||
-- Time for Now
|
||||
function mod:get_main_time()
|
||||
return Managers.time:time("main")
|
||||
end
|
||||
|
||||
function mod:get_gameplay_time()
|
||||
return Managers.time:time("gameplay")
|
||||
end
|
||||
|
||||
function mod:get_latest_fixed_time()
|
||||
return FixedFrame.get_latest_fixed_time()
|
||||
end
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install AutoMark (fork) into the Darktide mods folder.
|
||||
set -euo pipefail
|
||||
|
||||
DEFAULT_GAMEDIR="/mnt/AetherVault/games/SteamLibrary/steamapps/common/Warhammer 40,000 DARKTIDE"
|
||||
GAMEDIR="${GAMEDIR:-$DEFAULT_GAMEDIR}"
|
||||
MODS="$GAMEDIR/mods"
|
||||
MOD="AutoMark"
|
||||
|
||||
[ -d "$MODS" ] || { echo "no mods folder at: $MODS (set GAMEDIR=...)" >&2; exit 1; }
|
||||
[ -d "$MODS/dmf" ] || echo "warning: DMF not found in $MODS — the mod needs it" >&2
|
||||
|
||||
rsync -a --delete "$PWD/$MOD/" "$MODS/$MOD/"
|
||||
|
||||
ORDER="$MODS/mod_load_order.txt"
|
||||
if ! grep -qx "$MOD" "$ORDER" 2>/dev/null; then
|
||||
echo "$MOD" >>"$ORDER"
|
||||
echo "added $MOD to mod_load_order.txt"
|
||||
fi
|
||||
|
||||
echo "installed -> $MODS/$MOD (takes effect on next game start)"
|
||||
Reference in New Issue
Block a user