2017-05-08 08:56:11 +02:00
|
|
|
local baseUtils = {}
|
|
|
|
|
|
|
|
-- imports
|
|
|
|
|
2018-01-14 09:07:29 +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 mapUtils = require("MapUtils")
|
|
|
|
local chunkPropertyUtils = require("ChunkPropertyUtils")
|
2017-06-08 02:57:24 +02:00
|
|
|
|
2017-05-08 08:56:11 +02:00
|
|
|
-- constants
|
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
local NEUTRAL_WORM_TIERS = constants.NEUTRAL_WORM_TIERS
|
|
|
|
local NEUTRAL_WORM_VARIATIONS = constants.NEUTRAL_WORM_VARIATIONS
|
|
|
|
local NEUTRAL_NEST_TIERS = constants.NEUTRAL_NEST_TIERS
|
|
|
|
local NEUTRAL_NEST_VARIATIONS = constants.NEUTRAL_NEST_VARIATIONS
|
|
|
|
|
|
|
|
local ACID_WORM_TIERS = constants.ACID_WORM_TIERS
|
|
|
|
local ACID_WORM_VARIATIONS = constants.ACID_WORM_VARIATIONS
|
|
|
|
local ACID_NEST_TIERS = constants.ACID_NEST_TIERS
|
|
|
|
local ACID_NEST_VARIATIONS = constants.ACID_NEST_VARIATIONS
|
|
|
|
|
|
|
|
local SUICIDE_BITER_NEST_TIERS = constants.SUICIDE_BITER_NEST_TIERS
|
|
|
|
local SUICIDE_BITER_NEST_VARIATIONS = constants.SUICIDE_BITER_NEST_VARIATIONS
|
2017-05-08 08:56:11 +02:00
|
|
|
|
|
|
|
local BASE_ALIGNMENT_NEUTRAL = constants.BASE_ALIGNMENT_NEUTRAL
|
2018-01-21 09:42:47 +02:00
|
|
|
local BASE_ALIGNMENT_ACID = constants.BASE_ALIGNMENT_ACID
|
|
|
|
local BASE_ALIGNMENT_SUICIDE = constants.BASE_ALIGNMENT_SUICIDE
|
|
|
|
|
|
|
|
local BASE_WORM_UPGRADE = constants.BASE_WORM_UPGRADE
|
|
|
|
local BASE_SPAWNER_UPGRADE = constants.BASE_SPAWNER_UPGRADE
|
|
|
|
local BASE_UPGRADE = constants.BASE_UPGRADE
|
|
|
|
|
|
|
|
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-21 09:42:47 +02:00
|
|
|
local BASE_ALIGNMENT_PATHS = constants.BASE_ALIGNMENT_PATHS
|
|
|
|
|
2018-01-16 09:21:12 +02:00
|
|
|
local EVOLUTION_INCREMENTS = constants.EVOLUTION_INCREMENTS
|
|
|
|
|
2017-05-08 08:56:11 +02:00
|
|
|
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
|
|
|
|
|
2018-01-16 09:21:12 +02:00
|
|
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
|
|
|
|
2017-05-08 08:56:11 +02:00
|
|
|
-- imported functions
|
|
|
|
|
2017-06-16 03:30:26 +02:00
|
|
|
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
|
2018-01-21 09:42:47 +02:00
|
|
|
local roundToFloor = mathUtils.roundToFloor
|
2017-05-08 08:56:11 +02:00
|
|
|
|
2018-01-14 09:07:29 +02:00
|
|
|
local isRampant = stringUtils.isRampant
|
2017-05-08 08:56:11 +02:00
|
|
|
|
2018-01-16 09:21:12 +02:00
|
|
|
local gaussianRandomRange = mathUtils.gaussianRandomRange
|
|
|
|
|
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
|
|
|
|
|
2018-01-16 09:21:12 +02:00
|
|
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
|
|
|
local getChunkByXY = mapUtils.getChunkByXY
|
2018-01-15 09:41:55 +02:00
|
|
|
local getChunkBase = chunkPropertyUtils.getChunkBase
|
|
|
|
local setChunkBase = chunkPropertyUtils.setChunkBase
|
2017-06-01 03:46:53 +02:00
|
|
|
|
2017-07-01 06:36:23 +02:00
|
|
|
local mRandom = math.random
|
|
|
|
|
2017-05-19 09:47:24 +02:00
|
|
|
-- module code
|
2017-05-08 08:56:11 +02:00
|
|
|
|
2018-01-15 09:41:55 +02:00
|
|
|
function baseUtils.findNearbyBase(map, chunk, chunkRadius)
|
2018-01-16 09:21:12 +02:00
|
|
|
if (chunk == SENTINEL_IMPASSABLE_CHUNK) then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
local tested = {}
|
|
|
|
|
2018-01-15 09:41:55 +02:00
|
|
|
local x = chunk.x
|
|
|
|
local y = chunk.y
|
|
|
|
|
|
|
|
local foundBase = getChunkBase(map, chunk)
|
|
|
|
if foundBase then
|
|
|
|
return foundBase
|
|
|
|
end
|
|
|
|
|
2017-05-12 06:50:06 +02:00
|
|
|
local closest = MAGIC_MAXIMUM_NUMBER
|
2018-01-15 09:41:55 +02:00
|
|
|
for xi = x-chunkRadius, x+chunkRadius, CHUNK_SIZE do
|
|
|
|
for yi = y-chunkRadius, y+chunkRadius, CHUNK_SIZE do
|
|
|
|
if (xi ~= x) and (yi ~= y) then
|
2018-01-16 09:21:12 +02:00
|
|
|
local base = getChunkBase(map, getChunkByXY(map, xi, yi))
|
2018-01-15 09:41:55 +02:00
|
|
|
if base then
|
2018-01-16 09:21:12 +02:00
|
|
|
if not tested[base] then
|
|
|
|
tested[base] = true
|
|
|
|
local distance = euclideanDistancePoints(base.x, base.y, x, y)
|
|
|
|
if (distance <= (BASE_DISTANCE_THRESHOLD + (base.level * BASE_DISTANCE_LEVEL_BONUS))) and (distance < closest) then
|
|
|
|
closest = distance
|
|
|
|
foundBase = base
|
|
|
|
end
|
2018-01-15 09:41:55 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-05-08 08:56:11 +02:00
|
|
|
end
|
|
|
|
end
|
2018-01-15 09:41:55 +02:00
|
|
|
|
2017-05-28 06:50:37 +02:00
|
|
|
return foundBase
|
2017-05-19 09:47:24 +02:00
|
|
|
end
|
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
local function findUpgrade(base, evoIndex, natives, evolutionTable)
|
|
|
|
-- local used = { }
|
|
|
|
-- local alignments = base.alignments
|
2018-01-16 09:21:12 +02:00
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
-- local alignmentPick = base.alignments[mRandom(#base.alignments)]
|
|
|
|
local alignmentPick = base.alignment
|
2018-01-16 09:21:12 +02:00
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
-- while alignmentPick do
|
|
|
|
-- used[alignmentPick] = true
|
2018-01-16 09:21:12 +02:00
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
for evo=evoIndex, 0, -EVOLUTION_INCREMENTS do
|
|
|
|
local entitySet = evolutionTable[alignmentPick][evo]
|
|
|
|
if (#entitySet > 0) then
|
|
|
|
return entitySet[mRandom(#entitySet)]
|
2018-01-16 09:21:12 +02:00
|
|
|
end
|
|
|
|
end
|
2018-01-21 09:42:47 +02:00
|
|
|
|
|
|
|
-- alignmentPick = nil
|
|
|
|
-- for x = #alignments, 1, -1 do
|
|
|
|
-- if not used[alignments[x]] then
|
|
|
|
-- alignmentPick = alignments[x]
|
|
|
|
-- break
|
|
|
|
-- end
|
|
|
|
-- end
|
|
|
|
-- end
|
2018-01-16 09:21:12 +02:00
|
|
|
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2018-01-15 09:41:55 +02:00
|
|
|
function baseUtils.upgradeEntity(map, entity, surface, natives, evolutionFactor, tick)
|
2018-01-14 09:07:29 +02:00
|
|
|
if not isRampant(entity.name) then
|
|
|
|
local position = entity.position
|
2018-01-21 09:42:47 +02:00
|
|
|
local entityType = entity.type
|
|
|
|
entity.destroy()
|
2018-01-16 09:21:12 +02:00
|
|
|
local chunk = getChunkByPosition(map, position)
|
2018-01-15 09:41:55 +02:00
|
|
|
local base = getChunkBase(map, chunk)
|
|
|
|
|
|
|
|
if not base then
|
2018-01-20 09:15:13 +02:00
|
|
|
base = baseUtils.createBase(map, natives, evolutionFactor, chunk, surface, tick)
|
2018-01-15 09:41:55 +02:00
|
|
|
end
|
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
local distance = roundToFloor(mMin(1,
|
|
|
|
euclideanDistancePoints(position.x, position.y, 0, 0) * BASE_DISTANCE_TO_EVO_INDEX),
|
|
|
|
EVOLUTION_INCREMENTS)
|
|
|
|
local evoIndex = mMax(distance, roundToFloor(evolutionFactor, EVOLUTION_INCREMENTS))
|
2018-01-16 09:21:12 +02:00
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
local spawnerName = findUpgrade(base, evoIndex, natives, ((entityType == "unit-spawner") and natives.evolutionTableUnitSpawner) or natives.evolutionTableWorm)
|
2018-01-16 09:21:12 +02:00
|
|
|
if spawnerName then
|
2018-01-21 09:42:47 +02:00
|
|
|
local newPosition = surface.find_non_colliding_position(spawnerName, position, CHUNK_SIZE, 4)
|
|
|
|
if newPosition then
|
|
|
|
entity = surface.create_entity({name = spawnerName, position = newPosition})
|
|
|
|
end
|
2018-01-16 09:21:12 +02:00
|
|
|
end
|
2018-01-14 09:07:29 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
return entity
|
|
|
|
end
|
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
function baseUtils.upgradeBase(base)
|
|
|
|
local paths = BASE_ALIGNMENT_PATHS[base.alignment]
|
|
|
|
if paths then
|
|
|
|
base.alignment = paths[mRandom(#paths)]
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
|
|
|
|
function baseUtils.processBase(map, surface, natives, tick, base, evolutionFactor)
|
|
|
|
local areaTop = map.position2Top
|
|
|
|
local areaBottom = map.position2Bottom
|
|
|
|
|
|
|
|
areaTop[1] = base.x
|
|
|
|
areaTop[2] = base.y
|
|
|
|
|
|
|
|
areaBottom[1] = base.x + CHUNK_SIZE
|
|
|
|
areaBottom[2] = base.y + CHUNK_SIZE
|
|
|
|
|
|
|
|
local entity
|
|
|
|
local cost
|
|
|
|
local choice = mRandom()
|
|
|
|
if (choice <= 0.3) then
|
|
|
|
if (base.points >= BASE_SPAWNER_UPGRADE) then
|
|
|
|
entity = surface.find_entities_filtered(map.filteredEntitiesSpawnerQueryLimited)
|
|
|
|
cost = BASE_SPAWNER_UPGRADE
|
|
|
|
end
|
|
|
|
elseif (choice <= 0.6) then
|
|
|
|
if (base.points >= BASE_WORM_UPGRADE) then
|
|
|
|
entity = surface.find_entities_filtered(map.filteredEntitiesWormQueryLimited)
|
|
|
|
cost = BASE_WORM_UPGRADE
|
|
|
|
end
|
|
|
|
elseif (choice >= 0.995) then
|
|
|
|
if (base.points >= BASE_UPGRADE) then
|
|
|
|
if baseUtils.upgradeBase(base) then
|
|
|
|
base.points = base.points - BASE_UPGRADE
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if entity and (#entity > 0) then
|
|
|
|
baseUtils.upgradeEntity(map, entity[mRandom(#entity)], surface, natives, evolutionFactor, tick)
|
|
|
|
base.points = base.points - cost
|
|
|
|
end
|
|
|
|
|
|
|
|
base.points = base.points + natives.baseIncrement
|
|
|
|
|
|
|
|
base.tick = tick
|
|
|
|
end
|
|
|
|
|
|
|
|
function baseUtils.createBase(map, natives, evolutionFactor, chunk, surface, tick, expansion)
|
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
|
|
|
|
|
|
|
local meanLevel = mFloor(distance / 200)
|
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
-- if then
|
|
|
|
-- end
|
|
|
|
--local alignments = { BASE_ALIGNMENT_NEUTRAL }
|
|
|
|
local alignment = BASE_ALIGNMENT_NEUTRAL
|
2018-01-16 09:21:12 +02:00
|
|
|
|
2017-05-12 06:50:06 +02:00
|
|
|
local base = {
|
2018-01-15 09:41:55 +02:00
|
|
|
x = x,
|
|
|
|
y = y,
|
2018-01-20 09:15:13 +02:00
|
|
|
tick = tick,
|
2018-01-21 09:42:47 +02:00
|
|
|
alignment = alignment,
|
|
|
|
points = 0,
|
|
|
|
level = gaussianRandomRange(meanLevel, meanLevel * 0.3, meanLevel * 0.50, meanLevel * 1.50)
|
2017-05-12 06:50:06 +02:00
|
|
|
}
|
2018-01-15 09:41:55 +02:00
|
|
|
|
|
|
|
setChunkBase(map, chunk, base)
|
|
|
|
|
|
|
|
-- if not buildHive(map, base, surface) then
|
|
|
|
-- return nil
|
|
|
|
-- end
|
|
|
|
|
2018-01-16 09:21:12 +02:00
|
|
|
natives.bases[#natives.bases+1] = base
|
2018-01-15 09:41:55 +02:00
|
|
|
|
2017-05-12 06:50:06 +02:00
|
|
|
return base
|
2017-05-08 08:56:11 +02:00
|
|
|
end
|
|
|
|
|
2018-01-21 09:42:47 +02:00
|
|
|
local function fileEntity(baseAlignment, entity, evolutionTable)
|
|
|
|
local evoRequirement = mFloor(entity.prototype.build_base_evolution_requirement/EVOLUTION_INCREMENTS) * EVOLUTION_INCREMENTS
|
|
|
|
local eTable = evolutionTable[baseAlignment]
|
|
|
|
if not eTable then
|
|
|
|
eTable = {}
|
|
|
|
evolutionTable[baseAlignment] = eTable
|
|
|
|
end
|
|
|
|
local aTable = eTable[evoRequirement]
|
|
|
|
if not aTable then
|
|
|
|
aTable = {}
|
|
|
|
eTable[evoRequirement] = aTable
|
|
|
|
end
|
|
|
|
aTable[#aTable+1] = entity.name
|
|
|
|
end
|
|
|
|
|
|
|
|
local function processUnitClass(biterVariation, biterTier, spitterVariation, spitterTier, wormVariation, wormTier, surface, natives, baseAlignment, baseAlignmentString)
|
|
|
|
local position = { x = 0, y = 0 }
|
|
|
|
|
|
|
|
for v=1,biterVariation do
|
|
|
|
for t=1,biterTier do
|
|
|
|
local entity = surface.create_entity({
|
|
|
|
name= baseAlignmentString .. "-biter-nest-v" .. v .. "-t" .. t .. "-rampant",
|
|
|
|
position = position
|
|
|
|
})
|
|
|
|
fileEntity(baseAlignment, entity, natives.evolutionTableUnitSpawner)
|
|
|
|
entity.destroy()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for v=1,spitterVariation do
|
|
|
|
for t=1,spitterTier do
|
|
|
|
local entity = surface.create_entity({
|
|
|
|
name=baseAlignmentString .. "-spitter-nest-v" .. v .. "-t" .. t .. "-rampant",
|
|
|
|
position = position
|
|
|
|
})
|
|
|
|
fileEntity(baseAlignment, entity, natives.evolutionTableUnitSpawner)
|
|
|
|
entity.destroy()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for v=1,wormVariation do
|
|
|
|
for t=1,wormTier do
|
|
|
|
local entity = surface.create_entity({
|
|
|
|
name=baseAlignmentString .. "-worm-v" .. v .. "-t" .. t .. "-rampant",
|
|
|
|
position = position
|
|
|
|
})
|
|
|
|
fileEntity(baseAlignment, entity, natives.evolutionTableWorm)
|
|
|
|
entity.destroy()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function baseUtils.rebuildNativeTables(natives, surface)
|
|
|
|
natives.evolutionTableUnitSpawner = {}
|
|
|
|
natives.evolutionTableWorm = {}
|
|
|
|
|
|
|
|
processUnitClass(NEUTRAL_NEST_VARIATIONS,
|
|
|
|
NEUTRAL_NEST_TIERS,
|
|
|
|
NEUTRAL_NEST_VARIATIONS,
|
|
|
|
NEUTRAL_NEST_TIERS,
|
|
|
|
NEUTRAL_WORM_VARIATIONS,
|
|
|
|
NEUTRAL_WORM_TIERS,
|
|
|
|
surface,
|
|
|
|
natives,
|
|
|
|
BASE_ALIGNMENT_NEUTRAL,
|
|
|
|
"neutral")
|
|
|
|
|
|
|
|
processUnitClass(ACID_NEST_VARIATIONS,
|
|
|
|
ACID_NEST_TIERS,
|
|
|
|
ACID_NEST_VARIATIONS,
|
|
|
|
ACID_NEST_TIERS,
|
|
|
|
ACID_WORM_VARIATIONS,
|
|
|
|
ACID_WORM_TIERS,
|
|
|
|
surface,
|
|
|
|
natives,
|
|
|
|
BASE_ALIGNMENT_ACID,
|
|
|
|
"acid")
|
|
|
|
|
|
|
|
processUnitClass(PHYSICAL_NEST_VARIATIONS,
|
|
|
|
PHYSICAL_NEST_TIERS,
|
|
|
|
PHYSICAL_NEST_VARIATIONS,
|
|
|
|
PHYSICAL_NEST_TIERS,
|
|
|
|
PHYSICAL_WORM_VARIATIONS,
|
|
|
|
PHYSICAL_WORM_TIERS,
|
|
|
|
surface,
|
|
|
|
natives,
|
|
|
|
BASE_ALIGNMENT_PHYSICAL,
|
|
|
|
"physical")
|
|
|
|
|
|
|
|
processUnitClass(FIRE_NEST_VARIATIONS,
|
|
|
|
FIRE_NEST_TIERS,
|
|
|
|
FIRE_NEST_VARIATIONS,
|
|
|
|
FIRE_NEST_TIERS,
|
|
|
|
FIRE_WORM_VARIATIONS,
|
|
|
|
FIRE_WORM_TIERS,
|
|
|
|
surface,
|
|
|
|
natives,
|
|
|
|
BASE_ALIGNMENT_FIRE,
|
|
|
|
"fire")
|
|
|
|
|
|
|
|
processUnitClass(ELECTRIC_NEST_VARIATIONS,
|
|
|
|
ELECTRIC_NEST_TIERS,
|
|
|
|
ELECTRIC_NEST_VARIATIONS,
|
|
|
|
ELECTRIC_NEST_TIERS,
|
|
|
|
ELECTRIC_WORM_VARIATIONS,
|
|
|
|
ELECTRIC_WORM_TIERS,
|
|
|
|
surface,
|
|
|
|
natives,
|
|
|
|
BASE_ALIGNMENT_ELECTRIC,
|
|
|
|
"electric")
|
|
|
|
end
|
|
|
|
|
2017-05-08 08:56:11 +02:00
|
|
|
return baseUtils
|
|
|
|
|