1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-24 20:14:35 +02:00

FACTO-287: Re-added kamikaze state and pheromone

This commit is contained in:
Aaron Veden 2023-04-04 22:37:58 -07:00
parent 4d6966c380
commit 63eed3e08b
No known key found for this signature in database
GPG Key ID: FF5990B1C6DD3F84
9 changed files with 109 additions and 15 deletions

View File

@ -1,4 +1,6 @@
Version: 3.2.3
Improvements:
- Re-added kamikaze squad state to prevent unit group dancing and then disbanding
Bugfixes:
- Fixed occasionally compression number wouldn't appear on unit group
- Fixed squad compression could take place when attacking

View File

@ -49,6 +49,7 @@ local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local KAMIKAZE_PHEROMONE = Constants.KAMIKAZE_PHEROMONE
local BUILDING_PHEROMONES = Constants.BUILDING_PHEROMONES
local CHUNK_SIZE = Constants.CHUNK_SIZE
@ -396,11 +397,12 @@ function ChunkUtils.createChunk(map, topX, topY)
id = newChunkId(),
map = map
}
chunk[CHUNK_TICK] = 0
chunk[BASE_PHEROMONE] = 0
chunk[PLAYER_PHEROMONE] = 0
chunk[RESOURCE_PHEROMONE] = 0
chunk[ENEMY_PHEROMONE] = 0
chunk[CHUNK_TICK] = 0
chunk[KAMIKAZE_PHEROMONE] = 0
return chunk
end

View File

@ -189,11 +189,12 @@ constants.PLAYER_GENERATOR_PERSISTANCE = 0.92
-- chunk attributes
constants.BASE_PHEROMONE = 1
constants.PLAYER_PHEROMONE = 2
constants.RESOURCE_PHEROMONE = 3
constants.ENEMY_PHEROMONE = 4
constants.CHUNK_TICK = 5
constants.CHUNK_TICK = 1
constants.BASE_PHEROMONE = 2
constants.PLAYER_PHEROMONE = 3
constants.RESOURCE_PHEROMONE = 4
constants.ENEMY_PHEROMONE = 5
constants.KAMIKAZE_PHEROMONE = 6
-- constants.PATH_RATING = 7

View File

