mirror of
https://github.com/GreenComfyTea/MHR-Overlay.git
synced 2026-01-24 04:18:11 -08:00
332 lines
9.5 KiB
Lua
332 lines
9.5 KiB
Lua
log.info("[monster_has_hp_bar.lua] loaded")
|
|
|
|
local status = ""
|
|
local hp_table = {}
|
|
|
|
local scene_manager = sdk.get_native_singleton("via.SceneManager")
|
|
if not scene_manager then
|
|
log.error("[monster_has_hp_bar.lua] No scene manager")
|
|
return
|
|
end
|
|
|
|
local scene_view = sdk.call_native_func(scene_manager, sdk.find_type_definition("via.SceneManager"), "get_MainView")
|
|
if not scene_view then
|
|
log.error("[monster_has_hp_bar.lua] No main view")
|
|
return
|
|
end
|
|
|
|
local size = scene_view:call("get_Size")
|
|
if not size then
|
|
log.error("[monster_has_hp_bar.lua] No scene view size")
|
|
return
|
|
end
|
|
|
|
local screen_width = size:get_field("w")
|
|
if not screen_width then
|
|
log.error("[monster_has_hp_bar.lua] No screen width")
|
|
return
|
|
end
|
|
|
|
local screen_height = size:get_field("h")
|
|
if not screen_height then
|
|
log.error("[monster_has_hp_bar.lua] No screen height")
|
|
return
|
|
end
|
|
|
|
function record_hp(enemy)
|
|
if not enemy then return end
|
|
|
|
local physical_param = enemy:get_field("<PhysicalParam>k__BackingField")
|
|
if not physical_param then
|
|
status = "No physical param"
|
|
return
|
|
end
|
|
|
|
local vital_param = physical_param:call("getVital", 0, 0)
|
|
if not vital_param then
|
|
status = "No vital param"
|
|
return
|
|
end
|
|
|
|
local hp = vital_param:call("get_Current")
|
|
local max_hp = vital_param:call("get_Max")
|
|
local hp_entry = hp_table[enemy]
|
|
|
|
if not hp_entry then
|
|
hp_entry = {}
|
|
hp_table[enemy] = hp_entry
|
|
|
|
-- Grab enemy name.
|
|
local message_manager = sdk.get_managed_singleton("snow.gui.MessageManager")
|
|
if not message_manager then
|
|
status = "No message manager"
|
|
return
|
|
end
|
|
|
|
local enemy_type = enemy:get_field("<EnemyType>k__BackingField")
|
|
if not enemy_type then
|
|
status = "No enemy type"
|
|
return
|
|
end
|
|
|
|
local enemy_name = message_manager:call("getEnemyNameMessage", enemy_type)
|
|
hp_entry.name = enemy_name
|
|
end
|
|
|
|
hp_entry.hp = hp
|
|
hp_entry.max_hp = max_hp
|
|
end
|
|
|
|
local type_def = sdk.find_type_definition("snow.enemy.EnemyCharacterBase")
|
|
local update_method = type_def:get_method("update")
|
|
|
|
sdk.hook(update_method, function(args)
|
|
record_hp(sdk.to_managed_object(args[2]))
|
|
end, function(retval) end)
|
|
|
|
re.on_draw_ui(function()
|
|
if string.len(status) > 0 then
|
|
imgui.text("[monster_has_hp_bar.lua] Status: " .. status)
|
|
end
|
|
end)
|
|
|
|
local shadow_shift_x = 1
|
|
local shadow_shift_y = 1
|
|
|
|
re.on_frame(function()
|
|
monster_hp();
|
|
quest_time();
|
|
dps_meter();
|
|
|
|
status = ""
|
|
end)
|
|
|
|
function monster_hp()
|
|
--[[
|
|
local player_manager = sdk.get_managed_singleton("snow.player.PlayerManager")
|
|
if not player_manager then
|
|
status = "No player manager"
|
|
return
|
|
end
|
|
|
|
local player = player_manager:call("findMasterPlayer")
|
|
if not player then
|
|
status = "No local player"
|
|
return
|
|
end
|
|
|
|
local player_game_object = player:call("get_GameObject")
|
|
if not player_game_object then
|
|
status = "No local player game object"
|
|
return
|
|
end
|
|
|
|
local player_transform = player_game_object:call("get_Transform")
|
|
if not player_transform then
|
|
status = "No local player transform"
|
|
return
|
|
end
|
|
|
|
local player_position = player_transform:call("get_Position")
|
|
if not player_position then
|
|
status = "No local player position"
|
|
return
|
|
end
|
|
--]]
|
|
|
|
local enemy_manager = sdk.get_managed_singleton("snow.enemy.EnemyManager")
|
|
if not enemy_manager then
|
|
status = "No enemy manager"
|
|
return
|
|
end
|
|
|
|
--local closest_enemy = nil
|
|
--local closest_dist = 999999
|
|
|
|
for i = 0, 4 do
|
|
local enemy = enemy_manager:call("getBossEnemy", i)
|
|
if not enemy then
|
|
break
|
|
end
|
|
|
|
local hp_entry = hp_table[enemy]
|
|
if not hp_entry then
|
|
status = "No hp entry"
|
|
break
|
|
end
|
|
|
|
--[[
|
|
local enemy_game_object = enemy:call("get_GameObject")
|
|
if not enemy_game_object then
|
|
status = "No enemy game object"
|
|
break
|
|
end
|
|
|
|
local enemy_transform = enemy_game_object:call("get_Transform")
|
|
if not enemy_transform then
|
|
status = "No enemy transform"
|
|
break
|
|
end
|
|
|
|
local enemy_position = enemy_transform:call("get_Position")
|
|
if not enemy_position then
|
|
status = "No enemy position"
|
|
break
|
|
end
|
|
|
|
local distance = (player_position - enemy_position):length()
|
|
|
|
if distance < closest_dist then
|
|
closest_dist = distance
|
|
closest_enemy = enemy
|
|
end
|
|
--]]
|
|
|
|
local width = 200
|
|
local height = 20
|
|
|
|
local spacing = 20
|
|
|
|
local x = 450 + width * i + spacing * i
|
|
local y = screen_height - 27
|
|
|
|
local hp_percent = hp_entry.hp / hp_entry.max_hp
|
|
local hp_width = width * hp_percent
|
|
local missing_hp_width = width - hp_width
|
|
|
|
local text_name = hp_entry.name
|
|
local text_hp = string.format("%d/%d\t(%d%%)", hp_entry.hp, hp_entry.max_hp, math.floor(hp_percent * 100))
|
|
|
|
--border
|
|
--draw.filled_rect(x - 1, y - 1, width + 2, height + 2, 0xAA000000)
|
|
--missing hp
|
|
draw.filled_rect(x + hp_width, y, missing_hp_width, height, 0xAA000000)
|
|
--remaining hp
|
|
draw.filled_rect(x, y, hp_width, height, 0xFF52A674)
|
|
|
|
--text shadow
|
|
draw.text(text_name, x + 5 + shadow_shift_x, y - height + shadow_shift_y + 2, 0xFF000000)
|
|
draw.text(text_hp, x + shadow_shift_x + width / 4, y + shadow_shift_y + 2, 0xFF000000)
|
|
|
|
--text itself
|
|
draw.text(text_name, x + 5, y - height + 2, 0xFFE1F4CC)
|
|
draw.text(text_hp, x + width / 4, y + 2, 0xFFFFFFFF)
|
|
|
|
status = ""
|
|
end
|
|
|
|
--[[
|
|
if not closest_enemy then
|
|
hp_table = {}
|
|
status = "No enemy"
|
|
return
|
|
end
|
|
|
|
local hp_entry = hp_table[closest_enemy]
|
|
if not hp_entry then
|
|
status = "No hp entry"
|
|
return
|
|
end
|
|
|
|
local x = 0
|
|
local y = 0
|
|
local w = screen_width
|
|
local h = 20
|
|
local hp_percent = hp_entry.hp / hp_entry.max_hp
|
|
local hp_w = w * hp_percent
|
|
local missing_hp_w = w - hp_w
|
|
|
|
draw.filled_rect(x + hp_w, y, missing_hp_w, h, 0xAA000000)
|
|
draw.filled_rect(x, y, hp_w, h, 0xAA228B22)
|
|
draw.text(hp_entry.name .. "\t" .. math.floor(hp_percent * 100) .. "%\t" .. hp_entry.hp .. "/" .. hp_entry.max_hp, x + 5, y + 2, 0xFFFFFFFF)
|
|
status = ""
|
|
--]]
|
|
end
|
|
|
|
function quest_time()
|
|
local quest_manager = sdk.get_managed_singleton("snow.QuestManager")
|
|
if not quest_manager then
|
|
status = "No quest manager"
|
|
return
|
|
end
|
|
|
|
local quest_time_elapsed_minutes = quest_manager:call("getQuestElapsedTimeMin");
|
|
if not quest_time_elapsed_minutes then
|
|
status = "No quest time elapsed minutes"
|
|
return
|
|
end
|
|
|
|
local quest_time_total_elapsed_seconds = quest_manager:call("getQuestElapsedTimeSec");
|
|
if not quest_time_total_elapsed_seconds 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 elapsed_time = string.format("%02d:%06.3f", quest_time_elapsed_minutes, quest_time_elapsed_seconds)
|
|
|
|
local x = 65
|
|
local y = 189
|
|
|
|
--shadow
|
|
draw.text(elapsed_time, x + shadow_shift_x, y + shadow_shift_y, 0xFF000000)
|
|
|
|
--text
|
|
draw.text(elapsed_time, x, y, 0xFFE1F4CC)
|
|
end
|
|
|
|
function dps_meter()
|
|
local player_manager = sdk.get_managed_singleton("snow.player.PlayerManager")
|
|
if not player_manager then
|
|
status = "No player manager"
|
|
return
|
|
end
|
|
|
|
local player = player_manager:call("findMasterPlayer")
|
|
if not player then
|
|
status = "No local player"
|
|
return
|
|
end
|
|
|
|
local quest_manager = sdk.get_managed_singleton("snow.QuestManager")
|
|
if not quest_manager then
|
|
status = "No quest manager"
|
|
return
|
|
end
|
|
|
|
local kpi_data = quest_manager:call("get_KpiData");
|
|
if not kpi_data then
|
|
status = "No kpi data"
|
|
return
|
|
end
|
|
|
|
local player_total_attack_damage = kpi_data:call("get_PlayerTotalAttackDamage");
|
|
if not player_total_attack_damage then
|
|
status = "No player total attack damage"
|
|
return
|
|
end
|
|
|
|
local player_total_elemental_attack_damage = kpi_data:call("get_PlayerTotalElementalAttackDamage");
|
|
if not player_total_elemental_attack_damage then
|
|
status = "No player total elemental attack damage"
|
|
return
|
|
end
|
|
|
|
local player_total_status_ailments_damage = kpi_data:call("get_PlayerTotalStatusAilmentsDamage");
|
|
if not player_total_status_ailments_damage then
|
|
status = "No player total status ailments damage"
|
|
return
|
|
end
|
|
|
|
local player_total_damage = player_total_attack_damage + player_total_elemental_attack_damage + player_total_status_ailments_damage
|
|
|
|
--shadow
|
|
draw.text("Damage: " .. player_total_damage, 450 + shadow_shift_x, screen_height - 75 + shadow_shift_y, 0xFF000000)
|
|
--text
|
|
draw.text("Damage: " .. player_total_damage, 450, screen_height - 75, 0xFFE1F4CC)
|
|
end |