Implemented Monster Ailments.

This commit is contained in:
GreenComfyTea
2022-04-20 18:10:26 +03:00
parent e6fd36eea0
commit 46a76a6a10
15 changed files with 4290 additions and 537 deletions

View File

@@ -141,7 +141,7 @@ function damage_hook.init_module()
player = require("MHR_Overlay.Damage_Meter.player");
small_monster = require("MHR_Overlay.Monsters.small_monster");
large_monster = require("MHR_Overlay.Monsters.large_monster");
ailments = require("MHR_Overlay.Damage_Meter.ailments");
ailments = require("MHR_Overlay.Monsters.ailments");
end
return damage_hook;

View File

@@ -349,6 +349,155 @@ function config.init()
background = 0x88000000
}
}
},
ailments = {
visibility = false,
offset = {
x = 10,
y = 75
},
spacing = {
x = 0,
y = 24,
},
settings = {
hide_ailments_with_zero_buildup = true,
hide_inactive_ailments_with_no_buildup_support = true,
hide_all_inactive_ailments = false,
hide_all_active_ailments = false,
hide_disabled_ailments = true,
time_limit = 15
},
sorting = {
type = "Normal",
reversed_order = false
},
ailment_name_label = {
visibility = true,
text = "%s",
include = {
ailment_name = true,
activation_count = true
},
offset = {
x = 5,
y = 0
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
text_label = {
visibility = false,
text = language.current_language.UI.buildup,
offset = {
x = -60,
y = 6
},
color = 0xF1F4A3CC,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
value_label = {
visibility = true,
text = "%.0f/%.0f", -- current_buildup/max_buildup
offset = {
x = 60,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
percentage_label = {
visibility = false,
text = "%5.1f%%",
offset = {
x = 0,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
timer_label = {
visibility = true,
text = "%2.0f:%02.0f",
offset = {
x = 140,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
bar = {
visibility = true,
offset = {
x = 0,
y = 14
},
size = {
width = 90,
height = 4
},
colors = {
foreground = 0xA7ff80ce,
background = 0xA7000000
}
}
}
},
@@ -361,7 +510,8 @@ function config.init()
render_highlighted_monster = true,
render_not_highlighted_monsters = true,
max_distance = 300,
opacity_falloff = true
opacity_falloff = true,
time_limit = 15
},
world_offset = {
@@ -712,6 +862,7 @@ function config.init()
settings = {
hide_undamaged_parts = true,
time_limit = 15
},
sorting = {
@@ -819,6 +970,156 @@ function config.init()
background = 0x88000000
}
}
},
ailments = {
visibility = false,
offset = {
x = 10,
y = 45
},
spacing = {
x = 0,
y = 24,
},
settings = {
hide_ailments_with_zero_buildup = true,
hide_inactive_ailments_with_no_buildup_support = true,
hide_all_inactive_ailments = false,
hide_all_active_ailments = false,
hide_disabled_ailments = true,
offset_is_relative_to_parts = true,
time_limit = 15
},
sorting = {
type = "Normal",
reversed_order = false
},
ailment_name_label = {
visibility = true,
text = "%s",
include = {
ailment_name = true,
activation_count = true
},
offset = {
x = 5,
y = 0
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
text_label = {
visibility = false,
text = language.current_language.UI.buildup,
offset = {
x = -60,
y = 7
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
value_label = {
visibility = true,
text = "%.0f/%.0f", -- current_buildup/max_buildup
offset = {
x = 45,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
percentage_label = {
visibility = true,
text = "%5.1f%%",
offset = {
x = 135,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
timer_label = {
visibility = true,
text = "%2.0f:%02.0f",
offset = {
x = 140,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
bar = {
visibility = true,
offset = {
x = 0,
y = 14
},
size = {
width = 185,
height = 5
},
colors = {
foreground = 0xA7ff80ce,
background = 0xA7000000
}
}
}
},
@@ -826,7 +1127,7 @@ function config.init()
enabled = true,
spacing = {
x = 220,
x = 250,
y = 40,
},
@@ -835,7 +1136,8 @@ function config.init()
render_highlighted_monster = true,
render_not_highlighted_monsters = true,
highlighted_monster_location = "Normal",
orientation = "Horizontal"
orientation = "Horizontal",
time_limit = 15
},
sorting = {
@@ -1176,7 +1478,7 @@ function config.init()
offset = {
x = 10,
y = 50
y = 73
},
spacing = {
@@ -1186,6 +1488,7 @@ function config.init()
settings = {
hide_undamaged_parts = true,
time_limit = 15
},
sorting = {
@@ -1293,6 +1596,157 @@ function config.init()
background = 0x88000000
}
}
},
ailments = {
visibility = true,
offset = {
x = 10,
y = 45
},
spacing = {
x = 0,
y = 24,
},
settings = {
hide_ailments_with_zero_buildup = true,
hide_inactive_ailments_with_no_buildup_support = true,
hide_all_inactive_ailments = false,
hide_all_active_ailments = false,
hide_disabled_ailments = true,
offset_is_relative_to_parts = true,
time_limit = 15
},
sorting = {
type = "Normal",
reversed_order = false
},
ailment_name_label = {
visibility = true,
text = "%s",
include = {
ailment_name = true,
activation_count = true
},
offset = {
x = 5,
y = 0
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
text_label = {
visibility = false,
text = language.current_language.UI.buildup,
offset = {
x = -60,
y = 7
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
value_label = {
visibility = true,
text = "%.0f/%.0f", -- current_buildup/max_buildup
offset = {
x = 45,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
percentage_label = {
visibility = true,
text = "%5.1f%%",
offset = {
x = 135,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
timer_label = {
visibility = true,
text = "%2.0f:%02.0f",
offset = {
x = 140,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
bar = {
visibility = true,
offset = {
x = 0,
y = 14
},
size = {
width = 185,
height = 5
},
colors = {
foreground = 0xA7ff80ce,
background = 0xA7000000
}
}
}
},
@@ -1642,6 +2096,7 @@ function config.init()
settings = {
hide_undamaged_parts = true,
time_limit = 15
},
sorting = {
@@ -1749,6 +2204,156 @@ function config.init()
background = 0x88000000
}
}
},
ailments = {
visibility = true,
offset = {
x = 10,
y = 45
},
spacing = {
x = 0,
y = 24,
},
settings = {
hide_ailments_with_zero_buildup = true,
hide_inactive_ailments_with_no_buildup_support = true,
hide_all_inactive_ailments = false,
hide_all_active_ailments = false,
hide_disabled_ailments = true,
offset_is_relative_to_parts = true,
time_limit = 0
},
sorting = {
type = "Normal",
reversed_order = false
},
ailment_name_label = {
visibility = true,
text = "%s",
include = {
ailment_name = true,
activation_count = true
},
offset = {
x = 5,
y = 0
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
text_label = {
visibility = false,
text = language.current_language.UI.buildup,
offset = {
x = -60,
y = 7
},
color = 0xFFffb2e2,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
value_label = {
visibility = true,
text = "%.0f/%.0f", -- current_buildup/max_buildup
offset = {
x = 45,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
percentage_label = {
visibility = true,
text = "%5.1f%%",
offset = {
x = 135,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
timer_label = {
visibility = true,
text = "%2.0f:%02.0f",
offset = {
x = 140,
y = 13
},
color = 0xFFFFFFFF,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
bar = {
visibility = true,
offset = {
x = 0,
y = 14
},
size = {
width = 185,
height = 5
},
colors = {
foreground = 0xA7ff80ce,
background = 0xA7000000
}
}
}
}
},
@@ -1892,12 +2497,32 @@ function config.init()
color = 0xFF000000
}
},
dps_label = {
visibility = true,
text = "%.1f",
offset = {
x = 155,
y = 0
},
color = 0xFFCCF4E1,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
damage_value_label = {
visibility = true,
text = "%.0f",
offset = {
x = 145,
x = 205,
y = 0
},
color = 0xFFCCF4E1,
@@ -1916,27 +2541,7 @@ function config.init()
visibility = true,
text = "%5.1f%%",
offset = {
x = 205,
y = 0
},
color = 0xFFCCF4E1,
shadow = {
visibility = true,
offset = {
x = 1,
y = 1
},
color = 0xFF000000
}
},
dps_label = {
visibility = true,
text = "%.1f",
offset = {
x = 265,
x = 262,
y = 0
},
color = 0xFFCCF4E1,
@@ -1969,12 +2574,13 @@ function config.init()
color = 0xFF000000
}
},
total_damage_value_label = {
total_dps_label = {
visibility = true,
text = "%.0f",
text = "%.1f",
offset = {
x = 145,
x = 155,
y = 0
},
color = 0xFFFF7373,
@@ -1988,13 +2594,12 @@ function config.init()
color = 0xFF000000
}
},
total_dps_label = {
total_damage_value_label = {
visibility = true,
text = "%.1f",
text = "%.0f",
offset = {
x = 265,
x = 205,
y = 0
},
color = 0xFFFF7373,
@@ -2017,7 +2622,7 @@ function config.init()
},
size = {
width = 250,
width = 310,
height = 5
},
@@ -2035,7 +2640,7 @@ function config.init()
},
size = {
width = 250,
width = 310,
height = 5
},

View File

@@ -57,6 +57,30 @@ language.default_language = {
rock = "Rock"
},
ailments = {
paralysis = "Paralysis",
sleep = "Sleep",
stun = "Stun",
flash = "Flash",
poison = "Poison",
blast = "Blast",
exhaust ="Exhaust",
mount = "Mount",
waterblight = "Waterblight",
fireblight = "Fireblight",
iceblight = "Iceblight",
thunderblight = "Thunderblight",
fall_trap = "Fall Trap",
shock_trap = "Shock Trap",
tranq_bomb = "Tranq Bomb",
dung_bomb = "Dung Bomb",
steel_fang = "Steel Fang",
quick_sand = "Quick Sand",
fall_otomo_trap = "Fall Otomo Trap",
shock_otomo_trap = "Shock Otomo Trap"
},
UI = {
HP = "HP:",
stamina = "Stamina:",
@@ -65,7 +89,8 @@ language.default_language = {
silver = "Silver",
mini = "Mini",
total_damage = "Total Damage",
player = "Player"
player = "Player",
buildup = "Buildup:"
},
customization_menu = {
@@ -256,6 +281,22 @@ language.default_language = {
all_UI = "All UI",
assign_new_key = "Assign new key",
press_any_key = "Press any key...",
buildup = "Buildup",
buildup_percentage = "Buildup Percentage",
ailments = "Ailments",
hide_ailments_with_zero_buildup = "Hide Ailments when Buildup is 0",
hide_inactive_ailments_with_no_buildup_support = "Hide Inactive Ailments with no Buildup Support",
hide_all_inactive_ailments = "Hide All Inactive Ailments",
hide_all_active_ailments = "Hide All Active Ailments",
hide_disabled_ailments = "Hide Disabled Ailments",
offset_is_relative_to_parts = "Offset is Relative to Parts",
time_limit = "Time Limit (seconds)",
ailment_name_label = "Ailment Name Label",
ailment_name = "Ailment Name",
activation_count = "Activation Count"
}
};

View File

@@ -0,0 +1,691 @@
local ailments = {};
local player;
local language;
local config;
local ailment_UI_entity;
local time;
local small_monster;
local large_monster;
local table_helpers;
--0 Paralyze
--1 Sleep
--2 Stun
--3 Flash
--4 Poison
--5 Blast
--6 Stamina
--7 MarionetteStart
--8 Water
--9 Fire
--10 Ice
--11 Thunder
--12 FallTrap
--13 ShockTrap
--14 Capture
--15 Koyashi
--16 SteelFang
ailments.paralyze_id = 0;
ailments.sleep_id = 1;
ailments.stun_id = 2;
ailments.flash_id = 3;
ailments.poison_id = 4;
ailments.blast_id = 5;
ailments.exhaust_id = 6;
ailments.mount_id = 7;
ailments.water_id = 8;
ailments.fire_id = 9;
ailments.ice_id = 10;
ailments.thunder_id = 11;
ailments.fall_trap_id = 12;
ailments.shock_trap_id = 13;
ailments.capture_id = 14 --tranq bomb
ailments.koyashi_id = 15; --dung bomb
ailments.steel_fang_id = 16;
ailments.fall_quick_sand_id = 17;
ailments.fall_otomo_trap_id = 18;
ailments.shock_otomo_trap_id = 19;
function ailments.new(_ailments, ailment_id)
_ailments[ailment_id] = {};
_ailments[ailment_id].is_enable = true;
_ailments[ailment_id].id = ailment_id;
_ailments[ailment_id].total_buildup = 0;
_ailments[ailment_id].buildup_limit = 0;
_ailments[ailment_id].buildup_percentage = 0;
_ailments[ailment_id].timer = 0;
_ailments[ailment_id].duration = 100000;
_ailments[ailment_id].timer_percentage = 0;
_ailments[ailment_id].is_active = false;
_ailments[ailment_id].activate_count = 0;
_ailments[ailment_id].last_change_time = time.total_elapsed_seconds;
if ailment_id == ailments.paralyze_id then
_ailments[ailment_id].name = language.current_language.ailments.paralysis;
elseif ailment_id == ailments.sleep_id then
_ailments[ailment_id].name = language.current_language.ailments.sleep;
elseif ailment_id == ailments.stun_id then
_ailments[ailment_id].name = language.current_language.ailments.stun;
elseif ailment_id == ailments.flash_id then
_ailments[ailment_id].name = language.current_language.ailments.flash;
elseif ailment_id == ailments.poison_id then
_ailments[ailment_id].name = language.current_language.ailments.poison;
elseif ailment_id == ailments.blast_id then
_ailments[ailment_id].name = language.current_language.ailments.blast;
elseif ailment_id == ailments.exhaust_id then
_ailments[ailment_id].name = language.current_language.ailments.exhaust;
elseif ailment_id == ailments.mount_id then
_ailments[ailment_id].name = language.current_language.ailments.mount;
elseif ailment_id == ailments.water_id then
_ailments[ailment_id].name = language.current_language.ailments.waterblight;
elseif ailment_id == ailments.fire_id then
_ailments[ailment_id].name = language.current_language.ailments.fireblight;
elseif ailment_id == ailments.ice_id then
_ailments[ailment_id].name = language.current_language.ailments.iceblight;
elseif ailment_id == ailments.thunder_id then
_ailments[ailment_id].name = language.current_language.ailments.thunderblight;
elseif ailment_id == ailments.fall_trap_id then
_ailments[ailment_id].name = language.current_language.ailments.fall_trap;
elseif ailment_id == ailments.shock_trap_id then
_ailments[ailment_id].name = language.current_language.ailments.shock_trap;
elseif ailment_id == ailments.capture_id then
_ailments[ailment_id].name = language.current_language.ailments.tranq_bomb;
elseif ailment_id == ailments.koyashi_id then
_ailments[ailment_id].name = language.current_language.ailments.dung_bomb;
elseif ailment_id == ailments.steel_fang_id then
_ailments[ailment_id].name = language.current_language.ailments.steel_fang;
elseif ailment_id == ailments.fall_quick_sand_id then
_ailments[ailment_id].name = language.current_language.ailments.quick_sand;
elseif ailment_id == ailments.fall_otomo_trap_id then
_ailments[ailment_id].name = language.current_language.ailments.fall_otomo_trap;
elseif ailment_id == ailments.shock_otomo_trap_id then
_ailments[ailment_id].name = language.current_language.ailments.shock_otomo_trap;
end
end
function ailments.init_ailments()
local _ailments = {};
ailments.new(_ailments, ailments.paralyze_id);
ailments.new(_ailments, ailments.sleep_id);
ailments.new(_ailments, ailments.stun_id);
ailments.new(_ailments, ailments.flash_id);
ailments.new(_ailments, ailments.poison_id);
ailments.new(_ailments, ailments.blast_id);
ailments.new(_ailments, ailments.exhaust_id);
ailments.new(_ailments, ailments.mount_id);
ailments.new(_ailments, ailments.water_id);
ailments.new(_ailments, ailments.fire_id);
ailments.new(_ailments, ailments.ice_id);
ailments.new(_ailments, ailments.thunder_id);
ailments.new(_ailments, ailments.fall_trap_id);
ailments.new(_ailments, ailments.shock_trap_id);
ailments.new(_ailments, ailments.capture_id); --tranq bomb
ailments.new(_ailments, ailments.koyashi_id); --dung bomb
ailments.new(_ailments, ailments.steel_fang_id);
ailments.new(_ailments, ailments.fall_quick_sand_id);
ailments.new(_ailments, ailments.fall_otomo_trap_id);
ailments.new(_ailments, ailments.shock_otomo_trap_id);
_ailments[ailments.poison_id].buildup = {};
_ailments[ailments.poison_id].buildup_share = {};
_ailments[ailments.blast_id].buildup = {};
_ailments[ailments.blast_id].buildup_share = {};
return _ailments;
end
local enemy_character_base_type_def = sdk.find_type_definition("snow.enemy.EnemyCharacterBase");
local enemy_condition_damage_param_base_type_def = sdk.find_type_definition("snow.enemy.EnemyConditionDamageParamBase");
local damage_param_field = enemy_character_base_type_def:get_field("<DamageParam>k__BackingField");
local damage_param_type = damage_param_field:get_type();
local get_condition_param_method = damage_param_type:get_method("get_ConditionParam");
local poison_param_field = damage_param_type:get_field("_PoisonParam");
local blast_param_field = damage_param_type:get_field("_BlastParam");
local poison_param_type = poison_param_field:get_type();
local blast_param_type = blast_param_field:get_type();
local get_is_enable_method = enemy_condition_damage_param_base_type_def:get_method("get_IsEnable");
local get_is_active_method = enemy_condition_damage_param_base_type_def:get_method("get_IsActive");
local get_activate_count_method = enemy_condition_damage_param_base_type_def:get_method("get_ActivateCount");
local get_stock_method = enemy_condition_damage_param_base_type_def:get_method("get_Stock");
local get_limit_method = enemy_condition_damage_param_base_type_def:get_method("get_Limit");
local get_active_time_method = enemy_condition_damage_param_base_type_def:get_method("get_ActiveTime");
local get_active_timer_method = enemy_condition_damage_param_base_type_def:get_method("get_ActiveTimer");
local poison_damage_field = poison_param_type:get_field("<Damage>k__BackingField");
local poison_get_is_damage_method = poison_param_type:get_method("get_IsDamage");
local blast_damage_method = blast_param_type:get_method("get_BlastDamage");
local blast_adjust_rate_method = blast_param_type:get_method("get_BlastDamageAdjustRateByEnemyLv");
function ailments.update_ailments(enemy, monster)
if enemy == nil then
return;
end
local damage_param = damage_param_field:get_data(enemy);
if damage_param == nil then
return;
end
local condition_param = get_condition_param_method:call(damage_param);
if condition_param == nil then
return;
end
local condition_param_table = condition_param:get_elements();
if condition_param == nil then
return;
end
for index, ailment_param in ipairs(condition_param_table) do
local id = index - 1;
local is_enable = get_is_enable_method:call(ailment_param);
local activate_count = get_activate_count_method:call(ailment_param):get_element(0):get_field("mValue");
local buildup = get_stock_method:call(ailment_param):get_element(0):get_field("mValue");
local buildup_limit = get_limit_method:call(ailment_param):get_element(0):get_field("mValue");
local timer = get_active_timer_method:call(ailment_param);
local duration = get_active_time_method:call(ailment_param);
local is_active = get_is_active_method:call(ailment_param);
if is_enable ~= nil then
monster.ailments[id].is_enable = is_enable;
end
if activate_count ~= nil then
monster.ailments[id].activate_count = activate_count;
end
if buildup ~= nil then
monster.ailments[id].total_buildup = buildup;
end
if buildup_limit ~= nil then
monster.ailments[id].buildup_limit = buildup_limit;
end
if buildup ~= nil and buildup_limit ~= nil and buildup_limit ~= 0 then
monster.ailments[id].buildup_percentage = buildup / buildup_limit;
end
if timer ~= nil then
monster.ailments[id].timer = timer;
end
if duration ~= nil then
monster.ailments[id].duration = duration;
end
if timer ~= nil and duration ~= nil then
if duration ~= 0 then
monster.ailments[id].timer_percentage = timer / duration;
end
end
if is_active ~= nil then
monster.ailments[id].is_active = is_active;
end
end
end
-- Code by coavins
function ailments.update_poison_blast(enemy, is_large)
if enemy == nil then
return;
end
local monster;
if is_large then
monster = large_monster.get_monster(enemy);
else
monster = small_monster.get_monster(enemy);
end
local damage_param = damage_param_field:get_data(enemy);
if damage_param ~= nil then
local poison_param = poison_param_field:get_data(damage_param);
if poison_param ~= nil then
-- if applied, then calculate share for poison
local activate_count = get_activate_count_method:call(poison_param):get_element(0):get_field("mValue");
if activate_count > monster.ailments[ailments.poison_id].activate_count then
monster.ailments[ailments.poison_id].activate_count = activate_count;
ailments.calculate_ailment_contribution(monster, ailments.poison_id);
end
-- if poison tick, apply damage
local poison_damage = poison_damage_field:get_data(poison_param);
local is_damage = poison_get_is_damage_method:call(poison_param);
if is_damage then
ailments.apply_ailment_damage(monster, ailments.poison_id, poison_damage);
end
end
local blast_param = blast_param_field:get_data(damage_param);
if blast_param ~= nil then
-- if applied, then calculate share for blast and apply damage
local activate_count = get_activate_count_method:call(blast_param):get_element(0):get_field("mValue");
if activate_count > monster.ailments[ailments.blast_id].activate_count then
monster.ailments[ailments.blast_id].activate_count = activate_count;
ailments.calculate_ailment_contribution(monster, ailments.blast_id);
local blast_damage = blast_damage_method:call(blast_param);
local blast_adjust_rate = blast_adjust_rate_method:call(blast_param);
ailments.apply_ailment_damage(monster, ailments.blast_id, blast_damage * blast_adjust_rate);
end
end
end
end
function ailments.draw_dynamic(monster, ailments_position_on_screen, opacity_scale)
--sort parts here
local displayed_ailments = {};
for REpart, ailment in pairs(monster.ailments) do
if config.current_config.large_monster_UI.dynamic.ailments.settings.hide_ailments_with_zero_buildup and ailment.total_buildup == 0 and ailment.buildup_limit ~= 0 and ailment.activate_count == 0 then
goto continue;
end
if config.current_config.large_monster_UI.dynamic.ailments.settings.hide_inactive_ailments_with_no_buildup_support and ailment.buildup_limit == 0 then
goto continue;
end
if config.current_config.large_monster_UI.dynamic.ailments.settings.hide_all_inactive_ailments and not ailment.is_active then
goto continue;
end
if config.current_config.large_monster_UI.dynamic.ailments.settings.hide_all_active_ailments and ailment.is_active then
goto continue;
end
if config.current_config.large_monster_UI.dynamic.ailments.settings.hide_disabled_ailments and not ailment.is_enable then
goto continue;
end
if config.current_config.large_monster_UI.dynamic.ailments.settings.time_limit ~= 0 and time.total_elapsed_seconds - ailment.last_change_time > config.current_config.large_monster_UI.dynamic.ailments.settings.time_limit then
goto continue;
end
table.insert(displayed_ailments, ailment);
::continue::
end
if config.current_config.large_monster_UI.dynamic.ailments.sorting.type == "Normal" then
if config.current_config.large_monster_UI.dynamic.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.id > right.id;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.dynamic.ailments.sorting.type == "Buildup" then
if config.current_config.large_monster_UI.dynamic.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.total_buildup > right.total_buildup;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.total_buildup < right.total_buildup;
end);
end
elseif config.current_config.large_monster_UI.dynamic.ailments.sorting.type == "Buildup Percentage" then
if config.current_config.large_monster_UI.dynamic.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.buildup_percentage > right.buildup_percentage;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.buildup_percentage < right.buildup_percentage;
end);
end
end
for j, ailment in ipairs(displayed_ailments) do
local ailment_position_on_screen = {
x = ailments_position_on_screen.x + config.current_config.large_monster_UI.dynamic.ailments.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = ailments_position_on_screen.y + config.current_config.large_monster_UI.dynamic.ailments.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
ailment_UI_entity.draw_dynamic(ailment, monster.ailment_dynamic_UI, ailment_position_on_screen, opacity_scale);
end
end
function ailments.draw_static(monster, ailments_position_on_screen, opacity_scale)
--sort parts here
local displayed_ailments = {};
for REpart, ailment in pairs(monster.ailments) do
if config.current_config.large_monster_UI.static.ailments.settings.hide_ailments_with_zero_buildup and ailment.total_buildup == 0 and ailment.buildup_limit ~= 0 and ailment.activate_count == 0 then
goto continue;
end
if config.current_config.large_monster_UI.static.ailments.settings.hide_inactive_ailments_with_no_buildup_support and ailment.buildup_limit == 0 then
goto continue;
end
if config.current_config.large_monster_UI.static.ailments.settings.hide_all_inactive_ailments and not ailment.is_active then
goto continue;
end
if config.current_config.large_monster_UI.static.ailments.settings.hide_all_active_ailments and ailment.is_active then
goto continue;
end
if config.current_config.large_monster_UI.static.ailments.settings.hide_disabled_ailments and not ailment.is_enable then
goto continue;
end
if config.current_config.large_monster_UI.static.ailments.settings.time_limit ~= 0 and time.total_elapsed_seconds - ailment.last_change_time > config.current_config.large_monster_UI.static.ailments.settings.time_limit then
goto continue;
end
table.insert(displayed_ailments, ailment);
::continue::
end
if config.current_config.large_monster_UI.static.ailments.sorting.type == "Normal" then
if config.current_config.large_monster_UI.static.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.id > right.id;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.static.ailments.sorting.type == "Buildup" then
if config.current_config.large_monster_UI.static.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.total_buildup > right.total_buildup;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.total_buildup < right.total_buildup;
end);
end
elseif config.current_config.large_monster_UI.static.ailments.sorting.type == "Buildup Percentage" then
if config.current_config.large_monster_UI.static.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.buildup_percentage > right.buildup_percentage;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.buildup_percentage < right.buildup_percentage;
end);
end
end
for j, ailment in ipairs(displayed_ailments) do
local ailment_position_on_screen = {
x = ailments_position_on_screen.x + config.current_config.large_monster_UI.static.ailments.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = ailments_position_on_screen.y + config.current_config.large_monster_UI.static.ailments.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
ailment_UI_entity.draw_static(ailment, monster.ailment_static_UI, ailment_position_on_screen, opacity_scale);
end
end
function ailments.draw_highlighted(monster, ailments_position_on_screen, opacity_scale)
--sort parts here
local displayed_ailments = {};
for id, ailment in pairs(monster.ailments) do
if config.current_config.large_monster_UI.highlighted.ailments.settings.hide_ailments_with_zero_buildup and ailment.total_buildup == 0 and ailment.buildup_limit ~= 0 and ailment.activate_count == 0 then
goto continue;
end
if config.current_config.large_monster_UI.highlighted.ailments.settings.hide_inactive_ailments_with_no_buildup_support and ailment.buildup_limit == 0 then
goto continue;
end
if config.current_config.large_monster_UI.highlighted.ailments.settings.hide_all_inactive_ailments and not ailment.is_active then
goto continue;
end
if config.current_config.large_monster_UI.highlighted.ailments.settings.hide_all_active_ailments and ailment.is_active then
goto continue;
end
if config.current_config.large_monster_UI.highlighted.ailments.settings.hide_disabled_ailments and not ailment.is_enable then
goto continue;
end
if config.current_config.large_monster_UI.highlighted.ailments.settings.time_limit ~= 0 and time.total_elapsed_seconds - ailment.last_change_time > config.current_config.large_monster_UI.highlighted.ailments.settings.time_limit then
goto continue;
end
table.insert(displayed_ailments, ailment);
::continue::
end
if config.current_config.large_monster_UI.highlighted.ailments.sorting.type == "Normal" then
if config.current_config.large_monster_UI.highlighted.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.id > right.id;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.highlighted.ailments.sorting.type == "Buildup" then
if config.current_config.large_monster_UI.highlighted.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.total_buildup > right.total_buildup;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.total_buildup < right.total_buildup;
end);
end
elseif config.current_config.large_monster_UI.highlighted.ailments.sorting.type == "Buildup Percentage" then
if config.current_config.large_monster_UI.highlighted.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
return left.buildup_percentage > right.buildup_percentage;
end);
else
table.sort(displayed_ailments, function(left, right)
return left.buildup_percentage < right.buildup_percentage;
end);
end
end
for j, ailment in ipairs(displayed_ailments) do
local ailment_position_on_screen = {
x = ailments_position_on_screen.x + config.current_config.large_monster_UI.highlighted.ailments.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = ailments_position_on_screen.y + config.current_config.large_monster_UI.highlighted.ailments.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
ailment_UI_entity.draw_highlighted(ailment, monster.ailment_highlighted_UI, ailment_position_on_screen, opacity_scale);
end
end
function ailments.draw_small(monster, ailments_position_on_screen, opacity_scale)
--sort parts here
local displayed_ailments = {};
for REpart, ailment in pairs(monster.ailments) do
if config.current_config.small_monster_UI.ailments.settings.hide_ailments_with_zero_buildup and ailment.total_buildup == 0 and ailment.buildup_limit ~= 0 and ailment.activate_count == 0 then
goto continue;
end
if config.current_config.small_monster_UI.ailments.settings.hide_inactive_ailments_with_no_buildup_support and ailment.buildup_limit == 0 then
goto continue;
end
if config.current_config.small_monster_UI.ailments.settings.hide_all_inactive_ailments and not ailment.is_active then
goto continue;
end
if config.current_config.small_monster_UI.ailments.settings.hide_all_active_ailments and ailment.is_active then
goto continue;
end
if config.current_config.small_monster_UI.ailments.settings.hide_disabled_ailments and not ailment.is_enable then
goto continue;
end
if config.current_config.small_monster_UI.ailments.settings.time_limit ~= 0 and time.total_elapsed_seconds - ailment.last_change_time > config.current_config.small_monster_UI.ailments.settings.time_limit then
goto continue;
end
table.insert(displayed_ailments, ailment);
::continue::
end
if config.current_config.small_monster_UI.ailments.sorting.type == "Normal" then
if config.current_config.small_monster_UI.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
if config.current_config.small_monster_UI.ailments.settings.prioritize_active_ailments and left.is_active then return false; end
return left.id > right.id;
end);
else
table.sort(displayed_ailments, function(left, right)
if config.current_config.small_monster_UI.ailments.settings.prioritize_active_ailments and left.is_active then return true; end
return left.id < right.id;
end);
end
elseif config.current_config.small_monster_UI.ailments.sorting.type == "Buildup" then
if config.current_config.small_monster_UI.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
if config.current_config.small_monster_UI.ailments.settings.prioritize_active_ailments and left.is_active then return false; end
return left.total_buildup > right.total_buildup;
end);
else
table.sort(displayed_ailments, function(left, right)
if config.current_config.small_monster_UI.ailments.settings.prioritize_active_ailments and left.is_active then return true; end
return left.total_buildup < right.total_buildup;
end);
end
elseif config.current_config.small_monster_UI.ailments.sorting.type == "Buildup Percentage" then
if config.current_config.small_monster_UI.ailments.sorting.reversed_order then
table.sort(displayed_ailments, function(left, right)
if config.current_config.small_monster_UI.ailments.settings.prioritize_active_ailments and left.is_active then return false; end
return left.buildup_percentage > right.buildup_percentage;
end);
else
table.sort(displayed_ailments, function(left, right)
if config.current_config.small_monster_UI.ailments.settings.prioritize_active_ailments and left.is_active then return true; end
return left.buildup_percentage < right.buildup_percentage;
end);
end
end
for j, ailment in ipairs(displayed_ailments) do
local ailment_position_on_screen = {
x = ailments_position_on_screen.x + config.current_config.small_monster_UI.ailments.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = ailments_position_on_screen.y + config.current_config.small_monster_UI.ailments.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
ailment_UI_entity.draw_small(ailment, monster.ailment_UI, ailment_position_on_screen, opacity_scale);
end
end
function ailments.apply_ailment_buildup(monster, attacker_id, ailment_type, ailment_buildup)
if monster == nil or player == nil or (ailment_type ~= ailments.poison_id and ailment_type ~= ailments.blast_id) then
return;
end
-- get the buildup accumulator for this type
if monster.ailments[ailment_type].buildup == nil then
monster.ailments[ailment_type].buildup = {};
end
-- accumulate this buildup for this attacker
monster.ailments[ailment_type].buildup[attacker_id] = (monster.ailments[ailment_type].buildup[attacker_id] or 0) + ailment_buildup;
end
-- Code by coavins
function ailments.calculate_ailment_contribution(monster, ailment_type)
-- get total
local total = 0;
for attacker_id, player_buildup in pairs(monster.ailments[ailment_type].buildup) do
total = total + player_buildup;
end
for attacker_id, player_buildup in pairs(monster.ailments[ailment_type].buildup) do
-- update ratio for this attacker
monster.ailments[ailment_type].buildup_share[attacker_id] = player_buildup / total;
-- clear accumulated buildup for this attacker
-- they have to start over to earn a share of next ailment trigger
monster.ailments[ailment_type].buildup[attacker_id] = 0;
end
end
-- Code by coavins
function ailments.apply_ailment_damage(monster, ailment_type, ailment_damage)
-- we only track poison and blast for now
if ailment_type == nil or ailment_damage == nil then
return;
end
local damage_source_type = "";
if ailment_type == ailments.poison_id then
damage_source_type = "poison";
elseif ailment_type == ailments.blast_id then
damage_source_type = "blast";
else
return;
end
local damage = ailment_damage;
-- split up damage according to ratio of buildup on boss for this type
for attacker_id, percentage in pairs(monster.ailments[ailment_type].buildup_share) do
local damage_portion = damage * percentage;
local damage_object = {};
damage_object.total_damage = damage_portion;
damage_object.physical_damage = 0;
damage_object.elemental_damage = 0;
damage_object.ailment_damage = damage_portion;
local attacking_player = player.get_player(attacker_id);
if attacking_player ~= nil then
player.update_damage(attacking_player, damage_source_type, true, damage_object);
end
player.update_damage(player.total, damage_source_type, true, damage_object);
end
end
function ailments.init_module()
player = require("MHR_Overlay.Damage_Meter.player");
language = require("MHR_Overlay.Misc.language");
config = require("MHR_Overlay.Misc.config");
ailment_UI_entity = require("MHR_Overlay.UI.UI_Entities.ailment_UI_entity");
time = require("MHR_Overlay.Game_Handler.time");
small_monster = require("MHR_Overlay.Monsters.small_monster");
large_monster = require("MHR_Overlay.Monsters.large_monster");
table_helpers = require("MHR_Overlay.Misc.table_helpers");
end
return ailments;

View File

@@ -10,6 +10,7 @@ local body_part_UI_entity;
local screen;
local drawing;
local part_names;
local time;
body_part.list = {};
@@ -26,6 +27,8 @@ function body_part.new(REpart, name, id)
part.name = name;
part.flinch_count = 0;
part.last_change_time = time.total_elapsed_seconds;
body_part.init_dynamic_UI(part);
body_part.init_static_UI(part);
body_part.init_highlighted_UI(part);
@@ -75,6 +78,10 @@ function body_part.update(part, new_health, new_max_health)
if new_health > part.health then
part.flinch_count = part.flinch_count + 1;
end
if part.health ~= new_health then
part.last_change_time = time.total_elapsed_seconds;
end
part.health = new_health;
part.max_health = new_max_health;
@@ -84,16 +91,194 @@ function body_part.update(part, new_health, new_max_health)
end
end
function body_part.draw_dynamic(part, position_on_screen, opacity_scale)
body_part_UI_entity.draw_dynamic(part, position_on_screen, opacity_scale);
function body_part.draw_dynamic(monster, parts_position_on_screen, opacity_scale)
--sort parts here
local displayed_parts = {};
for REpart, part in pairs(monster.parts) do
if config.current_config.large_monster_UI.dynamic.parts.settings.hide_undamaged_parts and part.health == part.max_health and part.flinch_count == 0 then
goto continue;
end
if config.current_config.large_monster_UI.dynamic.parts.settings.time_limit ~= 0 and time.total_elapsed_seconds - part.last_change_time > config.current_config.large_monster_UI.dynamic.parts.settings.time_limit then
goto continue;
end
table.insert(displayed_parts, part);
::continue::
end
if config.current_config.large_monster_UI.dynamic.parts.sorting.type == "Normal" then
if config.current_config.large_monster_UI.dynamic.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.id > right.id;
end);
else
table.sort(displayed_parts, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.dynamic.parts.sorting.type == "Health" then
if config.current_config.large_monster_UI.dynamic.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health > right.health;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health < right.health;
end);
end
elseif config.current_config.large_monster_UI.dynamic.parts.sorting.type == "Health Percentage" then
if config.current_config.large_monster_UI.dynamic.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health_percentage > right.health_percentage;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health_percentage < right.health_percentage;
end);
end
end
local last_part_position_on_screen;
for j, part in ipairs(displayed_parts) do
local part_position_on_screen = {
x = parts_position_on_screen.x + config.current_config.large_monster_UI.dynamic.parts.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.dynamic.parts.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
body_part_UI_entity.draw_dynamic(part, part_position_on_screen, opacity_scale);
last_part_position_on_screen = part_position_on_screen;
end
return last_part_position_on_screen;
end
function body_part.draw_static(part, position_on_screen, opacity_scale)
body_part_UI_entity.draw_static(part, position_on_screen, opacity_scale);
function body_part.draw_static(monster, parts_position_on_screen, opacity_scale)
--sort parts here
local displayed_parts = {};
for REpart, part in pairs(monster.parts) do
if config.current_config.large_monster_UI.static.parts.settings.hide_undamaged_parts and part.health == part.max_health and part.flinch_count == 0 then
goto continue;
end
if config.current_config.large_monster_UI.static.parts.settings.time_limit ~= 0 and time.total_elapsed_seconds - part.last_change_time > config.current_config.large_monster_UI.static.parts.settings.time_limit then
goto continue;
end
table.insert(displayed_parts, part);
::continue::
end
if config.current_config.large_monster_UI.static.parts.sorting.type == "Normal" then
if config.current_config.large_monster_UI.static.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.id > right.id;
end);
else
table.sort(displayed_parts, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.static.parts.sorting.type == "Health" then
if config.current_config.large_monster_UI.static.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health > right.health;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health < right.health;
end);
end
elseif config.current_config.large_monster_UI.static.parts.sorting.type == "Health Percentage" then
if config.current_config.large_monster_UI.static.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health_percentage > right.health_percentage;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health_percentage < right.health_percentage;
end);
end
end
local last_part_position_on_screen;
for j, part in ipairs(displayed_parts) do
local part_position_on_screen = {
x = parts_position_on_screen.x + config.current_config.large_monster_UI.static.parts.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.static.parts.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
body_part_UI_entity.draw_static(part, part_position_on_screen, opacity_scale);
last_part_position_on_screen = part_position_on_screen;
end
return last_part_position_on_screen;
end
function body_part.draw_highlighted(part, position_on_screen, opacity_scale)
body_part_UI_entity.draw_highlighted(part, position_on_screen, opacity_scale);
function body_part.draw_highlighted(monster, parts_position_on_screen, opacity_scale)
--sort parts here
local displayed_parts = {};
for REpart, part in pairs(monster.parts) do
if config.current_config.large_monster_UI.highlighted.parts.settings.hide_undamaged_parts and part.health == part.max_health and part.flinch_count == 0 then
goto continue;
end
if config.current_config.large_monster_UI.highlighted.parts.settings.time_limit ~= 0 and time.total_elapsed_seconds - part.last_change_time > config.current_config.large_monster_UI.highlighted.parts.settings.time_limit then
goto continue;
end
table.insert(displayed_parts, part);
::continue::
end
if config.current_config.large_monster_UI.highlighted.parts.sorting.type == "Normal" then
if config.current_config.large_monster_UI.highlighted.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.id > right.id;
end);
else
table.sort(displayed_parts, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.highlighted.parts.sorting.type == "Health" then
if config.current_config.large_monster_UI.highlighted.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health > right.health;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health < right.health;
end);
end
elseif config.current_config.large_monster_UI.highlighted.parts.sorting.type == "Health Percentage" then
if config.current_config.large_monster_UI.highlighted.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health_percentage > right.health_percentage;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health_percentage < right.health_percentage;
end);
end
end
local last_part_position_on_screen;
for j, part in ipairs(displayed_parts) do
local part_position_on_screen = {
x = parts_position_on_screen.x + config.current_config.large_monster_UI.highlighted.parts.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.highlighted.parts.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
};
body_part_UI_entity.draw_highlighted(part, part_position_on_screen, opacity_scale);
last_part_position_on_screen = part_position_on_screen;
end
return last_part_position_on_screen;
end
function body_part.init_module()
@@ -108,6 +293,7 @@ function body_part.init_module()
screen = require("MHR_Overlay.Game_Handler.screen");
drawing = require("MHR_Overlay.UI.drawing");
part_names = require("MHR_Overlay.Misc.part_names");
time = require("MHR_Overlay.Game_Handler.time");
end
return body_part;

View File

@@ -7,10 +7,12 @@ local table_helpers;
local health_UI_entity;
local stamina_UI_entity;
local rage_UI_entity;
local ailment_UI_entity;
local screen;
local drawing;
local ailments;
local player;
local time;
local body_part;
local part_names;
@@ -66,16 +68,7 @@ function large_monster.new(enemy)
monster.parts = {};
monster.ailment = {};
monster.ailment[ailments.poison_id] = {};
monster.ailment[ailments.poison_id].buildup = {};
monster.ailment[ailments.poison_id].share = {};
monster.ailment[ailments.poison_id].activate_count = 0;
monster.ailment[ailments.blast_id] = {};
monster.ailment[ailments.blast_id].buildup = {};
monster.ailment[ailments.blast_id].share = {};
monster.ailment[ailments.blast_id].activate_count = 0;
monster.ailments = ailments.init_ailments();
monster.rider_id = -1;
@@ -130,7 +123,6 @@ function large_monster.init(monster, enemy)
if enemy_name ~= nil then
monster.name = enemy_name;
end
local set_info = get_set_info_method:call(enemy);
if set_info ~= nil then
local unique_id = get_unique_id_method:call(set_info);
@@ -173,6 +165,56 @@ function large_monster.init(monster, enemy)
end
end
function large_monster.init_dynamic_UI(monster)
monster.dynamic_name_label = table_helpers.deep_copy(config.current_config.large_monster_UI.dynamic.monster_name_label);
monster.health_dynamic_UI = health_UI_entity.new(
config.current_config.large_monster_UI.dynamic.health.visibility,
config.current_config.large_monster_UI.dynamic.health.bar,
config.current_config.large_monster_UI.dynamic.health.text_label,
config.current_config.large_monster_UI.dynamic.health.value_label,
config.current_config.large_monster_UI.dynamic.health.percentage_label
);
monster.health_dynamic_UI.bar.capture_line.offset.x = monster.health_dynamic_UI.bar.capture_line.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.capture_line.offset.y = monster.health_dynamic_UI.bar.capture_line.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.capture_line.size.width = monster.health_dynamic_UI.bar.capture_line.size.width * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.capture_line.size.height = monster.health_dynamic_UI.bar.capture_line.size.height * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.colors = config.current_config.large_monster_UI.dynamic.health.bar.normal_colors;
monster.stamina_dynamic_UI = stamina_UI_entity.new(
config.current_config.large_monster_UI.dynamic.stamina.visibility,
config.current_config.large_monster_UI.dynamic.stamina.bar,
config.current_config.large_monster_UI.dynamic.stamina.text_label,
config.current_config.large_monster_UI.dynamic.stamina.value_label,
config.current_config.large_monster_UI.dynamic.stamina.percentage_label
);
monster.rage_dynamic_UI = rage_UI_entity.new(
config.current_config.large_monster_UI.dynamic.rage.visibility,
config.current_config.large_monster_UI.dynamic.rage.bar,
config.current_config.large_monster_UI.dynamic.rage.text_label,
config.current_config.large_monster_UI.dynamic.rage.value_label,
config.current_config.large_monster_UI.dynamic.rage.percentage_label,
config.current_config.large_monster_UI.dynamic.rage.timer_label
);
for REpart, part in pairs(monster.parts) do
body_part.init_dynamic_UI(part);
end
monster.ailment_dynamic_UI = ailment_UI_entity.new(
config.current_config.large_monster_UI.dynamic.ailments.visibility,
config.current_config.large_monster_UI.dynamic.ailments.bar,
config.current_config.large_monster_UI.dynamic.ailments.ailment_name_label,
config.current_config.large_monster_UI.dynamic.ailments.text_label,
config.current_config.large_monster_UI.dynamic.ailments.value_label,
config.current_config.large_monster_UI.dynamic.ailments.percentage_label,
config.current_config.large_monster_UI.dynamic.ailments.timer_label
);
end
function large_monster.init_static_UI(monster)
monster.static_name_label = table_helpers.deep_copy(config.current_config.large_monster_UI.static.monster_name_label);
@@ -214,46 +256,16 @@ function large_monster.init_static_UI(monster)
for REpart, part in pairs(monster.parts) do
body_part.init_static_UI(part);
end
end
function large_monster.init_dynamic_UI(monster)
monster.dynamic_name_label = table_helpers.deep_copy(config.current_config.large_monster_UI.dynamic.monster_name_label);
monster.health_dynamic_UI = health_UI_entity.new(
config.current_config.large_monster_UI.dynamic.health.visibility,
config.current_config.large_monster_UI.dynamic.health.bar,
config.current_config.large_monster_UI.dynamic.health.text_label,
config.current_config.large_monster_UI.dynamic.health.value_label,
config.current_config.large_monster_UI.dynamic.health.percentage_label
monster.ailment_static_UI = ailment_UI_entity.new(
config.current_config.large_monster_UI.static.ailments.visibility,
config.current_config.large_monster_UI.static.ailments.bar,
config.current_config.large_monster_UI.static.ailments.ailment_name_label,
config.current_config.large_monster_UI.static.ailments.text_label,
config.current_config.large_monster_UI.static.ailments.value_label,
config.current_config.large_monster_UI.static.ailments.percentage_label,
config.current_config.large_monster_UI.static.ailments.timer_label
);
monster.health_dynamic_UI.bar.capture_line.offset.x = monster.health_dynamic_UI.bar.capture_line.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.capture_line.offset.y = monster.health_dynamic_UI.bar.capture_line.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.capture_line.size.width = monster.health_dynamic_UI.bar.capture_line.size.width * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.capture_line.size.height = monster.health_dynamic_UI.bar.capture_line.size.height * config.current_config.global_settings.modifiers.global_scale_modifier;
monster.health_dynamic_UI.bar.colors = config.current_config.large_monster_UI.dynamic.health.bar.normal_colors;
monster.stamina_dynamic_UI = stamina_UI_entity.new(
config.current_config.large_monster_UI.dynamic.stamina.visibility,
config.current_config.large_monster_UI.dynamic.stamina.bar,
config.current_config.large_monster_UI.dynamic.stamina.text_label,
config.current_config.large_monster_UI.dynamic.stamina.value_label,
config.current_config.large_monster_UI.dynamic.stamina.percentage_label
);
monster.rage_dynamic_UI = rage_UI_entity.new(
config.current_config.large_monster_UI.dynamic.rage.visibility,
config.current_config.large_monster_UI.dynamic.rage.bar,
config.current_config.large_monster_UI.dynamic.rage.text_label,
config.current_config.large_monster_UI.dynamic.rage.value_label,
config.current_config.large_monster_UI.dynamic.rage.percentage_label,
config.current_config.large_monster_UI.dynamic.rage.timer_label
);
for REpart, part in pairs(monster.parts) do
body_part.init_dynamic_UI(part);
end
end
function large_monster.init_highlighted_UI(monster)
@@ -294,12 +306,21 @@ function large_monster.init_highlighted_UI(monster)
for REpart, part in pairs(monster.parts) do
body_part.init_highlighted_UI(part);
end
monster.ailment_highlighted_UI = ailment_UI_entity.new(
config.current_config.large_monster_UI.highlighted.ailments.visibility,
config.current_config.large_monster_UI.highlighted.ailments.bar,
config.current_config.large_monster_UI.highlighted.ailments.ailment_name_label,
config.current_config.large_monster_UI.highlighted.ailments.text_label,
config.current_config.large_monster_UI.highlighted.ailments.value_label,
config.current_config.large_monster_UI.highlighted.ailments.percentage_label,
config.current_config.large_monster_UI.highlighted.ailments.timer_label
);
end
local physical_param_field = enemy_character_base_type_def:get_field("<PhysicalParam>k__BackingField");
local stamina_param_field = enemy_character_base_type_def:get_field("<StaminaParam>k__BackingField");
local anger_param_field = enemy_character_base_type_def:get_field("<AngerParam>k__BackingField");
local damage_param_field = enemy_character_base_type_def:get_field("<DamageParam>k__BackingField");
local check_die_method = enemy_character_base_type_def:get_method("checkDie");
local physical_param_type = physical_param_field:get_type();
@@ -323,20 +344,6 @@ local anger_param_get_timer_method = anger_param_type:get_method("get_Timer");
local get_timer_anger_method = anger_param_type:get_method("get_TimerAnger");
local get_count_anger_method = anger_param_type:get_method("get_CountAnger");
local damage_param_type = damage_param_field:get_type();
local poison_param_field = damage_param_type:get_field("_PoisonParam");
local blast_param_field = damage_param_type:get_field("_BlastParam");
local poison_param_type = poison_param_field:get_type();
local poison_get_activate_count_method = poison_param_type:get_method("get_ActivateCount");
local poison_damage_field = poison_param_type:get_field("<Damage>k__BackingField");
local poison_get_is_damage_method = poison_param_type:get_method("get_IsDamage");
local blast_param_type = blast_param_field:get_type();
local blast_get_activate_count_method = blast_param_type:get_method("get_ActivateCount");
local blast_damage_method = blast_param_type:get_method("get_BlastDamage");
local blast_adjust_rate_method = blast_param_type:get_method("get_BlastDamageAdjustRateByEnemyLv");
local mario_param_field = enemy_character_base_type_def:get_field("<MarioParam>k__BackingField");
local mario_param_type = mario_param_field:get_type();
@@ -408,52 +415,6 @@ function large_monster.update_all_riders()
end
-- Code by coavins
function large_monster.update_ailments(enemy)
if enemy == nil then
return;
end
local monster = large_monster.get_monster(enemy);
local damage_param = damage_param_field:get_data(enemy);
if damage_param ~= nil then
local poison_param = poison_param_field:get_data(damage_param);
if poison_param ~= nil then
-- if applied, then calculate share for poison
local activate_count = poison_get_activate_count_method:call(poison_param):get_element(0):get_field("mValue");
if activate_count > monster.ailment[ailments.poison_id].activate_count then
monster.ailment[ailments.poison_id].activate_count = activate_count;
ailments.calculate_ailment_contribution(monster, ailments.poison_id);
end
-- if poison tick, apply damage
local poison_damage = poison_damage_field:get_data(poison_param);
local is_damage = poison_get_is_damage_method:call(poison_param);
if is_damage then
ailments.apply_ailment_damage(monster, ailments.poison_id, poison_damage);
end
end
local blast_param = blast_param_field:get_data(damage_param);
if blast_param ~= nil then
-- if applied, then calculate share for blast and apply damage
local activate_count = blast_get_activate_count_method:call(blast_param):get_element(0):get_field("mValue");
if activate_count > monster.ailment[ailments.blast_id].activate_count then
monster.ailment[ailments.blast_id].activate_count = activate_count;
ailments.calculate_ailment_contribution(monster, ailments.blast_id);
local blast_damage = blast_damage_method:call(blast_param);
local blast_adjust_rate = blast_adjust_rate_method:call(blast_param);
ailments.apply_ailment_damage(monster, ailments.blast_id, blast_damage * blast_adjust_rate);
end
end
end
end
function large_monster.update(enemy)
if not config.current_config.large_monster_UI.dynamic.enabled
and not config.current_config.large_monster_UI.static.enabled
@@ -577,8 +538,6 @@ function large_monster.update(enemy)
::continue::
end
--large_monster.update_position(enemy);
if health ~= nil then
monster.health = health;
end
@@ -665,6 +624,8 @@ function large_monster.update(enemy)
if rage_count ~= nil then
monster.rage_count = rage_count;
end
ailments.update_ailments(enemy, monster);
end
function large_monster.draw_dynamic(monster, position_on_screen, opacity_scale)
@@ -712,6 +673,11 @@ function large_monster.draw_dynamic(monster, position_on_screen, opacity_scale)
x = position_on_screen.x + config.current_config.large_monster_UI.dynamic.parts.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = position_on_screen.y + config.current_config.large_monster_UI.dynamic.parts.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
local ailments_position_on_screen = {
x = position_on_screen.x + config.current_config.large_monster_UI.dynamic.ailments.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = position_on_screen.y + config.current_config.large_monster_UI.dynamic.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
health_UI_entity.draw(monster, monster.health_dynamic_UI, health_position_on_screen, opacity_scale);
drawing.draw_capture_line(monster.health_dynamic_UI.bar, health_position_on_screen, opacity_scale, monster.capture_percentage);
@@ -719,57 +685,17 @@ function large_monster.draw_dynamic(monster, position_on_screen, opacity_scale)
stamina_UI_entity.draw(monster, monster.stamina_dynamic_UI, stamina_position_on_screen, opacity_scale);
rage_UI_entity.draw(monster, monster.rage_dynamic_UI, rage_position_on_screen, opacity_scale);
--sort parts here
local displayed_parts = {};
for REpart, part in pairs(monster.parts) do
if config.current_config.large_monster_UI.dynamic.parts.settings.hide_undamaged_parts and part.health == part.max_health and part.flinch_count == 0 then
goto continue;
end
local last_part_position_on_screen = body_part.draw_dynamic(monster, parts_position_on_screen, opacity_scale);
table.insert(displayed_parts, part);
::continue::
end
if config.current_config.large_monster_UI.dynamic.parts.sorting.type == "Normal" then
if config.current_config.large_monster_UI.dynamic.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.id > right.id;
end);
if config.current_config.large_monster_UI.dynamic.ailments.settings.offset_is_relative_to_parts then
if last_part_position_on_screen == nil then
ailments_position_on_screen = parts_position_on_screen;
else
table.sort(displayed_parts, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.dynamic.parts.sorting.type == "Health" then
if config.current_config.large_monster_UI.dynamic.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health > right.health;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health < right.health;
end);
end
elseif config.current_config.large_monster_UI.dynamic.parts.sorting.type == "Health Percentage" then
if config.current_config.large_monster_UI.dynamic.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health_percentage > right.health_percentage;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health_percentage < right.health_percentage;
end);
ailments_position_on_screen.y = last_part_position_on_screen.y + config.current_config.large_monster_UI.dynamic.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
end
end
for j, part in ipairs(displayed_parts) do
local part_position_on_screen = {
x = parts_position_on_screen.x + config.current_config.large_monster_UI.dynamic.parts.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.dynamic.parts.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
body_part.draw_dynamic(part, part_position_on_screen, opacity_scale);
end
ailments.draw_dynamic(monster, ailments_position_on_screen, opacity_scale);
end
function large_monster.draw_static(monster, position_on_screen, opacity_scale)
@@ -818,66 +744,32 @@ function large_monster.draw_static(monster, position_on_screen, opacity_scale)
y = position_on_screen.y + config.current_config.large_monster_UI.static.parts.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
local ailments_position_on_screen = {
x = position_on_screen.x + config.current_config.large_monster_UI.static.ailments.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = position_on_screen.y + config.current_config.large_monster_UI.static.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
health_UI_entity.draw(monster, monster.health_static_UI, health_position_on_screen, opacity_scale);
drawing.draw_capture_line(monster.health_static_UI.bar, health_position_on_screen, opacity_scale, monster.capture_percentage);
stamina_UI_entity.draw(monster, monster.stamina_static_UI, stamina_position_on_screen, opacity_scale);
rage_UI_entity.draw(monster, monster.rage_static_UI, rage_position_on_screen, opacity_scale);
--sort parts here
local displayed_parts = {};
for REpart, part in pairs(monster.parts) do
if config.current_config.large_monster_UI.static.parts.settings.hide_undamaged_parts and part.health == part.max_health and part.flinch_count == 0 then
goto continue;
end
local last_part_position_on_screen = body_part.draw_static(monster, parts_position_on_screen, opacity_scale);
table.insert(displayed_parts, part);
::continue::
end
if config.current_config.large_monster_UI.static.parts.sorting.type == "Normal" then
if config.current_config.large_monster_UI.static.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.id > right.id;
end);
if config.current_config.large_monster_UI.static.ailments.settings.offset_is_relative_to_parts then
if last_part_position_on_screen == nil then
ailments_position_on_screen = parts_position_on_screen;
else
table.sort(displayed_parts, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.static.parts.sorting.type == "Health" then
if config.current_config.large_monster_UI.static.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health > right.health;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health < right.health;
end);
end
elseif config.current_config.large_monster_UI.static.parts.sorting.type == "Health Percentage" then
if config.current_config.large_monster_UI.static.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health_percentage > right.health_percentage;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health_percentage < right.health_percentage;
end);
ailments_position_on_screen.y = last_part_position_on_screen.y + config.current_config.large_monster_UI.static.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
end
end
for j, part in ipairs(displayed_parts) do
local part_position_on_screen = {
x = parts_position_on_screen.x + config.current_config.large_monster_UI.static.parts.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.static.parts.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
body_part.draw_static(part, part_position_on_screen, opacity_scale);
end
ailments.draw_static(monster, ailments_position_on_screen, opacity_scale);
end
function large_monster.draw_highlighted(monster, position_on_screen, opacity_scale)
local monster_name_text = "";
if config.current_config.large_monster_UI.highlighted.monster_name_label.include.monster_name then
monster_name_text = string.format("%s ", monster.name);
@@ -923,63 +815,33 @@ function large_monster.draw_highlighted(monster, position_on_screen, opacity_sca
y = position_on_screen.y + config.current_config.large_monster_UI.highlighted.parts.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
local ailments_position_on_screen = {
x = position_on_screen.x + config.current_config.large_monster_UI.highlighted.ailments.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = position_on_screen.y + config.current_config.large_monster_UI.highlighted.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
health_UI_entity.draw(monster, monster.health_highlighted_UI, health_position_on_screen, opacity_scale);
drawing.draw_capture_line(monster.health_highlighted_UI.bar, health_position_on_screen, opacity_scale, monster.capture_percentage);
stamina_UI_entity.draw(monster, monster.stamina_highlighted_UI, stamina_position_on_screen, opacity_scale);
rage_UI_entity.draw(monster, monster.rage_highlighted_UI, rage_position_on_screen, opacity_scale);
--sort parts here
local displayed_parts = {};
for REpart, part in pairs(monster.parts) do
if config.current_config.large_monster_UI.highlighted.parts.settings.hide_undamaged_parts and part.health == part.max_health and part.flinch_count == 0 then
goto continue;
end
local last_part_position_on_screen = body_part.draw_highlighted(monster, parts_position_on_screen, opacity_scale);
table.insert(displayed_parts, part);
::continue::
end
if config.current_config.large_monster_UI.highlighted.ailments.settings.offset_is_relative_to_parts then
if config.current_config.large_monster_UI.highlighted.parts.sorting.type == "Normal" then
if config.current_config.large_monster_UI.highlighted.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.id > right.id;
end);
if last_part_position_on_screen == nil then
ailments_position_on_screen = {
x = position_on_screen.x + config.current_config.large_monster_UI.highlighted.ailments.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.highlighted.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
else
table.sort(displayed_parts, function(left, right)
return left.id < right.id;
end);
end
elseif config.current_config.large_monster_UI.highlighted.parts.sorting.type == "Health" then
if config.current_config.large_monster_UI.highlighted.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health > right.health;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health < right.health;
end);
end
elseif config.current_config.large_monster_UI.highlighted.parts.sorting.type == "Health Percentage" then
if config.current_config.large_monster_UI.highlighted.parts.sorting.reversed_order then
table.sort(displayed_parts, function(left, right)
return left.health_percentage > right.health_percentage;
end);
else
table.sort(displayed_parts, function(left, right)
return left.health_percentage < right.health_percentage;
end);
ailments_position_on_screen.y = last_part_position_on_screen.y + config.current_config.large_monster_UI.highlighted.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
end
end
for j, part in ipairs(displayed_parts) do
local part_position_on_screen = {
x = parts_position_on_screen.x + config.current_config.large_monster_UI.highlighted.parts.spacing.x * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier,
y = parts_position_on_screen.y + config.current_config.large_monster_UI.highlighted.parts.spacing.y * (j - 1) * config.current_config.global_settings.modifiers.global_scale_modifier;
}
body_part.draw_highlighted(part, part_position_on_screen, opacity_scale);
end
ailments.draw_highlighted(monster, ailments_position_on_screen, opacity_scale);
end
function large_monster.init_list()
@@ -996,11 +858,13 @@ function large_monster.init_module()
health_UI_entity = require("MHR_Overlay.UI.UI_Entities.health_UI_entity");
stamina_UI_entity = require("MHR_Overlay.UI.UI_Entities.stamina_UI_entity");
rage_UI_entity = require("MHR_Overlay.UI.UI_Entities.rage_UI_entity");
ailment_UI_entity = require("MHR_Overlay.UI.UI_Entities.ailment_UI_entity");
screen = require("MHR_Overlay.Game_Handler.screen");
drawing = require("MHR_Overlay.UI.drawing");
part_names = require("MHR_Overlay.Misc.part_names");
ailments = require("MHR_Overlay.Damage_Meter.ailments");
ailments = require("MHR_Overlay.Monsters.ailments");
player = require("MHR_Overlay.Damage_Meter.player");
time = require("MHR_Overlay.Game_Handler.time");
end
return large_monster;

View File

@@ -2,6 +2,7 @@ local monster = {};
local small_monster;
local large_monster;
local config;
local ailments;
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");
@@ -66,26 +67,30 @@ function monster.update_monster(enemy)
if is_large == nil then
return;
end
ailments.update_poison_blast(enemy, is_large);
if is_large then
monster.update_large_monster(enemy);
else
monster.update_small_monster(enemy);
end
end
function monster.update_large_monster(enemy)
if not config.current_config.large_monster_UI.dynamic.enabled and
not config.current_config.large_monster_UI.static.enabled and
not config.current_config.large_monster_UI.highlighted.enabled then
return;
end
-- this is the VERY LEAST thing we should do all the time
-- so the position doesn't lag all over the place
-- due to how infrequently we update the monster(s).
if is_large then
large_monster.update_position(enemy);
large_monster.update_ailments(enemy);
else
small_monster.update_position(enemy);
small_monster.update_ailments(enemy);
end
large_monster.update_position(enemy);
if updated_monsters[enemy] then
if is_large then
if not config.current_config.global_settings.performance.prioritize_large_monsters then
return;
end
else
return;
end
if not config.current_config.global_settings.performance.prioritize_large_monsters and updated_monsters[enemy] then
return;
end
-- is it old tick?
@@ -96,29 +101,51 @@ function monster.update_monster(enemy)
-- actually update the enemy now. we don't do this very often
-- due to how much CPU time it takes to update each monster.
if is_large then
if not config.current_config.global_settings.performance.prioritize_large_monsters then
updates_this_tick = updates_this_tick + 1;
last_update_tick = tick_count;
num_updated_monsters = num_updated_monsters + 1;
updated_monsters[enemy] = true;
end
large_monster.update(enemy);
else
if not config.current_config.global_settings.performance.prioritize_large_monsters then
updates_this_tick = updates_this_tick + 1;
last_update_tick = tick_count;
num_updated_monsters = num_updated_monsters + 1;
updated_monsters[enemy] = true;
small_monster.update(enemy);
end
large_monster.update(enemy);
end
function monster.update_small_monster(enemy)
if not config.current_config.small_monster_UI.enabled then
return;
end
-- this is the VERY LEAST thing we should do all the time
-- so the position doesn't lag all over the place
-- due to how infrequently we update the monster(s).
small_monster.update_position(enemy);
if updated_monsters[enemy] then
return;
end
-- is it old tick?
-- is update limit reached?
if tick_count == last_update_tick and updates_this_tick >= config.current_config.global_settings.performance.max_monster_updates_per_tick then
return;
end
-- actually update the enemy now. we don't do this very often
-- due to how much CPU time it takes to update each monster.
updates_this_tick = updates_this_tick + 1;
last_update_tick = tick_count;
num_updated_monsters = num_updated_monsters + 1;
updated_monsters[enemy] = true;
small_monster.update(enemy);
end
function monster.init_module()
small_monster = require("MHR_Overlay.Monsters.small_monster");
large_monster = require("MHR_Overlay.Monsters.large_monster");
config = require("MHR_Overlay.Misc.config");
ailments = require("MHR_Overlay.Monsters.ailments");
end
return monster;

View File

@@ -8,6 +8,7 @@ local stamina_UI_entity;
local screen;
local drawing;
local ailments;
local ailment_UI_entity;
small_monster.list = {};
@@ -33,16 +34,7 @@ function small_monster.new(enemy)
monster.name = "Small Monster";
monster.ailment = {};
monster.ailment[ailments.poison_id] = {};
monster.ailment[ailments.poison_id].buildup = {};
monster.ailment[ailments.poison_id].share = {};
monster.ailment[ailments.poison_id].activate_count = 0;
monster.ailment[ailments.blast_id] = {};
monster.ailment[ailments.blast_id].buildup = {};
monster.ailment[ailments.blast_id].share = {};
monster.ailment[ailments.blast_id].activate_count = 0;
monster.ailments = ailments.init_ailments();
small_monster.init(monster, enemy);
small_monster.init_UI(monster);
@@ -96,13 +88,22 @@ function small_monster.init_UI(monster)
config.current_config.small_monster_UI.stamina.value_label,
config.current_config.small_monster_UI.stamina.percentage_label
);
monster.ailment_UI = ailment_UI_entity.new(
config.current_config.small_monster_UI.ailments.visibility,
config.current_config.small_monster_UI.ailments.bar,
config.current_config.small_monster_UI.ailments.ailment_name_label,
config.current_config.small_monster_UI.ailments.text_label,
config.current_config.small_monster_UI.ailments.value_label,
config.current_config.small_monster_UI.ailments.percentage_label,
config.current_config.small_monster_UI.ailments.timer_label
);
end
local enemy_character_base_type_def = sdk.find_type_definition("snow.enemy.EnemyCharacterBase");
local physical_param_field = enemy_character_base_type_def:get_field("<PhysicalParam>k__BackingField");
local status_param_field = enemy_character_base_type_def:get_field("<StatusParam>k__BackingField");
local stamina_param_field = enemy_character_base_type_def:get_field("<StaminaParam>k__BackingField");
local damage_param_field = enemy_character_base_type_def:get_field("<DamageParam>k__BackingField");
local check_die_method = enemy_character_base_type_def:get_method("checkDie");
local physical_param_type = physical_param_field:get_type();
@@ -117,20 +118,6 @@ local stamina_param_type = stamina_param_field:get_type();
local get_stamina_method = stamina_param_type:get_method("getStamina");
local get_max_stamina_method = stamina_param_type:get_method("getMaxStamina");
local damage_param_type = damage_param_field:get_type();
local poison_param_field = damage_param_type:get_field("_PoisonParam");
local blast_param_field = damage_param_type:get_field("_BlastParam");
local poison_param_type = poison_param_field:get_type();
local poison_get_activate_count_method = poison_param_type:get_method("get_ActivateCount");
local poison_damage_field = poison_param_type:get_field("<Damage>k__BackingField");
local poison_get_is_damage_method = poison_param_type:get_method("get_IsDamage");
local blast_param_type = blast_param_field:get_type();
local blast_get_activate_count_method = blast_param_type:get_method("get_ActivateCount");
local blast_damage_method = blast_param_type:get_method("get_BlastDamage");
local blast_adjust_rate_method = blast_param_type:get_method("get_BlastDamageAdjustRateByEnemyLv");
local get_gameobject_method = sdk.find_type_definition("via.Component"):get_method("get_GameObject");
local get_transform_method = sdk.find_type_definition("via.GameObject"):get_method("get_Transform");
local get_position_method = sdk.find_type_definition("via.Transform"):get_method("get_Position");
@@ -173,53 +160,6 @@ function small_monster.update_position(enemy)
end
end
-- Code by coavins
function small_monster.update_ailments(enemy)
if enemy == nil then
return;
end
local monster = small_monster.get_monster(enemy);
local damage_param = damage_param_field:get_data(enemy);
if damage_param ~= nil then
local poison_param = poison_param_field:get_data(damage_param);
if poison_param ~= nil then
-- if applied, then calculate share for poison
local activate_count = poison_get_activate_count_method:call(poison_param):get_element(0):get_field("mValue");
if activate_count > monster.ailment[ailments.poison_id].activate_count then
monster.ailment[ailments.poison_id].activate_count = activate_count;
ailments.calculate_ailment_contribution(monster, ailments.poison_id);
end
-- if poison tick, apply damage
local poison_damage = poison_damage_field:get_data(poison_param);
local is_damage = poison_get_is_damage_method:call(poison_param);
if is_damage then
ailments.apply_ailment_damage(monster, ailments.poison_id, poison_damage);
end
end
--xy = "test"
local blast_param = blast_param_field:get_data(damage_param);
if blast_param ~= nil then
-- if applied, then calculate share for blast and apply damage
local activate_count = blast_get_activate_count_method:call(blast_param):get_element(0):get_field("mValue");
if activate_count > monster.ailment[ailments.blast_id].activate_count then
monster.ailment[ailments.blast_id].activate_count = activate_count;
ailments.calculate_ailment_contribution(monster, ailments.blast_id);
local blast_damage = blast_damage_method:call(blast_param);
local blast_adjust_rate = blast_adjust_rate_method:call(blast_param);
ailments.apply_ailment_damage(monster, ailments.blast_id, blast_damage * blast_adjust_rate);
end
end
end
end
function small_monster.update(enemy)
if enemy == nil then
return;
@@ -306,6 +246,8 @@ function small_monster.update(enemy)
monster.stamina_percentage = stamina / max_stamina;
end
end
ailments.update_ailments(enemy, monster)
end
function small_monster.draw(monster, position_on_screen, opacity_scale)
@@ -320,9 +262,16 @@ function small_monster.draw(monster, position_on_screen, opacity_scale)
x = position_on_screen.x + config.current_config.small_monster_UI.stamina.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = position_on_screen.y + config.current_config.small_monster_UI.stamina.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
local ailments_position_on_screen = {
x = position_on_screen.x + config.current_config.small_monster_UI.ailments.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier,
y = position_on_screen.y + config.current_config.small_monster_UI.ailments.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier
};
health_UI_entity.draw(monster, monster.health_UI, health_position_on_screen, opacity_scale);
stamina_UI_entity.draw(monster, monster.stamina_UI, stamina_position_on_screen, opacity_scale);
ailments.draw_small(monster, ailments_position_on_screen, opacity_scale);
end
function small_monster.init_list()
@@ -338,7 +287,8 @@ function small_monster.init_module()
stamina_UI_entity = require("MHR_Overlay.UI.UI_Entities.stamina_UI_entity");
screen = require("MHR_Overlay.Game_Handler.screen");
drawing = require("MHR_Overlay.UI.drawing");
ailments = require("MHR_Overlay.Damage_Meter.ailments");
ailments = require("MHR_Overlay.Monsters.ailments");
ailment_UI_entity = require("MHR_Overlay.UI.UI_Entities.ailment_UI_entity");
end
return small_monster;

View File

@@ -0,0 +1,164 @@
local ailment_UI_entity = {};
local config;
local table_helpers;
local drawing;
local language;
function ailment_UI_entity.new(visibility, bar, name_label, text_label, value_label, percentage_label, timer_label)
local entity = {};
entity.visibility = visibility;
entity.bar = table_helpers.deep_copy(bar);
entity.name_label = table_helpers.deep_copy(name_label);
entity.text_label = table_helpers.deep_copy(text_label);
entity.value_label = table_helpers.deep_copy(value_label);
entity.percentage_label = table_helpers.deep_copy(percentage_label);
entity.timer_label = table_helpers.deep_copy(timer_label);
entity.bar.offset.x = entity.bar.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.bar.offset.y = entity.bar.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.bar.size.width = entity.bar.size.width * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.bar.size.height = entity.bar.size.height * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.name_label.offset.x = entity.name_label.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.name_label.offset.y = entity.name_label.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.text_label.offset.x = entity.text_label.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.text_label.offset.y = entity.text_label.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.value_label.offset.x = entity.value_label.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.value_label.offset.y = entity.value_label.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.percentage_label.offset.x = entity.percentage_label.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.percentage_label.offset.y = entity.percentage_label.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.timer_label.offset.x = entity.timer_label.offset.x * config.current_config.global_settings.modifiers.global_scale_modifier;
entity.timer_label.offset.y = entity.timer_label.offset.y * config.current_config.global_settings.modifiers.global_scale_modifier;
return entity;
end
function ailment_UI_entity.draw_dynamic(ailment, ailment_UI, position_on_screen, opacity_scale)
if not ailment_UI.visibility then
return;
end
local ailment_name = "";
if config.current_config.large_monster_UI.dynamic.ailments.ailment_name_label.include.ailment_name then
ailment_name = ailment.name .. " ";
end
if config.current_config.large_monster_UI.dynamic.ailments.ailment_name_label.include.activation_count and ailment.activate_count ~= 0 then
ailment_name = ailment_name .. "x" .. tostring(ailment.activate_count);
end
if ailment.is_active then
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.timer_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.timer_label, position_on_screen, opacity_scale, 0, ailment.timer);
else
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.buildup_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.value_label, position_on_screen, opacity_scale, ailment.total_buildup, ailment.buildup_limit);
drawing.draw_label(ailment_UI.percentage_label, position_on_screen, opacity_scale, 100 * ailment.buildup_percentage);
end
end
function ailment_UI_entity.draw_static(ailment, ailment_UI, position_on_screen, opacity_scale)
if not ailment_UI.visibility then
return;
end
local ailment_name = "";
if config.current_config.large_monster_UI.static.ailments.ailment_name_label.include.ailment_name then
ailment_name = ailment.name .. " ";
end
if config.current_config.large_monster_UI.static.ailments.ailment_name_label.include.activation_count and ailment.activate_count ~= 0 then
ailment_name = ailment_name .. "x" .. tostring(ailment.activate_count);
end
if ailment.is_active then
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.timer_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.timer_label, position_on_screen, opacity_scale, 0, ailment.timer);
else
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.buildup_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.value_label, position_on_screen, opacity_scale, ailment.total_buildup, ailment.buildup_limit);
drawing.draw_label(ailment_UI.percentage_label, position_on_screen, opacity_scale, 100 * ailment.buildup_percentage);
end
end
function ailment_UI_entity.draw_highlighted(ailment, ailment_UI, position_on_screen, opacity_scale)
if not ailment_UI.visibility then
return;
end
local ailment_name = "";
if config.current_config.large_monster_UI.highlighted.ailments.ailment_name_label.include.ailment_name then
ailment_name = ailment.name .. " ";
end
if config.current_config.large_monster_UI.highlighted.ailments.ailment_name_label.include.activation_count and ailment.activate_count ~= 0 then
ailment_name = ailment_name .. "x" .. tostring(ailment.activate_count);
end
if ailment.is_active then
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.timer_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.timer_label, position_on_screen, opacity_scale, 0, ailment.timer);
else
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.buildup_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.value_label, position_on_screen, opacity_scale, ailment.total_buildup, ailment.buildup_limit);
drawing.draw_label(ailment_UI.percentage_label, position_on_screen, opacity_scale, 100 * ailment.buildup_percentage);
end
end
function ailment_UI_entity.draw_small(ailment, ailment_UI, position_on_screen, opacity_scale)
if not ailment_UI.visibility then
return;
end
local ailment_name = "";
if config.current_config.small_monster_UI.ailments.ailment_name_label.include.ailment_name then
ailment_name = ailment.name .. " ";
end
if config.current_config.small_monster_UI.ailments.ailment_name_label.include.activation_count and ailment.activate_count ~= 0 then
ailment_name = ailment_name .. "x" .. tostring(ailment.activate_count);
end
if ailment.is_active then
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.timer_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.timer_label, position_on_screen, opacity_scale, 0, ailment.timer);
else
drawing.draw_bar(ailment_UI.bar, position_on_screen, opacity_scale, ailment.buildup_percentage);
drawing.draw_label(ailment_UI.name_label, position_on_screen, opacity_scale, ailment_name);
drawing.draw_label(ailment_UI.text_label, position_on_screen, opacity_scale, language.current_language.UI.buildup);
drawing.draw_label(ailment_UI.value_label, position_on_screen, opacity_scale, ailment.total_buildup, ailment.buildup_limit);
drawing.draw_label(ailment_UI.percentage_label, position_on_screen, opacity_scale, 100 * ailment.buildup_percentage);
end
end
function ailment_UI_entity.init_module()
table_helpers = require("MHR_Overlay.Misc.table_helpers");
drawing = require("MHR_Overlay.UI.drawing");
config = require("MHR_Overlay.Misc.config");
language = require("MHR_Overlay.Misc.language");
end
return ailment_UI_entity;

File diff suppressed because it is too large Load Diff