mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-06 00:23:49 +02:00
168 lines
4.9 KiB
Lua
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
|