1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-28 21:08:22 +02:00
Rampant/libs/UnitGroupUtils.lua

278 lines
9.4 KiB
Lua
Raw Normal View History

2019-02-16 06:17:30 +02:00
if unitGroupUtilsG then
return unitGroupUtilsG
end
local unitGroupUtils = {}
-- imports
2018-01-14 07:48:21 +02:00
local mapUtils = require("MapUtils")
2016-08-07 05:38:47 +02:00
local constants = require("Constants")
local chunkPropertyUtils = require("ChunkPropertyUtils")
2020-02-02 21:30:50 +02:00
local chunkUtils = require("ChunkUtils")
2019-04-08 07:22:02 +02:00
local movementUtils = require("MovementUtils")
-- constants
2020-05-23 23:29:56 +02:00
local TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT
2019-04-08 07:22:02 +02:00
2020-05-20 04:37:16 +02:00
local DIVISOR_DEATH_TRAIL_TABLE = constants.DIVISOR_DEATH_TRAIL_TABLE
2017-06-01 04:48:59 +02:00
local SQUAD_QUEUE_SIZE = constants.SQUAD_QUEUE_SIZE
2017-05-27 02:58:33 +02:00
local DEFINES_GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
local DEFINES_GROUP_STATE_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
local SQUAD_RETREATING = constants.SQUAD_RETREATING
local SQUAD_GUARDING = constants.SQUAD_GUARDING
2018-01-14 07:48:21 +02:00
2017-01-20 07:58:36 +02:00
local NO_RETREAT_SQUAD_SIZE_BONUS_MAX = constants.NO_RETREAT_SQUAD_SIZE_BONUS_MAX
2017-04-16 08:04:22 +02:00
local AI_MAX_BITER_GROUP_SIZE = constants.AI_MAX_BITER_GROUP_SIZE
2017-06-01 09:03:07 +02:00
local AI_SQUAD_MERGE_THRESHOLD = constants.AI_SQUAD_MERGE_THRESHOLD
2017-04-16 08:04:22 +02:00
-- imported functions
2019-03-07 08:12:39 +02:00
local tRemove = table.remove
local mRandom = math.random
2019-04-08 07:22:02 +02:00
local findMovementPosition = movementUtils.findMovementPosition
2020-05-17 07:06:55 +02:00
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
2020-05-20 04:37:16 +02:00
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator
local getDeathGenerator = chunkPropertyUtils.getDeathGenerator
local next = next
local table_size = table_size
2019-04-08 07:22:02 +02:00
2017-01-20 07:58:36 +02:00
local mLog = math.log10
2017-06-01 04:48:59 +02:00
local mMin = math.min
local getSquadsOnChunk = chunkPropertyUtils.getSquadsOnChunk
2018-01-14 07:48:21 +02:00
local getNeighborChunks = mapUtils.getNeighborChunks
-- module code
2017-01-20 07:58:36 +02:00
2019-03-10 01:16:35 +02:00
function unitGroupUtils.findNearbyRetreatingSquad(map, chunk)
2019-03-09 02:42:20 +02:00
local squads = getSquadsOnChunk(map, chunk)
for i=1,#squads do
local squad = squads[i]
local unitGroup = squad.group
if unitGroup and unitGroup.valid and (squad.status == SQUAD_RETREATING) then
2019-03-09 02:42:20 +02:00
return squad
end
2018-01-14 07:48:21 +02:00
end
local neighbors = getNeighborChunks(map, chunk.x, chunk.y)
for i=1,#neighbors do
2019-03-09 02:42:20 +02:00
local neighbor = neighbors[i]
2020-05-15 22:51:38 +02:00
if neighbor ~= -1 then
2019-03-09 02:42:20 +02:00
squads = getSquadsOnChunk(map, neighbor)
for squadIndex=1,#squads do
local squad = squads[squadIndex]
local unitGroup = squad.group
if unitGroup and unitGroup.valid and (squad.status == SQUAD_RETREATING) then
return squad
end
end
end
end
return nil
end
2019-03-09 02:42:20 +02:00
function unitGroupUtils.findNearbySquad(map, chunk)
2019-03-09 02:42:20 +02:00
local squads = getSquadsOnChunk(map, chunk)
for i=1,#squads do
local squad = squads[i]
local unitGroup = squad.group
2019-10-20 22:45:43 +02:00
if unitGroup and unitGroup.valid then
return squad
2019-03-09 02:42:20 +02:00
end
end
2019-10-20 22:45:43 +02:00
local neighbors = getNeighborChunks(map, chunk.x, chunk.y)
2018-01-14 07:48:21 +02:00
for i=1,#neighbors do
2019-03-09 02:42:20 +02:00
local neighbor = neighbors[i]
2020-05-15 22:51:38 +02:00
if neighbor ~= -1 then
2019-03-09 02:42:20 +02:00
squads = getSquadsOnChunk(map, neighbor)
for squadIndex=1,#squads do
local squad = squads[squadIndex]
local unitGroup = squad.group
if unitGroup and unitGroup.valid then
return squad
end
end
end
end
2019-02-11 08:14:17 +02:00
return nil
end
2018-01-14 07:48:21 +02:00
2019-03-07 08:12:39 +02:00
function unitGroupUtils.createSquad(position, surface, group, settlers)
local unitGroup = group or surface.create_unit_group({position=position})
2019-02-11 08:14:17 +02:00
2018-01-14 07:48:21 +02:00
local squad = {
2019-03-09 02:42:20 +02:00
group = unitGroup,
status = SQUAD_GUARDING,
rabid = false,
frenzy = false,
2019-02-16 20:45:42 +02:00
settlers = settlers or false,
2019-03-09 02:42:20 +02:00
kamikaze = false,
frenzyPosition = {x = 0,
y = 0},
maxDistance = 0,
2020-05-17 07:06:55 +02:00
groupNumber = unitGroup.group_number,
2019-03-09 08:23:00 +02:00
originPosition = {x = 0,
y = 0},
2020-05-15 22:51:38 +02:00
chunk = -1
2018-01-14 07:48:21 +02:00
}
2019-03-07 08:12:39 +02:00
2019-03-09 08:23:00 +02: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-07 05:38:47 +02:00
return squad
end
2020-05-17 07:06:55 +02:00
function unitGroupUtils.cleanSquads(natives, iterator)
2020-05-22 23:40:51 +02:00
-- local profiler = game.create_profiler()
2020-05-17 07:06:55 +02:00
local squads = natives.groupNumberToSquad
local map = natives.map
local k, squad = next(squads, iterator)
local nextK
2020-05-20 04:37:16 +02:00
-- for i=1,2 do
if not k then
if (table_size(squads) == 0) then
-- this is needed as the next command remembers the max length a table has been
natives.groupNumberToSquad = {}
end
else
local group = squad.group
if not group.valid then
2020-05-23 23:29:56 +02:00
addDeathGenerator(map, squad.chunk, TEN_DEATH_PHEROMONE_GENERATOR_AMOUNT)
removeSquadFromChunk(map, squad)
2020-05-17 07:06:55 +02:00
if (map.regroupIterator == k) then
map.regroupIterator = nil
end
2020-05-22 21:43:44 +02:00
if squad.settlers then
natives.builderCount = natives.builderCount - 1
2020-05-23 23:29:56 +02:00
else
natives.squadCount = natives.squadCount - 1
2020-05-22 21:43:44 +02:00
end
2020-05-17 07:06:55 +02:00
nextK,squad = next(squads, k)
squads[k] = nil
k = nextK
2020-05-20 04:37:16 +02:00
-- else
-- game.print({"", "3b", profiler})
-- profiler.restart()
-- local members = group.members
-- local memberCount = #members
-- if (memberCount == 0) then
-- game.print({"", "4a", profiler})
-- profiler.restart()
-- local deathGen = getDeathGenerator(map, squad.chunk)
-- local penalties = squad.penalties
-- for xc=1,mMin(#squad.penalties,5) do
-- addDeathGenerator(map,
-- penalties[xc].c,
-- deathGen * DIVISOR_DEATH_TRAIL_TABLE[xc])
-- end
-- removeSquadFromChunk(map, squad)
-- group.destroy()
-- game.print({"", "4ea", profiler})
-- profiler.restart()
-- elseif (memberCount > AI_MAX_BITER_GROUP_SIZE) then
-- game.print({"", "4b", profiler})
-- profiler.restart()
-- unitGroupUtils.recycleBiters(natives, members)
-- removeSquadFromChunk(map, squad)
-- group.destroy()
-- game.print({"", "4eb", profiler})
-- profiler.restart()
-- end
-- game.print({"", "3be", profiler})
2020-05-17 07:06:55 +02:00
end
end
2020-05-20 04:37:16 +02:00
-- end
map.squadIterator = k
2020-05-17 07:06:55 +02:00
end
2019-10-20 22:45:43 +02:00
function unitGroupUtils.membersToSquad(cmd, size, members, overwriteGroup)
for i=1,size do
local member = members[i]
if member.valid and (overwriteGroup or (not overwriteGroup and not member.unit_group)) then
member.set_command(cmd)
2016-08-07 05:38:47 +02:00
end
end
end
function unitGroupUtils.calculateKamikazeThreshold(memberCount, natives)
local squadSizeBonus = mLog((memberCount / natives.attackWaveMaxSize) + 0.1) + 1
2017-06-01 03:46:53 +02:00
return natives.kamikazeThreshold + (NO_RETREAT_SQUAD_SIZE_BONUS_MAX * squadSizeBonus)
2017-01-20 07:58:36 +02:00
end
2017-06-11 02:59:06 +02:00
function unitGroupUtils.recycleBiters(natives, biters)
local unitCount = #biters
for i=1,unitCount do
2019-03-09 02:42:20 +02:00
biters[i].destroy()
2017-06-11 02:59:06 +02:00
end
natives.points = natives.points + (unitCount * natives.unitRefundAmount)
2018-01-14 07:48:21 +02:00
end
function unitGroupUtils.regroupSquads(natives, surface, iterator)
2019-11-30 02:49:22 +02:00
local map = natives.map
2020-05-17 07:06:55 +02:00
local squads = natives.groupNumberToSquad
2020-05-21 03:03:32 +02:00
local cmd = map.formLocalCommand
2017-06-01 04:48:59 +02:00
local k, squad = next(squads, iterator)
2020-05-22 23:40:51 +02:00
if k then
local group = squad.group
if group and group.valid then
cmd.command.group = group
local groupState = group.state
if (groupState ~= DEFINES_GROUP_STATE_ATTACKING_TARGET) and
(groupState ~= DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
then
local status = squad.status
local chunk = squad.chunk
if (chunk ~= -1) then
local merging = false
for _,mergeSquad in pairs(getSquadsOnChunk(map, chunk)) do
if (mergeSquad ~= squad) then
local mergeGroup = mergeSquad.group
if mergeGroup and mergeGroup.valid and (mergeSquad.status == status) then
local mergeGroupState = mergeGroup.state
if (mergeGroupState ~= DEFINES_GROUP_STATE_ATTACKING_TARGET) and
(mergeGroupState ~= DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
then
merging = true
mergeGroup.destroy()
2019-03-09 02:42:20 +02:00
end
end
2019-10-20 22:45:43 +02:00
end
2020-05-22 23:40:51 +02:00
end
if merging then
surface.set_multi_command(cmd)
2019-10-20 22:45:43 +02:00
end
2019-02-11 08:14:17 +02:00
end
2019-03-07 08:12:39 +02:00
end
end
2020-05-22 23:40:51 +02:00
k,squad = next(squads, k)
2017-06-01 04:48:59 +02:00
end
2019-02-11 08:14:17 +02:00
map.regroupIterator = k
end
2019-02-16 06:17:30 +02:00
unitGroupUtilsG = unitGroupUtils
return unitGroupUtils