1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-26 20:54:12 +02:00
Rampant/libs/MapProcessor.lua

195 lines
6.1 KiB
Lua
Raw Normal View History

local mapProcessor = {}
-- imports
2016-08-21 23:48:55 +02:00
local pheromoneUtils = require("PheromoneUtils")
local aiBuilding = require("AIBuilding")
2016-08-29 02:05:28 +02:00
local constants = require("Constants")
2016-10-15 02:00:18 +02:00
local mapUtils = require("MapUtils")
2016-09-14 13:16:33 +02:00
-- constants
local PROCESS_QUEUE_SIZE = constants.PROCESS_QUEUE_SIZE
local ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT = constants.ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT
local SCAN_QUEUE_SIZE = constants.SCAN_QUEUE_SIZE
local CHUNK_SIZE = constants.CHUNK_SIZE
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
2016-10-15 02:00:18 +02:00
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
local PROCESS_PLAYER_BOUND = constants.PROCESS_PLAYER_BOUND
local CHUNK_TICK = constants.CHUNK_TICK
-- imported functions
2016-08-21 23:48:55 +02:00
local scents = pheromoneUtils.scents
local processPheromone = pheromoneUtils.processPheromone
2016-08-26 00:20:06 +02:00
local makeScouts = aiBuilding.makeScouts
2016-08-21 23:48:55 +02:00
local formSquads = aiBuilding.formSquads
2016-10-15 02:00:18 +02:00
local getChunkByIndex = mapUtils.getChunkByIndex
local getChunkByPosition = mapUtils.getChunkByPosition
local playerScent = pheromoneUtils.playerScent
2016-08-29 02:05:28 +02:00
local mMin = math.min
-- module code
2016-10-15 02:00:18 +02:00
local function nonRepeatingRandom(players)
local ordering = {}
for _,player in pairs(players) do
ordering[#ordering+1] = player.index
end
for i=#ordering,1,-1 do
local s = math.random(i)
local t = ordering[i]
ordering[i] = ordering[s]
ordering[s] = t
end
return ordering
end
--[[
processing is not consistant as it depends on the number of chunks that have been generated
so if we process 400 chunks an iteration and 200 chunks have been generated than these are
processed 3 times a second and 1200 generated chunks would be processed once a second
In theory, this might be fine as smaller bases have less surface to attack and need to have
pheromone dissipate at a faster rate.
--]]
function mapProcessor.processMap(regionMap, surface, natives, evolution_factor)
2016-08-29 02:05:28 +02:00
local roll = regionMap.processRoll
local index = regionMap.processPointer
2016-08-26 00:20:06 +02:00
local scouts = false
local squads = false
2016-08-29 02:05:28 +02:00
if (index == 1) then
2016-08-26 00:20:06 +02:00
roll = math.random()
2016-08-29 02:05:28 +02:00
regionMap.processRoll = roll
2016-08-26 00:20:06 +02:00
end
if (0.05 <= roll) and (roll <= 0.10) then
scouts = true
end
2016-10-15 02:00:18 +02:00
if (natives.state == AI_STATE_AGGRESSIVE) and (0.11 <= roll) and (roll <= 0.35) then
squads = true
end
2016-08-29 02:05:28 +02:00
local processQueue = regionMap.processQueue
2016-09-14 13:16:33 +02:00
local endIndex = mMin(index + PROCESS_QUEUE_SIZE, #processQueue)
2016-08-29 02:05:28 +02:00
for x=index,endIndex do
local chunk = processQueue[x]
2016-08-21 23:48:55 +02:00
scents(chunk)
2016-08-21 23:48:55 +02:00
2016-08-26 00:20:06 +02:00
if scouts then
makeScouts(surface, natives, chunk, evolution_factor)
2016-08-21 23:48:55 +02:00
end
2016-08-26 00:20:06 +02:00
if squads then
2016-10-15 02:00:18 +02:00
formSquads(regionMap, surface, natives, chunk, evolution_factor)
end
2016-08-21 23:48:55 +02:00
2016-10-15 02:00:18 +02:00
processPheromone(regionMap, chunk)
2016-08-29 02:05:28 +02:00
end
if (endIndex == #processQueue) then
regionMap.processPointer = 1
else
regionMap.processPointer = endIndex + 1
end
end
2016-10-15 02:00:18 +02:00
--[[
Localized player radius were processing takes place in realtime, doesn't store state
between calls.
vs
the slower passive version processing the entire map in multiple passes.
--]]
function mapProcessor.processPlayers(players, regionMap, surface, natives, evolution_factor, tick)
-- put down player pheromone for player hunters
-- randomize player order to ensure a single player isn't singled out
local playerOrdering = nonRepeatingRandom(players)
local scouts = false
local squads = false
local roll = math.random()
if (0.05 <= roll) and (roll <= 0.7) then
scouts = true
end
if (natives.state == AI_STATE_AGGRESSIVE) and (0.11 <= roll) and (roll <= 0.20) then
squads = true
end
for i=1,#playerOrdering do
local player = players[playerOrdering[i]]
if (player ~= nil) and player.connected and (player.character ~= nil) and player.character.valid and (player.character.surface.index == 1) then
local playerPosition = player.character.position
local playerChunk = getChunkByPosition(regionMap, playerPosition.x, playerPosition.y)
if (playerChunk ~= nil) then
playerScent(playerChunk)
end
end
end
for i=1,#playerOrdering do
local player = players[playerOrdering[i]]
if (player ~= nil) and player.connected and (player.character ~= nil) and player.character.valid and (player.character.surface.index == 1) then
local playerPosition = player.character.position
local playerChunk = getChunkByPosition(regionMap, playerPosition.x, playerPosition.y)
if (playerChunk ~= nil) then
for x=playerChunk.cX - PROCESS_PLAYER_BOUND, playerChunk.cX + PROCESS_PLAYER_BOUND do
for y=playerChunk.cY - PROCESS_PLAYER_BOUND, playerChunk.cY + PROCESS_PLAYER_BOUND do
local chunk = getChunkByIndex(regionMap, x, y)
if (chunk ~= nil) and (chunk[CHUNK_TICK] ~= tick) then
chunk[CHUNK_TICK] = tick
scents(chunk)
if scouts then
makeScouts(surface, natives, chunk, evolution_factor)
end
if squads then
formSquads(regionMap, surface, natives, chunk, evolution_factor)
end
processPheromone(regionMap, chunk)
end
end
end
end
end
end
end
2016-11-04 01:51:35 +02:00
--[[
Passive scan to find ai generated nests, required while ai creates bases or until an event is exposed by devs
--]]
2016-08-29 02:05:28 +02:00
function mapProcessor.scanMap(regionMap, surface)
local index = regionMap.scanPointer
local processQueue = regionMap.processQueue
2016-09-14 13:16:33 +02:00
local endIndex = mMin(index + SCAN_QUEUE_SIZE, #processQueue)
2016-08-29 02:05:28 +02:00
for x=index,endIndex do
2016-10-15 02:00:18 +02:00
local chunk = processQueue[x]
2016-08-29 02:05:28 +02:00
2016-10-15 02:00:18 +02:00
local spawners = surface.count_entities_filtered({area = {{chunk.pX, chunk.pY},
{chunk.pX + CHUNK_SIZE, chunk.pY + CHUNK_SIZE}},
type = "unit-spawner",
force = "enemy"})
chunk[ENEMY_BASE_GENERATOR] = spawners * ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT
end
2016-08-29 02:05:28 +02:00
if (endIndex == #processQueue) then
2016-10-15 02:00:18 +02:00
regionMap.scanPointer = 1
2016-08-29 02:05:28 +02:00
else
2016-10-15 02:00:18 +02:00
regionMap.scanPointer = endIndex + 1
end
end
2016-09-08 22:02:23 +02:00
return mapProcessor