1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-06 00:23:49 +02:00
ComfyFactorio/modules/biter_health_booster.lua
2024-10-25 16:15:09 +02:00

168 lines
4.9 KiB
Lua

-- Biters, Spawners and Worms gain additional health / resistance -- mewmew
-- Use storage.biter_health_boost or storage.biter_health_boost_forces to modify their health.
-- 1 = vanilla health, 2 = 200% vanilla health
-- do not use values below 1
local math_floor = math.floor
local math_round = math.round
local Public = {}
local entity_types = {
['unit'] = true,
['turret'] = true,
['unit-spawner'] = true
}
if is_loaded('maps.biter_hatchery.terrain') then
entity_types['unit-spawner'] = nil
end
local function clean_table()
--Perform a table cleanup every 1000 boosts
storage.biter_health_boost_count = storage.biter_health_boost_count + 1
if storage.biter_health_boost_count % 1000 ~= 0 then
return
end
local units_to_delete = {}
--Mark all health boost entries for deletion
for key, _ in pairs(storage.biter_health_boost_units) do
units_to_delete[key] = true
end
--Remove valid health boost entries from deletion
local validtypes = {}
for k, v in pairs(entity_types) do
if v then
table.insert(validtypes, k)
end
end
for _, surface in pairs(game.surfaces) do
for _, unit in pairs(surface.find_entities_filtered({ type = validtypes })) do
units_to_delete[unit.unit_number] = nil
end
end
--Remove abandoned health boost entries
for key, _ in pairs(units_to_delete) do
storage.biter_health_boost_units[key] = nil
end
end
local function create_boss_healthbar(entity, size)
return rendering.draw_sprite(
{
sprite = 'virtual-signal/signal-white',
tint = { 0, 200, 0 },
x_scale = size * 15,
y_scale = size,
render_layer = 'light-effect',
target = {
entity = entity,
offset = { 0, -2.5 },
},
surface = entity.surface
}
)
end
local function set_boss_healthbar(health, max_health, healthbar_id)
local m = health / max_health
local x_scale = healthbar_id.y_scale * 15
healthbar_id.x_scale = x_scale * m
healthbar_id.color = { math.floor(255 - 255 * m), math.floor(200 * m), 0 }
end
function Public.add_unit(unit, health_multiplier)
if not health_multiplier then
health_multiplier = storage.biter_health_boost
end
storage.biter_health_boost_units[unit.unit_number] = {
math_floor(unit.max_health * health_multiplier),
math_round(1 / health_multiplier, 5)
}
clean_table()
end
function Public.add_boss_unit(unit, health_multiplier, health_bar_size)
if not health_multiplier then
health_multiplier = storage.biter_health_boost
end
if not health_bar_size then
health_bar_size = 0.5
end
local health = math_floor(unit.max_health * health_multiplier)
storage.biter_health_boost_units[unit.unit_number] = {
health,
math_round(1 / health_multiplier, 5),
{ max_health = health, healthbar_id = create_boss_healthbar(unit, health_bar_size), last_update = game.tick }
}
clean_table()
end
local function on_entity_damaged(event)
local biter = event.entity
if not (biter and biter.valid) then
return
end
if not entity_types[biter.type] then
return
end
local biter_health_boost_units = storage.biter_health_boost_units
local unit_number = biter.unit_number
--Create new health pool
local health_pool = biter_health_boost_units[unit_number]
if not health_pool then
if storage.biter_health_boost_forces[biter.force.index] then
Public.add_unit(biter, storage.biter_health_boost_forces[biter.force.index])
else
Public.add_unit(biter, storage.biter_health_boost)
end
health_pool = storage.biter_health_boost_units[unit_number]
end
--Process boss unit health bars
local boss = health_pool[3]
if boss then
if boss.last_update + 10 < game.tick then
set_boss_healthbar(health_pool[1], boss.max_health, boss.healthbar_id)
boss.last_update = game.tick
end
end
--Reduce health pool
health_pool[1] = health_pool[1] - event.final_damage_amount
--Set entity health relative to health pool
biter.health = health_pool[1] * health_pool[2]
--Proceed to kill entity if health is 0
if biter.health > 0 then
return
end
if event.cause then
if event.cause.valid then
event.entity.die(event.cause.force, event.cause)
return
end
end
biter.die(biter.force)
end
local function on_init()
storage.biter_health_boost = 1
storage.biter_health_boost_forces = {}
storage.biter_health_boost_units = {}
storage.biter_health_boost_count = 0
end
local event = require 'utils.event'
event.on_init(on_init)
event.add(defines.events.on_entity_damaged, on_entity_damaged)
return Public