mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-16 10:19:27 +02:00
e2b6f6096d
Fixes an infrequent bug in hail_hydra that has existed a long time. Currently Factorio does not allow enemy entitities of type 'turret' to target entities of type 'car' (includes cars and tanks). Doing so logs an error. If this changes in the future then the condition cause.type ~= "car" below can be removed.
214 lines
6.3 KiB
Lua
214 lines
6.3 KiB
Lua
-- Cut off a limb, and two more shall take its place!
|
|
local Event = require 'utils.event'
|
|
local CreateParticles = require 'features.create_particles'
|
|
local Token = require 'utils.token'
|
|
local Global = require 'utils.global'
|
|
local table = require 'utils.table'
|
|
local random = math.random
|
|
local floor = math.floor
|
|
local ceil = math.ceil
|
|
local pairs = pairs
|
|
local type = type
|
|
local clear_table = table.clear_table
|
|
local compound = defines.command.compound
|
|
local logical_or = defines.compound_command.logical_or
|
|
local attack = defines.command.attack
|
|
local attack_area = defines.command.attack_area
|
|
local hail_hydra_conf = global.config.hail_hydra
|
|
|
|
local spawn_table = {}
|
|
for k, v in pairs(global.config.hail_hydra.hydras) do
|
|
spawn_table[k] = v
|
|
end
|
|
|
|
local function formula(evo)
|
|
evo = evo * 100
|
|
local value = (0.00003 * evo ^ 3 + 0.004 * evo ^ 2 + 0.3 * evo) * 0.01
|
|
return value <= 1 and value or 1
|
|
end
|
|
|
|
local primitives = {
|
|
evolution_scale = (hail_hydra_conf.evolution_scale ~= nil) and hail_hydra_conf.evolution_scale or 1,
|
|
online_player_scale_enabled = hail_hydra_conf.online_player_scale_enabled,
|
|
online_player_scale = hail_hydra_conf.online_player_scale,
|
|
enabled = nil
|
|
}
|
|
|
|
Global.register(
|
|
{
|
|
primitives = primitives,
|
|
spawn_table = spawn_table
|
|
},
|
|
function(tbl)
|
|
primitives = tbl.primitives
|
|
spawn_table = tbl.spawn_table
|
|
end
|
|
)
|
|
|
|
local Public = {}
|
|
|
|
local function backwards_compatibility(amount)
|
|
return {min = amount, max = amount + primitives.evolution_scale}
|
|
end
|
|
|
|
local function create_attack_command(position, target)
|
|
local command = {type = attack_area, destination = position, radius = 10}
|
|
if target then
|
|
command = {
|
|
type = compound,
|
|
structure_type = logical_or,
|
|
commands = {
|
|
{type = attack, target = target},
|
|
command
|
|
}
|
|
}
|
|
end
|
|
|
|
return command
|
|
end
|
|
|
|
local on_died =
|
|
Token.register(
|
|
function(event)
|
|
local entity = event.entity
|
|
local name = entity.name
|
|
|
|
local hydra = spawn_table[name]
|
|
if not hydra then
|
|
return
|
|
end
|
|
|
|
local position = entity.position
|
|
local force = entity.force
|
|
|
|
local num_online_players = #game.connected_players
|
|
local player_scale = 0
|
|
if primitives.online_player_scale_enabled then
|
|
player_scale = (num_online_players - primitives.online_player_scale) * 0.01
|
|
end
|
|
|
|
local evolution_scaled = formula(force.evolution_factor)
|
|
local evolution_factor = evolution_scaled + evolution_scaled * player_scale
|
|
|
|
local cause = event.cause
|
|
local surface = entity.surface
|
|
local create_entity = surface.create_entity
|
|
local create_particle = surface.create_particle
|
|
local find_non_colliding_position = surface.find_non_colliding_position
|
|
|
|
local command = create_attack_command(position, cause)
|
|
|
|
for hydra_spawn, amount in pairs(hydra) do
|
|
if (type(amount) == 'number') then
|
|
amount = backwards_compatibility(amount)
|
|
end
|
|
local trigger = amount.trigger
|
|
if trigger == nil or trigger < force.evolution_factor then
|
|
if amount.locked then
|
|
evolution_factor = evolution_scaled
|
|
end
|
|
local min = amount.min
|
|
local max = amount.max
|
|
max = (max ~= nil and max >= min) and max or min
|
|
if max ~= min then
|
|
amount = (max - min) * (evolution_factor / formula(1)) + min
|
|
else
|
|
amount = min
|
|
end
|
|
else
|
|
amount = 0
|
|
end
|
|
amount = (amount > 0) and amount or 0
|
|
|
|
local extra_chance = amount % 1
|
|
if extra_chance > 0 then
|
|
if random() <= extra_chance then
|
|
amount = ceil(amount)
|
|
else
|
|
amount = floor(amount)
|
|
end
|
|
end
|
|
local particle_count
|
|
|
|
if amount > 4 then
|
|
particle_count = 60
|
|
else
|
|
particle_count = amount * 15
|
|
end
|
|
|
|
CreateParticles.blood_explosion(create_particle, particle_count, position)
|
|
|
|
for _ = amount, 1, -1 do
|
|
position = find_non_colliding_position(hydra_spawn, position, 2, 0.4) or position
|
|
local spawned = create_entity({name = hydra_spawn, force = force, position = position})
|
|
if spawned and spawned.type == 'unit' then
|
|
spawned.set_command(command)
|
|
elseif spawned and cause and cause.valid and cause.force and cause.type ~= "car" then
|
|
spawned.shooting_target = cause
|
|
end
|
|
end
|
|
end
|
|
end
|
|
)
|
|
|
|
local function register_event()
|
|
if not primitives.enabled then
|
|
Event.add_removable(defines.events.on_entity_died, on_died)
|
|
primitives.enabled = true
|
|
end
|
|
end
|
|
|
|
--- Enables hail_hydra
|
|
function Public.enable_hail_hydra()
|
|
register_event()
|
|
end
|
|
|
|
--- Disables hail_hydra
|
|
function Public.disable_hail_hydra()
|
|
if primitives.enabled then
|
|
Event.remove_removable(defines.events.on_entity_died, on_died)
|
|
primitives.enabled = nil
|
|
end
|
|
end
|
|
|
|
--- Sets the evolution scale
|
|
-- @param scale <number>
|
|
function Public.set_evolution_scale(scale)
|
|
primitives.evolution_scale = scale
|
|
end
|
|
|
|
--- Sets the online player scale
|
|
-- @param scale <number>
|
|
function Public.set_evolution_scale(scale)
|
|
primitives.online_player_scale = scale
|
|
end
|
|
|
|
--- Toggles the online player scale feature
|
|
-- @param enable <boolean>
|
|
function Public.set_evolution_scale(enabled)
|
|
primitives.online_player_scale_enabled = enabled
|
|
end
|
|
|
|
--- Sets the hydra spawning table
|
|
-- @param hydras <table> see config.lua's hail_hydra section for example
|
|
function Public.set_hydras(hydras)
|
|
clear_table(spawn_table)
|
|
for k, v in pairs(hydras) do
|
|
spawn_table[k] = v
|
|
end
|
|
end
|
|
|
|
--- Adds to/overwrites parts of the hydra spawning table
|
|
-- @param hydras <table> see config.lua's hail_hydra section for example
|
|
function Public.add_hydras(hydras)
|
|
for k, v in pairs(hydras) do
|
|
spawn_table[k] = v
|
|
end
|
|
end
|
|
|
|
if global.config.hail_hydra.enabled then
|
|
register_event()
|
|
end
|
|
|
|
return Public
|