diff --git a/reframework/autorun/MHR_Overlay.lua b/reframework/autorun/MHR_Overlay.lua index fb84056..49b8516 100644 --- a/reframework/autorun/MHR_Overlay.lua +++ b/reframework/autorun/MHR_Overlay.lua @@ -42,6 +42,7 @@ local language = require("MHR_Overlay.Misc.language"); local table_helpers = require("MHR_Overlay.Misc.table_helpers"); local unicode_helpers = require("MHR_Overlay.Misc.unicode_helpers"); local part_names = require("MHR_Overlay.Misc.part_names"); +local utils = require("MHR_Overlay.Misc.utils"); --local buffs = require("MHR_Overlay.Buffs.buffs"); @@ -99,6 +100,7 @@ screen.init_module(); singletons.init_module(); table_helpers.init_module(); unicode_helpers.init_module(); +utils.init_module(); time.init_module(); language.init_module(); diff --git a/reframework/autorun/MHR_Overlay/Damage_Meter/damage_hook.lua b/reframework/autorun/MHR_Overlay/Damage_Meter/damage_hook.lua index 0cff58b..a858e39 100644 --- a/reframework/autorun/MHR_Overlay/Damage_Meter/damage_hook.lua +++ b/reframework/autorun/MHR_Overlay/Damage_Meter/damage_hook.lua @@ -8,6 +8,7 @@ local ailments; local table_helpers; local singletons; local non_players; +local utils; local sdk = sdk; local tostring = tostring; @@ -38,12 +39,16 @@ local draw = draw; local Vector2f = Vector2f; local reframework = reframework; +local wall_hit_damage_queue = {}; + local enemy_character_base_type_def = sdk.find_type_definition("snow.enemy.EnemyCharacterBase"); local enemy_character_base_after_calc_damage_damage_side_method = enemy_character_base_type_def:get_method("afterCalcDamage_DamageSide"); local is_boss_enemy_method = enemy_character_base_type_def:get_method("get_isBossEnemy"); local check_die_method = enemy_character_base_type_def:get_method("checkDie"); +local stock_direct_marionette_finish_shoot_hit_parts_damage_method = enemy_character_base_type_def:get_method("stockDirectMarionetteFinishShootHitPartsDamage"); + local enemy_calc_damage_info_type_def = sdk.find_type_definition("snow.hit.EnemyCalcDamageInfo.AfterCalcInfo_DamageSide"); local get_attacker_id_method = enemy_calc_damage_info_type_def:get_method("get_AttackerID"); local get_damage_attacker_type_method = enemy_calc_damage_info_type_def:get_method("get_DamageAttackerType"); @@ -255,13 +260,69 @@ function damage_hook.cart(dead_player_id, flag_cat_skill_insurance) quest_status.get_cart_count(); end ---function damage_hook.on_get_finish_shoot_wall_hit_damage_rate(enemy, rate, is_part_damage) +function damage_hook.on_stock_direct_marionette_finish_shoot_hit_parts_damage(enemy, damage_rate, is_endure, is_ignore_multi_rate, category, no) + local monster = large_monster.get_monster(enemy); ---xy = string.format("enemy: %s\nrate: %s\nis_part_damage: %s", tostring(enemy), tostring(rate), tostring(is_part_damage)); ---end + local damage = utils.round(monster.max_health * damage_rate); + large_monster.update_all_riders(); + local attacker_id = monster.rider_id; + + table.insert(wall_hit_damage_queue, + { + damage = damage, + is_large = monster.is_large + } + ); + + if attacker_id == -1 then + return; + end -local get_finish_shoot_wall_hit_damage_rate_method = enemy_character_base_type_def:get_method("stockFinishShootHitDamage"); + local player = players.get_player(attacker_id); + if player == nil then + player = non_players.get_servant(attacker_id); + end + + if player == nil then + return; + end + + local damage_source_type = damage_hook.get_damage_source_type(0, true); + local is_large_monster = monster.is_large; + + local large_monster_damage_object = {}; + large_monster_damage_object.total_damage = 0; + large_monster_damage_object.physical_damage = 0; + large_monster_damage_object.elemental_damage = 0; + large_monster_damage_object.ailment_damage = 0; + + local small_monster_damage_object = {}; + small_monster_damage_object.total_damage = 0; + small_monster_damage_object.physical_damage = 0; + small_monster_damage_object.elemental_damage = 0; + small_monster_damage_object.ailment_damage = 0; + + for _, damage_info in ipairs(wall_hit_damage_queue) do + if damage_info.is_large then + + large_monster_damage_object.total_damage = large_monster_damage_object.total_damage + damage_info.damage; + large_monster_damage_object.physical_damage = large_monster_damage_object.physical_damage + damage_info.damage; + else + small_monster_damage_object.total_damage = small_monster_damage_object.total_damage + damage_info.damage; + small_monster_damage_object.physical_damage = small_monster_damage_object.physical_damage + damage_info.damage; + end + + end + + wall_hit_damage_queue = {}; + + players.update_damage(players.total, damage_source_type, false, small_monster_damage_object); + players.update_damage(player, damage_source_type, false, small_monster_damage_object); + + players.update_damage(players.total, damage_source_type, true, large_monster_damage_object); + players.update_damage(player, damage_source_type, true, large_monster_damage_object); +end function damage_hook.init_module() quest_status = require("MHR_Overlay.Game_Handler.quest_status"); @@ -272,12 +333,20 @@ function damage_hook.init_module() table_helpers = require("MHR_Overlay.Misc.table_helpers"); singletons = require("MHR_Overlay.Game_Handler.singletons"); non_players = require("MHR_Overlay.Damage_Meter.non_players"); + utils = require("MHR_Overlay.Misc.utils"); - --sdk.hook(get_finish_shoot_wall_hit_damage_rate_method, function(args) - -- pcall(damage_hook.on_get_finish_shoot_wall_hit_damage_rate, sdk.to_managed_object(args[2]), sdk.to_float(args[3]), sdk.to_int64(args--[4])); - --end, function(retval) - -- return retval; - --end); + sdk.hook(stock_direct_marionette_finish_shoot_hit_parts_damage_method, function(args) + local enemy = sdk.to_managed_object(args[2]); + local damage_rate = sdk.to_float(args[3]); + local is_endure = (sdk.to_int64(args[4]) & 1) == 1; + local is_ignore_multi_rate = (sdk.to_int64(args[5]) & 1) == 1; + local category = sdk.to_int64(args[6]); --snow.enemy.EnemyDef.VitalCategory + local no = sdk.to_int64(args[7]); + + damage_hook.on_stock_direct_marionette_finish_shoot_hit_parts_damage(enemy, damage_rate, is_endure, is_ignore_multi_rate, category, no); + end, function(retval) + return retval; + end); sdk.hook(enemy_character_base_after_calc_damage_damage_side_method, function(args) pcall(damage_hook.update_damage, sdk.to_managed_object(args[2]), sdk.to_managed_object(args[3])); diff --git a/reframework/autorun/MHR_Overlay/Misc/utils.lua b/reframework/autorun/MHR_Overlay/Misc/utils.lua new file mode 100644 index 0000000..01d28bf --- /dev/null +++ b/reframework/autorun/MHR_Overlay/Misc/utils.lua @@ -0,0 +1,43 @@ +local utils = {}; + +local sdk = sdk; +local tostring = tostring; +local pairs = pairs; +local ipairs = ipairs; +local tonumber = tonumber; +local require = require; +local pcall = pcall; +local table = table; +local string = string; +local Vector3f = Vector3f; +local d2d = d2d; +local math = math; +local json = json; +local log = log; +local fs = fs; +local next = next; +local type = type; +local setmetatable = setmetatable; +local getmetatable = getmetatable; +local assert = assert; +local select = select; +local coroutine = coroutine; +local utf8 = utf8; +local re = re; +local imgui = imgui; +local draw = draw; +local Vector2f = Vector2f; +local reframework = reframework; + +function utils.sign(v) + return (v >= 0 and 1) or -1; +end +function utils.round(value, bracket) + bracket = bracket or 1; + return math.floor(value / bracket + utils.sign(value) * 0.5) * bracket; +end + +function utils.init_module() +end + +return utils; \ No newline at end of file diff --git a/reframework/autorun/MHR_Overlay/Monsters/large_monster.lua b/reframework/autorun/MHR_Overlay/Monsters/large_monster.lua index 13862d9..cea3f55 100644 --- a/reframework/autorun/MHR_Overlay/Monsters/large_monster.lua +++ b/reframework/autorun/MHR_Overlay/Monsters/large_monster.lua @@ -399,13 +399,22 @@ function large_monster.update_all_riders() local mario_param = enemy:get_field("k__BackingField"); if mario_param ~= nil then local is_marionette = get_is_marionette_method:call(mario_param); + + if is_marionette == nil then + goto continue; + end + if is_marionette then local player_id = get_mario_player_index_method:call(mario_param); - if monster.rider_id ~= player_id then + if player_id ~= nil then monster.rider_id = player_id; end + else + monster.rider_id = -1; end end + + ::continue:: end end