1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-26 03:20:07 +02:00

unit attack player and location, unit retreat work pretty well. Still needs balancing

This commit is contained in:
veden 2016-08-18 15:14:40 -07:00
parent e410b9e2f5
commit c3d658b4a2
8 changed files with 120 additions and 63 deletions

View File

@ -187,5 +187,6 @@ script.on_event(defines.events.on_chunk_generated, onChunkGenerated)
remote.add_interface("rampant", {
test1 = tests.test1,
test2 = tests.test2,
test3 = tests.test3
test3 = tests.test3,
test4 = tests.test4
})

View File

@ -13,11 +13,21 @@ local attackLocationNeighbors = {1,2,3,4,5,6,7,8}
local attackLocationCommand = {type=defines.command.attack_area,
destination=attackPosition,
radius=constants.HALF_CHUNK_SIZE,
distraction=defines.distraction.by_damage}
distraction=defines.distraction.by_anything}
local attackObjectCommand = {type=defines.command.attack,
target=1,
distraction=defines.distraction.by_anything}
local attackPlayerCommand = {type=defines.command.attack,
target=1}
local nearestAreaBox = {{1,2},
{3,4}}
local nearestTable = {area=nearestAreaBox,
force="player",
limit=1}
local mRandom = math.random
function aiAttack.squadAttackLocation(regionMap, surface, natives)
@ -35,6 +45,7 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
local group_states = factorio_defined.group_state
local mathRandom = mRandom
-- local getNeighborChunks = mapUtils.getCardinalChunks
local getNeighborChunks = mapUtils.getNeighborChunks
local positionToChunk = mapUtils.positionToChunkOffset
@ -44,8 +55,14 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
local group = squad.group
local squadStatus = squad.status
if group.valid and ((squadStatus == SQUAD_RAIDING) or (squadStatus == SQUAD_SUICIDE_RAID)) then
if (group.state == group_states.finished) or (group.state == group_states.gathering) then
local cX, cY = positionToChunk(group.position)
if ((group.state == group_states.finished) or (group.state == group_states.gathering) or (group.state == group_states.moving)) and (squad.cycles == 0) then
local cX, cY
-- if (squad.cX == nil) then
cX, cY = positionToChunk(group.position)
-- else
-- cX = squad.cX
-- cY = squad.cY
-- end
getNeighborChunks(regionMap, cX, cY, attackLocationNeighbors)
local attackChunk
local attackScore = -MAGIC_MAXIMUM_NUMBER
@ -56,8 +73,8 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
if (neighborChunk ~= nil) then
attackPosition.x = neighborChunk.pX
attackPosition.y = neighborChunk.pY
local damageScore = surface.get_pollution(attackPosition) + neighborChunk[PLAYER_BASE_PHEROMONE] + neighborChunk[PLAYER_PHEROMONE] --+ neighborChunk[PLAYER_DEFENSE_PHEROMONE]
local avoidScore = neighborChunk[DEATH_PHEROMONE] --+ neighborChunk[ENEMY_BASE_GENERATOR] + neighborChunk[ENEMY_BASE_PHEROMONE]
local damageScore = surface.get_pollution(attackPosition) + neighborChunk[PLAYER_BASE_PHEROMONE] + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[constants.PLAYER_DEFENSE_GENERATOR]
local avoidScore = neighborChunk[DEATH_PHEROMONE] + neighborChunk[ENEMY_BASE_GENERATOR] + neighborChunk[ENEMY_BASE_PHEROMONE] --
local score = damageScore - avoidScore
if (score > attackScore) then
attackScore = score
@ -70,21 +87,40 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
if (attackChunk ~= nil) then
-- print("==")
-- print (attackDirection, cX, cY)
-- utils.positionDirectionToChunkCorner(attackDirection, attackChunk, attackPosition)
attackPosition.x = attackChunk.pX + HALF_CHUNK_SIZE
attackPosition.y = attackChunk.pY + HALF_CHUNK_SIZE
group.set_command(attackLocationCommand)
group.start_moving()
end
elseif (group.state == group_states.attacking_distraction) and (mathRandom() < 0.3) then
local playerTarget = surface.find_nearest_enemy({position=group.position,
max_distance=CHUNK_SIZE,
force="enemy"})
if (playerTarget ~= nil) then
group.set_command({type=defines.command.attack,
target=playerTarget})
-- local target
if (attackChunk[constants.PLAYER_BASE_GENERATOR] == 0) or (attackChunk[constants.PLAYER_DEFENSE_GENERATOR] == 0) then
-- nearestAreaBox[1][1] = group.position.x - CHUNK_SIZE
-- nearestAreaBox[1][2] = group.position.y - CHUNK_SIZE
-- nearestAreaBox[2][1] = group.position.x + CHUNK_SIZE
-- nearestAreaBox[2][2] = group.position.y + CHUNK_SIZE
-- target = surface.find_entities_filtered(nearestTable)
-- if (#target == 1) and (target[1].prototype.max_health ~= 0) then
-- print(target[1].name)
-- attackObjectCommand.target = target[1]
-- group.set_command(attackObjectCommand)
-- end
-- if (target == nil) then
-- utils.positionDirectionToChunkCorner(attackDirection, attackChunk, attackPosition)
attackPosition.x = attackChunk.pX + HALF_CHUNK_SIZE
attackPosition.y = attackChunk.pY + HALF_CHUNK_SIZE
squad.cycles = 4
squad.cX = attackChunk.cX
squad.cY = attackChunk.cY
group.set_command(attackLocationCommand)
-- end
group.start_moving()
end
end
-- elseif (group.state == group_states.attacking_distraction) and (mathRandom() < 0.3) then
-- local playerTarget = surface.find_nearest_enemy({position=group.position,
-- max_distance=CHUNK_SIZE,
-- force="enemy"})
-- if (playerTarget ~= nil) then
-- group.set_command({type=defines.command.attack,
-- target=playerTarget})
-- end
end
end
end

View File

@ -48,7 +48,7 @@ function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
retreatPosition.x = neighborChunk.pX
retreatPosition.y = neighborChunk.pY
local dangerScore = neighborChunk[DEATH_PHEROMONE] + surface.get_pollution(retreatPosition) + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_PHEROMONE] - neighborChunk[ENEMY_BASE_PHEROMONE] + neighborChunk[ENEMY_BASE_GENERATOR]
local dangerScore = neighborChunk[DEATH_PHEROMONE] + surface.get_pollution(retreatPosition) + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_PHEROMONE] - neighborChunk[ENEMY_BASE_PHEROMONE] + (neighborChunk[ENEMY_BASE_GENERATOR] * 5)
if (dangerScore < exitScore) then
exitScore = dangerScore
exitPath = neighborChunk
@ -60,7 +60,14 @@ function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
utils.positionDirectionToChunkCorner(exitDirection, exitPath, retreatPosition)
-- in order for units in a group attacking to retreat, we have to create a new group and give the command to join
-- to each unit
-- retreatPosition.x = exitPath.pX + constants.HALF_CHUNK_SIZE
-- retreatPosition.y = exitPath.pY + constants.HALF_CHUNK_SIZE
if (squad ~= nil) and (squad.cX ~= nil) then
local chunk = mapUtils.getChunkByIndex(regionMap, squad.cX, squad.cY)
chunk[constants.DEATH_PHEROMONE] = chunk[constants.DEATH_PHEROMONE] + constants.DEATH_PHEROMONE_GENERATOR_AMOUNT
end
local newSquad = unitGroupUtils.findNearBySquad(natives,
retreatPosition,
constants.HALF_CHUNK_SIZE,

View File

@ -10,6 +10,7 @@ constants.RETREAT_LEVEL_DEATH_PHEROMONE = 15000
constants.CHUNK_SIZE = 32
constants.HALF_CHUNK_SIZE = constants.CHUNK_SIZE / 2
constants.QUARTER_CHUNK_SIZE = constants.HALF_CHUNK_SIZE / 2
constants.NORTH_SOUTH = 1
constants.EAST_WEST = 2
@ -17,13 +18,13 @@ constants.EAST_WEST = 2
constants.MOVEMENT_PHEROMONE_GENERATOR_AMOUNT = 150
constants.ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT = 35
constants.DEATH_PHEROMONE_GENERATOR_AMOUNT = 400
constants.DEATH_PHEROMONE_GENERATOR_AMOUNT = 25
constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT = 75
-- pheromone diffusion amounts
constants.STANDARD_PHERONOME_DIFFUSION_AMOUNT = 0.03
constants.DEATH_PHEROMONE_DIFFUSION_AMOUNT = 0.03
constants.DEATH_PHEROMONE_DIFFUSION_AMOUNT = 0.00
-- chunk attributes
@ -59,30 +60,30 @@ constants.SQUAD_SUICIDE_RAID = 9 -- when player stuff is close with no retreat
constants.buildingPheromones = {}
-- constants.buildingPheromones["container"] = 1
-- constants.buildingPheromones["storage-tank"] = 1
-- constants.buildingPheromones["transport-belt"] = 1
constants.buildingPheromones["generator"] = 35
-- constants.buildingPheromones["electric-pole"] = 1
constants.buildingPheromones["pump"] = 10
constants.buildingPheromones["offshore-pump"] = 10
constants.buildingPheromones["generator"] = 30
constants.buildingPheromones["pump"] = 4
constants.buildingPheromones["offshore-pump"] = 4
-- constants.buildingPheromones["constant-combinator"] = 1
-- constants.buildingPheromones["train-stop"] = 2
-- constants.buildingPheromones["rail-signal"] = 1
constants.buildingPheromones["electric-pole"] = 2
constants.buildingPheromones["transport-belt"] = 2
constants.buildingPheromones["accumulator"] = 20
constants.buildingPheromones["solar-panel"] = 10
constants.buildingPheromones["solar-panel"] = 16
constants.buildingPheromones["boiler"] = 30
constants.buildingPheromones["assembling-machine"] = 25
constants.buildingPheromones["assembling-machine"] = 24
constants.buildingPheromones["roboport"] = 20
constants.buildingPheromones["beacon"] = 15
constants.buildingPheromones["furnace"] = 20
constants.buildingPheromones["beacon"] = 20
constants.buildingPheromones["furnace"] = 30
constants.buildingPheromones["mining-drill"] = 40
-- player defense pheromones
constants.defensePheromones = {}
constants.defensePheromones["ammo-turret"] = 10
constants.defensePheromones["electric-turret"] = 10
constants.defensePheromones["fluid-turret"] = 15
constants.defensePheromones["turret"] = 5
constants.defensePheromones["ammo-turret"] = 5
constants.defensePheromones["electric-turret"] = 7.5
constants.defensePheromones["fluid-turret"] = 10
constants.defensePheromones["turret"] = 3
-- enemy units

View File

@ -12,18 +12,15 @@ local nearestTable = {position=nearestEnemyPosition,
function pheromoneUtils.deathScent(regionMap, surface, x, y, amount)
-- nearestEnemyPosition.x = x
-- nearestEnemyPosition.y = y
-- local playerKiller = surface.find_nearest_enemy(nearestTable)
-- if (playerKiller ~= nil) then
-- local chunk = regionMap[mathFloor(playerKiller.position.x * 0.03125)]
-- if (chunk ~= nil) then
-- chunk = chunk[mathFloor(playerKiller.position.y * 0.03125)]
-- if (chunk ~= nil) then
-- chunk[DEATH_PHEROMONE] = chunk[DEATH_PHEROMONE] + amount
-- end
-- end
-- end
nearestEnemyPosition.x = x
nearestEnemyPosition.y = y
local playerKiller = surface.find_nearest_enemy(nearestTable)
if (playerKiller ~= nil) then
local chunk = mapUtils.getChunkByPosition(regionMap, x, y)
if (chunk ~= nil) then
chunk[constants.DEATH_PHEROMONE] = chunk[constants.DEATH_PHEROMONE] + amount
end
end
local chunk = mapUtils.getChunkByPosition(regionMap, x, y)
if (chunk ~= nil) then
@ -41,7 +38,7 @@ end
function pheromoneUtils.playerBaseScent(regionMap, surface, natives, chunk, neighbors)
local baseScore = chunk[constants.PLAYER_BASE_GENERATOR]
if (baseScore > 0) then
chunk[constants.PLAYER_BASE_PHEROMONE] = chunk[constants.PLAYER_BASE_PHEROMONE] + baseScore
chunk[constants.PLAYER_BASE_PHEROMONE] = chunk[constants.PLAYER_BASE_PHEROMONE] + (baseScore * 2)
end
end
@ -78,10 +75,10 @@ function pheromoneUtils.processPheromone(regionMap, surface, natives, chunk, nei
local persistence
if (x == DEATH_PHEROMONE) then
diffusionAmount = DEATH_PHEROMONE_DIFFUSION_AMOUNT
persistence = 0.99
persistence = 0.98
else
diffusionAmount = STANDARD_PHERONOME_DIFFUSION_AMOUNT
persistence = 0.98
persistence = 0.95
end
local totalDiffused = 0
for i=1,4 do

View File

@ -116,6 +116,8 @@ function unitGroupUtils.regroupSquads(natives)
table.remove(squads, i)
else
if (squad.status == SQUAD_RETREATING) and (squad.cycles == 0) then
squad.cX = nil
squad.cY = nil
squad.status = SQUAD_GUARDING
elseif (squad.cycles > 0) then
squad.cycles = squad.cycles - 1

View File

@ -17,29 +17,29 @@ end
function utils.positionDirectionToChunkCorner(direction, chunk, position)
-- local position = {}
if (direction == 1) then
position.x = chunk.pX
position.y = chunk.pY
position.x = chunk.pX + constants.QUARTER_CHUNK_SIZE
position.y = chunk.pY + constants.QUARTER_CHUNK_SIZE
elseif (direction == 2) then
position.x = chunk.pX + constants.HALF_CHUNK_SIZE
position.y = chunk.pY
position.y = chunk.pY + constants.QUARTER_CHUNK_SIZE
elseif (direction == 3) then
position.x = chunk.pX + constants.CHUNK_SIZE
position.y = chunk.pY
position.x = chunk.pX + constants.HALF_CHUNK_SIZE + constants.QUARTER_CHUNK_SIZE
position.y = chunk.pY + constants.QUARTER_CHUNK_SIZE
elseif (direction == 4) then
position.x = chunk.pX
position.x = chunk.pX + constants.QUARTER_CHUNK_SIZE
position.y = chunk.pY + constants.HALF_CHUNK_SIZE
elseif (direction == 5) then
position.x = chunk.pX + constants.CHUNK_SIZE
position.x = chunk.pX + constants.HALF_CHUNK_SIZE + constants.QUARTER_CHUNK_SIZE
position.y = chunk.pY + constants.HALF_CHUNK_SIZE
elseif (direction == 6) then
position.x = chunk.pX
position.y = chunk.pY + constants.CHUNK_SIZE
position.x = chunk.pX + constants.QUARTER_CHUNK_SIZE
position.y = chunk.pY + constants.HALF_CHUNK_SIZE + constants.QUARTER_CHUNK_SIZE
elseif (direction == 7) then
position.x = chunk.pX + constants.HALF_CHUNK_SIZE
position.y = chunk.pY + constants.CHUNK_SIZE
position.y = chunk.pY + constants.HALF_CHUNK_SIZE + constants.QUARTER_CHUNK_SIZE
elseif (direction == 8) then
position.x = chunk.pX + constants.CHUNK_SIZE
position.y = chunk.pY + constants.CHUNK_SIZE
position.x = chunk.pX + constants.HALF_CHUNK_SIZE + constants.QUARTER_CHUNK_SIZE
position.y = chunk.pY + constants.HALF_CHUNK_SIZE + constants.QUARTER_CHUNK_SIZE
end
return position
end

View File

@ -51,4 +51,17 @@ function tests.test3()
print("--")
end
function tests.test4()
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
local entity = game.surfaces[1].find_nearest_enemy({position={chunkX, chunkY},
max_distance=constants.CHUNK_SIZE,
force = "enemy"})
if (entity ~= nil) then
print(entity.name)
end
print("--")
end
return tests