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
2023-01-03 01:31:07 +02:00
local stringUtils = require ( " StringUtils " )
2017-06-16 03:30:26 +02:00
local mathUtils = require ( " MathUtils " )
2017-05-08 08:56:11 +02:00
local constants = require ( " Constants " )
2018-01-15 09:41:55 +02:00
local chunkPropertyUtils = require ( " ChunkPropertyUtils " )
2019-11-30 02:49:22 +02:00
local mapUtils = require ( " MapUtils " )
2021-12-11 20:42:49 +02:00
local queryUtils = require ( " QueryUtils " )
2017-06-08 02:57:24 +02:00
2017-05-08 08:56:11 +02:00
-- constants
2022-07-09 23:27:53 +02:00
local TIERS = constants.TIERS
2022-07-07 06:14:00 +02:00
local EVO_TO_TIER_MAPPING = constants.EVO_TO_TIER_MAPPING
local PROXY_ENTITY_LOOKUP = constants.PROXY_ENTITY_LOOKUP
local BUILDING_HIVE_TYPE_LOOKUP = constants.BUILDING_HIVE_TYPE_LOOKUP
local COST_LOOKUP = constants.COST_LOOKUP
local UPGRADE_LOOKUP = constants.UPGRADE_LOOKUP
local ENEMY_ALIGNMENT_LOOKUP = constants.ENEMY_ALIGNMENT_LOOKUP
local EVOLUTION_TABLE_ALIGNMENT = constants.EVOLUTION_TABLE_ALIGNMENT
local BUILDING_EVOLVE_LOOKUP = constants.BUILDING_EVOLVE_LOOKUP
2021-11-26 22:25:07 +02:00
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
2021-07-22 02:48:52 +02:00
local FACTIONS_BY_DAMAGE_TYPE = constants.FACTIONS_BY_DAMAGE_TYPE
2022-02-28 04:45:42 +02:00
local BASE_GENERATION_STATE_ACTIVE = constants.BASE_GENERATION_STATE_ACTIVE
2019-02-12 08:30:13 +02:00
2018-01-21 09:42:47 +02:00
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
2018-01-15 09:41:55 +02:00
local CHUNK_SIZE = constants.CHUNK_SIZE
2018-01-16 09:21:12 +02:00
2022-02-28 04:45:42 +02:00
local BASE_AI_STATE_PEACEFUL = constants.BASE_AI_STATE_PEACEFUL
2017-05-08 08:56:11 +02:00
-- imported functions
2023-01-03 01:31:07 +02:00
local isMember = stringUtils.isMember
2021-12-11 20:42:49 +02:00
local setPositionXYInQuery = queryUtils.setPositionXYInQuery
2017-06-16 03:30:26 +02:00
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
2017-05-08 08:56:11 +02:00
2019-11-30 02:49:22 +02:00
local getChunkByPosition = mapUtils.getChunkByPosition
2018-01-29 03:51:24 +02:00
2021-12-06 01:33:24 +02:00
local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG
2018-01-16 09:21:12 +02:00
2017-06-01 03:46:53 +02:00
local mFloor = math.floor
2018-01-21 09:42:47 +02:00
local mMin = math.min
local mMax = math.max
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
2022-07-09 23:27:53 +02:00
for i = TIERS , 1 , - 1 do
2022-07-07 06:14:00 +02:00
if EVO_TO_TIER_MAPPING [ 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
2023-01-03 01:31:07 +02:00
local function findBaseMutation ( universe , targetEvolution , excludeFactions )
2022-02-28 04:45:42 +02:00
local tier = evoToTier ( universe , targetEvolution or universe.evolutionLevel , 2 )
2023-01-03 01:31:07 +02:00
local availableAlignments
2022-07-07 06:14:00 +02:00
local alignments = EVOLUTION_TABLE_ALIGNMENT [ tier ]
2019-02-03 08:01:28 +02:00
2023-01-03 01:31:07 +02:00
if excludeFactions then
availableAlignments = { }
for _ , alignment in pairs ( alignments ) do
if not isMember ( alignment [ 2 ] , excludeFactions ) then
availableAlignments [ # availableAlignments + 1 ] = alignment
end
end
else
availableAlignments = alignments
end
2022-03-20 01:29:12 +02:00
local roll = universe.random ( )
2023-01-03 01:31:07 +02:00
for i = 1 , # availableAlignments do
local alignment = availableAlignments [ i ]
2018-02-10 22:57:54 +02:00
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
2018-02-10 22:57:54 +02:00
end
2023-01-03 01:31:07 +02:00
return availableAlignments [ # availableAlignments ]
2019-11-30 02:49:22 +02:00
end
2019-02-03 08:01:28 +02:00
2022-01-16 22:05:34 +02:00
local function initialEntityUpgrade ( baseAlignment , tier , maxTier , map , useHiveType , entityType )
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
2022-07-07 06:14:00 +02:00
local alignmentTable = BUILDING_EVOLVE_LOOKUP [ baseAlignment ]
2022-10-21 07:29:12 +02:00
if not alignmentTable then
2023-01-03 01:31:07 +02:00
alignmentTable = BUILDING_EVOLVE_LOOKUP [ " neutral " ]
2022-10-21 07:29:12 +02:00
end
2021-12-15 06:28:16 +02:00
local upgrades = alignmentTable [ useTier ]
2019-12-16 03:16:56 +02:00
2022-10-21 07:29:12 +02:00
if alignmentTable and upgrades then
2019-12-16 03:16:56 +02:00
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 ]
2022-01-16 22:05:34 +02:00
if upgrade [ 3 ] == entityType then
2021-12-06 01:33:24 +02:00
entity = upgrade [ 2 ] [ map.random ( # upgrade [ 2 ] ) ]
2022-01-16 22:05:34 +02:00
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 )
2019-11-30 02:49:22 +02:00
local entity
2022-07-07 06:14:00 +02:00
local hiveType = BUILDING_HIVE_TYPE_LOOKUP [ originalEntity.name ]
2019-11-30 02:49:22 +02:00
2019-12-18 03:09:08 +02:00
for t = maxTier , tier , - 1 do
2022-07-07 06:14:00 +02:00
local factionLookup = UPGRADE_LOOKUP [ baseAlignment ] [ t ]
2019-12-18 03:09:08 +02:00
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
2018-01-26 02:52:26 +02:00
return entity
end
2023-01-02 23:24:18 +02:00
function baseUtils . findEntityUpgrade ( baseAlignment , currentEvo , evoIndex , originalEntity , map , evolve )
2021-02-20 09:31:36 +02:00
local universe = map.universe
2019-11-30 02:49:22 +02:00
local adjCurrentEvo = mMax (
2022-07-07 06:14:00 +02:00
( ( baseAlignment ~= ENEMY_ALIGNMENT_LOOKUP [ 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 )
2018-01-26 02:52:26 +02:00
2019-11-30 02:49:22 +02:00
if ( tier > maxTier ) then
2021-12-04 21:04:13 +02:00
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 )
2022-01-17 02:51:43 +02:00
local entityName = originalEntity.name
2022-07-07 06:14:00 +02:00
local entityType = BUILDING_HIVE_TYPE_LOOKUP [ entityName ]
2022-01-16 22:05:34 +02:00
if not entityType then
if map.random ( ) < 0.5 then
entityType = " biter-spawner "
else
entityType = " spitter-spawner "
end
end
2022-01-17 02:51:43 +02:00
local roll = map.random ( )
2022-01-16 22:05:34 +02:00
local makeHive = ( chunk ~= - 1 ) and
2022-01-17 02:51:43 +02:00
(
( entityType == " biter-spawner " ) or ( entityType == " spitter-spawner " )
)
and
(
(
2022-06-13 07:34:49 +02:00
( roll <= 0.01 ) and
2022-07-07 06:14:00 +02:00
not PROXY_ENTITY_LOOKUP [ entityName ]
2022-01-17 02:51:43 +02:00
)
or
(
2022-06-13 07:34:49 +02:00
( roll <= 0.210 ) and
2022-01-17 02:51:43 +02:00
( getResourceGenerator ( map , chunk ) > 0 )
)
)
2022-01-16 22:05:34 +02:00
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
2023-01-03 01:31:07 +02:00
-- local
function baseUtils . findBaseInitialAlignment ( universe , evoIndex , excludeFactions )
2021-11-27 00:09:10 +02:00
local dev = evoIndex * 0.15
2022-03-20 01:29:12 +02:00
local evoTop = gaussianRandomRangeRG ( evoIndex - ( evoIndex * 0.075 ) , dev , 0 , evoIndex , universe.random )
2018-01-26 02:52:26 +02:00
2019-11-30 02:49:22 +02:00
local result
2022-03-20 01:29:12 +02:00
if universe.random ( ) < 0.05 then
2023-01-03 01:31:07 +02:00
result = { findBaseMutation ( universe , evoTop , excludeFactions ) , findBaseMutation ( universe , evoTop , excludeFactions ) }
2019-11-30 02:49:22 +02:00
else
2023-01-03 01:31:07 +02:00
result = { findBaseMutation ( universe , evoTop , excludeFactions ) }
2018-01-16 09:21:12 +02:00
end
2019-02-03 08:01:28 +02:00
2019-11-30 02:49:22 +02:00
return result
2018-01-16 09:21:12 +02:00
end
2022-04-10 04:24:15 +02:00
function baseUtils . recycleBases ( universe )
local bases = universe.bases
local id = universe.recycleBaseIterator
2021-11-25 06:49:22 +02:00
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
2022-04-10 04:24:15 +02:00
universe.recycleBaseIterator = nil
2021-02-20 07:41:30 +02:00
else
2022-04-10 04:24:15 +02:00
universe.recycleBaseIterator = next ( bases , id )
local map = base.map
if ( base.chunkCount == 0 ) or not map.surface . valid then
2021-02-20 07:41:30 +02:00
bases [ id ] = nil
2022-04-30 05:18:50 +02:00
if universe.processBaseAIIterator == id then
universe.processBaseAIIterator = nil
end
2022-04-10 04:24:15 +02:00
if map.surface . valid then
map.universe . bases [ id ] = nil
end
2019-02-03 08:01:28 +02:00
end
2018-01-26 07:48:12 +02:00
end
end
2023-01-02 23:24:18 +02:00
function baseUtils . queueUpgrade ( entity , base , disPos , evolve , register , timeDelay )
base.universe . pendingUpgrades [ entity.unit_number ] = {
[ " position " ] = disPos ,
[ " register " ] = register ,
[ " evolve " ] = evolve ,
[ " base " ] = base ,
[ " entity " ] = entity ,
[ " delayTLL " ] = timeDelay
}
2019-02-12 08:30:13 +02:00
end
2022-03-20 01:29:12 +02:00
local function pickMutationFromDamageType ( universe , damageType , roll , base )
2021-07-20 06:22:38 +02:00
local baseAlignment = base.alignment
2021-07-22 02:48:52 +02:00
local damageFactions = FACTIONS_BY_DAMAGE_TYPE [ damageType ]
2021-07-26 02:25:14 +02:00
local mutation
2022-12-27 03:43:41 +02:00
local mutated = false
2021-07-20 06:22:38 +02:00
2022-12-27 03:43:41 +02:00
if damageFactions and ( # damageFactions > 0 ) then
2022-03-20 01:29:12 +02:00
mutation = damageFactions [ universe.random ( # damageFactions ) ]
2021-07-22 02:48:52 +02:00
if baseAlignment [ 2 ] then
2022-12-27 03:43:41 +02:00
if ( baseAlignment [ 1 ] ~= mutation ) and ( baseAlignment [ 2 ] ~= mutation ) then
mutated = true
end
2021-07-22 02:48:52 +02:00
if ( roll < 0.05 ) then
2021-07-26 02:25:14 +02:00
baseAlignment [ 1 ] = mutation
2022-12-27 03:43:41 +02:00
baseAlignment [ 2 ] = nil
2021-07-22 02:48:52 +02:00
elseif ( roll < 0.25 ) then
2021-07-26 02:25:14 +02:00
baseAlignment [ 1 ] = mutation
2021-07-22 02:48:52 +02:00
else
2021-07-26 02:25:14 +02:00
baseAlignment [ 2 ] = mutation
2021-07-22 02:48:52 +02:00
end
else
2022-12-27 03:43:41 +02:00
if ( baseAlignment [ 1 ] ~= mutation ) then
mutated = true
end
2021-07-22 02:48:52 +02:00
if ( roll < 0.85 ) then
2022-12-27 03:43:41 +02:00
baseAlignment [ 1 ] = mutation
2021-07-22 02:48:52 +02:00
else
2022-12-27 03:43:41 +02:00
baseAlignment [ 2 ] = mutation
2021-07-22 02:48:52 +02:00
end
end
2021-07-20 06:22:38 +02:00
else
2022-03-20 01:29:12 +02:00
mutation = findBaseMutation ( universe )
2021-07-20 06:22:38 +02:00
if baseAlignment [ 2 ] then
2022-12-27 03:43:41 +02:00
if ( baseAlignment [ 1 ] ~= mutation ) and ( baseAlignment [ 2 ] ~= mutation ) then
mutated = true
end
2021-07-20 06:22:38 +02:00
if ( roll < 0.05 ) then
baseAlignment [ 2 ] = nil
2021-07-26 02:25:14 +02:00
baseAlignment [ 1 ] = mutation
2021-07-20 06:22:38 +02:00
elseif ( roll < 0.25 ) then
2021-07-26 02:25:14 +02:00
baseAlignment [ 1 ] = mutation
2021-07-20 06:22:38 +02:00
else
2021-07-26 02:25:14 +02:00
baseAlignment [ 2 ] = mutation
2021-07-20 06:22:38 +02:00
end
else
2022-12-27 03:43:41 +02:00
if ( baseAlignment [ 1 ] ~= mutation ) then
mutated = true
end
2021-07-20 06:22:38 +02:00
if ( roll < 0.85 ) then
2021-07-26 02:25:14 +02:00
base.alignment [ 1 ] = mutation
2021-07-20 06:22:38 +02:00
else
2021-07-26 02:25:14 +02:00
base.alignment [ 2 ] = mutation
2021-07-20 06:22:38 +02:00
end
end
end
2022-12-27 03:43:41 +02:00
if mutated and 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 " ,
2023-01-03 04:49:56 +02:00
base.id ,
base.map . surface.name ,
2021-07-26 02:25:14 +02:00
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 ,
2022-03-20 01:29:12 +02:00
universe.MAX_BASE_MUTATIONS } )
2021-07-26 02:25:14 +02:00
else
game.print ( { " description.rampant--adaptation1DebugMessage " ,
2023-01-03 04:49:56 +02:00
base.id ,
base.map . surface.name ,
2021-07-26 02:25:14 +02:00
damageType ,
{ " description.rampant-- " .. baseAlignment [ 1 ] .. " EnemyName " } ,
base.x ,
2021-11-25 19:04:52 +02:00
base.y ,
base.mutations ,
2022-03-20 01:29:12 +02:00
universe.MAX_BASE_MUTATIONS } )
2021-07-26 02:25:14 +02:00
end
end
2022-12-27 03:43:41 +02:00
return mutated
2021-07-20 06:22:38 +02:00
end
2022-03-20 01:29:12 +02:00
function baseUtils . upgradeBaseBasedOnDamage ( universe , base )
2021-07-20 06:22:38 +02:00
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
2021-11-25 19:13:43 +02:00
base.damagedBy [ " RandomMutation " ] = mutationAmount
2021-07-20 06:22:38 +02:00
total = total + mutationAmount
local pickedDamage
2022-03-20 01:29:12 +02:00
local roll = universe.random ( )
2021-07-25 03:20:13 +02:00
for damageTypeName , amount in pairs ( base.damagedBy ) do
base.damagedBy [ damageTypeName ] = amount / total
end
2021-07-20 06:22:38 +02:00
for damageType , amount in pairs ( base.damagedBy ) do
2021-12-09 06:14:21 +02:00
roll = roll - amount
if ( roll <= 0 ) then
2021-07-20 06:22:38 +02:00
pickedDamage = damageType
break
end
end
2022-12-27 03:43:41 +02:00
return pickMutationFromDamageType ( universe , pickedDamage , roll , base )
2021-07-20 06:22:38 +02:00
end
2022-03-20 01:29:12 +02:00
function baseUtils . processBaseMutation ( chunk , map , base )
if not base.alignment [ 1 ] or
( base.stateGeneration ~= BASE_GENERATION_STATE_ACTIVE ) or
( map.random ( ) >= 0.30 )
then
2022-02-24 07:04:34 +02:00
return
end
2022-03-20 01:29:12 +02:00
if ( base.points >= MINIMUM_BUILDING_COST ) then
local surface = map.surface
local universe = map.universe
setPositionXYInQuery ( universe.pbFilteredEntitiesPointQueryLimited ,
chunk.x + ( CHUNK_SIZE * map.random ( ) ) ,
chunk.y + ( CHUNK_SIZE * map.random ( ) ) )
2019-11-04 08:19:22 +02:00
2021-12-11 20:42:49 +02:00
local entities = surface.find_entities_filtered ( universe.pbFilteredEntitiesPointQueryLimited )
2021-02-21 01:31:48 +02:00
if # entities ~= 0 then
local entity = entities [ 1 ]
2022-07-07 06:14:00 +02:00
local cost = ( COST_LOOKUP [ entity.name ] or MAGIC_MAXIMUM_NUMBER )
2021-02-21 01:31:48 +02:00
if ( base.points >= cost ) then
2023-01-03 04:10:13 +02:00
local position = entity.position
baseUtils.modifyBaseSpecialPoints ( base , - cost , " Scheduling Entity upgrade " , position.x , position.y )
2023-01-02 23:24:18 +02:00
baseUtils.queueUpgrade ( entity , base , nil , false , true )
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
2018-01-21 09:42:47 +02:00
end
2021-12-04 21:04:13 +02:00
function baseUtils . createBase ( map , chunk , tick )
2018-01-15 09:41:55 +02:00
local x = chunk.x
local y = chunk.y
local distance = euclideanDistancePoints ( x , y , 0 , 0 )
2018-01-16 09:21:12 +02:00
2019-11-30 02:49:22 +02:00
local meanLevel = mFloor ( distance * 0.005 )
2018-01-16 09:21:12 +02:00
2022-03-20 01:29:12 +02:00
local universe = map.universe
2019-02-03 08:01:28 +02:00
local distanceIndex = mMin ( 1 , distance * BASE_DISTANCE_TO_EVO_INDEX )
2022-03-20 01:29:12 +02:00
local evoIndex = mMax ( distanceIndex , universe.evolutionLevel )
2019-11-04 08:19:22 +02:00
2023-01-03 02:11:19 +02:00
local alignment =
( universe.NEW_ENEMIES and baseUtils.findBaseInitialAlignment ( universe , evoIndex ) )
or { " neutral " }
2019-02-03 08:01:28 +02:00
2022-03-20 01:29:12 +02:00
local baseLevel = gaussianRandomRangeRG ( meanLevel ,
meanLevel * 0.3 ,
meanLevel * 0.50 ,
meanLevel * 1.50 ,
universe.random )
2021-12-06 01:33:24 +02:00
local baseDistanceThreshold = gaussianRandomRangeRG ( BASE_DISTANCE_THRESHOLD ,
BASE_DISTANCE_THRESHOLD * 0.2 ,
BASE_DISTANCE_THRESHOLD * 0.75 ,
BASE_DISTANCE_THRESHOLD * 1.50 ,
2022-03-20 01:29:12 +02:00
universe.random )
2018-01-26 07:13:47 +02:00
local distanceThreshold = ( baseLevel * BASE_DISTANCE_LEVEL_BONUS ) + baseDistanceThreshold
2017-05-12 06:50:06 +02:00
local base = {
2019-02-03 08:01:28 +02:00
x = x ,
y = y ,
2022-03-20 01:29:12 +02:00
distanceThreshold = distanceThreshold * universe.baseDistanceModifier ,
tick = tick ,
2019-11-30 02:49:22 +02:00
alignment = alignment ,
2021-04-30 07:24:14 +02:00
damagedBy = { } ,
2021-07-25 03:20:13 +02:00
deathEvents = 0 ,
2021-11-25 19:04:52 +02:00
mutations = 0 ,
2022-03-20 01:29:12 +02:00
stateGeneration = BASE_GENERATION_STATE_ACTIVE ,
2022-02-28 04:45:42 +02:00
stateGenerationTick = 0 ,
2021-12-04 21:04:13 +02:00
chunkCount = 0 ,
2019-03-10 00:47:35 +02:00
createdTick = tick ,
2020-05-20 04:37:16 +02:00
points = 0 ,
2022-02-24 07:04:34 +02:00
unitPoints = 0 ,
2022-02-28 04:45:42 +02:00
stateAI = BASE_AI_STATE_PEACEFUL ,
2022-03-20 01:29:12 +02:00
stateAITick = 0 ,
maxAggressiveGroups = 0 ,
sentAggressiveGroups = 0 ,
2022-10-26 19:55:00 +02:00
resetExpensionGroupsTick = 0 ,
maxExpansionGroups = 0 ,
sentExpansionGroups = 0 ,
2022-02-28 04:45:42 +02:00
activeRaidNests = 0 ,
activeNests = 0 ,
destroyPlayerBuildings = 0 ,
lostEnemyUnits = 0 ,
lostEnemyBuilding = 0 ,
rocketLaunched = 0 ,
builtEnemyBuilding = 0 ,
ionCannonBlasts = 0 ,
artilleryBlasts = 0 ,
temperament = 0.5 ,
temperamentScore = 0 ,
2022-03-20 01:29:12 +02:00
universe = universe ,
2022-04-10 04:24:15 +02:00
map = map ,
2021-12-11 20:45:40 +02:00
id = universe.baseId
2017-05-12 06:50:06 +02:00
}
2021-12-11 20:45:40 +02:00
universe.baseId = universe.baseId + 1
2018-01-15 09:41:55 +02:00
2021-02-20 09:31:36 +02:00
map.bases [ base.id ] = base
2022-02-28 04:45:42 +02:00
universe.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
2023-01-03 04:10:13 +02:00
function baseUtils . modifyBaseUnitPoints ( base , points , tag , x , y )
2021-04-05 06:46:43 +02:00
2023-01-03 04:10:13 +02:00
if points > 0 and base.stateAI == BASE_AI_STATE_PEACEFUL then
return
end
tag = tag or " "
x = x or nil
y = y or nil
base.unitPoints = base.unitPoints + points
local universe = base.universe
local overflowMessage = " "
if base.unitPoints > universe.maxOverflowPoints then
base.unitPoints = universe.maxOverflowPoints
overflowMessage = " [Point cap reached] "
end
local printPointChange = " "
if points > 0 and universe.aiPointsPrintGainsToChat then
printPointChange = " + " .. string.format ( " %.2f " , points )
elseif points < 0 and universe.aiPointsPrintSpendingToChat then
printPointChange = string.format ( " %.2f " , points )
end
if printPointChange ~= " " then
local gps = " "
if x ~= nil then
gps = " [gps= " .. x .. " , " .. y .. " ] "
2021-04-05 06:46:43 +02:00
end
2023-01-03 04:10:13 +02:00
game.print ( " [ " .. base.id .. " ]: " .. base.map . surface.name .. " " .. printPointChange .. " [ " .. tag .. " ] Unit Total: " .. string.format ( " %.2f " , base.unitPoints ) .. overflowMessage .. gps )
2021-04-05 06:46:43 +02:00
end
2018-01-21 09:42:47 +02:00
end
2023-01-03 04:10:13 +02:00
function baseUtils . modifyBaseSpecialPoints ( base , points , tag , x , y )
2022-12-02 21:19:14 +02:00
if points > 0 and base.stateAI == BASE_AI_STATE_PEACEFUL then
return
end
2022-12-01 01:50:36 +02:00
tag = tag or " "
x = x or nil
y = y or nil
2023-01-03 04:10:13 +02:00
base.points = base.points + points
2022-12-01 01:50:36 +02:00
local universe = base.universe
local overflowMessage = " "
2023-01-03 04:10:13 +02:00
if base.points > universe.maxOverflowPoints then
base.points = universe.maxOverflowPoints
2022-12-01 01:50:36 +02:00
overflowMessage = " [Point cap reached] "
end
local printPointChange = " "
if points > 0 and universe.aiPointsPrintGainsToChat then
printPointChange = " + " .. string.format ( " %.2f " , points )
elseif points < 0 and universe.aiPointsPrintSpendingToChat then
printPointChange = string.format ( " %.2f " , points )
end
2023-01-03 04:10:13 +02:00
2022-12-01 01:50:36 +02:00
if printPointChange ~= " " then
local gps = " "
if x ~= nil then
gps = " [gps= " .. x .. " , " .. y .. " ] "
end
2023-01-03 04:10:13 +02:00
game.print ( " [ " .. base.id .. " ]: " .. base.map . surface.name .. " " .. printPointChange .. " [ " .. tag .. " ] Special Total: " .. string.format ( " %.2f " , base.points ) .. overflowMessage .. gps )
2022-12-01 01:50:36 +02:00
end
end
2019-02-16 06:17:30 +02:00
baseUtilsG = baseUtils
2017-05-08 08:56:11 +02:00
return baseUtils