1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-08 00:39:30 +02:00
ComfyFactorio/modules/biter_health_booster.lua
randomdud3 b6aec3bd07 Use the current health when calculating health pool changes
Ideally, you could keep the health modifier in the pool structure so you
dont need to calculate the inverse every time again, but since the 3rd
spot meant stuff for bosses and it was used in other places, i didn't
want to mess with it.
2020-01-02 23:51:29 +01:00

134 lines
4.2 KiB
Lua

-- Biters and Spitters gain additional health / resistance -- mewmew
-- Use global.biter_health_boost or global.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 function clean_table()
--Perform a table cleanup every 1000 boosts
global.biter_health_boost_count = global.biter_health_boost_count + 1
if global.biter_health_boost_count % 1000 ~= 0 then return end
local units_to_delete = {}
--Mark all health boost entries for deletion
for key, health in pairs(global.biter_health_boost_units) do
units_to_delete[key] = true
end
--Remove valid health boost entries from deletion
for _, surface in pairs(game.surfaces) do
for _, unit in pairs(surface.find_entities_filtered({type = "unit"})) do
units_to_delete[unit.unit_number] = nil
end
end
--Remove abandoned health boost entries
for key, _ in pairs(units_to_delete) do
global.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, target_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 = rendering.get_y_scale(healthbar_id) * 15
rendering.set_x_scale(healthbar_id, x_scale * m)
rendering.set_color(healthbar_id, {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 = global.biter_health_boost end
global.biter_health_boost_units[unit.unit_number] = {
math_floor(unit.prototype.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 = global.biter_health_boost end
if not health_bar_size then health_bar_size = 0.5 end
local health = math_floor(unit.prototype.max_health * health_multiplier)
global.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 biter.type ~= "unit" then return end
if event.final_damage_amount == 0 then return end
local biter_health_boost_units = global.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 global.biter_health_boost_forces[biter.force.index] then
Public.add_unit(biter, global.biter_health_boost_forces[biter.force.index])
else
Public.add_unit(biter, global.biter_health_boost)
end
health_pool = 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
--Calculate current actual health, accounting for regeneration
local current_health = biter.health * (1 / health_pool[2])
--Reduce health pool
health_pool[1] = current_health - 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()
global.biter_health_boost = 1
global.biter_health_boost_forces = {}
global.biter_health_boost_units = {}
global.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