1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2024-12-14 10:13:13 +02:00
RedMew/map_gen/Diggy/AlienEvolutionProgress.lua

141 lines
4.1 KiB
Lua

--[[-- info
Original (javascript) version: https://hastebin.com/udakacavap.js
Can be tested against: https://wiki.factorio.com/Enemies#Spawn_chances_by_evolution_factor
]]
-- dependencies
-- this
local AlienEvolutionProgress = {}
global.alien_spawner_cache = {
biters = {},
spitters = {},
}
-- values are in the form {evolution, weight}
local biters = {
{'small-biter', {{0.0, 0.3}, {0.6, 0.0}}},
{'medium-biter', {{0.2, 0.0}, {0.6, 0.3}, {0.7, 0.1}}},
{'big-biter', {{0.5, 0.0}, {1.0, 0.4}}},
{'behemoth-biter', {{0.9, 0.0}, {1.0, 0.3}}},
}
local spitters = {
{'small-biter', {{0.0, 0.3}, {0.35, 0.0}}},
{'small-spitter', {{0.25, 0.0}, {0.5, 0.3}, {0.7, 0.0}}},
{'medium-spitter', {{0.4, 0.0}, {0.7, 0.3}, {0.9, 0.1}}},
{'big-spitter', {{0.5, 0.0}, {1.0, 0.4}}},
{'behemoth-spitter', {{0.9, 0.0}, {1.0, 0.3}}},
}
local function lerp(low, high, pos)
local s = high[1] - low[1];
local l = (pos - low[1]) / s;
return (low[2] * (1 - l)) + (high[2] * l)
end
local function get_values(map, evo)
local result = {}
local sum = 0
for _, data in pairs(map) do
local list = data[2];
local low = list[1];
local high = list[#list];
for _, val in pairs(list) do
if(val[1] <= evo and val[1] > low[1]) then
low = val;
end
if(val[1] >= evo and val[1] < high[1]) then
high = val
end
end
local val
if (evo <= low[1]) then
val = low[2]
elseif (evo >= high[1]) then
val = high[2];
else
val = lerp(low, high, evo)
end
sum = sum + val;
result[data[1]] = val;
end
for index, _ in pairs(result) do
result[index] = result[index] / sum
end
return result;
end
local function get_name_by_random(collection)
local random = math.random()
local current = 0
for name, probability in pairs(collection) do
current = current + probability
if (current >= random) then
return name
end
end
Debug.print('AlienEvolutionProgress.get_name_by_random: Current \'' .. current .. '\' should be higher or equal to random \'' .. random .. '\'')
end
function AlienEvolutionProgress.getBiterValues(evolution)
local evolution_cache_key = evolution * 100
if (nil == global.alien_spawner_cache.biters[evolution_cache_key]) then
global.alien_spawner_cache.biters[evolution_cache_key] = get_values(biters, evolution)
end
return global.alien_spawner_cache.biters[evolution_cache_key]
end
function AlienEvolutionProgress.getSpitterValues(evolution)
local evolution_cache_key = evolution * 100
if (nil == global.alien_spawner_cache.spitters[evolution_cache_key]) then
global.alien_spawner_cache.biters[evolution_cache_key] = get_values(spitters, evolution)
end
return global.alien_spawner_cache.biters[evolution_cache_key]
end
function AlienEvolutionProgress.getBitersByEvolution(total_biters, evolution)
local biters_calculated = {}
local map = AlienEvolutionProgress.getBiterValues(evolution)
for i = 1, total_biters do
local random = get_name_by_random(map)
if (nil == biters_calculated[random]) then
biters_calculated[random] = 1
else
biters_calculated[random] = biters_calculated[random] + 1
end
end
return biters_calculated
end
function AlienEvolutionProgress.getSpittersByEvolution(total_spitters, evolution)
local spitters_calculated = {}
local map = AlienEvolutionProgress.getSpitterValues(evolution)
for i = 1, total_spitters do
local random = get_name_by_random(map)
if (nil == spitters_calculated[random]) then
spitters_calculated[random] = 1
else
spitters_calculated[random] = spitters_calculated[random] + 1
end
end
return spitters_calculated
end
return AlienEvolutionProgress