mirror of
https://github.com/veden/Rampant.git
synced 2024-12-26 20:54:12 +02:00
9e88e46,8c0b34f: Refactored pheromone distribution and added long term
death marker
This commit is contained in:
parent
1824943dce
commit
ac556c2c9d
@ -639,6 +639,10 @@ function upgrade.attempt(universe)
|
||||
base.resetExpensionGroupsTick = 0
|
||||
end
|
||||
|
||||
for _,map in pairs(universe.maps) do
|
||||
map.chunkToPermanentDeathGenerator = {}
|
||||
end
|
||||
|
||||
game.print("Rampant - Version 3.2.0")
|
||||
end
|
||||
|
||||
@ -696,6 +700,7 @@ function upgrade.prepMap(universe, surface)
|
||||
map.chunkToPassable = {}
|
||||
map.chunkToPathRating = {}
|
||||
map.chunkToDeathGenerator = {}
|
||||
map.chunkToPermanentDeathGenerator = {}
|
||||
|
||||
map.chunkScanCounts = {}
|
||||
|
||||
|
@ -9,6 +9,8 @@ Version: 3.2.0
|
||||
- Added console command /rampantRemoveNewEnemies which changes all new enemies to vanilla enemies for allowing the disabling of new enemies on an existing save
|
||||
- Added console command /rampantRemoveFaction to remove individual factions on existing saves
|
||||
- Added minimum evolution of 20% before faction adaptation will happen with mod setting to configure
|
||||
- Improved the potential field pheromone distribution
|
||||
- Added long term death pheromone that overtime will cause chunks saturated in death to be avoided more frequently and settled less
|
||||
Compatibility:
|
||||
- Added interface for adding and removing excluded surfaces
|
||||
Tweaks:
|
||||
@ -16,6 +18,9 @@ Version: 3.2.0
|
||||
- Changed spawner pollution check to use 75% of the chunk pollution diffuse value
|
||||
- Bases no longer gain points in AI_STATE_PEACEFUL (Dagothur)
|
||||
- Added baseId and surface name to the adaptation console message
|
||||
- Increased the number of chunks processed from 735 to 3000
|
||||
- Kamikaze squads no longer use a separate movement function
|
||||
- Reduced the raiding base threshold from 550 to 50 to account for the new pheromone distribution
|
||||
Bugfixes:
|
||||
- Removed layer-13 from projectiles
|
||||
- script_raised_built now looks for enemy faction and registers as needed
|
||||
|
34
control.lua
34
control.lua
@ -145,7 +145,7 @@ local createDrainPylon = unitUtils.createDrainPylon
|
||||
|
||||
local isDrained = chunkPropertyUtils.isDrained
|
||||
local setDrainedTick = chunkPropertyUtils.setDrainedTick
|
||||
local getDeathGeneratorRating = chunkPropertyUtils.getDeathGeneratorRating
|
||||
local getCombinedDeathGeneratorRating = chunkPropertyUtils.getCombinedDeathGeneratorRating
|
||||
|
||||
local retreatUnits = squadDefense.retreatUnits
|
||||
|
||||
@ -458,14 +458,13 @@ local function onDeath(event)
|
||||
end
|
||||
|
||||
if (chunk ~= -1) then
|
||||
deathScent(map, chunk)
|
||||
|
||||
if not base then
|
||||
base = findNearbyBase(map, chunk)
|
||||
end
|
||||
|
||||
local artilleryBlast = (cause and ((cause.type == "artillery-wagon") or (cause.type == "artillery-turret")))
|
||||
if (entityType == "unit") and not ENTITY_SKIP_COUNT_LOOKUP[entity.name] then
|
||||
deathScent(map, chunk)
|
||||
if base then
|
||||
base.lostEnemyUnits = base.lostEnemyUnits + 1
|
||||
if damageTypeName then
|
||||
@ -483,7 +482,7 @@ local function onDeath(event)
|
||||
end
|
||||
end
|
||||
|
||||
if (getDeathGeneratorRating(map, chunk) < universe.retreatThreshold) and cause and cause.valid then
|
||||
if (getCombinedDeathGeneratorRating(map, chunk) < universe.retreatThreshold) and cause and cause.valid then
|
||||
retreatUnits(chunk,
|
||||
cause,
|
||||
map,
|
||||
@ -494,6 +493,7 @@ local function onDeath(event)
|
||||
(entityType == "unit-spawner") or
|
||||
(entityType == "turret")
|
||||
then
|
||||
deathScent(map, chunk, true)
|
||||
if base then
|
||||
if (entityType == "unit-spawner") then
|
||||
modifyBaseUnitPoints(base, RECOVER_NEST_COST, "Nest Lost")
|
||||
@ -968,7 +968,7 @@ script.on_event(defines.events.on_tick,
|
||||
local tick = gameRef.tick
|
||||
local pick = tick % 8
|
||||
-- if not universe.profiler then
|
||||
-- universe.profiler = game.create_profiler()
|
||||
-- local profiler = game.create_profiler()
|
||||
-- end
|
||||
|
||||
local map = universe.activeMap
|
||||
@ -987,22 +987,17 @@ script.on_event(defines.events.on_tick,
|
||||
elseif (pick == 1) then
|
||||
processPlayers(gameRef.connected_players, universe, tick)
|
||||
elseif (pick == 2) then
|
||||
if map then
|
||||
processMap(map, tick)
|
||||
end
|
||||
elseif (pick == 3) then
|
||||
if map then
|
||||
processStaticMap(map)
|
||||
end
|
||||
disperseVictoryScent(universe)
|
||||
processVengence(universe)
|
||||
elseif (pick == 3) then
|
||||
disperseVictoryScent(universe)
|
||||
processAttackWaves(universe)
|
||||
processNests(universe, tick)
|
||||
elseif (pick == 4) then
|
||||
if map then
|
||||
scanResourceMap(map, tick)
|
||||
scanEnemyMap(map, tick)
|
||||
end
|
||||
elseif (pick == 5) then
|
||||
processAttackWaves(universe)
|
||||
if map then
|
||||
scanEnemyMap(map, tick)
|
||||
end
|
||||
@ -1010,13 +1005,16 @@ script.on_event(defines.events.on_tick,
|
||||
if map then
|
||||
scanPlayerMap(map, tick)
|
||||
end
|
||||
processNests(universe, tick)
|
||||
elseif (pick == 7) then
|
||||
processPendingChunks(universe, tick)
|
||||
processScanChunks(universe)
|
||||
planning(universe, gameRef.forces.enemy.evolution_factor)
|
||||
end
|
||||
|
||||
if map then
|
||||
processMap(map, tick)
|
||||
end
|
||||
|
||||
processBaseAIs(universe, tick)
|
||||
processActiveNests(universe, tick)
|
||||
processPendingUpgrades(universe, tick)
|
||||
@ -1025,8 +1023,7 @@ script.on_event(defines.events.on_tick,
|
||||
|
||||
-- if (game.tick % 20 == 0) then
|
||||
-- universe.profiler.divide(60)
|
||||
-- game.print({"", "--dispatch4 ", universe.profiler})
|
||||
-- universe.profiler.reset()
|
||||
-- game.print({"", "--dispatch4 ", profiler, " , ", pick," , ",math.random()})
|
||||
-- end
|
||||
end)
|
||||
|
||||
@ -1106,7 +1103,8 @@ remote.add_interface("rampantTests",
|
||||
killActiveSquads = tests.killActiveSquads,
|
||||
scanChunkPaths = tests.scanChunkPaths,
|
||||
scanEnemy = tests.scanEnemy,
|
||||
getEnemyStructureCount = tests.getEnemyStructureCount
|
||||
getEnemyStructureCount = tests.getEnemyStructureCount,
|
||||
chunkCount = tests.chunkCount
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -73,7 +73,6 @@ local getChunkByXY = mapUtils.getChunkByXY
|
||||
local scoreNeighborsForFormation = movementUtils.scoreNeighborsForFormation
|
||||
local scoreNeighborsForResource = movementUtils.scoreNeighborsForResource
|
||||
local createSquad = unitGroupUtils.createSquad
|
||||
local getDeathGeneratorRating = chunkPropertyUtils.getDeathGeneratorRating
|
||||
|
||||
local modifyBaseUnitPoints = baseUtils.modifyBaseUnitPoints
|
||||
|
||||
@ -109,19 +108,15 @@ local function attackWaveValidCandidate(chunk, map, base)
|
||||
end
|
||||
|
||||
local function scoreSettlerLocation(map, neighborChunk)
|
||||
return (getDeathGeneratorRating(map, neighborChunk) * neighborChunk[RESOURCE_PHEROMONE]) +
|
||||
-neighborChunk[PLAYER_PHEROMONE]
|
||||
return neighborChunk[RESOURCE_PHEROMONE] + -neighborChunk[PLAYER_PHEROMONE]
|
||||
end
|
||||
|
||||
local function scoreSiegeSettlerLocation(map, neighborChunk)
|
||||
return ((neighborChunk[RESOURCE_PHEROMONE] +
|
||||
neighborChunk[BASE_PHEROMONE]) * getDeathGeneratorRating(map, neighborChunk)) +
|
||||
-neighborChunk[PLAYER_PHEROMONE]
|
||||
return (neighborChunk[RESOURCE_PHEROMONE] + neighborChunk[BASE_PHEROMONE]) + -neighborChunk[PLAYER_PHEROMONE]
|
||||
end
|
||||
|
||||
local function scoreUnitGroupLocation(map, neighborChunk)
|
||||
return (neighborChunk[PLAYER_PHEROMONE] + neighborChunk[BASE_PHEROMONE]) *
|
||||
getDeathGeneratorRating(map, neighborChunk)
|
||||
return neighborChunk[PLAYER_PHEROMONE] + neighborChunk[BASE_PHEROMONE]
|
||||
end
|
||||
|
||||
local function validSiegeSettlerLocation(map, neighborChunk)
|
||||
|
@ -353,14 +353,6 @@ function chunkPropertyUtils.addResourceGenerator(map, chunk, delta)
|
||||
map.chunkToResource[chunk.id] = (map.chunkToResource[chunk.id] or 0) + delta
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getDeathGeneratorRating(map, chunk)
|
||||
return 1 - (map.chunkToDeathGenerator[chunk.id] or 0)
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getDeathGenerator(map, chunk)
|
||||
return map.chunkToDeathGenerator[chunk.id] or 0
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getPassable(map, chunk)
|
||||
return map.chunkToPassable[chunk.id] or CHUNK_ALL_DIRECTIONS
|
||||
end
|
||||
@ -446,13 +438,67 @@ function chunkPropertyUtils.setPathRating(map, chunk, value)
|
||||
end
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getDeathGeneratorRating(map, chunk)
|
||||
return 1 + (map.chunkToDeathGenerator[chunk.id] or 0)
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk)
|
||||
local amount = 1 + ((map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0))
|
||||
if (amount > 1) then
|
||||
return 1
|
||||
elseif (amount < 0) then
|
||||
return 0
|
||||
else
|
||||
return amount
|
||||
end
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getDeathGenerator(map, chunk)
|
||||
return map.chunkToDeathGenerator[chunk.id] or 0
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getPermanentDeathGeneratorRating(map, chunk)
|
||||
return 1 + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.getCombinedDeathGenerator(map, chunk)
|
||||
local amount = (map.chunkToDeathGenerator[chunk.id] or 0) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)
|
||||
if (amount > 1) then
|
||||
return 1
|
||||
elseif (amount < -1) then
|
||||
return -1
|
||||
else
|
||||
return amount
|
||||
end
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.addPermanentDeathGenerator(map, chunk, amount)
|
||||
local adjustedAmount = (amount * 0.25) + (map.chunkToPermanentDeathGenerator[chunk.id] or 0)
|
||||
if (adjustedAmount > 0.75) then
|
||||
map.chunkToPermanentDeathGenerator[chunk.id] = 0.75
|
||||
elseif (adjustedAmount < -0.75) then
|
||||
map.chunkToPermanentDeathGenerator[chunk.id] = -0.75
|
||||
else
|
||||
map.chunkToPermanentDeathGenerator[chunk.id] = adjustedAmount
|
||||
end
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.addDeathGenerator(map, chunk, value)
|
||||
map.chunkToDeathGenerator[chunk.id] = (map.chunkToDeathGenerator[chunk.id] or 0) + value
|
||||
local currentAmount = (map.chunkToDeathGenerator[chunk.id] or 0) + value
|
||||
if (currentAmount > 1) then
|
||||
map.chunkToDeathGenerator[chunk.id] = 1
|
||||
elseif (currentAmount < -1) then
|
||||
map.chunkToDeathGenerator[chunk.id] = -1
|
||||
else
|
||||
map.chunkToDeathGenerator[chunk.id] = currentAmount
|
||||
end
|
||||
end
|
||||
|
||||
function chunkPropertyUtils.setDeathGenerator(map, chunk, value)
|
||||
if (value <= 0.001) and (value >= -0.001) then
|
||||
map.chunkToDeathGenerator[chunk.id] = nil
|
||||
if (value > 1) then
|
||||
map.chunkToDeathGenerator[chunk.id] = 1
|
||||
elseif (value < -1) then
|
||||
map.chunkToDeathGenerator[chunk.id] = -1
|
||||
else
|
||||
map.chunkToDeathGenerator[chunk.id] = value
|
||||
end
|
||||
@ -474,7 +520,7 @@ function chunkPropertyUtils.decayDeathGenerator(map, chunk)
|
||||
local gen = map.chunkToDeathGenerator[chunk.id]
|
||||
if gen then
|
||||
local v = gen * MOVEMENT_GENERATOR_PERSISTANCE
|
||||
if v <= 0.001 then
|
||||
if (v < 0.0001) and (v > -0.0001) then
|
||||
map.chunkToDeathGenerator[chunk.id] = nil
|
||||
else
|
||||
map.chunkToDeathGenerator[chunk.id] = v
|
||||
|
@ -65,7 +65,7 @@ constants.TEMPERAMENT_RANGE_MAX = 10000
|
||||
constants.TEMPERAMENT_RANGE_MIN = -constants.TEMPERAMENT_RANGE_MAX
|
||||
constants.TEMPERAMENT_DIVIDER = 1 / (2 * constants.TEMPERAMENT_RANGE_MAX)
|
||||
|
||||
constants.PROCESS_QUEUE_SIZE = 105
|
||||
constants.PROCESS_QUEUE_SIZE = 50
|
||||
constants.SCAN_QUEUE_SIZE = 2
|
||||
constants.RESOURCE_QUEUE_SIZE = 2
|
||||
constants.ENEMY_QUEUE_SIZE = 1
|
||||
@ -73,7 +73,6 @@ constants.PLAYER_QUEUE_SIZE = 2
|
||||
constants.CLEANUP_QUEUE_SIZE = 8
|
||||
constants.ATTACK_QUEUE_SIZE = 18
|
||||
constants.BASE_QUEUE_SIZE = 1
|
||||
constants.PROCESS_STATIC_QUEUE_SIZE = 20
|
||||
constants.PROCESS_PLAYER_BOUND = 128
|
||||
constants.VICTORY_SCENT_BOUND = 128
|
||||
|
||||
@ -132,7 +131,7 @@ constants.AI_TUNNEL_COST = 100
|
||||
constants.AI_MAX_POINTS = 15500
|
||||
constants.AI_MAX_OVERFLOW_POINTS = constants.AI_MAX_POINTS * 3
|
||||
|
||||
constants.RAIDING_MINIMUM_BASE_THRESHOLD = 550
|
||||
constants.RAIDING_MINIMUM_BASE_THRESHOLD = 50
|
||||
|
||||
constants.AI_UNIT_REFUND = 3
|
||||
|
||||
@ -258,6 +257,7 @@ constants.GENERATOR_PHEROMONE_LEVEL_3 = 500
|
||||
constants.GENERATOR_PHEROMONE_LEVEL_4 = 1000
|
||||
constants.GENERATOR_PHEROMONE_LEVEL_5 = 1750
|
||||
constants.GENERATOR_PHEROMONE_LEVEL_6 = 6000
|
||||
constants.GENERATOR_PHEROMONE_VICTORY_NORMALIZER = 20000
|
||||
|
||||
constants.BUILDING_PHEROMONES = {}
|
||||
constants.BUILDING_PHEROMONES["wall"] = constants.GENERATOR_PHEROMONE_LEVEL_1
|
||||
@ -292,36 +292,9 @@ constants.BUILDING_PHEROMONES["reactor"] = constants.GENERATOR_PHEROMONE_LEVEL_6
|
||||
constants.BUILDING_PHEROMONES["rocket-silo"] = constants.GENERATOR_PHEROMONE_LEVEL_6
|
||||
|
||||
constants.VICTORY_SCENT = {}
|
||||
constants.VICTORY_SCENT["wall"] = constants.BUILDING_PHEROMONES["wall"] * 10
|
||||
constants.VICTORY_SCENT["transport-belt"] = constants.BUILDING_PHEROMONES["transport-belt"] * 10
|
||||
|
||||
constants.VICTORY_SCENT["splitter"] = constants.BUILDING_PHEROMONES["splitter"] * 10
|
||||
constants.VICTORY_SCENT["pump"] = constants.BUILDING_PHEROMONES["pump"] * 10
|
||||
constants.VICTORY_SCENT["offshore-pump"] = constants.BUILDING_PHEROMONES["offshore-pump"] * 10
|
||||
|
||||
constants.VICTORY_SCENT["lamp"] = constants.BUILDING_PHEROMONES["lamp"] * 10
|
||||
constants.VICTORY_SCENT["solar-panel"] = constants.BUILDING_PHEROMONES["solar-panel"] * 10
|
||||
constants.VICTORY_SCENT["programmable-speaker"] = constants.BUILDING_PHEROMONES["programmable-speaker"] * 10
|
||||
constants.VICTORY_SCENT["accumulator"] = constants.BUILDING_PHEROMONES["accumulator"] * 10
|
||||
constants.VICTORY_SCENT["assembling-machine"] = constants.BUILDING_PHEROMONES["assembling-machine"] * 10
|
||||
constants.VICTORY_SCENT["turret"] = constants.BUILDING_PHEROMONES["turret"] * 10
|
||||
constants.VICTORY_SCENT["ammo-turret"] = constants.BUILDING_PHEROMONES["ammo-turret"] * 10
|
||||
|
||||
constants.VICTORY_SCENT["furnace"] = constants.BUILDING_PHEROMONES["furnace"] * 10
|
||||
constants.VICTORY_SCENT["lab"] = constants.BUILDING_PHEROMONES["lab"] * 10
|
||||
constants.VICTORY_SCENT["roboport"] = constants.BUILDING_PHEROMONES["roboport"] * 10
|
||||
constants.VICTORY_SCENT["beacon"] = constants.BUILDING_PHEROMONES["beacon"] * 10
|
||||
constants.VICTORY_SCENT["radar"] = constants.BUILDING_PHEROMONES["radar"] * 10
|
||||
constants.VICTORY_SCENT["electric-turret"] = constants.BUILDING_PHEROMONES["electric-turret"] * 10
|
||||
|
||||
constants.VICTORY_SCENT["boiler"] = constants.BUILDING_PHEROMONES["boiler"] * 10
|
||||
constants.VICTORY_SCENT["generator"] = constants.BUILDING_PHEROMONES["generator"] * 10
|
||||
constants.VICTORY_SCENT["fluid-turret"] = constants.BUILDING_PHEROMONES["fluid-turret"] * 10
|
||||
constants.VICTORY_SCENT["mining-drill"] = constants.BUILDING_PHEROMONES["mining-drill"] * 10
|
||||
|
||||
constants.VICTORY_SCENT["artillery-turret"] = constants.BUILDING_PHEROMONES["artillery-turret"] * 10
|
||||
constants.VICTORY_SCENT["reactor"] = constants.BUILDING_PHEROMONES["reactor"] * 10
|
||||
constants.VICTORY_SCENT["rocket-silo"] = constants.BUILDING_PHEROMONES["rocket-silo"] * 10
|
||||
for key, building in pairs(constants.BUILDING_PHEROMONES) do
|
||||
constants.VICTORY_SCENT[key] = building / constants.GENERATOR_PHEROMONE_VICTORY_NORMALIZER
|
||||
end
|
||||
|
||||
-- map settings tweaks
|
||||
|
||||
|
@ -67,7 +67,7 @@ local removeChunkToNest = mapUtils.removeChunkToNest
|
||||
local processStaticPheromone = pheromoneUtils.processStaticPheromone
|
||||
local processPheromone = pheromoneUtils.processPheromone
|
||||
|
||||
local getDeathGeneratorRating = chunkPropertyUtils.getDeathGeneratorRating
|
||||
local getCombinedDeathGeneratorRating = chunkPropertyUtils.getCombinedDeathGeneratorRating
|
||||
local processBaseMutation = baseUtils.processBaseMutation
|
||||
|
||||
local processNestActiveness = chunkPropertyUtils.processNestActiveness
|
||||
@ -215,6 +215,21 @@ function mapProcessor.processPlayers(players, universe, tick)
|
||||
-- put down player pheromone for player hunters
|
||||
-- randomize player order to ensure a single player isn't singled out
|
||||
-- not looping everyone because the cost is high enough already in multiplayer
|
||||
for i=1,#players do
|
||||
local player = players[i]
|
||||
if validPlayer(player) then
|
||||
local char = player.character
|
||||
local map = universe.maps[char.surface.index]
|
||||
if map then
|
||||
local playerChunk = getChunkByPosition(map, char.position)
|
||||
|
||||
if (playerChunk ~= -1) then
|
||||
addPlayerToChunk(map, playerChunk, player.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (#players > 0) then
|
||||
local player = players[universe.random(#players)]
|
||||
if validPlayer(player) then
|
||||
@ -232,7 +247,7 @@ function mapProcessor.processPlayers(players, universe, tick)
|
||||
local vengence = allowingAttacks and
|
||||
(base.unitPoints >= AI_VENGENCE_SQUAD_COST) and
|
||||
((getEnemyStructureCount(map, playerChunk) > 0) or
|
||||
(getDeathGeneratorRating(map, playerChunk) < universe.retreatThreshold))
|
||||
(getCombinedDeathGeneratorRating(map, playerChunk) < universe.retreatThreshold))
|
||||
|
||||
for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do
|
||||
for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do
|
||||
@ -266,21 +281,6 @@ function mapProcessor.processPlayers(players, universe, tick)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for i=1,#players do
|
||||
local player = players[i]
|
||||
if validPlayer(player) then
|
||||
local char = player.character
|
||||
local map = universe.maps[char.surface.index]
|
||||
if map then
|
||||
local playerChunk = getChunkByPosition(map, char.position)
|
||||
|
||||
if (playerChunk ~= -1) then
|
||||
addPlayerToChunk(map, playerChunk, player.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function processCleanUp(universe, chunks, iterator, tick, duration)
|
||||
|
@ -74,9 +74,7 @@ function movementUtils.addMovementPenalty(squad, chunk)
|
||||
local penalty = penalties[i]
|
||||
if (penalty.c.id == chunk.id) then
|
||||
penalty.v = penalty.v + 1
|
||||
if (penalty.v > 2) and (penalty.v < 15) then
|
||||
squad.kamikaze = true
|
||||
elseif penalty.v >= 15 then
|
||||
if penalty.v >= 15 then
|
||||
local universe = squad.map.universe
|
||||
if universe.enabledMigration and
|
||||
(universe.builderCount < universe.AI_MAX_BUILDER_COUNT) then
|
||||
|
@ -33,10 +33,6 @@ local VICTORY_SCENT_BOUND = constants.VICTORY_SCENT_BOUND
|
||||
|
||||
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
|
||||
|
||||
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
||||
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH
|
||||
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST
|
||||
|
||||
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
||||
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
||||
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
||||
@ -51,19 +47,20 @@ local DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.DEATH_PHEROMONE_GENERATOR_AMO
|
||||
-- imported functions
|
||||
|
||||
local addVictoryGenerator = chunkPropertyUtils.addVictoryGenerator
|
||||
local getDeathGenerator = chunkPropertyUtils.getDeathGenerator
|
||||
local getCombinedDeathGenerator = chunkPropertyUtils.getCombinedDeathGenerator
|
||||
local getCombinedDeathGeneratorRating = chunkPropertyUtils.getCombinedDeathGeneratorRating
|
||||
local setDeathGenerator = chunkPropertyUtils.setDeathGenerator
|
||||
|
||||
local getPlayersOnChunk = chunkPropertyUtils.getPlayersOnChunk
|
||||
|
||||
local addPermanentDeathGenerator = chunkPropertyUtils.addPermanentDeathGenerator
|
||||
|
||||
local canMoveChunkDirection = mapUtils.canMoveChunkDirection
|
||||
local getNeighborChunks = mapUtils.getNeighborChunks
|
||||
local getChunkById = mapUtils.getChunkById
|
||||
|
||||
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
|
||||
local getNestCount = chunkPropertyUtils.getNestCount
|
||||
local getHiveCount = chunkPropertyUtils.getHiveCount
|
||||
local getPathRating = chunkPropertyUtils.getPathRating
|
||||
local getPassable = chunkPropertyUtils.getPassable
|
||||
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
|
||||
local getResourceGenerator = chunkPropertyUtils.getResourceGenerator
|
||||
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator
|
||||
@ -75,6 +72,7 @@ local linearInterpolation = mathUtils.linearInterpolation
|
||||
local getChunkByXY = mapUtils.getChunkByXY
|
||||
|
||||
local next = next
|
||||
local mMax = math.max
|
||||
|
||||
-- module code
|
||||
|
||||
@ -111,7 +109,9 @@ function pheromoneUtils.disperseVictoryScent(universe)
|
||||
for y = chunkY - VICTORY_SCENT_BOUND, chunkY + VICTORY_SCENT_BOUND,32 do
|
||||
local c = getChunkByXY(map, x, y)
|
||||
if (c ~= -1) then
|
||||
addDeathGenerator(map, c, -pheromonePack.v * VICTORY_SCENT_MULTIPLER[i] * getPathRating(map, c))
|
||||
local amount = pheromonePack.v * VICTORY_SCENT_MULTIPLER[i]
|
||||
addDeathGenerator(map, c, amount)
|
||||
addPermanentDeathGenerator(map, c, amount)
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
@ -120,503 +120,75 @@ function pheromoneUtils.disperseVictoryScent(universe)
|
||||
end
|
||||
|
||||
function pheromoneUtils.deathScent(map, chunk)
|
||||
addDeathGenerator(map, chunk, DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
end
|
||||
|
||||
function pheromoneUtils.processStaticPheromone(map, chunk)
|
||||
local chunkBase = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkResource = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkEnemy = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkPathRating = getPathRating(map, chunk)
|
||||
|
||||
local clear = getEnemyStructureCount(map, chunk) == 0
|
||||
|
||||
local tempNeighbors = getNeighborChunks(map, chunk.x, chunk.y)
|
||||
|
||||
local neighbor
|
||||
local neighborPass
|
||||
|
||||
local chunkPass = getPassable(map, chunk)
|
||||
local pheromone
|
||||
if (chunkPass == CHUNK_ALL_DIRECTIONS) then
|
||||
neighbor = tempNeighbors[2]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[7]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[4]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[5]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[1]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[3]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[6]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[8]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif (chunkPass == CHUNK_EAST_WEST) then
|
||||
|
||||
neighbor = tempNeighbors[4]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[5]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif (chunkPass == CHUNK_NORTH_SOUTH) then
|
||||
|
||||
neighbor = tempNeighbors[2]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[7]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < pheromone then
|
||||
chunkBase = pheromone
|
||||
end
|
||||
pheromone = neighbor[ENEMY_PHEROMONE]
|
||||
if chunkEnemy < pheromone then
|
||||
chunkEnemy = pheromone
|
||||
end
|
||||
pheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < pheromone then
|
||||
chunkResource = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
chunkBase = chunkBase * 0.9
|
||||
pheromone = getPlayerBaseGenerator(map, chunk)
|
||||
if chunkBase < pheromone then
|
||||
chunk[BASE_PHEROMONE] = pheromone * chunkPathRating
|
||||
else
|
||||
chunk[BASE_PHEROMONE] = chunkBase * chunkPathRating
|
||||
end
|
||||
|
||||
chunkEnemy = chunkEnemy * 0.9
|
||||
pheromone = (getNestCount(map, chunk) + getHiveCount(map, chunk)) * ENEMY_PHEROMONE_MULTIPLER
|
||||
if chunkEnemy < pheromone then
|
||||
chunk[ENEMY_PHEROMONE] = pheromone * chunkPathRating
|
||||
else
|
||||
chunk[ENEMY_PHEROMONE] = chunkEnemy * chunkPathRating
|
||||
end
|
||||
|
||||
chunkResource = chunkResource * 0.9
|
||||
pheromone = getResourceGenerator(map, chunk)
|
||||
if (pheromone > 0) and clear then
|
||||
pheromone = linearInterpolation(pheromone, 15000, 20000)
|
||||
end
|
||||
if chunkResource < pheromone then
|
||||
if clear then
|
||||
chunk[RESOURCE_PHEROMONE] = pheromone * chunkPathRating
|
||||
else
|
||||
chunk[RESOURCE_PHEROMONE] = pheromone * chunkPathRating * 0.0001
|
||||
end
|
||||
else
|
||||
if clear then
|
||||
chunk[RESOURCE_PHEROMONE] = chunkResource * chunkPathRating
|
||||
else
|
||||
chunk[RESOURCE_PHEROMONE] = chunkResource * chunkPathRating * 0.0001
|
||||
end
|
||||
end
|
||||
local amount = -DEATH_PHEROMONE_GENERATOR_AMOUNT
|
||||
addDeathGenerator(map, chunk, amount)
|
||||
addPermanentDeathGenerator(map, chunk, amount)
|
||||
end
|
||||
|
||||
function pheromoneUtils.processPheromone(map, chunk, player)
|
||||
local chunkPlayer = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkDeath = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkPathRating = getPathRating(map, chunk)
|
||||
local chunkPlayer = chunk[PLAYER_PHEROMONE]
|
||||
local chunkBase = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkDeath = getCombinedDeathGenerator(map, chunk)
|
||||
local chunkResource = -MAGIC_MAXIMUM_NUMBER
|
||||
local chunkEnemy = chunk[ENEMY_PHEROMONE]
|
||||
|
||||
local chunkCount = 1
|
||||
|
||||
local enemyStructureCount = getEnemyStructureCount(map, chunk)
|
||||
|
||||
local tempNeighbors = getNeighborChunks(map, chunk.x, chunk.y)
|
||||
|
||||
local neighbor
|
||||
local neighborPass
|
||||
|
||||
local chunkPass = getPassable(map, chunk)
|
||||
local pheromone
|
||||
if (chunkPass == CHUNK_ALL_DIRECTIONS) then
|
||||
neighbor = tempNeighbors[2]
|
||||
for i=1,8 do
|
||||
local tempPheromone
|
||||
local neighbor = tempNeighbors[i]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
if canMoveChunkDirection(map, i, chunk, neighbor) then
|
||||
chunkCount = chunkCount + 1
|
||||
chunkPlayer = chunkPlayer + neighbor[PLAYER_PHEROMONE]
|
||||
chunkEnemy = chunkEnemy + neighbor[ENEMY_PHEROMONE]
|
||||
chunkDeath = chunkDeath + getCombinedDeathGenerator(map, neighbor)
|
||||
tempPheromone = neighbor[BASE_PHEROMONE]
|
||||
if chunkBase < tempPheromone then
|
||||
chunkBase = tempPheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[7]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[4]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[5]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[1]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[3]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[6]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[8]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if (neighborPass == CHUNK_ALL_DIRECTIONS) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif (chunkPass == CHUNK_EAST_WEST) then
|
||||
|
||||
neighbor = tempNeighbors[4]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[5]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_EAST_WEST)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif (chunkPass == CHUNK_NORTH_SOUTH) then
|
||||
|
||||
neighbor = tempNeighbors[2]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
neighbor = tempNeighbors[7]
|
||||
if (neighbor ~= -1) then
|
||||
neighborPass = getPassable(map, neighbor)
|
||||
if ((neighborPass == CHUNK_ALL_DIRECTIONS) or (neighborPass == CHUNK_NORTH_SOUTH)) then
|
||||
pheromone = neighbor[PLAYER_PHEROMONE]
|
||||
if chunkPlayer < pheromone then
|
||||
chunkPlayer = pheromone
|
||||
end
|
||||
pheromone = getDeathGenerator(map, chunk)
|
||||
if chunkDeath < pheromone then
|
||||
chunkDeath = pheromone
|
||||
tempPheromone = neighbor[RESOURCE_PHEROMONE]
|
||||
if chunkResource < tempPheromone then
|
||||
chunkResource = tempPheromone
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if chunkDeath > 0 then
|
||||
setDeathGenerator(map, chunk, chunkDeath * 0.95)
|
||||
end
|
||||
setDeathGenerator(map, chunk, (chunkDeath / chunkCount) * 0.75)
|
||||
|
||||
if not player then
|
||||
decayDeathGenerator(map, chunk)
|
||||
end
|
||||
|
||||
chunkPlayer = chunkPlayer * 0.45
|
||||
pheromone = getPlayersOnChunk(map, chunk) * PLAYER_PHEROMONE_GENERATOR_AMOUNT
|
||||
if chunkPlayer < pheromone then
|
||||
chunk[PLAYER_PHEROMONE] = pheromone * chunkPathRating
|
||||
else
|
||||
chunk[PLAYER_PHEROMONE] = chunkPlayer * chunkPathRating
|
||||
local chunkDeathRating = getCombinedDeathGeneratorRating(map, chunk) * getPathRating(map, chunk)
|
||||
|
||||
chunk[PLAYER_PHEROMONE] = chunkDeathRating * mMax(
|
||||
getPlayersOnChunk(map, chunk) * PLAYER_PHEROMONE_GENERATOR_AMOUNT,
|
||||
(chunkPlayer / chunkCount) * 0.98
|
||||
)
|
||||
|
||||
chunk[BASE_PHEROMONE] = chunkDeathRating * mMax(
|
||||
getPlayerBaseGenerator(map, chunk),
|
||||
chunkBase * 0.9
|
||||
)
|
||||
|
||||
chunk[ENEMY_PHEROMONE] = chunkDeathRating * mMax(
|
||||
enemyStructureCount * ENEMY_PHEROMONE_MULTIPLER,
|
||||
(chunkEnemy / chunkCount) * 0.9
|
||||
)
|
||||
|
||||
local resourcePheromoneGenerator = getResourceGenerator(map, chunk)
|
||||
if (resourcePheromoneGenerator > 0) then
|
||||
chunkResource = linearInterpolation(resourcePheromoneGenerator, 15000, 20000)
|
||||
end
|
||||
if enemyStructureCount ~= 0 then
|
||||
chunkResource = chunkResource * 0.0001
|
||||
end
|
||||
chunk[RESOURCE_PHEROMONE] = chunkDeathRating * chunkResource * 0.9
|
||||
end
|
||||
|
||||
pheromoneUtilsG = pheromoneUtils
|
||||
|
@ -64,7 +64,7 @@ local findMovementPosition = movementUtils.findMovementPosition
|
||||
|
||||
local removeSquadFromChunk = chunkPropertyUtils.removeSquadFromChunk
|
||||
local addDeathGenerator = chunkPropertyUtils.addDeathGenerator
|
||||
local getDeathGeneratorRating = chunkPropertyUtils.getDeathGeneratorRating
|
||||
local getCombinedDeathGeneratorRating = chunkPropertyUtils.getCombinedDeathGeneratorRating
|
||||
|
||||
local getPlayersOnChunk = chunkPropertyUtils.getPlayersOnChunk
|
||||
local getHiveCount = chunkPropertyUtils.getHiveCount
|
||||
@ -86,26 +86,8 @@ local scoreNeighborsForAttack = movementUtils.scoreNeighborsForAttack
|
||||
local scoreNeighborsForSettling = movementUtils.scoreNeighborsForSettling
|
||||
|
||||
-- module code
|
||||
|
||||
local function scoreResourceLocationKamikaze(_, neighborChunk)
|
||||
local settle = neighborChunk[RESOURCE_PHEROMONE]
|
||||
return settle
|
||||
- (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||
- neighborChunk[ENEMY_PHEROMONE]
|
||||
end
|
||||
|
||||
local function scoreSiegeLocationKamikaze(_, neighborChunk)
|
||||
local settle = neighborChunk[BASE_PHEROMONE]
|
||||
+ neighborChunk[RESOURCE_PHEROMONE] * 0.5
|
||||
+ (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||
- neighborChunk[ENEMY_PHEROMONE]
|
||||
|
||||
return settle
|
||||
end
|
||||
|
||||
local function scoreResourceLocation(map, neighborChunk)
|
||||
local settle = (getDeathGeneratorRating(map, neighborChunk) * neighborChunk[RESOURCE_PHEROMONE])
|
||||
return settle
|
||||
return neighborChunk[RESOURCE_PHEROMONE]
|
||||
- (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||
- neighborChunk[ENEMY_PHEROMONE]
|
||||
end
|
||||
@ -114,19 +96,13 @@ local function scoreSiegeLocation(map, neighborChunk)
|
||||
local settle = neighborChunk[BASE_PHEROMONE]
|
||||
+ neighborChunk[RESOURCE_PHEROMONE] * 0.5
|
||||
+ (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||
- neighborChunk[ENEMY_PHEROMONE]
|
||||
|
||||
return settle * getDeathGeneratorRating(map, neighborChunk)
|
||||
return settle - neighborChunk[ENEMY_PHEROMONE]
|
||||
end
|
||||
|
||||
local function scoreAttackLocation(map, neighborChunk)
|
||||
local damage = neighborChunk[BASE_PHEROMONE] +
|
||||
(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||
return damage * getDeathGeneratorRating(map, neighborChunk)
|
||||
end
|
||||
|
||||
local function scoreAttackKamikazeLocation(_, neighborChunk)
|
||||
local damage = neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||
return damage
|
||||
end
|
||||
|
||||
@ -140,17 +116,11 @@ local function settleMove(map, squad)
|
||||
local chunk = getChunkByXY(map, x, y)
|
||||
local scoreFunction = scoreResourceLocation
|
||||
if (squad.type == BASE_AI_STATE_SIEGE) then
|
||||
if squad.kamikaze then
|
||||
scoreFunction = scoreSiegeLocationKamikaze
|
||||
else
|
||||
scoreFunction = scoreSiegeLocation
|
||||
end
|
||||
elseif squad.kamikaze then
|
||||
scoreFunction = scoreResourceLocationKamikaze
|
||||
scoreFunction = scoreSiegeLocation
|
||||
end
|
||||
local squadChunk = squad.chunk
|
||||
if squadChunk ~= -1 then
|
||||
addDeathGenerator(map, squadChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(map, squadChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
end
|
||||
if chunk ~= -1 then
|
||||
addSquadToChunk(map, chunk, squad)
|
||||
@ -240,9 +210,9 @@ local function settleMove(map, squad)
|
||||
targetPosition.x = position.x
|
||||
targetPosition.y = position.y
|
||||
if nextAttackChunk ~= -1 then
|
||||
addDeathGenerator(map, nextAttackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(map, nextAttackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
else
|
||||
addDeathGenerator(map, attackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(map, attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
end
|
||||
else
|
||||
cmd = universe.wanderCommand
|
||||
@ -311,12 +281,9 @@ local function attackMove(map, squad)
|
||||
local x, y = positionToChunkXY(groupPosition)
|
||||
local chunk = getChunkByXY(map, x, y)
|
||||
local attackScorer = scoreAttackLocation
|
||||
if squad.kamikaze then
|
||||
attackScorer = scoreAttackKamikazeLocation
|
||||
end
|
||||
local squadChunk = squad.chunk
|
||||
if squadChunk ~= -1 then
|
||||
addDeathGenerator(map, squadChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(map, squadChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
end
|
||||
if chunk ~= -1 then
|
||||
addSquadToChunk(map, chunk, squad)
|
||||
@ -368,9 +335,9 @@ local function attackMove(map, squad)
|
||||
targetPosition.x = position.x
|
||||
targetPosition.y = position.y
|
||||
if (nextAttackChunk ~= -1) then
|
||||
addDeathGenerator(map, nextAttackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(map, nextAttackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
else
|
||||
addDeathGenerator(map, attackChunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(map, attackChunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
end
|
||||
end
|
||||
|
||||
@ -432,7 +399,7 @@ function squadAttack.cleanSquads(universe, tick)
|
||||
local group = squad.group
|
||||
if not group.valid then
|
||||
if squad.chunk ~= -1 then
|
||||
addDeathGenerator(squad.map, squad.chunk, FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
addDeathGenerator(squad.map, squad.chunk, -FIVE_DEATH_PHEROMONE_GENERATOR_AMOUNT)
|
||||
end
|
||||
removeSquadFromChunk(squad.map, squad)
|
||||
if squad.settlers then
|
||||
|
@ -54,7 +54,6 @@ local findMovementPosition = movementUtils.findMovementPosition
|
||||
local getRetreatTick = chunkPropertyUtils.getRetreatTick
|
||||
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
|
||||
local setRetreatTick = chunkPropertyUtils.setRetreatTick
|
||||
local getDeathGeneratorRating = chunkPropertyUtils.getDeathGeneratorRating
|
||||
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
|
||||
|
||||
-- module code
|
||||
@ -62,8 +61,7 @@ local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
|
||||
local function scoreRetreatLocation(map, neighborChunk)
|
||||
return (-neighborChunk[BASE_PHEROMONE] +
|
||||
-(neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER) +
|
||||
-(getPlayerBaseGenerator(map, neighborChunk) * 1000)) *
|
||||
getDeathGeneratorRating(map, neighborChunk)
|
||||
-(getPlayerBaseGenerator(map, neighborChunk) * 1000))
|
||||
end
|
||||
|
||||
function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
|
||||
|
18
tests.lua
18
tests.lua
@ -25,6 +25,14 @@ local baseUtils = require("libs/BaseUtils")
|
||||
local queryUtils = require("libs/QueryUtils")
|
||||
-- local tendrilUtils = require("libs/TendrilUtils")
|
||||
|
||||
function tests.chunkCount()
|
||||
local count = 0
|
||||
for _,map in pairs(global.universe.maps) do
|
||||
count = count + #map.processQueue
|
||||
end
|
||||
print(count)
|
||||
end
|
||||
|
||||
function tests.pheromoneLevels(size)
|
||||
local player = game.player.character
|
||||
local playerChunkX = math.floor(player.position.x / 32) * constants.CHUNK_SIZE
|
||||
@ -442,7 +450,7 @@ local function scoreSiegeLocationKamikaze(_, neighborChunk)
|
||||
end
|
||||
|
||||
local function scoreResourceLocation(map, neighborChunk)
|
||||
local settle = (chunkPropertyUtils.getDeathGeneratorRating(map, neighborChunk) * neighborChunk[constants.RESOURCE_PHEROMONE])
|
||||
local settle = (neighborChunk[constants.RESOURCE_PHEROMONE])
|
||||
return settle
|
||||
- (neighborChunk[constants.PLAYER_PHEROMONE] * constants.PLAYER_PHEROMONE_MULTIPLER)
|
||||
- neighborChunk[constants.ENEMY_PHEROMONE]
|
||||
@ -454,13 +462,13 @@ local function scoreSiegeLocation(map, neighborChunk)
|
||||
+ (neighborChunk[constants.PLAYER_PHEROMONE] * constants.PLAYER_PHEROMONE_MULTIPLER)
|
||||
- neighborChunk[constants.ENEMY_PHEROMONE]
|
||||
|
||||
return settle * chunkPropertyUtils.getDeathGeneratorRating(map, neighborChunk)
|
||||
return settle
|
||||
end
|
||||
|
||||
local function scoreAttackLocation(map, neighborChunk)
|
||||
local damage = neighborChunk[constants.BASE_PHEROMONE] +
|
||||
(neighborChunk[constants.PLAYER_PHEROMONE] * constants.PLAYER_PHEROMONE_MULTIPLER)
|
||||
return damage * chunkPropertyUtils.getDeathGeneratorRating(map, neighborChunk)
|
||||
return damage
|
||||
end
|
||||
|
||||
local function scoreAttackKamikazeLocation(_, neighborChunk)
|
||||
@ -490,7 +498,7 @@ function tests.exportAiState()
|
||||
|
||||
s = s .. table.concat({chunk.x,
|
||||
chunk.y,
|
||||
chunkPropertyUtils.getDeathGeneratorRating(map, chunk),
|
||||
chunkPropertyUtils.getCombinedDeathGeneratorRating(map, chunk),
|
||||
chunk[constants.BASE_PHEROMONE],
|
||||
chunk[constants.PLAYER_PHEROMONE],
|
||||
chunk[constants.RESOURCE_PHEROMONE],
|
||||
@ -504,7 +512,7 @@ function tests.exportAiState()
|
||||
chunkPropertyUtils.getRetreatTick(map, chunk),
|
||||
chunkPropertyUtils.getResourceGenerator(map, chunk),
|
||||
chunkPropertyUtils.getPlayerBaseGenerator(map, chunk),
|
||||
chunkPropertyUtils.getDeathGenerator(map, chunk),
|
||||
chunkPropertyUtils.getCombinedDeathGenerator(map, chunk),
|
||||
scoreResourceLocationKamikaze(map, chunk),
|
||||
scoreResourceLocation(map, chunk),
|
||||
scoreSiegeLocationKamikaze(map, chunk),
|
||||
|
Loading…
Reference in New Issue
Block a user