1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-14 02:23:01 +02:00
Rampant/libs/BaseUtils.lua

747 lines
25 KiB
Lua
Raw Normal View History

2022-01-15 00:08:58 +02:00
-- Copyright (C) 2022 veden
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
2019-02-16 06:17:30 +02:00
if baseUtilsG then
return baseUtilsG
end
2017-05-08 08:56:11 +02:00
local baseUtils = {}
-- imports
local mathUtils = require("MathUtils")
2017-05-08 08:56:11 +02:00
local constants = require("Constants")
local chunkPropertyUtils = require("ChunkPropertyUtils")
2019-11-30 02:49:22 +02:00
local mapUtils = require("MapUtils")
local queryUtils = require("QueryUtils")
2017-06-08 02:57:24 +02:00
2017-05-08 08:56:11 +02:00
-- constants
local MINIMUM_BUILDING_COST = constants.MINIMUM_BUILDING_COST
2019-12-18 03:09:08 +02:00
local FACTION_MUTATION_MAPPING = constants.FACTION_MUTATION_MAPPING
2018-08-02 05:18:52 +02:00
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
local FACTIONS_BY_DAMAGE_TYPE = constants.FACTIONS_BY_DAMAGE_TYPE
2019-02-12 08:30:13 +02:00
local BASE_AI_STATE_ACTIVE = constants.BASE_AI_STATE_ACTIVE
2021-11-25 19:49:54 +02:00
local BASE_AI_STATE_DORMANT = constants.BASE_AI_STATE_DORMANT
2019-02-12 08:30:13 +02:00
2019-11-30 02:49:22 +02:00
local FACTION_SET = constants.FACTION_SET
2019-02-12 08:30:13 +02:00
local BASE_AI_MIN_STATE_DURATION = constants.BASE_AI_MIN_STATE_DURATION
local BASE_AI_MAX_STATE_DURATION = constants.BASE_AI_MAX_STATE_DURATION
2018-02-05 02:07:25 +02:00
2019-11-30 02:49:22 +02:00
local HIVE_BUILDINGS_COST = constants.HIVE_BUILDINGS_COST
local BASE_DISTANCE_THRESHOLD = constants.BASE_DISTANCE_THRESHOLD
local BASE_DISTANCE_LEVEL_BONUS = constants.BASE_DISTANCE_LEVEL_BONUS
local BASE_DISTANCE_TO_EVO_INDEX = constants.BASE_DISTANCE_TO_EVO_INDEX
2017-05-08 08:56:11 +02:00
local CHUNK_SIZE = constants.CHUNK_SIZE
2017-05-08 08:56:11 +02:00
-- imported functions
local setPositionXYInQuery = queryUtils.setPositionXYInQuery
2019-02-12 08:30:13 +02:00
local randomTickEvent = mathUtils.randomTickEvent
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
2017-05-08 08:56:11 +02:00
2019-11-30 02:49:22 +02:00
local getChunkByPosition = mapUtils.getChunkByPosition
2021-12-06 01:33:24 +02:00
local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG
2019-11-30 02:49:22 +02:00
local linearInterpolation = mathUtils.linearInterpolation
2017-06-01 03:46:53 +02:00
local mFloor = math.floor
local mMin = math.min
local mMax = math.max
2019-11-30 02:49:22 +02:00
local distort = mathUtils.distort
local getChunkBase = chunkPropertyUtils.getChunkBase
2017-06-01 03:46:53 +02:00
2019-11-30 02:49:22 +02:00
local getResourceGenerator = chunkPropertyUtils.getResourceGenerator
2020-05-20 04:37:16 +02:00
local next = next
2017-05-19 09:47:24 +02:00
-- module code
2017-05-08 08:56:11 +02:00
2021-11-27 00:00:08 +02:00
local function evoToTier(universe, evolutionFactor, maxSkips)
2019-11-30 02:49:22 +02:00
local v
2021-11-27 00:00:08 +02:00
local skipsRemaining = maxSkips
2019-12-16 03:16:56 +02:00
for i=10,1,-1 do
2021-02-20 09:31:36 +02:00
if universe.evoToTierMapping[i] <= evolutionFactor then
2019-11-30 02:49:22 +02:00
v = i
2021-12-06 01:33:24 +02:00
if (skipsRemaining == 0) or (universe.random() <= 0.75) then
2019-11-30 02:49:22 +02:00
break
2019-03-12 08:03:26 +02:00
end
2021-11-27 00:00:08 +02:00
skipsRemaining = skipsRemaining - 1
2019-10-19 21:13:48 +02:00
end
2019-03-12 08:03:26 +02:00
end
2019-11-30 02:49:22 +02:00
return v
2018-08-02 05:18:52 +02:00
end
2019-11-30 02:49:22 +02:00
function baseUtils.findNearbyBase(map, chunk)
local x = chunk.x
local y = chunk.y
local foundBase = getChunkBase(map, chunk)
if foundBase then
2019-10-19 21:13:48 +02:00
return foundBase
end
2021-02-20 09:31:36 +02:00
local bases = map.bases
2020-08-08 22:38:15 +02:00
local closest = MAGIC_MAXIMUM_NUMBER
2020-05-20 04:37:16 +02:00
for _, base in pairs(bases) do
2019-10-19 21:13:48 +02:00
local distance = euclideanDistancePoints(base.x, base.y, x, y)
2020-08-08 22:38:15 +02:00
if (distance <= base.distanceThreshold) and (distance < closest) then
closest = distance
2019-10-19 21:13:48 +02:00
foundBase = base
end
2017-05-08 08:56:11 +02:00
end
2019-02-03 08:01:28 +02:00
2017-05-28 06:50:37 +02:00
return foundBase
2017-05-19 09:47:24 +02:00
end
2021-02-20 09:31:36 +02:00
local function findBaseMutation(map, targetEvolution)
local universe = map.universe
2021-11-27 00:00:08 +02:00
local tier = evoToTier(universe, targetEvolution or map.evolutionLevel, 2)
2021-02-20 09:31:36 +02:00
local alignments = universe.evolutionTableAlignment[tier]
2019-02-03 08:01:28 +02:00
2021-12-06 01:33:24 +02:00
local roll = map.random()
2019-11-30 02:49:22 +02:00
for i=1,#alignments do
local alignment = alignments[i]
2019-11-30 02:49:22 +02:00
roll = roll - alignment[1]
2019-11-04 08:19:22 +02:00
2019-11-30 02:49:22 +02:00
if (roll <= 0) then
return alignment[2]
end
end
2019-11-30 02:49:22 +02:00
return alignments[#alignments]
end
2019-02-03 08:01:28 +02:00
local function initialEntityUpgrade(baseAlignment, tier, maxTier, map, useHiveType, entityType)
2021-02-20 09:31:36 +02:00
local evolutionTable = map.universe.buildingEvolveLookup
2019-11-30 02:49:22 +02:00
local entity
2019-12-16 03:16:56 +02:00
local useTier
2021-12-06 01:33:24 +02:00
local tierRoll = map.random()
2019-12-16 03:16:56 +02:00
if (tierRoll < 0.4) then
useTier = maxTier
elseif (tierRoll < 0.7) then
useTier = mMax(maxTier - 1, tier)
elseif (tierRoll < 0.9) then
useTier = mMax(maxTier - 2, tier)
else
useTier = mMax(maxTier - 3, tier)
end
local alignmentTable = evolutionTable[baseAlignment]
local upgrades = alignmentTable[useTier]
2019-12-16 03:16:56 +02:00
if upgrades then
if useHiveType then
for ui=1,#upgrades do
local upgrade = upgrades[ui]
if upgrade[3] == useHiveType then
2021-12-06 01:33:24 +02:00
entity = upgrade[2][map.random(#upgrade[2])]
2019-12-16 03:16:56 +02:00
break
2019-03-12 08:03:26 +02:00
end
2019-12-16 03:16:56 +02:00
end
2020-05-24 05:47:14 +02:00
end
if not entity then
2019-12-16 03:16:56 +02:00
for ui=1,#upgrades do
local upgrade = upgrades[ui]
if upgrade[3] == entityType then
2021-12-06 01:33:24 +02:00
entity = upgrade[2][map.random(#upgrade[2])]
end
end
if not entity then
local mapTypes = FACTION_MUTATION_MAPPING[entityType]
for i=1, #mapTypes do
local mappedType = mapTypes[i]
for ui=1,#upgrades do
local upgrade = upgrades[ui]
if upgrade[3] == mappedType then
return upgrade[2][map.random(#upgrade[2])]
end
end
2019-03-12 08:03:26 +02:00
end
end
2019-11-04 08:19:22 +02:00
end
2019-11-30 02:49:22 +02:00
end
2019-12-16 03:16:56 +02:00
2019-11-30 02:49:22 +02:00
return entity
end
2021-02-20 09:31:36 +02:00
local function entityUpgrade(baseAlignment, tier, maxTier, originalEntity, map)
local universe = map.universe
local buildingHiveTypeLookup = universe.buildingHiveTypeLookup
local evolutionTable = universe.upgradeLookup
2019-11-30 02:49:22 +02:00
local entity
2019-12-18 03:09:08 +02:00
local hiveType = buildingHiveTypeLookup[originalEntity.name]
2019-11-30 02:49:22 +02:00
2019-12-18 03:09:08 +02:00
for t=maxTier,tier,-1 do
local factionLookup = evolutionTable[baseAlignment][t]
local upgrades = factionLookup[hiveType]
if not upgrades then
local mapTypes = FACTION_MUTATION_MAPPING[hiveType]
for i=1, #mapTypes do
local upgrade = factionLookup[mapTypes[i]]
if upgrade and (#upgrade > 0) then
2021-12-06 01:33:24 +02:00
entity = upgrade[map.random(#upgrade)]
if map.random() < 0.55 then
2019-12-18 03:09:08 +02:00
return entity
end
end
end
elseif (#upgrades > 0) then
2021-12-06 01:33:24 +02:00
entity = upgrades[map.random(#upgrades)]
if map.random() < 0.55 then
2020-05-24 05:47:14 +02:00
return entity
2019-03-12 08:03:26 +02:00
end
2019-11-04 08:19:22 +02:00
end
end
return entity
end
2021-02-20 09:31:36 +02:00
local function findEntityUpgrade(baseAlignment, currentEvo, evoIndex, originalEntity, map, evolve)
local universe = map.universe
2019-11-30 02:49:22 +02:00
local adjCurrentEvo = mMax(
2021-02-20 09:31:36 +02:00
((baseAlignment ~= universe.enemyAlignmentLookup[originalEntity.name]) and 0) or currentEvo,
2019-11-30 02:49:22 +02:00
0
)
2021-11-27 00:00:08 +02:00
local tier = evoToTier(universe, adjCurrentEvo, 5)
local maxTier = evoToTier(universe, evoIndex, 4)
2019-11-30 02:49:22 +02:00
if (tier > maxTier) then
maxTier = tier
2019-11-30 02:49:22 +02:00
end
2019-12-16 03:16:56 +02:00
2019-11-30 02:49:22 +02:00
if evolve then
2021-02-20 09:31:36 +02:00
local chunk = getChunkByPosition(map, originalEntity.position)
local entityType = map.universe.buildingHiveTypeLookup[originalEntity.name]
if not entityType then
if map.random() < 0.5 then
entityType = "biter-spawner"
else
entityType = "spitter-spawner"
end
end
local makeHive = (chunk ~= -1) and
(getResourceGenerator(map, chunk) > 0) and
((entityType == "biter-spawner") or (entityType == "spitter-spawner"))
and (map.random() < 0.2)
return initialEntityUpgrade(baseAlignment, tier, maxTier, map, (makeHive and "hive"), entityType)
2019-11-30 02:49:22 +02:00
else
2021-02-20 09:31:36 +02:00
return entityUpgrade(baseAlignment, tier, maxTier, originalEntity, map)
2019-12-16 03:16:56 +02:00
end
2019-11-30 02:49:22 +02:00
end
2021-02-20 09:31:36 +02:00
local function findBaseInitialAlignment(map, evoIndex)
local dev = evoIndex * 0.15
2021-12-06 01:33:24 +02:00
local evoTop = gaussianRandomRangeRG(evoIndex - (evoIndex * 0.075), dev, 0, evoIndex, map.random)
2019-11-30 02:49:22 +02:00
local result
2021-12-06 01:33:24 +02:00
if map.random() < 0.05 then
2021-02-20 09:31:36 +02:00
result = {findBaseMutation(map, evoTop), findBaseMutation(map, evoTop)}
2019-11-30 02:49:22 +02:00
else
2021-02-20 09:31:36 +02:00
result = {findBaseMutation(map, evoTop)}
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
return result
end
function baseUtils.recycleBases(map)
2021-02-20 09:31:36 +02:00
local bases = map.bases
2021-11-25 06:49:22 +02:00
local id = map.recycleBaseIterator
local base
if not id then
id, base = next(bases, nil)
else
base = bases[id]
end
2021-02-20 07:41:30 +02:00
if not id then
2021-02-20 09:31:36 +02:00
map.recycleBaseIterator = nil
2021-02-20 07:41:30 +02:00
else
2021-11-25 06:49:22 +02:00
map.recycleBaseIterator = next(bases, id)
if base.chunkCount == 0 then
2021-02-20 07:41:30 +02:00
bases[id] = nil
2019-02-03 08:01:28 +02:00
end
2018-01-26 07:48:12 +02:00
end
end
function baseUtils.upgradeEntity(entity, base, map, disPos, evolve, register)
local position = entity.position
2019-11-04 08:19:22 +02:00
local currentEvo = entity.prototype.build_base_evolution_requirement or 0
2019-02-03 08:01:28 +02:00
2019-03-12 08:03:26 +02:00
local distance = mMin(1, euclideanDistancePoints(position.x, position.y, 0, 0) * BASE_DISTANCE_TO_EVO_INDEX)
2021-02-20 09:31:36 +02:00
local evoIndex = mMax(distance, map.evolutionLevel)
local baseAlignment = base.alignment
2019-11-30 02:49:22 +02:00
local pickedBaseAlignment
if baseAlignment[2] then
2021-12-06 01:33:24 +02:00
if map.random() < 0.75 then
pickedBaseAlignment = baseAlignment[2]
else
pickedBaseAlignment = baseAlignment[1]
end
else
pickedBaseAlignment = baseAlignment[1]
end
local spawnerName = findEntityUpgrade(pickedBaseAlignment,
2019-11-30 02:49:22 +02:00
currentEvo,
evoIndex,
entity,
2021-02-20 09:31:36 +02:00
map,
2019-12-16 03:16:56 +02:00
evolve)
2021-12-17 05:20:29 +02:00
if spawnerName and (spawnerName ~= entity.name) then
2021-11-26 08:49:28 +02:00
local entityData = {
["name"] = spawnerName,
["position"] = disPos,
["register"] = register,
["map"] = map,
["base"] = base,
["entity"] = entity
2021-11-26 08:49:28 +02:00
}
map.universe.pendingUpgrades[entity.unit_number] = entityData
2021-11-26 08:49:28 +02:00
return spawnerName
2019-02-13 03:12:32 +02:00
end
if entity.valid then
if map.universe.proxyEntityLookup[entity.name] then
entity.destroy()
end
end
2021-11-26 08:49:28 +02:00
return nil
2019-02-12 08:30:13 +02:00
end
local function pickMutationFromDamageType(map, damageType, roll, base)
local baseAlignment = base.alignment
local damageFactions = FACTIONS_BY_DAMAGE_TYPE[damageType]
2021-07-26 02:25:14 +02:00
local mutation
2021-07-25 05:23:38 +02:00
if (damageFactions and (#damageFactions > 0)) then
2021-12-06 01:33:24 +02:00
mutation = damageFactions[map.random(#damageFactions)]
if baseAlignment[2] then
if (roll < 0.05) then
baseAlignment[2] = nil
2021-07-26 02:25:14 +02:00
baseAlignment[1] = mutation
elseif (roll < 0.25) then
2021-07-26 02:25:14 +02:00
baseAlignment[1] = mutation
else
2021-07-26 02:25:14 +02:00
baseAlignment[2] = mutation
end
else
if (roll < 0.85) then
2021-07-26 02:25:14 +02:00
base.alignment[1] = mutation
else
2021-07-26 02:25:14 +02:00
base.alignment[2] = mutation
end
end
else
2021-07-26 02:25:14 +02:00
mutation = findBaseMutation(map)
if baseAlignment[2] then
if (roll < 0.05) then
baseAlignment[2] = nil
2021-07-26 02:25:14 +02:00
baseAlignment[1] = mutation
elseif (roll < 0.25) then
2021-07-26 02:25:14 +02:00
baseAlignment[1] = mutation
else
2021-07-26 02:25:14 +02:00
baseAlignment[2] = mutation
end
else
if (roll < 0.85) then
2021-07-26 02:25:14 +02:00
base.alignment[1] = mutation
else
2021-07-26 02:25:14 +02:00
base.alignment[2] = mutation
end
end
end
2021-07-26 02:25:14 +02:00
if (map.universe.printBaseAdaptation) then
2021-11-25 19:04:52 +02:00
if baseAlignment[2] then
2021-07-26 02:25:14 +02:00
game.print({"description.rampant--adaptation2DebugMessage",
damageType,
{"description.rampant--"..baseAlignment[1].."EnemyName"},
{"description.rampant--"..baseAlignment[2].."EnemyName"},
base.x,
2021-11-25 19:04:52 +02:00
base.y,
base.mutations,
map.universe.MAX_BASE_MUTATIONS})
2021-07-26 02:25:14 +02:00
else
game.print({"description.rampant--adaptation1DebugMessage",
damageType,
{"description.rampant--"..baseAlignment[1].."EnemyName"},
base.x,
2021-11-25 19:04:52 +02:00
base.y,
base.mutations,
map.universe.MAX_BASE_MUTATIONS})
2021-07-26 02:25:14 +02:00
end
end
end
local function upgradeBaseBasedOnDamage(map, base)
local total = 0
for _,amount in pairs(base.damagedBy) do
total = total + amount
end
2021-07-25 03:20:13 +02:00
local mutationAmount = total * 0.176471
base.damagedBy["RandomMutation"] = mutationAmount
total = total + mutationAmount
local pickedDamage
2021-12-06 01:33:24 +02:00
local roll = map.random()
2021-07-25 03:20:13 +02:00
for damageTypeName,amount in pairs(base.damagedBy) do
base.damagedBy[damageTypeName] = amount / total
end
for damageType,amount in pairs(base.damagedBy) do
roll = roll - amount
if (roll <= 0) then
pickedDamage = damageType
break
end
end
pickMutationFromDamageType(map, pickedDamage, roll, base)
end
2021-02-20 09:31:36 +02:00
function baseUtils.processBase(chunk, map, tick, base)
2019-11-30 02:49:22 +02:00
if not base.alignment[1] then
return
end
2019-11-04 08:19:22 +02:00
2021-02-20 09:31:36 +02:00
local surface = map.surface
local universe = map.universe
setPositionXYInQuery(universe.pbFilteredEntitiesPointQueryLimited,
chunk.x + (CHUNK_SIZE * map.random()),
chunk.y + (CHUNK_SIZE * map.random()))
2019-02-03 08:01:28 +02:00
2021-12-06 01:33:24 +02:00
local upgradeRoll = map.random()
if (base.state == BASE_AI_STATE_ACTIVE) and (base.points >= MINIMUM_BUILDING_COST) and (upgradeRoll < 0.30) then
local entities = surface.find_entities_filtered(universe.pbFilteredEntitiesPointQueryLimited)
if #entities ~= 0 then
local entity = entities[1]
local cost = (universe.costLookup[entity.name] or MAGIC_MAXIMUM_NUMBER)
if (base.points >= cost) then
local newEntity = baseUtils.upgradeEntity(entity,
base,
map)
if newEntity then
if universe.printBaseUpgrades then
surface.print("[gps=".. entity.position.x ..",".. entity.position.y .."] " .. "Scheduled upgrade for ".. entity.name .. " to " .. newEntity)
end
base.points = base.points - cost
end
2019-11-30 02:49:22 +02:00
end
2019-02-03 08:01:28 +02:00
end
2021-05-01 06:25:55 +02:00
end
2021-07-25 03:20:13 +02:00
local deathThreshold
if (map.evolutionLevel < 0.5) then
deathThreshold = 4500
elseif (map.evolutionLevel < 0.7) then
deathThreshold = 7500
2021-07-25 03:20:13 +02:00
elseif (map.evolutionLevel < 0.9) then
deathThreshold = 11000
2021-07-25 03:20:13 +02:00
else
deathThreshold = 16000
2021-07-25 03:20:13 +02:00
end
2021-07-25 05:23:38 +02:00
deathThreshold = universe.adaptationModifier * deathThreshold
2021-07-25 03:20:13 +02:00
if ((base.deathEvents > deathThreshold) and (upgradeRoll > 0.95)) then
2021-11-25 19:04:52 +02:00
if (base.mutations < universe.MAX_BASE_MUTATIONS) then
base.mutations = base.mutations + 1
upgradeBaseBasedOnDamage(map, base)
2021-11-25 19:04:52 +02:00
elseif (base.mutations == universe.MAX_BASE_MUTATIONS) then
2021-12-06 01:33:24 +02:00
local roll = map.random()
2021-11-25 19:04:52 +02:00
if (roll < 0.001) then
base.mutations = 0
if (map.universe.printBaseAdaptation) then
game.print({"description.rampant--adaptationResetDebugMessage",
base.x,
base.y,
base.mutations,
map.universe.MAX_BASE_MUTATIONS})
end
2021-11-25 19:04:52 +02:00
elseif (roll > 0.999) then
base.mutations = base.mutations + 1
if (map.universe.printBaseAdaptation) then
game.print({"description.rampant--adaptationFrozenDebugMessage",
base.x,
base.y})
end
2021-11-25 19:04:52 +02:00
end
end
base.damagedBy = {}
base.deathEvents = 0
end
2021-05-01 06:25:55 +02:00
base.points = base.points + map.baseIncrement
2019-02-12 08:30:13 +02:00
2021-04-30 07:24:14 +02:00
if (base.points > universe.maxPoints) then
base.points = universe.maxPoints
2019-02-12 08:30:13 +02:00
end
if (base.stateTick <= tick) then
2021-12-06 01:33:24 +02:00
local roll = map.random()
2021-11-25 19:49:54 +02:00
if (roll < 0.85) then
base.state = BASE_AI_STATE_ACTIVE
else
base.state = BASE_AI_STATE_DORMANT
end
2021-12-06 01:33:24 +02:00
base.stateTick = randomTickEvent(map.random,
tick,
2019-11-30 02:49:22 +02:00
BASE_AI_MIN_STATE_DURATION,
BASE_AI_MAX_STATE_DURATION)
2019-02-12 08:30:13 +02:00
end
2019-11-04 08:19:22 +02:00
base.tick = tick
end
function baseUtils.createBase(map, chunk, tick)
local x = chunk.x
local y = chunk.y
local distance = euclideanDistancePoints(x, y, 0, 0)
2019-11-30 02:49:22 +02:00
local meanLevel = mFloor(distance * 0.005)
2019-02-03 08:01:28 +02:00
local distanceIndex = mMin(1, distance * BASE_DISTANCE_TO_EVO_INDEX)
2021-02-20 09:31:36 +02:00
local evoIndex = mMax(distanceIndex, map.evolutionLevel)
2019-11-30 02:49:22 +02:00
local baseTick = tick
2019-11-04 08:19:22 +02:00
local alignment = findBaseInitialAlignment(map, evoIndex) or {"neutral"}
2019-02-03 08:01:28 +02:00
2021-12-06 01:33:24 +02:00
local baseLevel = gaussianRandomRangeRG(meanLevel, meanLevel * 0.3, meanLevel * 0.50, meanLevel * 1.50, map.random)
local baseDistanceThreshold = gaussianRandomRangeRG(BASE_DISTANCE_THRESHOLD,
BASE_DISTANCE_THRESHOLD * 0.2,
BASE_DISTANCE_THRESHOLD * 0.75,
BASE_DISTANCE_THRESHOLD * 1.50,
map.random)
local distanceThreshold = (baseLevel * BASE_DISTANCE_LEVEL_BONUS) + baseDistanceThreshold
local universe = map.universe
2017-05-12 06:50:06 +02:00
local base = {
2019-02-03 08:01:28 +02:00
x = x,
y = y,
2021-07-26 02:25:14 +02:00
distanceThreshold = distanceThreshold * map.universe.baseDistanceModifier,
2019-11-30 02:49:22 +02:00
tick = baseTick,
alignment = alignment,
2021-04-30 07:24:14 +02:00
state = BASE_AI_STATE_ACTIVE,
damagedBy = {},
2021-07-25 03:20:13 +02:00
deathEvents = 0,
2021-11-25 19:04:52 +02:00
mutations = 0,
2019-02-12 08:30:13 +02:00
stateTick = 0,
chunkCount = 0,
createdTick = tick,
2020-05-20 04:37:16 +02:00
points = 0,
id = universe.baseId
2017-05-12 06:50:06 +02:00
}
universe.baseId = universe.baseId + 1
2021-02-20 09:31:36 +02:00
map.bases[base.id] = base
2019-02-03 08:01:28 +02:00
2017-05-12 06:50:06 +02:00
return base
2017-05-08 08:56:11 +02:00
end
2021-02-20 09:31:36 +02:00
function baseUtils.rebuildNativeTables(universe, rg)
2019-11-30 02:49:22 +02:00
local alignmentSet = {}
2021-02-20 09:31:36 +02:00
universe.evolutionTableAlignment = alignmentSet
2019-11-30 02:49:22 +02:00
local buildingSpaceLookup = {}
2021-02-20 09:31:36 +02:00
universe.buildingSpaceLookup = buildingSpaceLookup
2019-11-30 02:49:22 +02:00
local enemyAlignmentLookup = {}
2021-02-20 09:31:36 +02:00
universe.enemyAlignmentLookup = enemyAlignmentLookup
2019-11-30 02:49:22 +02:00
local evoToTierMapping = {}
2021-02-20 09:31:36 +02:00
universe.evoToTierMapping = evoToTierMapping
2019-11-30 02:49:22 +02:00
local upgradeLookup = {}
2021-02-20 09:31:36 +02:00
universe.upgradeLookup = upgradeLookup
2019-11-30 02:49:22 +02:00
local buildingEvolveLookup = {}
2021-02-20 09:31:36 +02:00
universe.buildingEvolveLookup = buildingEvolveLookup
2019-11-30 02:49:22 +02:00
local costLookup = {}
2021-02-20 09:31:36 +02:00
universe.costLookup = costLookup
2019-11-30 02:49:22 +02:00
local buildingHiveTypeLookup = {}
2021-02-20 09:31:36 +02:00
universe.buildingHiveTypeLookup = buildingHiveTypeLookup
local proxyEntityLookup = {}
universe.proxyEntityLookup = proxyEntityLookup
local vanillaEntityLookups = {}
universe.vanillaEntityTypeLookup = vanillaEntityLookups
2019-11-30 02:49:22 +02:00
for i=1,10 do
2021-02-14 06:49:54 +02:00
evoToTierMapping[#evoToTierMapping+1] = (((i - 1) * 0.1) ^ 0.5) - 0.05
2019-11-30 02:49:22 +02:00
end
buildingHiveTypeLookup["biter-spawner"] = "biter-spawner"
buildingHiveTypeLookup["spitter-spawner"] = "spitter-spawner"
buildingHiveTypeLookup["small-worm-turret"] = "turret"
buildingHiveTypeLookup["medium-worm-turret"] = "turret"
buildingHiveTypeLookup["big-worm-turret"] = "turret"
buildingHiveTypeLookup["behemoth-worm-turret"] = "turret"
vanillaEntityLookups["biter-spawner"] = true
vanillaEntityLookups["spitter-spawner"] = true
vanillaEntityLookups["small-worm-turret"] = true
vanillaEntityLookups["medium-worm-turret"] = true
vanillaEntityLookups["big-worm-turret"] = true
vanillaEntityLookups["behemoth-worm-turret"] = true
2019-11-30 02:49:22 +02:00
for i=1,#FACTION_SET do
local faction = FACTION_SET[i]
local factionUpgradeLookup = {}
upgradeLookup[faction.type] = factionUpgradeLookup
local factionBuildingPicker = {}
buildingEvolveLookup[faction.type] = factionBuildingPicker
for t=1,10 do
local alignments = alignmentSet[t]
if not alignments then
alignments = {}
alignmentSet[t] = alignments
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
--[[
alignments table is a table that is used for selecting what factions are available
to pick given an evolution level.
evolutionTable is a table that given a faction allows the selection of a building
2019-12-16 03:16:56 +02:00
type based on the propabilities given. Once the the building type is selected given
2019-11-30 02:49:22 +02:00
a faction, then the evolution decides what level of building to select
--]]
local factionAcceptRate = faction.acceptRate
local low = factionAcceptRate[1]
local high = factionAcceptRate[2]
if (low <= t) and (t <= high) then
alignments[#alignments+1] = {
distort(rg,
linearInterpolation((t - low) / (high - low), factionAcceptRate[3], factionAcceptRate[4])),
faction.type
}
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
local tieredUpgradeBuildingSet = factionUpgradeLookup[t]
if not tieredUpgradeBuildingSet then
tieredUpgradeBuildingSet = {}
factionUpgradeLookup[t] = tieredUpgradeBuildingSet
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
local tieredBuildingPickerSet = factionBuildingPicker[t]
if not tieredBuildingPickerSet then
tieredBuildingPickerSet = {}
factionBuildingPicker[t] = tieredBuildingPickerSet
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
for b=1,#faction.buildings do
local building = faction.buildings[b]
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
local buildingSet = tieredUpgradeBuildingSet[building.type]
if not buildingSet then
buildingSet = {}
tieredUpgradeBuildingSet[building.type] = buildingSet
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
local variationSet = {}
2021-02-20 09:31:36 +02:00
for v=1,universe.ENEMY_VARIATIONS do
2019-11-30 02:49:22 +02:00
local entry = faction.type .. "-" .. building.name .. "-v" .. v .. "-t" .. t .. "-rampant"
enemyAlignmentLookup[entry] = faction.type
local proxyEntity = "entity-proxy-" .. building.type .. "-t" .. t .. "-rampant"
proxyEntityLookup[proxyEntity] = true
2019-11-30 02:49:22 +02:00
buildingSpaceLookup[entry] = proxyEntity
costLookup[entry] = HIVE_BUILDINGS_COST[building.type]
buildingHiveTypeLookup[entry] = building.type
if not buildingHiveTypeLookup[proxyEntity] then
buildingHiveTypeLookup[proxyEntity] = building.type
end
variationSet[#variationSet+1] = entry
end
2019-11-30 02:49:22 +02:00
local buildingAcceptRate = building.acceptRate
2019-02-03 08:01:28 +02:00
2021-02-14 06:49:54 +02:00
local buildingLow = buildingAcceptRate[1]
local buildingHigh = buildingAcceptRate[2]
if (buildingLow <= t) and (t <= buildingHigh) then
2019-11-30 02:49:22 +02:00
for vi=1,#variationSet do
local variation = variationSet[vi]
buildingSet[#buildingSet+1] = variation
end
tieredBuildingPickerSet[#tieredBuildingPickerSet+1] = {
distort(rg,
2021-02-14 06:49:54 +02:00
linearInterpolation((t - buildingLow) / (buildingHigh - buildingLow),
buildingAcceptRate[3],
buildingAcceptRate[4])),
2019-11-30 02:49:22 +02:00
variationSet,
building.type
}
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
end
end
2019-02-03 08:01:28 +02:00
end
2018-02-05 05:24:28 +02:00
2019-11-30 02:49:22 +02:00
for t=1,10 do
local alignments = alignmentSet[t]
local totalAlignment = 0
for i=1,#alignments do
totalAlignment = totalAlignment + alignments[i][1]
end
for i=1,#alignments do
alignments[i][1] = alignments[i][1] / totalAlignment
end
2019-02-14 07:53:31 +02:00
2019-11-30 02:49:22 +02:00
for fi=1,#FACTION_SET do
local faction = FACTION_SET[fi]
local factionBuildingSet = buildingEvolveLookup[faction.type][t]
local totalBuildingSet = 0
for i=1,#factionBuildingSet do
totalBuildingSet = totalBuildingSet + factionBuildingSet[i][1]
end
for i=1,#factionBuildingSet do
factionBuildingSet[i][1] = factionBuildingSet[i][1] / totalBuildingSet
end
end
2019-02-13 07:50:25 +02:00
end
2019-12-16 03:16:56 +02:00
2021-11-27 00:00:08 +02:00
local evoIndex = evoToTier(universe, universe.evolutionLevel, 2)
2021-04-05 06:46:43 +02:00
if universe.maps then
for _,map in pairs(universe.maps) do
for _,base in pairs(map.bases) do
for x=1,2 do
2021-04-05 06:46:43 +02:00
local alignment = base.alignment[x]
if alignment and not universe.buildingEvolveLookup[alignment] then
base.alignment = findBaseInitialAlignment(map, evoIndex)
2021-04-05 06:46:43 +02:00
break
elseif not alignment and (x == 1) then
base.alignment = findBaseInitialAlignment(map, evoIndex)
break
2021-04-05 06:46:43 +02:00
end
end
end
end
end
end
2019-02-16 06:17:30 +02:00
baseUtilsG = baseUtils
2017-05-08 08:56:11 +02:00
return baseUtils