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

682 lines
26 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 chunkUtilsG then
2020-04-28 05:41:18 +02:00
return chunkUtilsG
2019-02-16 06:17:30 +02:00
end
local chunkUtils = {}
-- imports
local baseUtils = require("BaseUtils")
local constants = require("Constants")
2017-11-21 09:27:03 +02:00
local mapUtils = require("MapUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils")
local mathUtils = require("MathUtils")
local queryUtils = require("QueryUtils")
2017-11-21 09:27:03 +02:00
-- constants
2017-05-12 06:50:06 +02:00
2019-11-30 02:49:22 +02:00
local HIVE_BUILDINGS_TYPES = constants.HIVE_BUILDINGS_TYPES
2017-11-21 09:27:03 +02:00
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
2017-06-08 02:57:24 +02:00
2019-03-09 02:42:20 +02:00
local CHUNK_PASS_THRESHOLD = constants.CHUNK_PASS_THRESHOLD
local BASE_AI_STATE_ONSLAUGHT = constants.BASE_AI_STATE_ONSLAUGHT
2019-02-11 08:14:17 +02:00
2016-10-15 02:00:18 +02:00
local BASE_PHEROMONE = constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
2017-06-08 02:57:24 +02:00
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
local CHUNK_SIZE = constants.CHUNK_SIZE
local CHUNK_SIZE_DIVIDER = constants.CHUNK_SIZE_DIVIDER
2017-06-10 10:38:20 +02:00
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST
2017-06-10 10:38:20 +02:00
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE
local RESOURCE_NORMALIZER = constants.RESOURCE_NORMALIZER
2016-10-15 02:00:18 +02:00
local CHUNK_TICK = constants.CHUNK_TICK
2019-10-19 21:13:48 +02:00
local GENERATOR_PHEROMONE_LEVEL_1 = constants.GENERATOR_PHEROMONE_LEVEL_1
local GENERATOR_PHEROMONE_LEVEL_3 = constants.GENERATOR_PHEROMONE_LEVEL_3
local GENERATOR_PHEROMONE_LEVEL_5 = constants.GENERATOR_PHEROMONE_LEVEL_5
local GENERATOR_PHEROMONE_LEVEL_6 = constants.GENERATOR_PHEROMONE_LEVEL_6
2017-05-12 06:50:06 +02:00
-- imported functions
local setAreaInQueryChunkSize = queryUtils.setAreaInQueryChunkSize
local setAreaXInQuery = queryUtils.setAreaXInQuery
local setAreaYInQuery = queryUtils.setAreaYInQuery
local setPlayerBaseGenerator = chunkPropertyUtils.setPlayerBaseGenerator
local addPlayerBaseGenerator = chunkPropertyUtils.addPlayerBaseGenerator
local setResourceGenerator = chunkPropertyUtils.setResourceGenerator
local addResourceGenerator = chunkPropertyUtils.addResourceGenerator
local addNestCount = chunkPropertyUtils.addNestCount
local removeNestCount = chunkPropertyUtils.removeNestCount
local addHiveCount = chunkPropertyUtils.addHiveCount
local removeHiveCount = chunkPropertyUtils.removeHiveCount
local addTrapCount = chunkPropertyUtils.addTrapCount
local removeTrapCount = chunkPropertyUtils.removeTrapCount
local addTurretCount = chunkPropertyUtils.addTurretCount
local removeTurretCount = chunkPropertyUtils.removeTurretCount
local addUtilityCount = chunkPropertyUtils.addUtilityCount
local removeUtilityCount = chunkPropertyUtils.removeUtilityCount
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
2019-02-20 08:16:43 +02:00
local setRaidNestActiveness = chunkPropertyUtils.setRaidNestActiveness
local setNestActiveness = chunkPropertyUtils.setNestActiveness
local getChunkById = mapUtils.getChunkById
2019-12-16 03:16:56 +02:00
local processNestActiveness = chunkPropertyUtils.processNestActiveness
local removeChunkBase = chunkPropertyUtils.removeChunkBase
2019-11-30 02:49:22 +02:00
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
local findNearbyBase = chunkPropertyUtils.findNearbyBase
local createBase = baseUtils.createBase
2017-11-21 09:27:03 +02:00
local upgradeEntity = baseUtils.upgradeEntity
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
2021-04-30 07:24:14 +02:00
local getChunkBase = chunkPropertyUtils.getChunkBase
local setChunkBase = chunkPropertyUtils.setChunkBase
2018-09-24 06:56:45 +02:00
local setPassable = chunkPropertyUtils.setPassable
local setPathRating = chunkPropertyUtils.setPathRating
local getChunkByXY = mapUtils.getChunkByXY
2018-01-14 07:48:21 +02:00
2020-05-25 05:25:21 +02:00
local mMin = math.min
local mMax = math.max
2017-11-21 09:27:03 +02:00
local mFloor = math.floor
2017-05-12 06:50:06 +02:00
-- module code
2017-05-06 11:03:28 +02:00
2018-01-14 07:48:21 +02:00
local function getEntityOverlapChunks(map, entity)
2021-11-26 08:49:28 +02:00
local boundingBox = entity.prototype.collision_box or entity.prototype.selection_box
2021-02-20 09:31:36 +02:00
local overlapArray = map.universe.chunkOverlapArray
2020-04-28 05:41:18 +02:00
2020-05-15 22:51:38 +02:00
overlapArray[1] = -1 --LeftTop
overlapArray[2] = -1 --RightTop
overlapArray[3] = -1 --LeftBottom
overlapArray[4] = -1 --RightBottom
2020-04-28 05:41:18 +02:00
if boundingBox then
local center = entity.position
local topXOffset = boundingBox.left_top.x
local topYOffset = boundingBox.left_top.y
2020-04-28 05:41:18 +02:00
local bottomXOffset = boundingBox.right_bottom.x
local bottomYOffset = boundingBox.right_bottom.y
2020-04-28 05:41:18 +02:00
local leftTopChunkX = mFloor((center.x + topXOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local leftTopChunkY = mFloor((center.y + topYOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local rightTopChunkX = mFloor((center.x + bottomXOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local leftBottomChunkY = mFloor((center.y + bottomYOffset) * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
overlapArray[1] = getChunkByXY(map, leftTopChunkX, leftTopChunkY) -- LeftTop
if (leftTopChunkX ~= rightTopChunkX) then
overlapArray[2] = getChunkByXY(map, rightTopChunkX, leftTopChunkY) -- RightTop
end
if (leftTopChunkY ~= leftBottomChunkY) then
overlapArray[3] = getChunkByXY(map, leftTopChunkX, leftBottomChunkY) -- LeftBottom
end
if (leftTopChunkX ~= rightTopChunkX) and (leftTopChunkY ~= leftBottomChunkY) then
overlapArray[4] = getChunkByXY(map, rightTopChunkX, leftBottomChunkY) -- RightBottom
end
end
return overlapArray
2017-11-21 09:27:03 +02:00
end
2021-02-20 07:41:30 +02:00
local function scanPaths(chunk, map)
local surface = map.surface
2020-04-28 05:41:18 +02:00
local pass = CHUNK_IMPASSABLE
local x = chunk.x
local y = chunk.y
2021-02-20 09:31:36 +02:00
local universe = map.universe
local filteredEntitiesCliffQuery = universe.spFilteredEntitiesCliffQuery
local filteredTilesPathQuery = universe.spFilteredTilesPathQuery
2020-04-28 05:41:18 +02:00
local count_entities_filtered = surface.count_entities_filtered
local count_tiles_filtered = surface.count_tiles_filtered
local passableNorthSouth = false
local passableEastWest = false
setAreaYInQuery(filteredEntitiesCliffQuery, y, y + CHUNK_SIZE)
2020-04-28 05:41:18 +02:00
for xi=x, x + CHUNK_SIZE do
setAreaXInQuery(filteredEntitiesCliffQuery, xi, xi + 1)
2020-04-28 05:41:18 +02:00
if (count_entities_filtered(filteredEntitiesCliffQuery) == 0) and
(count_tiles_filtered(filteredTilesPathQuery) == 0)
then
passableNorthSouth = true
break
end
end
setAreaXInQuery(filteredEntitiesCliffQuery, x, x + CHUNK_SIZE)
2020-04-28 05:41:18 +02:00
for yi=y, y + CHUNK_SIZE do
setAreaYInQuery(filteredEntitiesCliffQuery, yi, yi + 1)
2020-04-28 05:41:18 +02:00
if (count_entities_filtered(filteredEntitiesCliffQuery) == 0) and
(count_tiles_filtered(filteredTilesPathQuery) == 0)
then
passableEastWest = true
break
end
end
if passableEastWest and passableNorthSouth then
pass = CHUNK_ALL_DIRECTIONS
elseif passableEastWest then
pass = CHUNK_EAST_WEST
elseif passableNorthSouth then
pass = CHUNK_NORTH_SOUTH
end
return pass
end
local function scorePlayerBuildings(map, chunk)
2021-02-20 07:41:30 +02:00
local surface = map.surface
2021-02-20 09:31:36 +02:00
local universe = map.universe
setAreaInQueryChunkSize(universe.spbHasPlayerStructuresQuery, chunk)
if surface.count_entities_filtered(universe.spbHasPlayerStructuresQuery) > 0 then
return (surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryLowest) * GENERATOR_PHEROMONE_LEVEL_1) +
(surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryLow) * GENERATOR_PHEROMONE_LEVEL_3) +
(surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryHigh) * GENERATOR_PHEROMONE_LEVEL_5) +
(surface.count_entities_filtered(universe.spbFilteredEntitiesPlayerQueryHighest) * GENERATOR_PHEROMONE_LEVEL_6)
end
return 0
end
2021-02-20 07:41:30 +02:00
function chunkUtils.initialScan(chunk, map, tick)
local surface = map.surface
2021-02-20 09:31:36 +02:00
local universe = map.universe
setAreaInQueryChunkSize(universe.isFilteredTilesQuery, chunk)
local waterTiles = (1 - (surface.count_tiles_filtered(universe.isFilteredTilesQuery) * 0.0009765625)) * 0.80
local enemyBuildings = surface.find_entities_filtered(universe.isFilteredEntitiesEnemyStructureQuery)
2019-02-06 08:25:43 +02:00
2020-05-25 05:25:21 +02:00
if (waterTiles >= CHUNK_PASS_THRESHOLD) or (#enemyBuildings > 0) then
2021-02-14 06:49:54 +02:00
local neutralObjects = mMax(0,
mMin(1 - (surface.count_entities_filtered(universe.isFilteredEntitiesChunkNeutral) * 0.005),
2021-02-14 06:49:54 +02:00
1) * 0.20)
2021-02-20 07:41:30 +02:00
local pass = scanPaths(chunk, map)
2019-10-19 23:04:38 +02:00
local playerObjects = scorePlayerBuildings(map, chunk)
2020-04-28 05:41:18 +02:00
if ((playerObjects > 0) or (#enemyBuildings > 0)) and (pass == CHUNK_IMPASSABLE) then
pass = CHUNK_ALL_DIRECTIONS
end
2020-04-28 05:41:18 +02:00
if (pass ~= CHUNK_IMPASSABLE) then
local resources = surface.count_entities_filtered(universe.isCountResourcesQuery) * RESOURCE_NORMALIZER
2020-03-16 00:16:00 +02:00
local vanillaEntityTypeLookup = universe.vanillaEntityTypeLookup
2021-02-20 09:31:36 +02:00
local buildingHiveTypeLookup = universe.buildingHiveTypeLookup
2020-04-28 05:41:18 +02:00
local counts = map.chunkScanCounts
for i=1,#HIVE_BUILDINGS_TYPES do
counts[HIVE_BUILDINGS_TYPES[i]] = 0
2020-03-16 00:16:00 +02:00
end
if (#enemyBuildings > 0) then
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
2020-04-28 05:41:18 +02:00
if universe.NEW_ENEMIES then
local unitList = surface.find_entities_filtered(universe.isFilteredEntitiesUnitQuery)
2020-04-28 05:41:18 +02:00
for i=1,#unitList do
local unit = unitList[i]
if (unit.valid) then
unit.destroy()
2019-02-21 08:31:47 +02:00
end
2020-04-28 05:41:18 +02:00
end
for i = 1, #enemyBuildings do
local enemyBuilding = enemyBuildings[i]
chunkUtils.registerEnemyBaseStructure(map, enemyBuilding, base)
local entityName = enemyBuilding.name
local isVanilla = vanillaEntityTypeLookup[entityName]
if isVanilla or (not isVanilla and not buildingHiveTypeLookup[entityName]) then
upgradeEntity(enemyBuilding, base, map, nil, true)
2020-04-28 05:41:18 +02:00
end
end
else
for i=1,#enemyBuildings do
local building = enemyBuildings[i]
chunkUtils.registerEnemyBaseStructure(map, building, base)
2020-04-28 05:41:18 +02:00
end
end
2019-02-21 08:31:47 +02:00
end
2019-02-06 08:25:43 +02:00
2020-04-28 05:41:18 +02:00
setPlayerBaseGenerator(map, chunk, playerObjects)
setResourceGenerator(map, chunk, resources)
2019-02-06 08:25:43 +02:00
2020-04-28 05:41:18 +02:00
setPassable(map, chunk, pass)
2020-05-25 05:25:21 +02:00
setPathRating(map, chunk, waterTiles + neutralObjects)
2020-04-28 05:41:18 +02:00
return chunk
end
end
2020-05-15 22:51:38 +02:00
return -1
end
2021-02-20 07:41:30 +02:00
function chunkUtils.chunkPassScan(chunk, map)
local surface = map.surface
2021-02-20 09:31:36 +02:00
local universe = map.universe
setAreaInQueryChunkSize(universe.cpsFilteredTilesQuery, chunk)
local waterTiles = (1 - (surface.count_tiles_filtered(universe.cpsFilteredTilesQuery) * 0.0009765625)) * 0.80
local enemyCount = surface.count_entities_filtered(universe.cpsFilteredEnemyAnyFound)
if (waterTiles >= CHUNK_PASS_THRESHOLD) or (enemyCount > 0) then
2021-02-14 06:49:54 +02:00
local neutralObjects = mMax(0,
mMin(1 - (surface.count_entities_filtered(universe.cpsFilteredEntitiesChunkNeutral) * 0.005),
2021-02-14 06:49:54 +02:00
1) * 0.20)
2021-02-20 07:41:30 +02:00
local pass = scanPaths(chunk, map)
2019-02-06 08:25:43 +02:00
2020-04-28 05:41:18 +02:00
local playerObjects = getPlayerBaseGenerator(map, chunk)
if ((playerObjects > 0) or (enemyCount > 0)) and (pass == CHUNK_IMPASSABLE) then
2020-04-28 05:41:18 +02:00
pass = CHUNK_ALL_DIRECTIONS
end
2020-04-28 05:41:18 +02:00
setPassable(map, chunk, pass)
2020-05-25 05:25:21 +02:00
setPathRating(map, chunk, waterTiles + neutralObjects)
if pass == CHUNK_IMPASSABLE then
return -1
end
2020-04-28 05:41:18 +02:00
return chunk
end
2020-05-15 22:51:38 +02:00
return -1
end
2021-02-20 07:41:30 +02:00
function chunkUtils.mapScanPlayerChunk(chunk, map)
local playerObjects = scorePlayerBuildings(map, chunk)
setPlayerBaseGenerator(map, chunk, playerObjects)
end
2021-02-20 07:41:30 +02:00
function chunkUtils.mapScanResourceChunk(chunk, map)
2021-02-20 09:31:36 +02:00
local universe = map.universe
setAreaInQueryChunkSize(universe.msrcCountResourcesQuery, chunk)
local surface = map.surface
local resources = surface.count_entities_filtered(universe.msrcCountResourcesQuery) * RESOURCE_NORMALIZER
2020-04-28 05:41:18 +02:00
setResourceGenerator(map, chunk, resources)
local waterTiles = (1 - (surface.count_tiles_filtered(universe.msrcFilteredTilesQuery) * 0.0009765625)) * 0.80
2021-02-14 06:49:54 +02:00
local neutralObjects = mMax(0,
mMin(1 - (surface.count_entities_filtered(universe.msrcFilteredEntitiesChunkNeutral) * 0.005),
2021-02-14 06:49:54 +02:00
1) * 0.20)
2020-05-25 05:25:21 +02:00
setPathRating(map, chunk, waterTiles + neutralObjects)
end
function chunkUtils.mapScanEnemyChunk(chunk, map, tick)
2021-02-20 09:31:36 +02:00
local universe = map.universe
setAreaInQueryChunkSize(universe.msecFilteredEntitiesEnemyStructureQuery, chunk)
local buildings = map.surface.find_entities_filtered(universe.msecFilteredEntitiesEnemyStructureQuery)
2020-04-28 05:41:18 +02:00
local counts = map.chunkScanCounts
for i=1,#HIVE_BUILDINGS_TYPES do
counts[HIVE_BUILDINGS_TYPES[i]] = 0
end
if (#buildings > 0) then
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
for i=1,#buildings do
local building = buildings[i]
2020-04-28 05:41:18 +02:00
chunkUtils.registerEnemyBaseStructure(map, building, base)
end
end
end
function chunkUtils.addBasesToAllEnemyStructures(universe, tick)
for chunkId, chunkPack in pairs(universe.chunkToNests) do
local map = chunkPack.map
if map.surface.valid then
local chunk = getChunkById(map, chunkId)
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
setChunkBase(map, chunk, base)
end
end
for _, map in pairs(universe.maps) do
if map.surface.valid then
for chunkId in pairs(map.chunkToTurrets) do
local chunk = getChunkById(map, chunkId)
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
setChunkBase(map, chunk, base)
end
for chunkId in pairs(map.chunkToHives) do
local chunk = getChunkById(map, chunkId)
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
setChunkBase(map, chunk, base)
end
for chunkId in pairs(map.chunkToUtilities) do
local chunk = getChunkById(map, chunkId)
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
setChunkBase(map, chunk, base)
end
for chunkId in pairs(map.chunkToTraps) do
local chunk = getChunkById(map, chunkId)
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(map, chunk, tick)
end
setChunkBase(map, chunk, base)
end
end
end
end
2019-03-10 21:28:43 +02:00
function chunkUtils.entityForPassScan(map, entity)
2020-04-28 05:41:18 +02:00
local overlapArray = getEntityOverlapChunks(map, entity)
for i=1,#overlapArray do
local chunk = overlapArray[i]
if (chunk ~= -1) and not map.universe.chunkToPassScan[chunk.id] then
map.universe.chunkToPassScan[chunk.id] = {
map = map,
chunk = chunk
}
2020-04-28 05:41:18 +02:00
end
end
2019-03-10 21:28:43 +02:00
end
2021-12-06 05:40:39 +02:00
local function newChunkId(universe)
local id = universe.chunkId
universe.chunkId = universe.chunkId + 1
return id
end
function chunkUtils.createChunk(map, topX, topY)
2020-04-28 05:41:18 +02:00
local chunk = {
x = topX,
y = topY,
dOrigin = euclideanDistancePoints(topX, topY, 0, 0),
2021-12-06 05:40:39 +02:00
id = newChunkId(map.universe)
2020-04-28 05:41:18 +02:00
}
chunk[BASE_PHEROMONE] = 0
chunk[PLAYER_PHEROMONE] = 0
chunk[RESOURCE_PHEROMONE] = 0
chunk[CHUNK_TICK] = 0
return chunk
end
function chunkUtils.colorChunk(chunk, surface, color, ttl)
2020-05-24 05:47:14 +02:00
local lx = math.floor(chunk.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local ly = math.floor(chunk.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
2021-02-14 06:49:54 +02:00
rendering.draw_rectangle({
2020-05-24 05:47:14 +02:00
color = color or {0.1, 0.3, 0.1, 0.6},
width = 32 * 32,
filled = true,
left_top = {lx, ly},
right_bottom = {lx+32, ly+32},
surface = surface,
time_to_live = ttl or 180,
2020-05-24 05:47:14 +02:00
draw_on_ground = true,
visible = true
})
end
function chunkUtils.colorXY(x, y, surface, color)
2020-04-28 05:41:18 +02:00
local lx = math.floor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local ly = math.floor(y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
2020-05-24 05:47:14 +02:00
2021-02-14 06:49:54 +02:00
rendering.draw_rectangle({
2020-05-24 05:47:14 +02:00
color = color or {0.1, 0.3, 0.1, 0.6},
width = 32 * 32,
filled = true,
left_top = {lx, ly},
right_bottom = {lx+32, ly+32},
surface = surface,
time_to_live = 180,
draw_on_ground = true,
visible = true
})
2017-12-31 21:36:23 +02:00
end
function chunkUtils.registerEnemyBaseStructure(map, entity, base, skipCount)
2020-04-28 05:41:18 +02:00
local entityType = entity.type
local addFunc
local universe = map.universe
local hiveTypeLookup = universe.buildingHiveTypeLookup
local hiveType = hiveTypeLookup[entity.name]
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
addFunc = addNestCount
elseif (hiveType == "turret") then
addFunc = addTurretCount
elseif (hiveType == "trap") then
addFunc = addTrapCount
elseif (hiveType == "utility") then
addFunc = addUtilityCount
elseif (hiveType == "hive") then
addFunc = addHiveCount
else
if (entityType == "turret") then
addFunc = addTurretCount
2020-04-28 05:41:18 +02:00
else
addFunc = addNestCount
2020-04-28 05:41:18 +02:00
end
end
2020-04-28 05:41:18 +02:00
local added = false
local entityUnitNumber = entity.unit_number
local chunks = getEntityOverlapChunks(map, entity)
for i=1,#chunks do
local chunk = chunks[i]
if (chunk ~= -1) then
if addFunc(map, chunk, entityUnitNumber) then
added = true
setChunkBase(map, chunk, base)
end
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
2021-02-20 07:41:30 +02:00
processNestActiveness(map, chunk)
2020-04-28 05:41:18 +02:00
end
end
end
if added and (not skipCount) then
base.builtEnemyBuilding = base.builtEnemyBuilding + 1
end
2017-11-21 09:27:03 +02:00
end
function chunkUtils.unregisterEnemyBaseStructure(map, entity, damageTypeName, skipCount)
2020-04-28 05:41:18 +02:00
local entityType = entity.type
local removeFunc
local hiveTypeLookup = map.universe.buildingHiveTypeLookup
local hiveType = hiveTypeLookup[entity.name]
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
removeFunc = removeNestCount
elseif (hiveType == "turret") then
removeFunc = removeTurretCount
elseif (hiveType == "trap") then
removeFunc = removeTrapCount
elseif (hiveType == "utility") then
removeFunc = removeUtilityCount
elseif (hiveType == "hive") then
removeFunc = removeHiveCount
else
if (entityType == "turret") then
removeFunc = removeTurretCount
2020-04-28 05:41:18 +02:00
else
hiveType = "biter-spawner"
removeFunc = removeNestCount
2020-04-28 05:41:18 +02:00
end
end
2020-04-28 05:41:18 +02:00
local entityUnitNumber = entity.unit_number
local usedBases = {}
local chunks = getEntityOverlapChunks(map, entity)
for i=1,#chunks do
local chunk = chunks[i]
if (chunk ~= -1) then
local base = getChunkBase(map, chunk)
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
setRaidNestActiveness(map, chunk, 0, base)
setNestActiveness(map, chunk, 0, base)
end
if removeFunc(map, chunk, entityUnitNumber) then
if not usedBases[base.id] then
usedBases[base.id] = true
if damageTypeName then
base.damagedBy[damageTypeName] = (base.damagedBy[damageTypeName] or 0) + 3
base.deathEvents = base.deathEvents + 3
end
if (not skipCount) and (hiveType ~= "trap") then
base.lostEnemyBuilding = base.lostEnemyBuilding + 1
end
end
if (getEnemyStructureCount(map, chunk) <= 0) then
removeChunkBase(map, chunk, base)
end
end
2020-04-28 05:41:18 +02:00
end
end
2017-11-21 09:27:03 +02:00
end
function chunkUtils.accountPlayerEntity(entity, map, addObject, base)
2020-04-28 05:41:18 +02:00
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name ~= "enemy") then
local universe = map.universe
2020-04-28 05:41:18 +02:00
local entityValue = BUILDING_PHEROMONES[entity.type]
local overlapArray = getEntityOverlapChunks(map, entity)
if not addObject then
if base then
local pointValue = entityValue
if pointValue == GENERATOR_PHEROMONE_LEVEL_1 then
pointValue = 0
end
base.destroyPlayerBuildings = base.destroyPlayerBuildings + 1
if (base.stateAI == BASE_AI_STATE_ONSLAUGHT) then
base.unitPoints = base.unitPoints + pointValue
if universe.aiPointsPrintGainsToChat then
game.print(map.surface.name .. ": Points: +" .. math.floor(pointValue) .. ". [Structure Kill] Total: " .. string.format("%.2f", base.unitPoints))
end
2020-04-28 05:41:18 +02:00
else
base.unitPoints = base.unitPoints + (pointValue * 0.12)
if universe.aiPointsPrintGainsToChat then
game.print(map.surface.name .. ": Points: +" .. math.floor(pointValue) .. ". [Structure Kill] Total: " .. string.format("%.2f", base.unitPoints))
end
2020-04-28 05:41:18 +02:00
end
end
entityValue = -entityValue
end
for i=1,#overlapArray do
local chunk = overlapArray[i]
2020-05-15 22:51:38 +02:00
if (chunk ~= -1) then
2020-04-28 05:41:18 +02:00
addPlayerBaseGenerator(map, chunk, entityValue)
end
2020-04-28 05:41:18 +02:00
end
end
return entity
2017-11-21 09:27:03 +02:00
end
2018-01-14 07:48:21 +02:00
function chunkUtils.unregisterResource(entity, map)
2020-04-28 05:41:18 +02:00
if entity.prototype.infinite_resource then
return
end
local overlapArray = getEntityOverlapChunks(map, entity)
for i=1,#overlapArray do
local chunk = overlapArray[i]
2020-05-15 22:51:38 +02:00
if (chunk ~= -1) then
2020-04-28 05:41:18 +02:00
addResourceGenerator(map, chunk, -RESOURCE_NORMALIZER)
end
end
end
2019-05-16 07:11:43 +02:00
function chunkUtils.registerResource(entity, map)
2020-04-28 05:41:18 +02:00
local overlapArray = getEntityOverlapChunks(map, entity)
for i=1,#overlapArray do
local chunk = overlapArray[i]
2020-05-15 22:51:38 +02:00
if (chunk ~= -1) then
2020-04-28 05:41:18 +02:00
addResourceGenerator(map, chunk, RESOURCE_NORMALIZER)
end
end
2019-05-16 07:11:43 +02:00
end
2017-11-21 09:27:03 +02:00
function chunkUtils.makeImmortalEntity(surface, entity)
2020-04-28 05:41:18 +02:00
local repairPosition = entity.position
local repairName = entity.name
local repairForce = entity.force
local repairDirection = entity.direction
local wires
if (entity.type == "electric-pole") then
wires = entity.neighbours
end
entity.destroy()
local newEntity = surface.create_entity({position=repairPosition,
name=repairName,
direction=repairDirection,
force=repairForce})
if wires then
for _,v in pairs(wires.copper) do
if (v.valid) then
newEntity.connect_neighbour(v);
end
end
for _,v in pairs(wires.red) do
if (v.valid) then
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_RED, target_entity = v});
end
end
for _,v in pairs(wires.green) do
if (v.valid) then
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_GREEN, target_entity = v});
end
end
end
newEntity.destructible = false
2017-11-21 09:27:03 +02:00
end
2019-02-16 06:17:30 +02:00
chunkUtilsG = chunkUtils
return chunkUtils