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:
parent
e410b9e2f5
commit
c3d658b4a2
@ -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
|
||||
})
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
13
tests.lua
13
tests.lua
@ -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
|
Loading…
x
Reference in New Issue
Block a user