-- Biters, Spawners and Worms 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 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 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, _ in pairs(global.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 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 not entity_types[biter.type] 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 = global.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() 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