2022-01-14 14:08:58 -08: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-15 20:17:30 -08:00
|
|
|
if unitGroupUtilsG then
|
|
|
|
return unitGroupUtilsG
|
|
|
|
end
|
2016-08-04 21:47:51 -07:00
|
|
|
local unitGroupUtils = {}
|
|
|
|
|
2016-08-19 19:52:27 -07:00
|
|
|
-- imports
|
|
|
|
|
2018-01-13 21:48:21 -08:00
|
|
|
local mapUtils = require("MapUtils")
|
2016-08-06 20:38:47 -07:00
|
|
|
local constants = require("Constants")
|
2018-01-14 23:41:55 -08:00
|
|
|
local chunkPropertyUtils = require("ChunkPropertyUtils")
|
2021-12-28 13:17:39 -08:00
|
|
|
local mathUtils = require("MathUtils")
|
2016-08-04 21:47:51 -07:00
|
|
|
|
2016-08-19 19:52:27 -07:00
|
|
|
-- constants
|
|
|
|
|
2021-12-28 13:17:39 -08:00
|
|
|
local MINIMUM_EXPANSION_DISTANCE = constants.MINIMUM_EXPANSION_DISTANCE
|
2016-08-19 19:52:27 -07:00
|
|
|
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
|
|
|
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
2018-01-13 21:48:21 -08:00
|
|
|
|
2016-08-19 19:52:27 -07:00
|
|
|
-- imported functions
|
|
|
|
|
2021-12-28 13:17:39 -08:00
|
|
|
local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG
|
|
|
|
|
2018-01-14 23:41:55 -08:00
|
|
|
local getSquadsOnChunk = chunkPropertyUtils.getSquadsOnChunk
|
2018-01-13 21:48:21 -08:00
|
|
|
|
|
|
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
|
|
|
|
2016-08-19 19:52:27 -07:00
|
|
|
-- module code
|
2017-01-19 21:58:36 -08:00
|
|
|
|
2019-03-09 15:16:35 -08:00
|
|
|
function unitGroupUtils.findNearbyRetreatingSquad(map, chunk)
|
2019-03-08 16:42:20 -08:00
|
|
|
|
2020-05-23 20:47:14 -07:00
|
|
|
for _,squad in pairs(getSquadsOnChunk(map, chunk)) do
|
2019-10-13 22:49:52 -07:00
|
|
|
local unitGroup = squad.group
|
2020-05-23 20:47:14 -07:00
|
|
|
if (squad.status == SQUAD_RETREATING) and unitGroup and unitGroup.valid then
|
2019-03-08 16:42:20 -08:00
|
|
|
return squad
|
|
|
|
end
|
2018-01-13 21:48:21 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
local neighbors = getNeighborChunks(map, chunk.x, chunk.y)
|
|
|
|
|
|
|
|
for i=1,#neighbors do
|
2019-03-08 16:42:20 -08:00
|
|
|
local neighbor = neighbors[i]
|
2020-05-15 13:51:38 -07:00
|
|
|
if neighbor ~= -1 then
|
2020-05-23 20:47:14 -07:00
|
|
|
for _,squad in pairs(getSquadsOnChunk(map, neighbor)) do
|
2019-03-08 16:42:20 -08:00
|
|
|
local unitGroup = squad.group
|
2020-05-23 20:47:14 -07:00
|
|
|
if (squad.status == SQUAD_RETREATING) and unitGroup and unitGroup.valid then
|
2019-03-08 16:42:20 -08:00
|
|
|
return squad
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2016-08-04 21:47:51 -07:00
|
|
|
end
|
2018-01-31 20:01:28 -08:00
|
|
|
return nil
|
2016-08-04 21:47:51 -07:00
|
|
|
end
|
|
|
|
|
2019-03-08 16:42:20 -08:00
|
|
|
function unitGroupUtils.findNearbySquad(map, chunk)
|
2018-01-31 20:01:28 -08:00
|
|
|
|
2020-05-23 20:47:14 -07:00
|
|
|
for _,squad in pairs(getSquadsOnChunk(map, chunk)) do
|
2019-03-08 16:42:20 -08:00
|
|
|
local unitGroup = squad.group
|
2019-10-20 13:45:43 -07:00
|
|
|
if unitGroup and unitGroup.valid then
|
|
|
|
return squad
|
2019-03-08 16:42:20 -08:00
|
|
|
end
|
2018-01-31 20:01:28 -08:00
|
|
|
end
|
2019-10-20 13:45:43 -07:00
|
|
|
|
2018-01-31 20:01:28 -08:00
|
|
|
local neighbors = getNeighborChunks(map, chunk.x, chunk.y)
|
2018-01-13 21:48:21 -08:00
|
|
|
|
2018-01-31 20:01:28 -08:00
|
|
|
for i=1,#neighbors do
|
2019-03-08 16:42:20 -08:00
|
|
|
local neighbor = neighbors[i]
|
2020-05-15 13:51:38 -07:00
|
|
|
if neighbor ~= -1 then
|
2020-05-23 20:47:14 -07:00
|
|
|
for _,squad in pairs(getSquadsOnChunk(map, neighbor)) do
|
2019-03-08 16:42:20 -08:00
|
|
|
local unitGroup = squad.group
|
|
|
|
if unitGroup and unitGroup.valid then
|
|
|
|
return squad
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-01-31 20:01:28 -08:00
|
|
|
end
|
2019-02-10 22:14:17 -08:00
|
|
|
|
2018-01-31 20:01:28 -08:00
|
|
|
return nil
|
|
|
|
end
|
2018-01-13 21:48:21 -08:00
|
|
|
|
2021-12-28 13:17:39 -08:00
|
|
|
function unitGroupUtils.calculateSettlerMaxDistance(universe)
|
|
|
|
local targetDistance
|
|
|
|
local distanceRoll = universe.random()
|
|
|
|
if distanceRoll < 0.05 then
|
|
|
|
return 0
|
|
|
|
elseif distanceRoll < 0.30 then
|
|
|
|
targetDistance = universe.expansionLowTargetDistance
|
|
|
|
elseif distanceRoll < 0.70 then
|
|
|
|
targetDistance = universe.expansionMediumTargetDistance
|
|
|
|
elseif distanceRoll < 0.95 then
|
|
|
|
targetDistance = universe.expansionHighTargetDistance
|
|
|
|
else
|
|
|
|
return universe.expansionMaxDistance
|
|
|
|
end
|
|
|
|
return gaussianRandomRangeRG(targetDistance,
|
|
|
|
universe.expansionDistanceDeviation,
|
|
|
|
MINIMUM_EXPANSION_DISTANCE,
|
|
|
|
universe.expansionMaxDistance,
|
|
|
|
universe.random)
|
|
|
|
end
|
|
|
|
|
2022-03-19 16:29:12 -07:00
|
|
|
function unitGroupUtils.createSquad(position, map, group, settlers, base)
|
2021-12-05 19:40:39 -08:00
|
|
|
local unitGroup = group or map.surface.create_unit_group({position=position})
|
2019-02-10 22:14:17 -08:00
|
|
|
|
2018-01-13 21:48:21 -08:00
|
|
|
local squad = {
|
2019-03-08 16:42:20 -08:00
|
|
|
group = unitGroup,
|
|
|
|
status = SQUAD_GUARDING,
|
|
|
|
rabid = false,
|
2020-05-23 21:17:18 -07:00
|
|
|
penalties = {},
|
2022-03-19 16:29:12 -07:00
|
|
|
base = base,
|
|
|
|
type = base.stateAI,
|
2019-03-08 16:42:20 -08:00
|
|
|
frenzy = false,
|
2021-12-05 19:40:39 -08:00
|
|
|
map = map,
|
2021-12-05 17:17:41 -08:00
|
|
|
wanders = 0,
|
2019-02-16 10:45:42 -08:00
|
|
|
settlers = settlers or false,
|
2019-03-08 16:42:20 -08:00
|
|
|
kamikaze = false,
|
|
|
|
frenzyPosition = {x = 0,
|
|
|
|
y = 0},
|
|
|
|
maxDistance = 0,
|
2020-05-16 22:06:55 -07:00
|
|
|
groupNumber = unitGroup.group_number,
|
2019-03-08 22:23:00 -08:00
|
|
|
originPosition = {x = 0,
|
|
|
|
y = 0},
|
2021-11-28 16:26:48 -08:00
|
|
|
commandTick = nil,
|
2020-05-15 13:51:38 -07:00
|
|
|
chunk = -1
|
2018-01-13 21:48:21 -08:00
|
|
|
}
|
2019-03-06 22:12:39 -08:00
|
|
|
|
2021-12-28 13:17:39 -08:00
|
|
|
if settlers then
|
|
|
|
squad.maxDistance = unitGroupUtils.calculateSettlerMaxDistance(map.universe)
|
|
|
|
end
|
|
|
|
|
2019-03-08 22:23:00 -08:00
|
|
|
if position then
|
|
|
|
squad.originPosition.x = position.x
|
|
|
|
squad.originPosition.y = position.y
|
|
|
|
elseif group then
|
|
|
|
squad.originPosition.x = group.position.x
|
|
|
|
squad.originPosition.y = group.position.y
|
|
|
|
end
|
|
|
|
|
2016-08-06 20:38:47 -07:00
|
|
|
return squad
|
|
|
|
end
|
|
|
|
|
2021-12-10 13:30:11 -08:00
|
|
|
function unitGroupUtils.calculateKamikazeSquadThreshold(memberCount, universe)
|
2021-02-20 12:44:52 -08:00
|
|
|
local threshold = (memberCount / universe.attackWaveMaxSize) * 0.2 + (universe.evolutionLevel * 0.2)
|
2020-05-23 20:47:14 -07:00
|
|
|
return threshold
|
2016-08-04 21:47:51 -07:00
|
|
|
end
|
|
|
|
|
2021-12-10 13:30:11 -08:00
|
|
|
function unitGroupUtils.calculateKamikazeSettlerThreshold(memberCount, universe)
|
|
|
|
local threshold = (memberCount / universe.expansionMaxSize) * 0.2 + (universe.evolutionLevel * 0.2)
|
|
|
|
return threshold
|
|
|
|
end
|
|
|
|
|
2019-02-15 20:17:30 -08:00
|
|
|
unitGroupUtilsG = unitGroupUtils
|
2016-08-29 21:08:22 -07:00
|
|
|
return unitGroupUtils
|