@ -39,6 +39,7 @@ local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local KAMIKAZE_PHEROMONE = Constants.KAMIKAZE_PHEROMONE
local CHUNK_TICK = Constants.CHUNK_TICK
@ -575,6 +576,7 @@ function MapUtils.processPheromone(chunk, tick, player)
local chunkDeath = getCombinedDeathGenerator(chunk)
local chunkResource = -MAGIC_MAXIMUM_NUMBER
local chunkEnemy = chunk[ENEMY_PHEROMONE]
local chunkKamikaze = chunk[KAMIKAZE_PHEROMONE]
local chunkCount = 1
@ -590,6 +592,10 @@ function MapUtils.processPheromone(chunk, tick, player)
chunkPlayer = chunkPlayer + neighbor[PLAYER_PHEROMONE]
chunkEnemy = chunkEnemy + neighbor[ENEMY_PHEROMONE]
chunkDeath = chunkDeath + getCombinedDeathGenerator(neighbor)
tempPheromone = neighbor[KAMIKAZE_PHEROMONE]
if chunkKamikaze < tempPheromone then
chunkKamikaze = tempPheromone
end
tempPheromone = neighbor[BASE_PHEROMONE]
if chunkBase < tempPheromone then
chunkBase = tempPheromone
@ -612,12 +618,12 @@ function MapUtils.processPheromone(chunk, tick, player)
local chunkDeathRating = getCombinedDeathGeneratorRating(chunk) * getPathRating(chunk)
chunk[PLAYER_PHEROMONE] = chunkDeathRating * mMax(
chunk[PLAYER_PHEROMONE] = mMax(
chunk.playerGenerator or 0,
(chunkPlayer / chunkCount) * 0.98
)
chunk[BASE_PHEROMONE] = chunkDeathRating * mMax(
chunk[BASE_PHEROMONE] = mMax(
chunk.playerBaseGenerator or 0,
chunkBase * 0.9
)
@ -627,6 +633,14 @@ function MapUtils.processPheromone(chunk, tick, player)
(chunkEnemy / chunkCount) * 0.9
)
chunk[KAMIKAZE_PHEROMONE] = mMax(
chunkKamikaze,
chunk[PLAYER_PHEROMONE] + chunk[BASE_PHEROMONE]
) * 0.95
chunk[PLAYER_PHEROMONE] = chunk[PLAYER_PHEROMONE] * chunkDeathRating
chunk[BASE_PHEROMONE] = chunk[BASE_PHEROMONE] * chunkDeathRating
local resourcePheromoneGenerator = chunk.resourceGenerator or 0
if (resourcePheromoneGenerator > 0) then
chunkResource = linearInterpolation(resourcePheromoneGenerator, 15000, 20000)

View File

@ -45,6 +45,7 @@ local COMMAND_TIMEOUT = Constants.COMMAND_TIMEOUT
local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local KAMIKAZE_PHEROMONE = Constants.KAMIKAZE_PHEROMONE
local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local HALF_CHUNK_SIZE = Constants.HALF_CHUNK_SIZE
@ -161,6 +162,23 @@ local function scoreSiegeLocation(neighborChunk)
return score, preferred
end
local function scoreSiegeKamikazeLocation(neighborChunk)
local preferred = false
if (
not neighborChunk.playerBaseGenerator
and not neighborChunk.playerGenerator
)
then
preferred = true
end
local settle = neighborChunk[KAMIKAZE_PHEROMONE]
+ neighborChunk[RESOURCE_PHEROMONE] * 0.5
local score = settle - neighborChunk[ENEMY_PHEROMONE]
return score, preferred
end
local function scoreAttackLocation(neighborChunk)
local preferred = false
if (
@ -178,6 +196,22 @@ local function scoreAttackLocation(neighborChunk)
return damage, preferred
end
local function scoreAttackKamikazeLocation(neighborChunk)
local preferred = false
if (
neighborChunk.playerBaseGenerator
or neighborChunk.playerGenerator
)
then
preferred = true
end
local damage = neighborChunk[KAMIKAZE_PHEROMONE]
if preferred then
damage = damage * 2
end
return damage, preferred
end
local function findMovementPosition(surface, position)
return surface.find_non_colliding_position(
"behemoth-biter",
@ -238,7 +272,15 @@ local function addMovementPenalty(squad, chunk)
squad.maxDistance = calculateSettlerMaxDistance()
squad.status = SQUAD_SETTLING
elseif not squad.kamikaze then
squad.kamikaze = true
squad.penalties = {}
else
for entity in pairs(squad.group.members) do
if entity.valid then
entity.destroy()
end
end
squad.group.destroy()
end
end
@ -405,6 +447,9 @@ local function settleMove(squad)
local scoreFunction = scoreResourceLocation
if (squad.type == BASE_AI_STATE_SIEGE) then
scoreFunction = scoreSiegeLocation
if squad.kamikaze then
scoreFunction = scoreSiegeKamikazeLocation
end
end
local squadChunk = squad.chunk
if squadChunk ~= -1 then
@ -549,6 +594,9 @@ local function attackMove(squad)
end
local attackScorer = scoreAttackLocation
if squad.kamikaze then
attackScorer = scoreAttackKamikazeLocation
end
squad.frenzy = (squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100))
local searchPath = scoreNeighbors(

View File

@ -26,6 +26,13 @@ local Universe
-- Constants
local BASE_PHEROMONE = Constants.BASE_PHEROMONE
local PLAYER_PHEROMONE = Constants.PLAYER_PHEROMONE
local RESOURCE_PHEROMONE = Constants.RESOURCE_PHEROMONE
local ENEMY_PHEROMONE = Constants.ENEMY_PHEROMONE
local KAMIKAZE_PHEROMONE = Constants.KAMIKAZE_PHEROMONE
local CHUNK_TICK = Constants.CHUNK_TICK
local MINIMUM_EXPANSION_DISTANCE = Constants.MINIMUM_EXPANSION_DISTANCE
local DEFINES_COMMAND_GROUP = defines.command.group
local DEFINES_COMMAND_WANDER = defines.command.wander
@ -552,6 +559,20 @@ function Upgrade.attempt()
Universe.modAddedTick = game.tick
end
if global.gameVersion < 2 then
global.gameVersion = 2
for _, map in pairs(Universe.maps) do
for _, chunk in pairs(map.processQueue) do
chunk[CHUNK_TICK] = 0
chunk[BASE_PHEROMONE] = 0
chunk[PLAYER_PHEROMONE] = 0
chunk[RESOURCE_PHEROMONE] = 0
chunk[ENEMY_PHEROMONE] = 0
chunk[KAMIKAZE_PHEROMONE] = 0
end
end
end
end
function Upgrade.init(universe)

View File

@ -215,7 +215,8 @@ function tests.exportAiState()
chunk.hiveCount or 0,
chunk.trapCount or 0,
chunk.utilityCount or 0,
global.universe.chunkToVictory[chunk.id] or 0
global.universe.chunkToVictory[chunk.id] or 0,
chunk[constants.KAMIKAZE_PHEROMONE]
}, ",") .. "\n"
end
game.write_file("rampantState.txt", s, false)

View File

@ -58,7 +58,8 @@
hives
traps
utility
vg)
vg
kamikaze)
#:transparent)
(struct Chunk (x
@ -92,7 +93,8 @@
hives
traps
utility
vg)
vg
kamikaze)
#:transparent)
(require threading)
@ -143,7 +145,8 @@
"H:" (~v (Chunk-hives chunk)) "\n"
"T:" (~v (Chunk-traps chunk)) "\n"
"U:" (~v (Chunk-utility chunk)) "\n"
"vg:" (~v (Chunk-vg chunk)) "\n"))
"vg:" (~v (Chunk-vg chunk)) "\n"
"kam:" (~v (Chunk-kamikaze chunk)) "\n")))
(define (normalizeRange xs)
(let* ((sDev (stddev xs))
@ -187,7 +190,8 @@
(H (map Chunk-hives chunks))
(T (map Chunk-traps chunks))
(U (map Chunk-utility chunks))
(vg (map Chunk-vg chunks)))
(vg (map Chunk-vg chunks))
(kamikaze (map Chunk-kamikaze chunks)))
(ChunkRange (MinMax (apply min xs) (apply max xs))
(MinMax (apply min ys) (apply max ys))
@ -220,7 +224,8 @@
(MinMax (apply min H) (apply max H))
(MinMax (apply min T) (apply max T))
(MinMax (apply min U) (apply max U))
(MinMax (apply min vg) (apply max vg)))
(MinMax (apply min vg) (apply max vg))
(normalizeRange kamikaze)
))
(define (readState filePath)

View File

@ -279,7 +279,7 @@
(new radio-box%
[label "Show Layer"]
[choices (list "movement" "base" "player" "resource" "enemy" "passable" "tick" "rating" "nests" "worms" "rally" "retreat" "resourceGen" "playerGen" "deathGen" "scoreResourceKamikaze" "scoreResource" "scoreSiegeKamikaze" "scoreSiege" "scoreAttackKamikaze" "scoreAttack" "pollution" "aNe" "aRNe" "squads" "baseAlign" "hives" "traps" "utility" "vg")]
[choices (list "movement" "base" "player" "resource" "enemy" "passable" "tick" "rating" "nests" "worms" "rally" "retreat" "resourceGen" "playerGen" "deathGen" "scoreResourceKamikaze" "scoreResource" "scoreSiegeKamikaze" "scoreSiege" "scoreAttackKamikaze" "scoreAttack" "pollution" "aNe" "aRNe" "squads" "baseAlign" "hives" "traps" "utility" "vg" "kamikaze")]
[selection 0]
[parent botPanel]
(callback (lambda (radioButton event)