--------------------CUSTOMIZATION SECTION-------------------- --#region local config = { font = { family = "Consolas", size = 13, bold = true, italic = false }, small_monster_UI = { enabled = true, settings = { spacing = 110, orientation = "Horizontal" }, dynamic_positioning = { enabled = true, viewport_offset = { x = -50, y = -100 }, max_distance = 15000, opacity_falloff = true }, sorting = { type = "Normal", reversed_order = false, }, position = { x = 0, y = 0, anchor = "Top-Left" }, monster_name_label = { visibility = true, text = "%s", offset = { x = 5, y = 0 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_label = { visibility = false, text = "HP:", offset = { x = -25, y = 12 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_value_label = { visibility = true, text = "%.0f/%.0f", -- current_health/max_health offset = { x = 50, y = 25 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_percentage_label = { visibility = false, text = "%5.1f%%", offset = { x = 55, y = 0 }, color = 0xFFFFFFFF, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_bar = { visibility = true, offset = { x = 0, y = 17 }, size = { width = 100, height = 7 }, colors = { foreground = 0xB9B2ff7E, background = 0xB9000000, capture_health = 0xB9CCCC33 }, } }, large_monster_UI = { enabled = true, settings = { spacing = 220, orientation = "Horizontal" }, dynamic_positioning = { enabled = false, viewport_offset = { x = -100, y = -200 }, max_distance = 15000, opacity_falloff = true }, sorting = { type = "Normal", reversed_order = false, }, position = { x = 525, y = 44, anchor = "Bottom-Left" }, monster_name_label = { visibility = true, text = "%s", include = { monster_name = true, crown = true, size = true, silver_crown_threshold = false, gold_crown_threshold = false }, offset = { x = 5, y = 0 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_label = { visibility = false, text = "HP:", offset = { x = -25, y = 19 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_value_label = { visibility = true, text = "%.0f/%.0f", -- current_health/max_health offset = { x = 5, y = 19 }, color = 0xFFFFFFFF, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_percentage_label = { visibility = true, text = "%5.1f%%", offset = { x = 150, y = 19 }, color = 0xFFFFFFFF, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, health_bar = { visibility = true, offset = { x = 0, y = 17 }, size = { width = 200, height = 20 }, colors = { foreground = 0xB9B2ff7E, background = 0xB9000000, capture_health = 0xB9CCCC33 }, } }, time_UI = { enabled = true, position = { x = 65, y = 189, anchor = "Top-Left" }, time_label = { visibility = true, text = "%02d:%06.3f", offset = { x = 0, y = 0 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } } }, damage_meter_UI = { enabled = true, tracked_monster_types = { small_monsters = true, large_monsters = true }, tracked_damage_types = { player_damage = true, bomb_damage = true, kunai_damage = true, installation_damage = true, -- hunting_installations like ballista, cannon, etc. otomo_damage = true, monster_damage = true }, -- note that installations during narwa fight are counted as monster damage settings = { spacing = 24, orientation = "Vertical", -- "Vertical" or "Horizontal" hide_module_if_total_damage_is_zero = false, hide_player_if_player_damage_is_zero = false, total_damage_offset_is_relative = true, highlighted_bar = "Me", damage_bar_relative_to = "Top Damage", -- "total damage" or "top damage" my_damage_bar_location = "First", --"normal" or "first" or "last" }, sorting = { type = "Damage", -- "normal" or "damage" reversed_order = false, }, position = { x = 525, y = 225, --Possible values: "Top-Left", "Top-Right", "Bottom-Left", "Bottom-Right" anchor = "Bottom-Left" }, player_name_label = { visibility = true, include = { myself = { hunter_rank = true, word_player = false, player_id = false, player_name = true }, others = { hunter_rank = true, word_player = false, player_id = false, player_name = true } }, text = "%s", offset = { x = 5, y = 0 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, damage_value_label = { visibility = true, text = "%.0f", offset = { x = 145, y = 0 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, damage_percentage_label = { visibility = true, text = "%5.1f%%", offset = { x = 205, y = 0 }, color = 0xFFCCF4E1, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, total_damage_label = { visibility = true, text = "Total Damage", offset = { x = 5, y = 0 }, color = 0xFFFF7373, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, total_damage_value_label = { visibility = true, text = "%.0f", offset = { x = 145, y = 0 }, color = 0xFFFF7373, shadow = { visibility = true, offset = { x = 1, y = 1 }, color = 0xFF000000 } }, damage_bar = { visibility = true, offset = { x = 0, y = 17 }, size = { width = 250, height = 5 }, colors = { foreground = 0xD2CCA3F4, background = 0xB9000000 }, }, highlighted_damage_bar = { visibility = true, offset = { x = 0, y = 17 }, size = { width = 250, height = 5 }, colors = { foreground = 0xD2FFCD59, background = 0xB9000000 }, } } }; --#endregion ----------------------CUSTOMIZATION END---------------------- --------------------FUNCTION DEFINITIONS--------------------- --#region local init; local init_singletons; local init_scene_manager; local init_message_manager; local init_enemy_manager; local init_lobby_manager; local init_progress_manager; local init_quest_manager; local customization_ui; local save_config; local load_config; local get_window_size; local calculate_screen_coordinates; local table_find_index; local draw_label; local draw_bar; local old_draw_label; local old_draw_bar; local update_monster; local small_monster_data; local large_monster_data; local quest_time; local init_player; local merge_damage; local get_player; local update_player; local damage_meter; --#endregion --------------------FUNCTION DEFINITIONS--------------------- --------------------VARIABLE DEFINITIONS--------------------- --#region local config_file_name; local font; local fonts = {}; local selected_font_index; local is_customization_window_opened; local status; local x; local screen_width; local screen_height; local scene_view; local quest_status; local large_monsters; local small_monsters; local players; local total; local is_quest_online; local last_displayed_players; local myself_player_id; --Singletons local scene_manager; local message_manager; local enemy_manager; local lobby_manager; local progress_manager; local quest_manager; --#endregion --------------------VARIABLE DEFINITIONS--------------------- ----------------------CONFIG LOAD/SAVE----------------------- --#region load_config = function() local loaded_config = json.load_file(config_file_name); if loaded_config ~= nil then log.info('[MHR Overlay] config.json loaded successfully'); config = loaded_config; end end save_config = function () -- save current config to disk, replacing any existing file local success = json.dump_file(config_file_name, config); if success then log.info('[MHR Overlay] config.json saved successfully'); else log.error('[MHR Overlay] Failed to save config.json'); end end --#endregion ----------------------CONFIG LOAD/SAVE----------------------- ----------------------------INIT----------------------------- --#region config_file_name = 'MHR Overlay/config.json'; load_config(); init = function() init_singletons(); status = "OK"; x = ""; quest_status = 0; if quest_manager ~= nil then local _quest_status = quest_manager:call("getStatus"); if _quest_status == nil then status = "No quest status"; else quest_status = _quest_status; end end screen_width = 0; screen_height = 0; if scene_manager ~= nil then scene_view = sdk.call_native_func(scene_manager, sdk.find_type_definition("via.SceneManager"), "get_MainView"); if scene_view == nil then log.error("[MHR Overlay] No main view"); return false; else get_window_size(); end end large_monsters = {}; small_monsters = {}; players = {}; total = init_player(0, "Total", 0); is_quest_online = false; last_displayed_players = {}; myself_player_id = 0; log.info("[MHR Overlay] loaded"); orientation_types = {"Horizontal", "Vertical"}; monster_UI_orientation_index = table_find_index(orientation_types, config.large_monster_UI.settings.orientation, false); monster_UI_sort_types = {"Normal", "Health", "Health Percentage"}; monster_UI_sort_type_index = table_find_index(monster_UI_sort_types, config.large_monster_UI.sorting.type, false); damage_meter_UI_orientation_index = table_find_index(orientation_types, config.damage_meter_UI.settings.orientation, false); damage_meter_UI_highlighted_bar_types = {"Me", "Top Damage", "None"}; damage_meter_UI_highlighted_bar_index = table_find_index(damage_meter_UI_highlighted_bar_types, config.damage_meter_UI.settings.highlighted_bar, false); damage_meter_UI_damage_bar_relative_types = {"Total Damage", "Top Damage"}; damage_meter_UI_damage_bar_relative_index = table_find_index(damage_meter_UI_damage_bar_relative_types, config.damage_meter_UI.settings.damage_bar_relative_to, false); damage_meter_UI_my_damage_bar_location_types = {"Normal", "First", "Last"}; damage_meter_UI_my_damage_bar_location_index = table_find_index(damage_meter_UI_my_damage_bar_location_types, config.damage_meter_UI.settings.my_damage_bar_location, false); damage_meter_UI_sort_types = {"Normal", "Damage"}; damage_meter_UI_sort_type_index = table_find_index(damage_meter_UI_sort_types, config.damage_meter_UI.sorting.type, false); is_customization_window_opened = false; fonts = {"Arial", "Arial Black", "Bahnschrift", "Calibri", "Cambria", "Cambria Math", "Candara", "Comic Sans MS", "Consolas", "Constantia", "Corbel", "Courier New", "Ebrima", "Franklin Gothic Medium", "Gabriola", "Gadugi", "Georgia", "HoloLens MDL2 Assets", "Impact", "Ink Free", "Javanese Text", "Leelawadee UI", "Lucida Console", "Lucida Sans Unicode", "Malgun Gothic", "Marlett", "Microsoft Himalaya", "Microsoft JhengHei", "Microsoft New Tai Lue", "Microsoft PhagsPa", "Microsoft Sans Serif", "Microsoft Tai Le", "Microsoft YaHei", "Microsoft Yi Baiti", "MingLiU-ExtB", "Mongolian Baiti", "MS Gothic", "MV Boli", "Myanmar Text", "Nirmala UI", "Palatino Linotype", "Segoe MDL2 Assets", "Segoe Print", "Segoe Script", "Segoe UI", "Segoe UI Historic", "Segoe UI Emoji", "Segoe UI Symbol", "SimSun", "Sitka", "Sylfaen", "Symbol", "Tahoma", "Times New Roman", "Trebuchet MS", "Verdana", "Webdings", "Wingdings", "Yu Gothic"}; selected_font_index = table_find_index(fonts, config.font.family, false); return true; end init_singletons = function() init_scene_manager(); init_message_manager(); init_enemy_manager(); init_lobby_manager() init_progress_manager(); init_quest_manager(); end init_scene_manager = function() if scene_manager ~= nil then return; end scene_manager = sdk.get_native_singleton("via.SceneManager"); if scene_manager == nil then log.error("[MHR Overlay] No scene manager"); end end init_message_manager = function() if message_manager ~= nil then return; end message_manager = sdk.get_managed_singleton("snow.gui.MessageManager"); if message_manager == nil then log.error("[MHR Overlay] No message manager"); end end init_enemy_manager = function() if enemy_manager ~= nil then return; end enemy_manager = sdk.get_managed_singleton("snow.enemy.EnemyManager"); if enemy_manager == nil then log.error("[MHR Overlay] No enemy manager"); end end init_lobby_manager = function() if lobby_manager ~= nil then return; end lobby_manager = sdk.get_managed_singleton("snow.LobbyManager"); if lobby_manager == nil then log.error("[MHR Overlay] No lobby manager"); return false; end end init_progress_manager = function() if progress_manager ~= nil then return; end progress_manager = sdk.get_managed_singleton("snow.progress.ProgressManager"); if progress_manager == nil then log.error("[MHR Overlay] No progress manager"); return false; end end init_quest_manager = function() if quest_manager ~= nil then return; end quest_manager = sdk.get_managed_singleton("snow.QuestManager"); if quest_manager == nil then log.error("[MHR Overlay] No quest manager"); end end --#endregion ----------------------------INIT----------------------------- --------------------------D2D--------------------------- --#region d2d.register(function() font = d2d.create_font(config.font.family, config.font.size, config.font.bold, config.font.italic); end, function() status = "OK"; get_window_size(); init_singletons(); if config.small_monster_UI.enabled then small_monster_data(); end if config.large_monster_UI.enabled then large_monster_data(); end if config.time_UI.enabled then quest_time(); end if config.damage_meter_UI.enabled then damage_meter(); end --d2d.text(font, "x: " .. tostring(x), 450, 50, 0xFFFFFFFF); end) --#endregion --------------------------D2D--------------------------- ----------------------CUSTOMIZATION UI----------------------- --#region customization_ui = function() is_customization_window_opened = imgui.begin_window("MHR Overlay", is_customization_window_opened, 0x10120); if not is_customization_window_opened then return; end local config_changed = false; local changed; local status_string = tostring(status); imgui.text("Status: " .. status_string); if imgui.tree_node("Font") then imgui.text("Any changes to the font require script reload!"); changed, selected_font_index = imgui.combo("Family", selected_font_index, fonts); config_changed = config_changed or changed; if changed then config.font.family = fonts[selected_font_index]; end changed, config.font.size = imgui.slider_int("Size", config.font.size, 1, 100); config_changed = config_changed or changed; changed, config.font.bold = imgui.checkbox("Bold", config.font.bold); config_changed = config_changed or changed; changed, config.font.italic = imgui.checkbox("Italic", config.font.italic); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Modules") then changed, config.large_monster_UI.enabled = imgui.checkbox("Monster UI", config.large_monster_UI.enabled); config_changed = config_changed or changed; imgui.same_line(); changed, config.time_UI.enabled = imgui.checkbox("Time UI", config.time_UI.enabled); config_changed = config_changed or changed; imgui.same_line(); changed, config.damage_meter_UI.enabled = imgui.checkbox("Damage Meter UI", config.damage_meter_UI.enabled); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Small Monster UI") then changed, config.small_monster_UI.enabled = imgui.checkbox("Enabled", config.small_monster_UI.enabled); config_changed = config_changed or changed; if imgui.tree_node("Settings") then changed, config.small_monster_UI.settings.spacing = imgui.drag_float("Spacing", config.small_monster_UI.settings.spacing, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, monster_UI_orientation_index = imgui.combo("Orientation", monster_UI_orientation_index, orientation_types); config_changed = config_changed or changed; if changed then config.small_monster_UI.settings.orientation = orientation_types[monster_UI_orientation_index]; end imgui.tree_pop(); end if imgui.tree_node("Dynamic Positioning") then changed, config.small_monster_UI.dynamic_positioning.enabled = imgui.checkbox("Enabled", config.small_monster_UI.dynamic_positioning.enabled); config_changed = config_changed or changed; if imgui.tree_node("Viewport Offset") then changed, config.small_monster_UI.dynamic_positioning.viewport_offset.x = imgui.drag_float("X", config.small_monster_UI.dynamic_positioning.viewport_offset.x, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.dynamic_positioning.viewport_offset.y = imgui.drag_float("Y", config.small_monster_UI.dynamic_positioning.viewport_offset.y, 0.1, 0, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Position") then changed, config.small_monster_UI.position.x = imgui.drag_float("X", config.small_monster_UI.position.x, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.position.y = imgui.drag_float("Y", config.small_monster_UI.position.y, 0.1, 0, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Sorting") then changed, monster_UI_sort_type_index = imgui.combo("Type", monster_UI_sort_type_index, monster_UI_sort_types); config_changed = config_changed or changed; if changed then config.small_monster_UI.sorting.type = monster_UI_sort_types[monster_UI_sort_type_index]; end changed, config.small_monster_UI.reversed_order = imgui.checkbox("Reversed Order", config.small_monster_UI.reversed_order); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Monster Name Label") then changed, config.small_monster_UI.monster_name_label.visibility = imgui.checkbox("Visible", config.small_monster_UI.monster_name_label.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.small_monster_UI.monster_name_label.offset.x = imgui.drag_float("X", config.small_monster_UI.monster_name_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.monster_name_label.offset.y = imgui.drag_float("Y", config.small_monster_UI.monster_name_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.small_monster_UI.monster_name_label.shadow.visibility = imgui.checkbox("Enable", config.small_monster_UI.monster_name_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.small_monster_UI.monster_name_label.shadow.offset.x = imgui.drag_float("X", config.small_monster_UI.monster_name_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.monster_name_label.shadow.offset.y = imgui.drag_float("Y", config.small_monster_UI.monster_name_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Label") then changed, config.small_monster_UI.health_label.visibility = imgui.checkbox("Visible", config.small_monster_UI.health_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_label.offset.x = imgui.drag_float("X", config.small_monster_UI.health_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_label.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.small_monster_UI.health_label.shadow.visibility = imgui.checkbox("Enable", config.small_monster_UI.health_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_label.shadow.offset.x = imgui.drag_float("X", config.small_monster_UI.health_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_label.shadow.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_label.shadow.offset.y, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Value Label") then changed, config.small_monster_UI.health_value_label.visibility = imgui.checkbox("Visible", config.small_monster_UI.health_value_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_value_label.offset.x = imgui.drag_float("X", config.small_monster_UI.health_value_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_value_label.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_value_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.small_monster_UI.health_value_label.shadow.visibility = imgui.checkbox("Enable", config.small_monster_UI.health_value_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_value_label.shadow.offset.x = imgui.drag_float("X", config.small_monster_UI.health_value_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_value_label.shadow.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_value_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Percentage Label") then changed, config.small_monster_UI.health_percentage_label.visibility = imgui.checkbox("Visible", config.small_monster_UI.health_percentage_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_percentage_label.offset.x = imgui.drag_float("X", config.small_monster_UI.health_percentage_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_percentage_label.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_percentage_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.small_monster_UI.health_percentage_label.shadow.visibility = imgui.checkbox("Enable", config.small_monster_UI.health_percentage_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_percentage_label.shadow.offset.x = imgui.drag_float("X", config.small_monster_UI.health_percentage_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_percentage_label.shadow.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_percentage_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Bar") then changed, config.small_monster_UI.health_bar.visibility = imgui.checkbox("Visible", config.small_monster_UI.health_bar.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.small_monster_UI.health_bar.offset.x = imgui.drag_float("X", config.small_monster_UI.health_bar.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_bar.offset.y = imgui.drag_float("Y", config.small_monster_UI.health_bar.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Size") then changed, config.small_monster_UI.health_bar.size.width = imgui.drag_float("Width", config.small_monster_UI.health_bar.size.width, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.small_monster_UI.health_bar.size.height = imgui.drag_float("Height", config.small_monster_UI.health_bar.size.height, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Colors") then -- color pickers? imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Large Monster UI") then changed, config.large_monster_UI.enabled = imgui.checkbox("Enabled", config.large_monster_UI.enabled); config_changed = config_changed or changed; if imgui.tree_node("Settings") then changed, config.large_monster_UI.settings.spacing = imgui.drag_float("Spacing", config.large_monster_UI.settings.spacing, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, monster_UI_orientation_index = imgui.combo("Orientation", monster_UI_orientation_index, orientation_types); config_changed = config_changed or changed; if changed then config.large_monster_UI.settings.orientation = orientation_types[monster_UI_orientation_index]; end imgui.tree_pop(); end if imgui.tree_node("Dynamic Positioning") then changed, config.large_monster_UI.dynamic_positioning.enabled = imgui.checkbox("Enabled", config.large_monster_UI.dynamic_positioning.enabled); config_changed = config_changed or changed; if imgui.tree_node("Viewport Offset") then changed, config.large_monster_UI.dynamic_positioning.viewport_offset.x = imgui.drag_float("X", config.large_monster_UI.dynamic_positioning.viewport_offset.x, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.dynamic_positioning.viewport_offset.y = imgui.drag_float("Y", config.large_monster_UI.dynamic_positioning.viewport_offset.y, 0.1, 0, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Position") then changed, config.large_monster_UI.position.x = imgui.drag_float("X", config.large_monster_UI.position.x, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.position.y = imgui.drag_float("Y", config.large_monster_UI.position.y, 0.1, 0, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Sorting") then changed, monster_UI_sort_type_index = imgui.combo("Type", monster_UI_sort_type_index, monster_UI_sort_types); config_changed = config_changed or changed; if changed then config.large_monster_UI.sorting.type = monster_UI_sort_types[monster_UI_sort_type_index]; end changed, config.large_monster_UI.reversed_order = imgui.checkbox("Reversed Order", config.large_monster_UI.reversed_order); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Monster Name Label") then changed, config.large_monster_UI.monster_name_label.visibility = imgui.checkbox("Visible", config.large_monster_UI.monster_name_label.visibility); config_changed = config_changed or changed; if imgui.tree_node("Include") then changed, config.large_monster_UI.monster_name_label.include.monster_name = imgui.checkbox("Monster Name", config.large_monster_UI.monster_name_label.include.monster_name); config_changed = config_changed or changed; changed, config.large_monster_UI.monster_name_label.include.crown = imgui.checkbox("Crown", config.large_monster_UI.monster_name_label.include.crown); config_changed = config_changed or changed; changed, config.large_monster_UI.monster_name_label.include.size = imgui.checkbox("Size", config.large_monster_UI.monster_name_label.include.size); config_changed = config_changed or changed; changed, config.large_monster_UI.monster_name_label.include.silver_crown_threshold = imgui.checkbox("Silver Crown Threshold", config.large_monster_UI.monster_name_label.include.silver_crown_threshold); config_changed = config_changed or changed; changed, config.large_monster_UI.monster_name_label.include.gold_crown_threshold = imgui.checkbox("Gold Crown Threshold", config.large_monster_UI.monster_name_label.include.gold_crown_threshold); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Offset") then changed, config.large_monster_UI.monster_name_label.offset.x = imgui.drag_float("X", config.large_monster_UI.monster_name_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.monster_name_label.offset.y = imgui.drag_float("Y", config.large_monster_UI.monster_name_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.large_monster_UI.monster_name_label.shadow.visibility = imgui.checkbox("Enable", config.large_monster_UI.monster_name_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.large_monster_UI.monster_name_label.shadow.offset.x = imgui.drag_float("X", config.large_monster_UI.monster_name_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.monster_name_label.shadow.offset.y = imgui.drag_float("Y", config.large_monster_UI.monster_name_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Label") then changed, config.large_monster_UI.health_label.visibility = imgui.checkbox("Visible", config.large_monster_UI.health_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_label.offset.x = imgui.drag_float("X", config.large_monster_UI.health_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_label.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.large_monster_UI.health_label.shadow.visibility = imgui.checkbox("Enable", config.large_monster_UI.health_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_label.shadow.offset.x = imgui.drag_float("X", config.large_monster_UI.health_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_label.shadow.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_label.shadow.offset.y, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Value Label") then changed, config.large_monster_UI.health_value_label.visibility = imgui.checkbox("Visible", config.large_monster_UI.health_value_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_value_label.offset.x = imgui.drag_float("X", config.large_monster_UI.health_value_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_value_label.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_value_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.large_monster_UI.health_value_label.shadow.visibility = imgui.checkbox("Enable", config.large_monster_UI.health_value_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_value_label.shadow.offset.x = imgui.drag_float("X", config.large_monster_UI.health_value_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_value_label.shadow.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_value_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Percentage Label") then changed, config.large_monster_UI.health_percentage_label.visibility = imgui.checkbox("Visible", config.large_monster_UI.health_percentage_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_percentage_label.offset.x = imgui.drag_float("X", config.large_monster_UI.health_percentage_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_percentage_label.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_percentage_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.large_monster_UI.health_percentage_label.shadow.visibility = imgui.checkbox("Enable", config.large_monster_UI.health_percentage_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_percentage_label.shadow.offset.x = imgui.drag_float("X", config.large_monster_UI.health_percentage_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_percentage_label.shadow.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_percentage_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Health Bar") then changed, config.large_monster_UI.health_bar.visibility = imgui.checkbox("Visible", config.large_monster_UI.health_bar.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.large_monster_UI.health_bar.offset.x = imgui.drag_float("X", config.large_monster_UI.health_bar.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_bar.offset.y = imgui.drag_float("Y", config.large_monster_UI.health_bar.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Size") then changed, config.large_monster_UI.health_bar.size.width = imgui.drag_float("Width", config.large_monster_UI.health_bar.size.width, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.large_monster_UI.health_bar.size.height = imgui.drag_float("Height", config.large_monster_UI.health_bar.size.height, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Colors") then -- color pickers? imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Time UI") then changed, config.time_UI.enabled = imgui.checkbox("Enabled", config.time_UI.enabled); config_changed = config_changed or changed; if imgui.tree_node("Position") then changed, config.time_UI.position.x = imgui.drag_float("X", config.time_UI.position.x, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.time_UI.position.y = imgui.drag_float("Y", config.time_UI.position.y, 0.1, 0, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Time Label") then changed, config.time_UI.time_label.visibility = imgui.checkbox("Visible", config.time_UI.time_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.time_UI.time_label.offset.x = imgui.drag_float("X", config.time_UI.time_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.time_UI.time_label.offset.y = imgui.drag_float("Y", config.time_UI.time_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.time_UI.time_label.shadow.visibility = imgui.checkbox("Enable", config.time_UI.time_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.time_UI.time_label.shadow.offset.x = imgui.drag_float("X", config.time_UI.time_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.time_UI.time_label.shadow.offset.y = imgui.drag_float("Y", config.time_UI.time_label.shadow.offset.y, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Damage Meter UI") then changed, config.damage_meter_UI.enabled = imgui.checkbox("Enabled", config.damage_meter_UI.enabled); config_changed = config_changed or changed; if imgui.tree_node("Settings") then changed, config.damage_meter_UI.settings.hide_module_if_total_damage_is_zero = imgui.checkbox("Hide Module if Total Damage is 0", config.damage_meter_UI.settings.hide_module_if_total_damage_is_zero); config_changed = config_changed or changed; changed, config.damage_meter_UI.settings.hide_player_if_player_damage_is_zero = imgui.checkbox("Hide Player if Player Damage is 0", config.damage_meter_UI.settings.hide_player_if_player_damage_is_zero); config_changed = config_changed or changed; changed, config.damage_meter_UI.settings.total_damage_offset_is_relative = imgui.checkbox("Total Damage Offset is Relative", config.damage_meter_UI.settings.total_damage_offset_is_relative); config_changed = config_changed or changed; changed, config.damage_meter_UI.settings.spacing = imgui.drag_float("Spacing", config.damage_meter_UI.settings.spacing, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, damage_meter_UI_orientation_index = imgui.combo("Orientation", damage_meter_UI_orientation_index, orientation_types); config_changed = config_changed or changed; if changed then config.damage_meter_UI.settings.orientation = orientation_types[damage_meter_UI_orientation_index]; end changed, damage_meter_UI_highlighted_bar_index = imgui.combo("Highlighted Bar", damage_meter_UI_highlighted_bar_index, damage_meter_UI_highlighted_bar_types); config_changed = config_changed or changed; if changed then config.damage_meter_UI.settings.highlighted_bar = damage_meter_UI_highlighted_bar_types[damage_meter_UI_highlighted_bar_index]; end changed, damage_meter_UI_damage_bar_relative_index = imgui.combo("Damage Bars are Relative to", damage_meter_UI_damage_bar_relative_index, damage_meter_UI_damage_bar_relative_types); config_changed = config_changed or changed; if changed then config.damage_meter_UI.settings.damage_bar_relative_to = damage_meter_UI_damage_bar_relative_types[damage_meter_UI_damage_bar_relative_index]; end changed, damage_meter_UI_my_damage_bar_location_index = imgui.combo("My Damage Bar Location", damage_meter_UI_my_damage_bar_location_index, damage_meter_UI_my_damage_bar_location_types); config_changed = config_changed or changed; if changed then config.damage_meter_UI.settings.my_damage_bar_location = damage_meter_UI_my_damage_bar_location_types[damage_meter_UI_my_damage_bar_location_index]; end imgui.tree_pop(); end if imgui.tree_node("Tracked Monster Types") then changed, config.damage_meter_UI.tracked_monster_types.small_monsters = imgui.checkbox("Small Monsters", config.damage_meter_UI.tracked_monster_types.small_monsters); config_changed = config_changed or changed; changed, config.damage_meter_UI.tracked_monster_types.large_monsters = imgui.checkbox("Large Monsters", config.damage_meter_UI.tracked_monster_types.large_monsters); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Tracked Damage Types") then changed, config.damage_meter_UI.tracked_damage_types.player_damage = imgui.checkbox("Player Damage", config.damage_meter_UI.tracked_damage_types.player_damage); config_changed = config_changed or changed; changed, config.damage_meter_UI.tracked_damage_types.bomb_damage = imgui.checkbox("Bomb Damage", config.damage_meter_UI.tracked_damage_types.bomb_damage); config_changed = config_changed or changed; changed, config.damage_meter_UI.tracked_damage_types.kunai_damage = imgui.checkbox("Kunai Damage", config.damage_meter_UI.tracked_damage_types.kunai_damage); config_changed = config_changed or changed; changed, config.damage_meter_UI.tracked_damage_types.installation_damage = imgui.checkbox("Installation Damage", config.damage_meter_UI.tracked_damage_types.installation_damage); config_changed = config_changed or changed; changed, config.damage_meter_UI.tracked_damage_types.otomo_damage = imgui.checkbox("Otomo Damage", config.damage_meter_UI.tracked_damage_types.otomo_damage); config_changed = config_changed or changed; changed, config.damage_meter_UI.tracked_damage_types.monster_damage = imgui.checkbox("Monster Damage", config.damage_meter_UI.tracked_damage_types.monster_damage); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Position") then changed, config.damage_meter_UI.position.x = imgui.drag_float("X", config.damage_meter_UI.position.x, 0.1, 0, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.position.y = imgui.drag_float("Y", config.damage_meter_UI.position.y, 0.1, 0, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Sorting") then changed, damage_meter_UI_sort_type_index = imgui.combo("Type", damage_meter_UI_sort_type_index, damage_meter_UI_sort_types); config_changed = config_changed or changed; if changed then config.damage_meter_UI.sorting.type = damage_meter_UI_sort_types[damage_meter_UI_sort_type_index]; end changed, config.damage_meter_UI.reversed_order = imgui.checkbox("Reversed Order", config.damage_meter_UI.reversed_order); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Player Name Label") then changed, config.damage_meter_UI.player_name_label.visibility = imgui.checkbox("Visible", config.damage_meter_UI.player_name_label.visibility); config_changed = config_changed or changed; if imgui.tree_node("Include") then if imgui.tree_node("Me") then changed, config.damage_meter_UI.player_name_label.include.myself.hunter_rank = imgui.checkbox("Hunter Rank", config.damage_meter_UI.player_name_label.include.myself.hunter_rank); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.include.myself.word_player = imgui.checkbox("Word \"Player\"", config.damage_meter_UI.player_name_label.include.myself.word_player); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.include.myself.player_id = imgui.checkbox("Player ID", config.damage_meter_UI.player_name_label.include.myself.player_id); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.include.myself.player_name = imgui.checkbox("Player Name", config.damage_meter_UI.player_name_label.include.myself.player_name); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Other Players") then changed, config.damage_meter_UI.player_name_label.include.others.hunter_rank = imgui.checkbox("Hunter Rank", config.damage_meter_UI.player_name_label.include.others.hunter_rank); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.include.others.word_player = imgui.checkbox("Word \"Player\"", config.damage_meter_UI.player_name_label.include.others.word_player); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.include.others.player_id = imgui.checkbox("Player ID", config.damage_meter_UI.player_name_label.include.others.player_id); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.include.others.player_name = imgui.checkbox("Player Name", config.damage_meter_UI.player_name_label.include.others.player_name); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Offset") then changed, config.damage_meter_UI.player_name_label.offset.x = imgui.drag_float("X", config.damage_meter_UI.player_name_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.offset.y = imgui.drag_float("Y", config.damage_meter_UI.player_name_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.damage_meter_UI.player_name_label.shadow.visibility = imgui.checkbox("Enable", config.damage_meter_UI.player_name_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.player_name_label.shadow.offset.x = imgui.drag_float("X", config.damage_meter_UI.player_name_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.player_name_label.shadow.offset.y = imgui.drag_float("Y", config.damage_meter_UI.player_name_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Damage Value Label") then changed, config.damage_meter_UI.damage_value_label.visibility = imgui.checkbox("Visible", config.damage_meter_UI.damage_value_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.damage_meter_UI.damage_value_label.offset.x = imgui.drag_float("X", config.damage_meter_UI.damage_value_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_value_label.offset.y = imgui.drag_float("Y", config.damage_meter_UI.damage_value_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.damage_meter_UI.damage_value_label.shadow.visibility = imgui.checkbox("Enable", config.damage_meter_UI.damage_value_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.damage_value_label.shadow.offset.x = imgui.drag_float("X", config.damage_meter_UI.damage_value_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_value_label.shadow.offset.y = imgui.drag_float("Y", config.damage_meter_UI.damage_value_label.shadow.offset.y, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Damage Percentage Label") then changed, config.damage_meter_UI.damage_percentage_label.visibility = imgui.checkbox("Visible", config.damage_meter_UI.damage_percentage_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.damage_meter_UI.damage_percentage_label.offset.x = imgui.drag_float("X", config.damage_meter_UI.damage_percentage_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_percentage_label.offset.y = imgui.drag_float("Y", config.damage_meter_UI.damage_percentage_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.damage_meter_UI.damage_percentage_label.shadow.visibility = imgui.checkbox("Enable", config.damage_meter_UI.damage_percentage_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.damage_percentage_label.shadow.offset.x = imgui.drag_float("X", config.damage_meter_UI.damage_percentage_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_percentage_label.shadow.offset.y = imgui.drag_float("Y", config.damage_meter_UI.damage_percentage_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Total Damage Label") then changed, config.damage_meter_UI.total_damage_label.visibility = imgui.checkbox("Visible", config.damage_meter_UI.total_damage_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.damage_meter_UI.total_damage_label.offset.x = imgui.drag_float("X", config.damage_meter_UI.total_damage_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.total_damage_label.offset.y = imgui.drag_float("Y", config.damage_meter_UI.total_damage_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.damage_meter_UI.total_damage_label.shadow.visibility = imgui.checkbox("Enable", config.damage_meter_UI.total_damage_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.total_damage_label.shadow.offset.x = imgui.drag_float("X", config.damage_meter_UI.total_damage_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.total_damage_label.shadow.offset.y = imgui.drag_float("Y", config.damage_meter_UI.total_damage_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Total Damage Value Label") then changed, config.damage_meter_UI.total_damage_value_label.visibility = imgui.checkbox("Visible", config.damage_meter_UI.total_damage_value_label.visibility); config_changed = config_changed or changed; -- add text format if imgui.tree_node("Offset") then changed, config.damage_meter_UI.total_damage_value_label.offset.x = imgui.drag_float("X", config.damage_meter_UI.total_damage_value_label.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.total_damage_value_label.offset.y = imgui.drag_float("Y", config.damage_meter_UI.total_damage_value_label.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end --color picker? if imgui.tree_node("Shadow") then changed, config.damage_meter_UI.total_damage_value_label.shadow.visibility = imgui.checkbox("Enable", config.damage_meter_UI.total_damage_value_label.shadow.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.total_damage_value_label.shadow.offset.x = imgui.drag_float("X", config.damage_meter_UI.total_damage_value_label.shadow.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.total_damage_value_label.shadow.offset.y = imgui.drag_float("Y", config.damage_meter_UI.total_damage_value_label.shadow.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Damage Bar") then changed, config.damage_meter_UI.damage_bar.visibility = imgui.checkbox("Visible", config.damage_meter_UI.damage_bar.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.damage_bar.offset.x = imgui.drag_float("X", config.damage_meter_UI.damage_bar.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_bar.offset.y = imgui.drag_float("Y", config.damage_meter_UI.damage_bar.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Size") then changed, config.damage_meter_UI.damage_bar.size.width = imgui.drag_float("Width", config.damage_meter_UI.damage_bar.size.width, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_bar.size.height = imgui.drag_float("Height", config.damage_meter_UI.damage_bar.size.height, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Colors") then -- color pickers? imgui.tree_pop(); end imgui.tree_pop(); end if imgui.tree_node("Highlighted Damage Bar") then changed, config.damage_meter_UI.highlighted_damage_bar.visibility = imgui.checkbox("Visible", config.damage_meter_UI.highlighted_damage_bar.visibility); config_changed = config_changed or changed; if imgui.tree_node("Offset") then changed, config.damage_meter_UI.highlighted_damage_bar.offset.x = imgui.drag_float("X", config.damage_meter_UI.highlighted_damage_bar.offset.x, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.highlighted_damage_bar.offset.y = imgui.drag_float("Y", config.damage_meter_UI.highlighted_damage_bar.offset.y, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Size") then changed, config.damage_meter_UI.damage_bar.size.width = imgui.drag_float("Width", config.damage_meter_UI.damage_bar.size.width, 0.1, -screen_width, screen_width, "%.1f"); config_changed = config_changed or changed; changed, config.damage_meter_UI.damage_bar.size.height = imgui.drag_float("Height", config.damage_meter_UI.damage_bar.size.height, 0.1, -screen_height, screen_height, "%.1f"); config_changed = config_changed or changed; imgui.tree_pop(); end if imgui.tree_node("Colors") then -- color pickers? imgui.tree_pop(); end imgui.tree_pop(); end imgui.tree_pop(); end imgui.end_window(); if config_changed then save_config(); end end --#endregion ----------------------CUSTOMIZATION UI----------------------- ---------------------------GLOBAL---------------------------- --#region re.on_draw_ui(function() if imgui.button('MHR Overlay') then is_customization_window_opened = not is_customization_window_opened; end end); re.on_frame(function() if is_customization_window_opened then customization_ui(); end --monster_health(); end); get_window_size = function () local size = scene_view:call("get_Size"); if size == nil then log.error("[MHR Overlay] No scene view size"); return end screen_width = size:get_field("w"); if screen_width == nil then log.error("[MHR Overlay] No screen width"); return end screen_height = size:get_field("h"); if screen_height == nil then log.error("[MHR Overlay] No screen height"); return end end calculate_screen_coordinates = function (position) if position.anchor == "Top-Left" then return {x = position.x, y = position.y}; end if position.anchor == "Top-Right" then local screen_x = screen_width - position.x; return {x = screen_x, y = position.y}; end if position.anchor == "Bottom-Left" then local screen_y = screen_height - position.y; return {x = position.x, y = screen_y}; end if position.anchor == "Bottom-Right" then local screen_x = screen_width - position.x; local screen_y = screen_height - position.y; return {x = screen_x, y = screen_y}; end return {x = position.x, y = position.y}; end table_find_index = function (table, value, nullable) for i = 1, #table do if table[i] == value then return i; end end if not nullable then return 1; end return nil; end --#endregion ---------------------------GLOBAL---------------------------- ------------------------DRAW HELPERS------------------------- --#region draw_label = function(label, position, ...) if label == nil then return; end if not label.visibility then return; end local text = string.format(label.text, table.unpack({...})); if label.shadow.visibility then d2d.text(font, text, position.x + label.offset.x + label.shadow.offset.x, position.y + label.offset.y + label.shadow.offset.y, label.shadow.color); end d2d.text(font, text, position.x + label.offset.x, position.y + label.offset.y, label.color); end draw_bar = function (bar, position, percentage) if bar == nil then return; end if not bar.visibility then return; end local foreground_width = bar.size.width * percentage; local background_width = bar.size.width - foreground_width; --foreground d2d.fill_rect(position.x + bar.offset.x, position.y + bar.offset.y, foreground_width, bar.size.height, bar.colors.foreground); --background d2d.fill_rect(position.x + foreground_width + bar.offset.x, position.y + bar.offset.y, background_width, bar.size.height, bar.colors.background); end old_draw_label = function(label, position, ...) if label == nil then return; end if not label.visibility then return; end local text = string.format(label.text, table.unpack({...})); if label.shadow.visibility then draw.text(text, position.x + label.offset.x + label.shadow.offset.x, position.y + label.offset.y + label.shadow.offset.y, label.shadow.color); end draw.text(text, position.x + label.offset.x, position.y + label.offset.y, label.color); end old_draw_bar = function (bar, position, percentage) if bar == nil then return; end if not bar.visibility then return; end local foreground_width = bar.size.width * percentage; local background_width = bar.size.width - foreground_width; --foreground draw.filled_rect(position.x + bar.offset.x, position.y + bar.offset.y, foreground_width, bar.size.height, bar.colors.foreground); --background draw.filled_rect(position.x + foreground_width + bar.offset.x, position.y + bar.offset.y, background_width, bar.size.height, bar.colors.background); end --#endregion ------------------------DRAW HELPERS------------------------- ------------------------QUEST STATUS------------------------- --#region local quest_manager_type_definition = sdk.find_type_definition("snow.QuestManager"); local on_changed_game_status = quest_manager_type_definition:get_method("onChangedGameStatus"); sdk.hook(on_changed_game_status, function(args) local status = sdk.to_int64(args[3]); if status ~= nil then quest_status = status; end end, function(retval) return retval; end); --#endregion ------------------------QUEST STATUS------------------------- ------------------------MONSTER HOOK------------------------- --#region local enemy_character_base_type_def = sdk.find_type_definition("snow.enemy.EnemyCharacterBase"); local enemy_character_base_type_def_update_method = enemy_character_base_type_def:get_method("update"); sdk.hook(enemy_character_base_type_def_update_method, function(args) update_monster(sdk.to_managed_object(args[2])); end, function(retval) return retval; end); update_monster = function (enemy) if enemy == nil then return; end local is_boss_enemy = enemy:call("get_isBossEnemy"); if is_boss_enemy == nil then return; end local physical_param = enemy:get_field("k__BackingField"); if physical_param == nil then status = "No physical param"; return; end local vital_param = physical_param:call("getVital", 0, 0); if vital_param == nil then status = "No vital param"; return; end local health = vital_param:call("get_Current"); local max_health = vital_param:call("get_Max"); local missing_health = max_health - health; local capture_health = physical_param:call("get_CaptureHpVital"); local health_percentage = 1; if max_health ~= 0 then health_percentage = health / max_health; end local enemy_game_object = enemy:call("get_GameObject"); if enemy_game_object == nil then status = "No enemy game object"; return; end local enemy_transform = enemy_game_object:call("get_Transform"); if enemy_transform == nil then status = "No enemy transform"; return; end local position = enemy_transform:call("get_Position"); if not position then status = "No enemy position"; return; end local monster_list = large_monsters; if not is_boss_enemy then monster_list = small_monsters; end local monster = monster_list[enemy]; if monster == nil then monster = {}; monster_list[enemy] = monster; local enemy_type = enemy:get_field("k__BackingField"); if enemy_type == nil then status = "No enemy type"; return; end local enemy_name = message_manager:call("getEnemyNameMessage", enemy_type); monster.name = enemy_name; if is_boss_enemy then local size_info = enemy_manager:call("findEnemySizeInfo", enemy_type); monster.small_border = size_info:call("get_SmallBorder"); monster.big_border = size_info:call("get_KingBorder"); monster.size = enemy:call("get_MonsterListRegisterScale"); if monster.size < monster.small_border then monster.crown = "Silver"; elseif monster.size > monster.big_border then monster.crown = "Gold"; else monster.crown = ""; end end end monster.health = health; monster.max_health = max_health; monster.health_percentage = health_percentage; monster.missing_health = missing_health; monster.capture_health = capture_health; monster.position = position; end --#endregion ------------------------MONSTER HOOK------------------------- ----------------------SMALL MONSTER UI----------------------- --#region small_monster_data = function() if enemy_manager == nil then status = "No enemy manager"; return; end local displayed_monsters = {}; local enemy_count = enemy_manager:call("getZakoEnemyCount"); if enemy_count == nil then status = "No enemy count"; return; end for i = 0, enemy_count - 1 do local enemy = enemy_manager:call("getZakoEnemy", i); if enemy == nil then status = "No enemy"; break; end local monster = small_monsters[enemy]; if monster == nil then status = "No monster hp entry"; break; end table.insert(displayed_monsters, monster); end if not config.small_monster_UI.dynamic_positioning.enabled then --sort here if config.small_monster_UI.sorting.type == "Normal" and config.small_monster_UI.sorting.reversed_order then local reversed_monsters = {}; for i = #displayed_monsters, 1, -1 do table.insert(reversed_monsters, large_monsters[i]); end displayed_monsters = reversed_monsters; elseif config.small_monster_UI.sorting.type == "Health" then table.sort(displayed_monsters, function(left, right) local result = left.health > right.health; if config.small_monster_UI.sorting.reversed_order then result = not result; end return result; end); elseif config.small_monster_UI.sorting.type == "Health Percentage" then table.sort(displayed_monsters, function(left, right) local result = left.health_percentage < right.health_percentage; if config.small_monster_UI.sorting.reversed_order then result = not result; end return result; end); end end local i = 0; for _, monster in ipairs(displayed_monsters) do local position_on_screen; if config.small_monster_UI.dynamic_positioning.enabled then position_on_screen = draw.world_to_screen(monster.position); if position_on_screen == nil then goto continue; end position_on_screen.x = position_on_screen.x + config.small_monster_UI.dynamic_positioning.viewport_offset.x; position_on_screen.y = position_on_screen.y + config.small_monster_UI.dynamic_positioning.viewport_offset.y; else position_on_screen = calculate_screen_coordinates(config.small_monster_UI.position); if config.small_monster_UI.settings.orientation == "Horizontal" then position_on_screen.x = position_on_screen.x + config.small_monster_UI.settings.spacing * i; else position_on_screen.y = position_on_screen.y + config.small_monster_UI.settings.spacing * i; end end --do return end; --remaining health --[[ if monster.health <= monster.capture_health then remaining_health_color = monster_UI.colors.health_bar.capture_health else remaining_health_color = monster_UI.colors.health_bar.remaining_health end --]] draw_bar(config.small_monster_UI.health_bar, position_on_screen, monster.health_percentage); draw_label(config.small_monster_UI.monster_name_label, position_on_screen, monster.name); draw_label(config.small_monster_UI.health_label, position_on_screen); draw_label(config.small_monster_UI.health_value_label, position_on_screen, monster.health, monster.max_health); draw_label(config.small_monster_UI.health_percentage_label, position_on_screen, 100 * monster.health_percentage); i = i + 1; ::continue:: end end --#endregion ----------------------SMALL MONSTER UI----------------------- ----------------------LARGE MONSTER UI----------------------- --#region large_monster_data = function() if enemy_manager == nil then status = "No enemy manager"; return; end local displayed_monsters = {}; local enemy_count = enemy_manager:call("getBossEnemyCount"); if enemy_count == nil then status = "No enemy count"; return; end for i = 0, enemy_count - 1 do local enemy = enemy_manager:call("getBossEnemy", i); if enemy == nil then status = "No enemy"; break; end local monster = large_monsters[enemy]; if monster == nil then status = "No monster hp entry"; break; end table.insert(displayed_monsters, monster); end if not config.large_monster_UI.dynamic_positioning.enabled then --sort here if config.large_monster_UI.sorting.type == "Normal" and config.large_monster_UI.sorting.reversed_order then local reversed_monsters = {}; for i = #displayed_monsters, 1, -1 do table.insert(reversed_monsters, large_monsters[i]); end displayed_monsters = reversed_monsters; elseif config.large_monster_UI.sorting.type == "Health" then table.sort(displayed_monsters, function(left, right) local result = left.health > right.health; if config.large_monster_UI.sorting.reversed_order then result = not result; end return result; end); elseif config.large_monster_UI.sorting.type == "Health Percentage" then table.sort(displayed_monsters, function(left, right) local result = left.health_percentage < right.health_percentage; if config.large_monster_UI.sorting.reversed_order then result = not result; end return result; end); end end local i = 0; for _, monster in ipairs(displayed_monsters) do local position_on_screen; if config.large_monster_UI.dynamic_positioning.enabled then position_on_screen = draw.world_to_screen(monster.position); if position_on_screen == nil then goto continue; end position_on_screen.x = position_on_screen.x + config.large_monster_UI.dynamic_positioning.viewport_offset.x; position_on_screen.y = position_on_screen.y + config.large_monster_UI.dynamic_positioning.viewport_offset.y; else position_on_screen = calculate_screen_coordinates(config.large_monster_UI.position); if config.large_monster_UI.settings.orientation == "Horizontal" then position_on_screen.x = position_on_screen.x + config.large_monster_UI.settings.spacing * i; else position_on_screen.y = position_on_screen.y + config.large_monster_UI.settings.spacing * i; end end --remaining health --[[ if monster.health <= monster.capture_health then remaining_health_color = monster_UI.colors.health_bar.capture_health else remaining_health_color = monster_UI.colors.health_bar.remaining_health end --]] draw_bar(config.large_monster_UI.health_bar, position_on_screen, monster.health_percentage); local monster_name_text = ""; if config.large_monster_UI.monster_name_label.include.monster_name then monster_name_text = string.format("%s ", monster.name); end if config.large_monster_UI.monster_name_label.include.crown and monster.crown ~= "" then monster_name_text = monster_name_text .. string.format("%s ", monster.crown); end if config.large_monster_UI.monster_name_label.include.size then monster_name_text = monster_name_text .. string.format("#%.0f ", 100 * monster.size); end if config.large_monster_UI.monster_name_label.include.silver_crown_threshold and config.large_monster_UI.monster_name_label.include.gold_crown_threshold then monster_name_text = monster_name_text .. string.format("(Silver: <%.0f, Gold: >%.0f)", 100 * monster.small_border, 100 * monster.big_border); elseif config.large_monster_UI.monster_name_label.include.silver_crown_threshold then monster_name_text = monster_name_text .. string.format("(Silver: <%.0f)", 100 * monster.small_border); elseif config.large_monster_UI.monster_name_label.include.gold_crown_threshold then monster_name_text = monster_name_text .. string.format("(Gold: >%.0f)", 100 * monster.big_border); end draw_label(config.large_monster_UI.monster_name_label, position_on_screen, monster_name_text); draw_label(config.large_monster_UI.health_label, position_on_screen); draw_label(config.large_monster_UI.health_value_label, position_on_screen, monster.health, monster.max_health); draw_label(config.large_monster_UI.health_percentage_label, position_on_screen, 100 * monster.health_percentage); i = i + 1; ::continue:: end end --#endregion ----------------------LARGE MONSTER UI----------------------- ---------------------------TIME UI--------------------------- --#region quest_time = function() if quest_manager == nil then status = "No quest manager"; return; end local quest_time_elapsed_minutes = quest_manager:call("getQuestElapsedTimeMin"); if quest_time_elapsed_minutes == nil then status = "No quest time elapsed minutes"; return; end local quest_time_total_elapsed_seconds = quest_manager:call("getQuestElapsedTimeSec"); if quest_time_total_elapsed_seconds == nil then status = "No quest time total elapsed seconds"; return; end if quest_time_total_elapsed_seconds == 0 then return; end local quest_time_elapsed_seconds = quest_time_total_elapsed_seconds - quest_time_elapsed_minutes * 60; local position_on_screen = calculate_screen_coordinates(config.time_UI.position); draw_label(config.time_UI.time_label, position_on_screen, quest_time_elapsed_minutes, quest_time_elapsed_seconds); end --#endregion ---------------------------TIME UI--------------------------- -----------------------DAMAGE METER UI----------------------- --#region local enemy_character_base_type_def = sdk.find_type_definition("snow.enemy.EnemyCharacterBase"); local enemy_character_base_after_calc_damage_damage_side = enemy_character_base_type_def:get_method("afterCalcDamage_DamageSide"); sdk.hook(enemy_character_base_after_calc_damage_damage_side, function(args) local enemy = sdk.to_managed_object(args[2]); if enemy == nil then return; end local is_boss_enemy = enemy:call("get_isBossEnemy"); if is_boss_enemy == nil then return; end if not config.damage_meter_UI.tracked_monster_types.small_monsters and not is_boss_enemy then return; end if not config.damage_meter_UI.tracked_monster_types.large_monsters and not is_boss_enemy then return; end local dead_or_captured = enemy:call("checkDie"); if dead_or_captured == nil then return; end if dead_or_captured then return; end local enemy_calc_damage_info = sdk.to_managed_object(args[3]); -- snow.hit.EnemyCalcDamageInfo.AfterCalcInfo_DamageSide local attacker_id = enemy_calc_damage_info:call("get_AttackerID"); local attacker_type = enemy_calc_damage_info:call("get_DamageAttackerType"); if attacker_id >= 100 then return; end -- 4 is virtual player in singleplayer that 'owns' 2nd otomo if not is_quest_online and attacker_id == 4 then attacker_id = myself_player_id; end local damage_object = {} damage_object.total_damage = enemy_calc_damage_info:call("get_TotalDamage");; damage_object.physical_damage = enemy_calc_damage_info:call("get_PhysicalDamage"); damage_object.elemental_damage = enemy_calc_damage_info:call("get_ElementDamage"); damage_object.ailment_damage = enemy_calc_damage_info:call("get_ConditionDamage"); -- -1 - bombs -- 0 - player -- 9 - kunai -- 11 - wyverblast -- 12 - ballista -- 13 - cannon -- 14 - machine cannon -- 16 - defender ballista/cannon -- 17 - wyvernfire artillery -- 18 - dragonator -- 19 - otomo -- 23 - monster local damage_source_type = tostring(attacker_type); if attacker_type == 0 then damage_source_type = "player"; elseif attacker_type == 1 then damage_source_type = "bomb"; elseif attacker_type == 9 then damage_source_type = "kunai"; elseif attacker_type == 11 then damage_source_type = "wyvernblast"; elseif attacker_type == 12 or attacker_type == 13 or attacker_type == 14 or attacker_type == 18 then damage_source_type = "installation"; elseif attacker_type == 19 then damage_source_type = "otomo"; elseif attacker_type == 23 then damage_source_type = "monster"; end local player = get_player(attacker_id); if player == nil then return; end --x = x.. string.format("[attacker] %d [type] %s [dmg] %d", attacker_id, damage_source_type, damage_object.total_damage); update_player(total, damage_source_type, damage_object); update_player(player, damage_source_type, damage_object); end, function(retval) return retval; end); init_player = function(player_id, player_name, player_hunter_rank) player = {}; player.id = player_id; player.name = player_name; player.hunter_rank = player_hunter_rank; player.total_damage = 0; player.physical_damage = 0; player.elemental_damage = 0; player.ailment_damage = 0; player.bombs = {}; player.bombs.total_damage = 0; player.bombs.physical_damage = 0; player.bombs.elemental_damage = 0; player.bombs.ailment_damage = 0; player.kunai = {}; player.kunai.total_damage = 0; player.kunai.physical_damage = 0; player.kunai.elemental_damage = 0; player.kunai.ailment_damage = 0; player.installations = {}; player.installations.total_damage = 0; player.installations.physical_damage = 0; player.installations.elemental_damage = 0; player.installations.ailment_damage = 0; player.otomo = {}; player.otomo.total_damage = 0; player.otomo.physical_damage = 0; player.otomo.elemental_damage = 0; player.otomo.ailment_damage = 0; player.monster = {}; player.monster.total_damage = 0; player.monster.physical_damage = 0; player.monster.elemental_damage = 0; player.monster.ailment_damage = 0; player.display = {}; player.display.total_damage = 0; player.display.physical_damage = 0; player.display.elemental_damage = 0; player.display.ailment_damage = 0; return player; end get_player = function(player_id) if players[player_id] == nil then return nil; end return players[player_id]; end update_player = function(player, damage_source_type, damage_object) if player == nil then return; end if damage_source_type == "player" then merge_damage(player, damage_object); elseif damage_source_type == "bomb" then merge_damage(player.bombs, damage_object); elseif damage_source_type == "kunai" then merge_damage(player.kunai, damage_object); elseif damage_source_type == "wyvernblast" then merge_damage(player, damage_object); elseif damage_source_type == "installation" then merge_damage(player.installations, damage_object); elseif damage_source_type == "otomo" then merge_damage(player.otomo, damage_object); elseif damage_source_type == "monster" then merge_damage(player.monster, damage_object); else merge_damage(player, damage_object); end player.display.total_damage = 0; player.display.physical_damage = 0; player.display.elemental_damage = 0; player.display.ailment_damage = 0; if config.damage_meter_UI.tracked_damage_types.player_damage then merge_damage(player.display, player); end if config.damage_meter_UI.tracked_damage_types.bomb_damage then merge_damage(player.display, player.bombs); end if config.damage_meter_UI.tracked_damage_types.kunai_damage then merge_damage(player.display, player.kunai); end if config.damage_meter_UI.tracked_damage_types.installation_damage then merge_damage(player.display, player.installations); end if config.damage_meter_UI.tracked_damage_types.otomo_damage then merge_damage(player.display, player.otomo); end if config.damage_meter_UI.tracked_damage_types.monster_damage then merge_damage(player.display, player.monster); end end merge_damage = function(first, second) first.total_damage = first.total_damage + second.total_damage; first.physical_damage = first.physical_damage + second.physical_damage; first.elemental_damage = first.elemental_damage + second.elemental_damage; first.ailment_damage = first.ailment_damage + second.ailment_damage; end damage_meter = function() if quest_status < 2 then players = {}; total = init_player(0, "Total", 0); return; end if total.display.total_damage == 0 and config.damage_meter_UI.settings.hide_module_if_total_damage_is_zero then return; end if lobby_manager == nil then status = "No lobby manager"; return; end if progress_manager == nil then status = "No progress manager"; return; end is_quest_online = lobby_manager:call("IsQuestOnline"); if is_quest_online == nil then is_quest_online = false; end --myself player local myself_player_info = lobby_manager:get_field("_myHunterInfo"); if myself_player_info == nil then status = "No myself player info list"; return; end local myself_player_name = myself_player_info:get_field("_name"); if myself_player_name == nil then status = "No myself player name"; return; end myself_player_id = 0; if is_quest_online then myself_player_id = lobby_manager:get_field("_myselfQuestIndex"); if myself_player_id == nil then status = "No myself player id"; return; end else myself_player_id = lobby_manager:get_field("_myselfIndex"); if myself_player_id == nil then status = "No myself player id"; return; end end local myself_hunter_rank = progress_manager:call("get_HunterRank"); if myself_hunter_rank == nil then status = "No myself hunter rank"; myself_hunter_rank = 0; end if players[myself_player_id] == nil then players[myself_player_id] = init_player(myself_player_id, myself_player_name, myself_hunter_rank); end local quest_players = {}; if quest_status > 2 then quest_players = last_displayed_players; else --other players local player_info_list = lobby_manager:get_field("_questHunterInfo"); if player_info_list == nil then status = "No player info list"; end local count = player_info_list:call("get_Count"); if count == nil then status = "No player info list count"; return; end for i = 0, count - 1 do local player_info = player_info_list:call("get_Item", i); if player_info == nil then goto continue; end local player_id = player_info:get_field("_memberIndex"); if player_id == nil then goto continue; end local player_hunter_rank = player_info:get_field("_hunterRank"); if player_hunter_rank == nil then goto continue; end if player_id == myself_player_id and config.damage_meter_UI.settings.my_damage_bar_location ~= "Normal" then players[myself_player_id].hunter_rank = player_hunter_rank; goto continue; end local player_name = player_info:get_field("_name"); if player_name == nil then goto continue; end if players[player_id] == nil then players[player_id] = init_player(player_id, player_name, player_hunter_rank); elseif players[player_id].name ~= player_name then players[player_id] = init_player(player_id, player_name, player_hunter_rank); end table.insert(quest_players, players[player_id]); ::continue:: end --sort here if config.damage_meter_UI.sort_type == "normal" and config.damage_meter_UI.reverse_order then local reversed_quest_players = {}; for i = #quest_players, 1, -1 do table.insert(reversed_quest_players, quest_players[i]); end quest_players = reversed_quest_players; elseif config.damage_meter_UI.sort_type == "damage" then table.sort(quest_players, function(left, right) local result = left.display.total_damage > right.display.total_damage; if config.damage_meter_UI.reverse_order then result = not result; end return result; end); end if config.damage_meter_UI.settings.my_damage_bar_location == "First" then table.insert(quest_players, 1, players[myself_player_id]); elseif config.damage_meter_UI.settings.my_damage_bar_location == "Last" then table.insert(quest_players, #quest_players + 1, players[myself_player_id]); elseif #quest_players == 0 then table.insert(quest_players, 1, players[myself_player_id]); end last_displayed_players = quest_players; end local top_damage = 0; for _, player in ipairs(quest_players) do if player.display.total_damage > top_damage then top_damage = player.display.total_damage; end end --draw local position_on_screen = calculate_screen_coordinates(config.damage_meter_UI.position); for _, player in ipairs(quest_players) do if player.display.total_damage == 0 and config.damage_meter_UI.settings.hide_player_if_player_damage_is_zero then goto continue1; end local player_damage_percentage = 0; if total.display.total_damage ~= 0 then player_damage_percentage = player.display.total_damage / total.display.total_damage; end if player.id == myself_player_id and config.damage_meter_UI.settings.highlighted_bar == "Me" then draw_bar(config.damage_meter_UI.highlighted_damage_bar, position_on_screen, player_damage_percentage); elseif config.damage_meter_UI.settings.highlighted_bar == "Top Damage" and player.display.total_damage == top_damage then draw_bar(config.damage_meter_UI.highlighted_damage_bar, position_on_screen, player_damage_percentage); else draw_bar(config.damage_meter_UI.damage_bar, position_on_screen, player_damage_percentage); end local player_name_text = ""; local player_include = config.damage_meter_UI.player_name_label.include.others; if player.id == myself_player_id then player_include = config.damage_meter_UI.player_name_label.include.myself; end if player_include.hunter_rank then player_name_text = string.format("[%d] ", player.hunter_rank); end if player_include.word_player then player_name_text = player_name_text .. "Player "; end if player_include.player_id then player_name_text = player_name_text .. string.format("%d ", player.id); end if player_include.player_name then player_name_text = player_name_text .. player.name; end draw_label(config.damage_meter_UI.player_name_label, position_on_screen, player_name_text) draw_label(config.damage_meter_UI.damage_value_label, position_on_screen, player.display.total_damage); draw_label(config.damage_meter_UI.damage_percentage_label, position_on_screen, 100 * player_damage_percentage); if config.damage_meter_UI.settings.orientation == "Horizontal" then position_on_screen.x = position_on_screen.x + config.damage_meter_UI.settings.spacing; else position_on_screen.y = position_on_screen.y + config.damage_meter_UI.settings.spacing; end ::continue1:: end --draw total damage draw_label(config.damage_meter_UI.total_damage_label, position_on_screen); draw_label(config.damage_meter_UI.total_damage_value_label, position_on_screen, total.display.total_damage); end --#endregion -----------------------DAMAGE METER UI----------------------- --#region if not init() then return; end --#endregion