mirror of
https://github.com/veden/Rampant.git
synced 2025-02-09 13:36:53 +02:00
death pheromone working
This commit is contained in:
parent
40a471cbf8
commit
ab7aaedac5
39
control.lua
39
control.lua
@ -1,5 +1,6 @@
|
|||||||
local chunkUtils = require("libs/ChunkUtils")
|
local chunkUtils = require("libs/ChunkUtils")
|
||||||
local mapUtils = require("libs/MapUtils")
|
local mapUtils = require("libs/MapUtils")
|
||||||
|
local unitGroupUtils = require("libs/UnitGroupUtils")
|
||||||
local chunkProcessor = require("libs/ChunkProcessor")
|
local chunkProcessor = require("libs/ChunkProcessor")
|
||||||
local mapProcessor = require("libs/MapProcessor")
|
local mapProcessor = require("libs/MapProcessor")
|
||||||
local constants = require("libs/Constants")
|
local constants = require("libs/Constants")
|
||||||
@ -65,26 +66,34 @@ end
|
|||||||
function onTick(event)
|
function onTick(event)
|
||||||
if (event.tick % 40 == 0) then
|
if (event.tick % 40 == 0) then
|
||||||
-- using coroutines to keep the cpu load time managable will still being able to work large maps
|
-- using coroutines to keep the cpu load time managable will still being able to work large maps
|
||||||
|
local working, errorMsg = true, nil
|
||||||
if (chunkRoutine ~= nil) and (coroutine.status(chunkRoutine) ~= "dead") then
|
if (chunkRoutine ~= nil) and (coroutine.status(chunkRoutine) ~= "dead") then
|
||||||
coroutine.resume(chunkRoutine)
|
working, errorMsg = coroutine.resume(chunkRoutine)
|
||||||
elseif (#pendingChunks > 0) then
|
elseif (#pendingChunks > 0) then
|
||||||
-- coroutines start suspended, so you have to resume them after creation
|
-- coroutines start suspended, so you have to resume them after creation
|
||||||
chunkRoutine = coroutine.create(chunkProcessor.processPendingChunks)
|
chunkRoutine = coroutine.create(chunkProcessor.processPendingChunks)
|
||||||
coroutine.resume(chunkRoutine, regionMap, surface, natives, pendingChunks)
|
working, errorMsg = coroutine.resume(chunkRoutine, regionMap, surface, natives, pendingChunks)
|
||||||
|
end
|
||||||
|
if not working then
|
||||||
|
error(errorMsg)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- put down player pheromone for player hunters
|
-- put down player pheromone for player hunters
|
||||||
-- pheromoneUtils.playerScent(regionMap, game.players)
|
pheromoneUtils.playerScent(regionMap, game.players)
|
||||||
|
|
||||||
-- ai.attackPlayerNearNest(regionMap, surface, natives, game.players)
|
-- ai.attackPlayerNearNest(regionMap, surface, natives, game.players)
|
||||||
|
|
||||||
if (mapRoutine ~= nil) and (coroutine.status(mapRoutine) ~= "dead") then
|
if (mapRoutine ~= nil) and (coroutine.status(mapRoutine) ~= "dead") then
|
||||||
coroutine.resume(mapRoutine)
|
working, errorMsg = coroutine.resume(mapRoutine)
|
||||||
elseif (mapRoutine == nil) or (coroutine.status(mapRoutine) == "dead") then
|
elseif (mapRoutine == nil) or (coroutine.status(mapRoutine) == "dead") then
|
||||||
mapRoutine = coroutine.create(mapProcessor.processMap)
|
mapRoutine = coroutine.create(mapProcessor.processMap)
|
||||||
coroutine.resume(mapRoutine, regionMap, surface, natives)
|
working, errorMsg = coroutine.resume(mapRoutine, regionMap, surface, natives)
|
||||||
|
end
|
||||||
|
if not working then
|
||||||
|
error(errorMsg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unitGroupUtils.regroupSquads(natives)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -96,12 +105,11 @@ function onDeath(event)
|
|||||||
pheromoneUtils.deathScent(regionMap,
|
pheromoneUtils.deathScent(regionMap,
|
||||||
entityPosition.x,
|
entityPosition.x,
|
||||||
entityPosition.y,
|
entityPosition.y,
|
||||||
50)
|
200)
|
||||||
|
|
||||||
ai.addAutonomousUnitGroup(entity.unit_group, natives)
|
local squad = unitGroupUtils.convertUnitGroupToSquad(natives, entity.unit_group)
|
||||||
|
|
||||||
--ai.purgeUnitGroups(natives)
|
ai.retreatUnits(entityPosition, squad, regionMap, surface, natives)
|
||||||
ai.retreatUnitGroup(entityPosition, entity.unit_group, regionMap, surface, natives)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -111,12 +119,19 @@ function onInitialTick(event)
|
|||||||
if (surface == nil) then
|
if (surface == nil) then
|
||||||
surface = game.surfaces[1]
|
surface = game.surfaces[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
game.forces.player.research_all_technologies()
|
||||||
|
game.players[1].cheat_mode = true
|
||||||
|
|
||||||
|
-- turn off base expansion
|
||||||
|
game.forces.enemy.ai_controllable = false
|
||||||
|
|
||||||
-- add processing handler into generated chunk event loop
|
-- add processing handler into generated chunk event loop
|
||||||
-- chunkProcessor.install(chunkUtils.checkChunkPassability)
|
chunkProcessor.install(chunkUtils.checkChunkPassability)
|
||||||
-- chunkProcessor.install(chunkUtils.scoreChunk)
|
chunkProcessor.install(chunkUtils.scoreChunk)
|
||||||
|
|
||||||
-- add processing handler into chunk map processing
|
-- add processing handler into chunk map processing
|
||||||
-- mapProcessor.install(pheromoneUtils.enemyBaseScent)
|
mapProcessor.install(pheromoneUtils.enemyBaseScent)
|
||||||
-- mapProcessor.install(ai.sendScouts)
|
-- mapProcessor.install(ai.sendScouts)
|
||||||
mapProcessor.install(pheromoneUtils.processPheromone)
|
mapProcessor.install(pheromoneUtils.processPheromone)
|
||||||
|
|
||||||
|
182
libs/AI.lua
182
libs/AI.lua
@ -1,137 +1,131 @@
|
|||||||
local ai = {}
|
local ai = {}
|
||||||
|
|
||||||
local retreatNeighbors = {1,2,3,4,5,6,7,8}
|
local retreatNeighbors = {1,2,3,4,5,6,7,8} -- used to minimize garbage generation
|
||||||
|
local retreatPosition = {x=0, y=0} -- used to minimize garbage generation
|
||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
local unitGroupUtils = require("UnitGroupUtils")
|
local unitGroupUtils = require("UnitGroupUtils")
|
||||||
|
|
||||||
--[[
|
|
||||||
function ai.attackPlayerNearNest(regionMap, surface, natives, players)
|
function ai.attackPlayerNearNest(regionMap, surface, natives, players)
|
||||||
|
local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE
|
||||||
|
|
||||||
for i=1,#players do
|
for i=1,#players do
|
||||||
local player = players[i]
|
local player = players[i]
|
||||||
local chunk = mapUtils.getChunkByPosition(regionMap, player.position.x, player.position.y)
|
local chunk = mapUtils.getChunkByPosition(regionMap, player.position.x, player.position.y)
|
||||||
if (chunk ~= nil) and (chunk[constants.BASE_PHEROMONE] > 125) and (chunk[constants.DEATH_PHEROMONE] < 800) then
|
if (chunk ~= nil) and (chunk[ENEMY_BASE_PHEROMONE] > 125) then -- TODO scaled base
|
||||||
local enemies = surface.find_enemy_units(player.position,
|
local enemies = surface.find_enemy_units(player.position,
|
||||||
30)
|
30)
|
||||||
if (#enemies > 0) then
|
if (#enemies > 0) then
|
||||||
local unitGroup
|
local unitGroup
|
||||||
local enemyIndex = 1
|
local enemyIndex = 1
|
||||||
while (enemyIndex <= #enemies) and (unitGroup == nil) do
|
-- while (enemyIndex <= #enemies) and (unitGroup == nil) do
|
||||||
local enemy = enemies[enemyIndex]
|
-- local enemy = enemies[enemyIndex]
|
||||||
if (enemy.unit_group ~= nil) then
|
-- if (enemy.unit_group ~= nil) thena
|
||||||
unitGroup = enemy.unit_group
|
-- unitGroup = enemy.unit_group
|
||||||
end
|
-- end
|
||||||
enemyIndex = enemyIndex + 1
|
-- enemyIndex = enemyIndex + 1
|
||||||
end
|
-- end
|
||||||
if (unitGroup == nil) then
|
if (unitGroup == nil) then
|
||||||
unitGroup = surface.create_unit_group({position=enemies[1].position})
|
unitGroup = surface.create_unit_group({position=enemies[1].position})
|
||||||
-- natives.squads[#natives.squads+1] = unitGroup
|
natives.squads[#natives.squads+1] = unitGroup
|
||||||
end
|
end
|
||||||
-- print("before " .. tostring(unitGroup.state))
|
|
||||||
for x=1,#enemies do
|
for x=1,#enemies do
|
||||||
local enemy = enemies[x]
|
local enemy = enemies[x]
|
||||||
if (enemy.unit_group == nil) then
|
if (enemy.unit_group == nil) then
|
||||||
-- unitGroup.add_member(enemy)
|
unitGroup.add_member(enemy)
|
||||||
enemy.set_command({type=defines.command.group,
|
-- enemy.set_command({type=defines.command.group,
|
||||||
group=unitGroup,
|
-- group=unitGroup,
|
||||||
distraction=defines.distraction.none})
|
-- distraction=defines.distraction.none})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- print("after " .. tostring(unitGroup.state))
|
|
||||||
if (unitGroup.state == defines.group_state.gathering) then
|
if (unitGroup.state == defines.group_state.gathering) then
|
||||||
unitGroup.set_command({type=defines.command.attack,
|
unitGroup.set_command({type=defines.command.attack,
|
||||||
target=player.character})
|
target=player.character})
|
||||||
unitGroup.start_moving()
|
|
||||||
end
|
end
|
||||||
|
unitGroup.start_moving()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
]]--
|
|
||||||
|
|
||||||
function ai.retreatUnitGroup(position, unitGroup, regionMap, surface, natives)
|
function ai.retreatUnits(position, squad, regionMap, surface, natives)
|
||||||
if (unitGroup ~= nil) then
|
local DEATH_PHEROMONE = constants.DEATH_PHEROMONE
|
||||||
local memberCount = #unitGroup.members
|
|
||||||
if (memberCount > 0) then
|
local chunk = mapUtils.getChunkByPosition(regionMap, position.x, position.y)
|
||||||
local chunk = mapUtils.getChunkByPosition(regionMap, position.x, position.y)
|
if (chunk ~= nil) and (chunk[DEATH_PHEROMONE] > 1500) then -- TODO sliding scale of death based on evolution
|
||||||
if (chunk ~= nil) then
|
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
||||||
if (chunk[constants.DEATH_PHEROMONE] > 1500) and (memberCount > 5) then
|
local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE
|
||||||
mapUtils.getNeighborChunks(regionMap,
|
|
||||||
chunk.cX,
|
local performRetreat = false
|
||||||
chunk.cY,
|
local enemiesToSquad
|
||||||
retreatNeighbors)
|
|
||||||
local exitPath
|
if (squad == nil) then
|
||||||
local exitScore = constants.MAX_PHEROMONE + 1
|
enemiesToSquad = surface.find_enemy_units(position, 20)
|
||||||
local exitDirection
|
if (#enemiesToSquad > 0) then
|
||||||
for i=1, 8 do
|
performRetreat = true
|
||||||
local neighborChunk = retreatNeighbors[i]
|
end
|
||||||
if (neighborChunk ~= nil) then
|
elseif (squad ~= nil) and squad.group.valid and (squad.status ~= constants.SQUAD_RETREATING) and (squad.status ~= constants.SQUAD_SUICIDE) then
|
||||||
if (neighborChunk[constants.DEATH_PHEROMONE] < exitScore) then
|
if (#squad.group.members == 0) then
|
||||||
exitScore = neighborChunk[constants.DEATH_PHEROMONE]
|
squad.group.destroy()
|
||||||
exitPath = neighborChunk
|
else
|
||||||
exitDirection = i
|
performRetreat = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if (exitPath ~= nil) then
|
if performRetreat then
|
||||||
local exitPosition = {x=exitPath.pX,
|
mapUtils.getNeighborChunks(regionMap,
|
||||||
y=exitPath.pY}
|
chunk.cX,
|
||||||
local nearGroup = unitGroupUtils.findNearByUnitGroup(natives, exitPosition, 50)
|
chunk.cY,
|
||||||
|
retreatNeighbors)
|
||||||
if (nearGroup == nil) then
|
local exitPath
|
||||||
nearGroup = surface.create_unit_group({position=exitPosition})
|
local exitScore = constants.MAGIC_MAXIMUM_NUMBER
|
||||||
natives.squads[#natives.squads+1] = nearGroup
|
local exitDirection
|
||||||
end
|
for i=1, 8 do
|
||||||
for i=1, memberCount do
|
local neighborChunk = retreatNeighbors[i]
|
||||||
local member = unitGroup.members[i]
|
if (neighborChunk ~= nil) then
|
||||||
if (member ~= nil) and member.valid then
|
retreatPosition.x = neighborChunk.pX
|
||||||
member.set_command({type=defines.command.group,
|
retreatPosition.y = neighborChunk.pY
|
||||||
group=nearGroup,
|
|
||||||
distraction=defines.distraction.none})
|
local dangerScore = neighborChunk[DEATH_PHEROMONE] + surface.get_pollution(retreatPosition) + neighborChunk[PLAYER_PHEROMONE] - neighborChunk[ENEMY_BASE_PHEROMONE]
|
||||||
end
|
if (dangerScore < exitScore) then
|
||||||
end
|
exitScore = dangerScore
|
||||||
-- unitGroup.destroy()
|
exitPath = neighborChunk
|
||||||
|
exitDirection = i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif (memberCount == 0) then
|
|
||||||
unitGroup.destroy()
|
-- center position in chunk for retreat
|
||||||
end
|
retreatPosition.x = exitPath.pX + constants.HALF_CHUNK_SIZE
|
||||||
end
|
retreatPosition.y = exitPath.pY + constants.HALF_CHUNK_SIZE
|
||||||
end
|
|
||||||
|
-- in order for units in a group attacking to retreat, we have to create a new group and give the command to join
|
||||||
function ai.addAutonomousUnitGroup(unitGroup, natives)
|
-- to each unit
|
||||||
if (unitGroup ~= nil) then
|
local newSquad = unitGroupUtils.findNearBySquad(natives,
|
||||||
local squads = natives.squads
|
retreatPosition,
|
||||||
local addUnitGroup = true
|
18)
|
||||||
local i = 1
|
if (newSquad == nil) then
|
||||||
while (i <= #squads) and addUnitGroup do
|
newSquad = unitGroupUtils.createSquad(retreatPosition, surface, natives)
|
||||||
local squad = squads[i]
|
|
||||||
if (squad == unitGroup) then
|
|
||||||
addUnitGroup = false
|
|
||||||
end
|
end
|
||||||
i = i + 1
|
if (enemiesToSquad ~= nil) then
|
||||||
end
|
unitGroupUtils.membersToSquad(newSquad, enemiesToSquad, false)
|
||||||
if addUnitGroup then
|
else
|
||||||
squads[#squads+1] = unitGroup
|
unitGroupUtils.membersToSquad(newSquad, squad.group.members, true)
|
||||||
|
end
|
||||||
|
newSquad.status = constants.SQUAD_RETREATING
|
||||||
|
newSquad.cycles = 5
|
||||||
|
-- unitGroupUtils.setSquadCommand(newSquad,
|
||||||
|
-- {type=defines.command.go_to_location,
|
||||||
|
-- destination=retreatPosition,
|
||||||
|
-- distraction=defines.distraction.by_enemy},
|
||||||
|
-- constants.SQUAD_RETREATING)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- function ai.purgeUnitGroups(natives)
|
|
||||||
-- for i=1, #natives.squads do
|
|
||||||
-- local squad = natives.squads[i]
|
|
||||||
-- if (squad == nil) then
|
|
||||||
-- table.remove(natives.squads, i)
|
|
||||||
-- elseif (not squad.valid) then
|
|
||||||
-- table.remove(natives.squads, i)
|
|
||||||
-- elseif (#squad.members == 0) then
|
|
||||||
-- squad.destroy()
|
|
||||||
-- table.remove(natives.squads, i)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- function ai.sendScouts(regionMap, surface, natives, chunk, neighbors, validNeighbors)
|
-- function ai.sendScouts(regionMap, surface, natives, chunk, neighbors, validNeighbors)
|
||||||
|
|
||||||
-- return validNeighbors
|
-- return validNeighbors
|
||||||
|
@ -1,13 +1,27 @@
|
|||||||
local constants = {}
|
local constants = {}
|
||||||
|
|
||||||
|
constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest score
|
||||||
|
|
||||||
constants.MAX_PHEROMONE = 7000
|
constants.MAX_PHEROMONE = 7000
|
||||||
constants.DIFFUSION_AMOUNT = 0.04
|
constants.BASE_PHEROMONE_PRODUCTION = 35
|
||||||
|
constants.DIFFUSION_AMOUNT = 0.02
|
||||||
|
constants.DEATH_DIFFUSION_AMOUNT = 0.005
|
||||||
constants.CHUNK_SIZE = 32
|
constants.CHUNK_SIZE = 32
|
||||||
|
constants.HALF_CHUNK_SIZE = constants.CHUNK_SIZE / 2
|
||||||
constants.NORTH_SOUTH = true
|
constants.NORTH_SOUTH = true
|
||||||
constants.EAST_WEST = false
|
constants.EAST_WEST = false
|
||||||
|
|
||||||
constants.DEATH_PHEROMONE = 1
|
constants.DEATH_PHEROMONE = 1
|
||||||
constants.BASE_PHEROMONE = 2
|
constants.ENEMY_BASE_PHEROMONE = 2
|
||||||
constants.PLAYER_PHEROMONE = 3
|
constants.PLAYER_PHEROMONE = 3
|
||||||
|
|
||||||
|
constants.SQUAD_RETREATING = 1
|
||||||
|
constants.SQUAD_GUARDING = 2
|
||||||
|
constants.SQUAD_SIEGE = 3
|
||||||
|
constants.SQUAD_HUNTING = 4
|
||||||
|
constants.SQUAD_SUICIDE = 5
|
||||||
|
constants.SQUAD_ATTACKING = 6
|
||||||
|
constants.SQUAD_BURROWING = 7
|
||||||
|
constants.SQUAD_SCOUTING = 8
|
||||||
|
|
||||||
return constants
|
return constants
|
@ -6,28 +6,25 @@ local mMin = math.min
|
|||||||
local mFloor = math.floor
|
local mFloor = math.floor
|
||||||
|
|
||||||
function pheromoneUtils.deathScent(regionMap, x, y, amount)
|
function pheromoneUtils.deathScent(regionMap, x, y, amount)
|
||||||
pheromoneUtils.placePheromoneByPosition(regionMap,
|
local mathFloor = mFloor
|
||||||
x,
|
local DEATH_PHEROMONE = constants.DEATH_PHEROMONE
|
||||||
y,
|
|
||||||
constants.DEATH_PHEROMONE,
|
local chunk = regionMap[mathFloor(x * 0.03125)]
|
||||||
200)
|
if (chunk ~= nil) then
|
||||||
|
chunk = chunk[mathFloor(y * 0.03125)]
|
||||||
|
if (chunk ~= nil) then
|
||||||
|
chunk[DEATH_PHEROMONE] = chunk[DEATH_PHEROMONE] + amount
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function pheromoneUtils.enemyBaseScent(regionMap, surface, natives, chunk, neighbors, validNeighbors)
|
function pheromoneUtils.enemyBaseScent(regionMap, surface, natives, chunk, neighbors, validNeighbors)
|
||||||
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
local BASE_PHEROMONE_PRODUCTION = constants.BASE_PHEROMONE_PRODUCTION
|
||||||
local x = chunk.cX
|
local ENEMY_BASE_PHEROMONE = constants.ENEMY_BASE_PHEROMONE
|
||||||
local y = chunk.cY
|
|
||||||
|
local spawners = chunk.bG
|
||||||
local nativeBase = natives.bases[x]
|
if (spawners > 0) then
|
||||||
if (nativeBase ~= nil) then
|
chunk[ENEMY_BASE_PHEROMONE] = chunk[ENEMY_BASE_PHEROMONE] + (spawners * constants.BASE_PHEROMONE_PRODUCTION)
|
||||||
nativeBase = nativeBase[y]
|
|
||||||
if (nativeBase ~= nil) then
|
|
||||||
local spawners = nativeBase.bG
|
|
||||||
if (spawners > 0) then
|
|
||||||
local nativeChunk = regionMap[x][y]
|
|
||||||
nativeChunk[BASE_PHEROMONE] = nativeChunk[BASE_PHEROMONE] + (spawners * 35)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return validNeighbors
|
return validNeighbors
|
||||||
end
|
end
|
||||||
@ -44,26 +41,25 @@ function pheromoneUtils.playerScent(regionMap, players)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function pheromoneUtils.placePheromoneByPosition(regionMap, x, y, pType, amount)
|
|
||||||
local chunk = mapUtils.getChunkByPosition(regionMap, x, y)
|
|
||||||
if (chunk~=nil) then
|
|
||||||
chunk[pType] = mMin(constants.MAX_PHEROMONE, chunk[pType] + amount)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function pheromoneUtils.placePheromoneByChunk(regionMap, x, y, pType, amount)
|
|
||||||
local chunk = regionMap[x][y]
|
|
||||||
chunk[pType] = mMin(constants.MAX_PHEROMONE, chunk[pType] + amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
function pheromoneUtils.processPheromone(regionMap, surface, natives, chunk, neighbors, validNeighbors)
|
function pheromoneUtils.processPheromone(regionMap, surface, natives, chunk, neighbors, validNeighbors)
|
||||||
local mathMin = mMin
|
local mathMin = mMin
|
||||||
local getNeighborChunks = mapUtils.getNeighborChunks
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
||||||
local DIFFUSION_AMOUNT = constants.DIFFUSION_AMOUNT
|
local DIFFUSION_AMOUNT = constants.DIFFUSION_AMOUNT
|
||||||
|
local DEATH_DIFFUSION_AMOUNT = constants.DEATH_DIFFUSION_AMOUNT
|
||||||
local MAX_PHEROMONE = constants.MAX_PHEROMONE
|
local MAX_PHEROMONE = constants.MAX_PHEROMONE
|
||||||
|
local DEATH_PHEROMONE = constants.DEATH_PHEROMONE
|
||||||
|
|
||||||
for x=1,3 do
|
for x=1,3 do
|
||||||
if ((x ~= DEATH_PHEROMONE) and (chunk[x] > 75)) or ((x == DEATH_PHEROMONE) and (chunk[x] > 125)) then
|
local threshold
|
||||||
|
local diffusionAmount
|
||||||
|
if (x == DEATH_PHEROMONE) then
|
||||||
|
threshold = 125
|
||||||
|
diffusionAmount = DEATH_DIFFUSION_AMOUNT
|
||||||
|
else
|
||||||
|
threshold = 75
|
||||||
|
diffusionAmount = DIFFUSION_AMOUNT
|
||||||
|
end
|
||||||
|
if (chunk[x] > threshold) then
|
||||||
if not validNeighbors then
|
if not validNeighbors then
|
||||||
getNeighborChunks(regionMap, chunk.cX, chunk.cY, neighbors)
|
getNeighborChunks(regionMap, chunk.cX, chunk.cY, neighbors)
|
||||||
validNeighbors = true
|
validNeighbors = true
|
||||||
@ -72,7 +68,7 @@ function pheromoneUtils.processPheromone(regionMap, surface, natives, chunk, nei
|
|||||||
for i=1,8 do
|
for i=1,8 do
|
||||||
local neighborChunk = neighbors[i]
|
local neighborChunk = neighbors[i]
|
||||||
if (neighborChunk ~= nil) then
|
if (neighborChunk ~= nil) then
|
||||||
local diffusedAmount = (chunk[x] * DIFFUSION_AMOUNT)
|
local diffusedAmount = (chunk[x] * diffusionAmount)
|
||||||
totalDiffused = totalDiffused + diffusedAmount
|
totalDiffused = totalDiffused + diffusedAmount
|
||||||
neighborChunk[x] = mathMin(MAX_PHEROMONE, neighborChunk[x] + diffusedAmount)
|
neighborChunk[x] = mathMin(MAX_PHEROMONE, neighborChunk[x] + diffusedAmount)
|
||||||
end
|
end
|
||||||
|
@ -1,14 +1,17 @@
|
|||||||
local unitGroupUtils = {}
|
local unitGroupUtils = {}
|
||||||
|
|
||||||
local utils = require("Utils")
|
local utils = require("Utils")
|
||||||
|
local constants = require("Constants")
|
||||||
|
|
||||||
function unitGroupUtils.findNearByUnitGroup(natives, position, distance)
|
function unitGroupUtils.findNearBySquad(natives, position, distance)
|
||||||
|
local getDistance = utils.euclideanDistanceNamed
|
||||||
local squads = natives.squads
|
local squads = natives.squads
|
||||||
local i = 1
|
local i = 1
|
||||||
while (i <= #squads) do
|
while (i <= #squads) do
|
||||||
local squad = squads[i]
|
local squad = squads[i]
|
||||||
if (squad ~= nil) and squad.valid then
|
local unitGroup = squad.group
|
||||||
if (utils.euclideanDistanceNamed(squad.position, position) <= distance) then
|
if (unitGroup ~= nil) and unitGroup.valid then
|
||||||
|
if (getDistance(unitGroup.position, position) <= distance) then
|
||||||
return squad
|
return squad
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -16,8 +19,84 @@ function unitGroupUtils.findNearByUnitGroup(natives, position, distance)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function unitGroupUtils.mergeNearByUnitGroup(natives, unitGroup)
|
function unitGroupUtils.createSquad(position, surface, natives)
|
||||||
|
local unitGroup = surface.create_unit_group({position=position})
|
||||||
|
|
||||||
|
local squad = { group = unitGroup,
|
||||||
|
status = constants.SQUAD_GUARDING,
|
||||||
|
cycles = -1 }
|
||||||
|
natives.squads[#natives.squads+1] = squad
|
||||||
|
return squad
|
||||||
|
end
|
||||||
|
|
||||||
|
function unitGroupUtils.membersToSquad(squad, members, overwriteGroup)
|
||||||
|
if members ~= nil then
|
||||||
|
local group = squad.group
|
||||||
|
for i=1,#members do
|
||||||
|
local member = members[i]
|
||||||
|
if (member ~= nil) and member.valid and (overwriteGroup or (not overwriteGroup and (member.unit_group == nil))) then
|
||||||
|
member.set_command({type=defines.command.group,
|
||||||
|
group=group,
|
||||||
|
distraction=defines.distraction.none})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function unitGroupUtils.convertUnitGroupToSquad(natives, unitGroup)
|
||||||
|
local returnSquad
|
||||||
|
if (unitGroup ~= nil) then
|
||||||
|
local squads = natives.squads
|
||||||
|
local addUnitGroup = true
|
||||||
|
local i = 1
|
||||||
|
while (i <= #squads) and addUnitGroup do
|
||||||
|
local squad = squads[i]
|
||||||
|
if (squad.group == unitGroup) then
|
||||||
|
addUnitGroup = false
|
||||||
|
returnSquad = squad
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
if addUnitGroup then
|
||||||
|
returnSquad = { group = unitGroup,
|
||||||
|
status = constants.SQUAD_GUARDING,
|
||||||
|
cycles = -1 }
|
||||||
|
squads[#squads+1] = returnSquad
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return returnSquad
|
||||||
|
end
|
||||||
|
|
||||||
|
function unitGroupUtils.setSquadCommand(squad, command, state, cycles)
|
||||||
|
local group = squad.group
|
||||||
|
if (group ~= nil) and group.valid then
|
||||||
|
squad.status = state
|
||||||
|
squad.cycles = cycles
|
||||||
|
group.set_command(command)
|
||||||
|
-- group.start_moving()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function unitGroupUtils.regroupSquads(natives)
|
||||||
|
local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
||||||
|
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
||||||
|
|
||||||
|
for i=#natives.squads,1,-1 do
|
||||||
|
local squad = natives.squads[i]
|
||||||
|
if (squad.group == nil) then
|
||||||
|
table.remove(natives.squads, i)
|
||||||
|
elseif not squad.group.valid then
|
||||||
|
table.remove(natives.squads, i)
|
||||||
|
elseif (#squad.group.members == 0) then
|
||||||
|
squad.group.destroy()
|
||||||
|
table.remove(natives.squads, i)
|
||||||
|
elseif (squad.status == SQUAD_RETREATING) and (squad.cycles == 0) then
|
||||||
|
squad.status = SQUAD_GUARDING
|
||||||
|
elseif (squad.cycles > 0) then
|
||||||
|
squad.cycles = squad.cycles - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return unitGroupUtils
|
return unitGroupUtils
|
@ -69,6 +69,8 @@ function chunkUtils.checkChunkPassability(chunk, surface, natives)
|
|||||||
chunk.nS = passableNorthSouth
|
chunk.nS = passableNorthSouth
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local spawnCount = 0
|
||||||
|
|
||||||
function chunkUtils.scoreChunk(chunk, surface, natives)
|
function chunkUtils.scoreChunk(chunk, surface, natives)
|
||||||
local x = chunk.pX
|
local x = chunk.pX
|
||||||
local y = chunk.pY
|
local y = chunk.pY
|
||||||
@ -80,14 +82,7 @@ function chunkUtils.scoreChunk(chunk, surface, natives)
|
|||||||
{x+CHUNK_SIZE, y+CHUNK_SIZE}},
|
{x+CHUNK_SIZE, y+CHUNK_SIZE}},
|
||||||
type="unit-spawner",
|
type="unit-spawner",
|
||||||
force="enemy"})
|
force="enemy"})
|
||||||
if (natives.bases[cX] == nil) then
|
chunk.bG = spawners
|
||||||
natives.bases[cX] = {}
|
|
||||||
end
|
|
||||||
local nativeX = natives.bases[cX]
|
|
||||||
if (nativeX[cY] == nil) then
|
|
||||||
nativeX[cY] = {}
|
|
||||||
end
|
|
||||||
nativeX[cY].bG = spawners
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkUtils.createChunk(topX, topY)
|
function chunkUtils.createChunk(topX, topY)
|
||||||
@ -97,7 +92,7 @@ function chunkUtils.createChunk(topX, topY)
|
|||||||
cX = topX * 0.03125,
|
cX = topX * 0.03125,
|
||||||
cY = topY * 0.03125
|
cY = topY * 0.03125
|
||||||
}
|
}
|
||||||
chunk[constants.BASE_PHEROMONE] = 0
|
chunk[constants.ENEMY_BASE_PHEROMONE] = 0
|
||||||
chunk[constants.PLAYER_PHEROMONE] = 0
|
chunk[constants.PLAYER_PHEROMONE] = 0
|
||||||
chunk[constants.DEATH_PHEROMONE] = 0
|
chunk[constants.DEATH_PHEROMONE] = 0
|
||||||
return chunk
|
return chunk
|
||||||
|
21
tests.lua
21
tests.lua
@ -25,7 +25,26 @@ function tests.test1()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function test2()
|
function tests.test2()
|
||||||
|
local position = game.players[1].position
|
||||||
|
|
||||||
|
local spawners = game.surfaces[1].find_entities_filtered({type="unit-spawner"})
|
||||||
|
for i=1, #spawners do
|
||||||
|
local spawner = spawners[i]
|
||||||
|
if (spawner ~= nil) and spawner.valid then
|
||||||
|
spawner.destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
game.forces.enemy.kill_all_units()
|
||||||
|
|
||||||
|
position.x = position.x + 10
|
||||||
|
position.y = position.y - 40
|
||||||
|
|
||||||
|
for i=position.x, position.x+30, 5 do
|
||||||
|
game.surfaces[1].create_entity({name="biter-spawner",
|
||||||
|
position={i, position.y}})
|
||||||
|
end
|
||||||
-- local playerPosition = game.players[1].position
|
-- local playerPosition = game.players[1].position
|
||||||
-- playerPosition.x = playerPosition.x + 10
|
-- playerPosition.x = playerPosition.x + 10
|
||||||
-- local turret = game.surfaces[1].create_entity({name="small-worm-turret", position=playerPosition})
|
-- local turret = game.surfaces[1].create_entity({name="small-worm-turret", position=playerPosition})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user