mirror of
https://github.com/veden/Rampant.git
synced 2024-12-26 20:54:12 +02:00
304 lines
9.9 KiB
Lua
304 lines
9.9 KiB
Lua
-- Copyright (C) 2022 veden
|
|
|
|
-- This program is free software: you can redistribute it and/or modify
|
|
-- it under the terms of the GNU General Public License as published by
|
|
-- the Free Software Foundation, either version 3 of the License, or
|
|
-- (at your option) any later version.
|
|
|
|
-- This program is distributed in the hope that it will be useful,
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
-- GNU General Public License for more details.
|
|
|
|
-- You should have received a copy of the GNU General Public License
|
|
-- along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
if movementUtilsG then
|
|
return movementUtilsG
|
|
end
|
|
local movementUtils = {}
|
|
|
|
-- imports
|
|
|
|
local constants = require("Constants")
|
|
local mapUtils = require("MapUtils")
|
|
local mathUtils = require("MathUtils")
|
|
local unitGroupUtils = require("UnitGroupUtils")
|
|
|
|
-- constants
|
|
|
|
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
|
|
|
|
local SQUAD_SETTLING = constants.SQUAD_SETTLING
|
|
|
|
-- imported functions
|
|
|
|
local calculateSettlerMaxDistance = unitGroupUtils.calculateSettlerMaxDistance
|
|
|
|
local canMoveChunkDirection = mapUtils.canMoveChunkDirection
|
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
|
|
|
local tableRemove = table.remove
|
|
local tableInsert = table.insert
|
|
|
|
local distortPosition = mathUtils.distortPosition
|
|
|
|
-- module code
|
|
|
|
function movementUtils.findMovementPosition(surface, position)
|
|
local pos = position
|
|
pos = surface.find_non_colliding_position("chunk-scanner-squad-movement-rampant", pos, 10, 2, false)
|
|
return pos
|
|
end
|
|
|
|
function movementUtils.findMovementPositionEntity(entityName, surface, position)
|
|
local pos = position
|
|
pos = surface.find_non_colliding_position(entityName, pos, 5, 4, true)
|
|
return pos
|
|
end
|
|
|
|
function movementUtils.findMovementPositionDistort(surface, position)
|
|
local pos = position
|
|
pos = surface.find_non_colliding_position("chunk-scanner-squad-movement-rampant", pos, 10, 2, false)
|
|
return distortPosition(pos, 8)
|
|
end
|
|
|
|
function movementUtils.addMovementPenalty(squad, chunk)
|
|
if (chunk == -1) then
|
|
return
|
|
end
|
|
local penalties = squad.penalties
|
|
local penaltyCount = #penalties
|
|
for i=1,penaltyCount do
|
|
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
|
|
local universe = squad.map.universe
|
|
if universe.enabledMigration and
|
|
(universe.builderCount < universe.AI_MAX_BUILDER_COUNT) then
|
|
squad.settler = true
|
|
squad.originPosition.x = squad.group.position.x
|
|
squad.originPosition.y = squad.group.position.y
|
|
squad.maxDistance = calculateSettlerMaxDistance(universe)
|
|
|
|
squad.status = SQUAD_SETTLING
|
|
else
|
|
squad.group.destroy()
|
|
end
|
|
end
|
|
return
|
|
end
|
|
end
|
|
if (penaltyCount == 10) then
|
|
tableRemove(penalties, 10)
|
|
end
|
|
tableInsert(penalties,
|
|
1,
|
|
{ v = 1,
|
|
c = chunk })
|
|
end
|
|
|
|
--[[
|
|
Expects all neighbors adjacent to a chunk
|
|
--]]
|
|
function movementUtils.scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scoreFunction)
|
|
local highestChunk = -1
|
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
local highestDirection
|
|
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
if (neighborChunk ~= -1) then
|
|
if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > highestScore) then
|
|
highestScore = score
|
|
highestChunk = neighborChunk
|
|
highestDirection = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local nextHighestChunk = -1
|
|
local nextHighestScore = highestScore
|
|
local nextHighestDirection
|
|
|
|
if (highestChunk ~= -1) then
|
|
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
|
|
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > nextHighestScore) then
|
|
nextHighestScore = score
|
|
nextHighestChunk = neighborChunk
|
|
nextHighestDirection = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return highestChunk, highestDirection, nextHighestChunk, nextHighestDirection
|
|
end
|
|
|
|
|
|
--[[
|
|
Expects all neighbors adjacent to a chunk
|
|
--]]
|
|
function movementUtils.scoreNeighborsForSettling(map, chunk, neighborDirectionChunks, scoreFunction)
|
|
local highestChunk = -1
|
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
local highestDirection = 0
|
|
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
if (neighborChunk ~= -1) then
|
|
if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > highestScore) then
|
|
highestScore = score
|
|
highestChunk = neighborChunk
|
|
highestDirection = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (chunk ~= -1) and (scoreFunction(map, chunk) > highestScore) then
|
|
return chunk, 0, -1, 0
|
|
end
|
|
|
|
local nextHighestChunk = -1
|
|
local nextHighestScore = highestScore
|
|
local nextHighestDirection = 0
|
|
|
|
if (highestChunk ~= -1) then
|
|
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
|
|
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > nextHighestScore) then
|
|
nextHighestScore = score
|
|
nextHighestChunk = neighborChunk
|
|
nextHighestDirection = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return highestChunk, highestDirection, nextHighestChunk, nextHighestDirection
|
|
end
|
|
|
|
--[[
|
|
Expects all neighbors adjacent to a chunk
|
|
--]]
|
|
function movementUtils.scoreNeighborsForResource(chunk, neighborDirectionChunks, validFunction, scoreFunction, map)
|
|
local highestChunk = -1
|
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
local highestDirection
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
if (neighborChunk ~= -1) and
|
|
canMoveChunkDirection(map, x, chunk, neighborChunk) and
|
|
validFunction(map, chunk, neighborChunk)
|
|
then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > highestScore) then
|
|
highestScore = score
|
|
highestChunk = neighborChunk
|
|
highestDirection = x
|
|
end
|
|
end
|
|
end
|
|
|
|
if (chunk ~= -1) and (scoreFunction(map, chunk) > highestScore) then
|
|
return -1, -1
|
|
end
|
|
|
|
return highestChunk, highestDirection
|
|
end
|
|
|
|
--[[
|
|
Expects all neighbors adjacent to a chunk
|
|
--]]
|
|
function movementUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFunction, map)
|
|
local highestChunk = -1
|
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
local highestDirection
|
|
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
if (neighborChunk ~= -1) then
|
|
if (chunk == -1) or canMoveChunkDirection(map, x, chunk, neighborChunk) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > highestScore) then
|
|
highestScore = score
|
|
highestChunk = neighborChunk
|
|
highestDirection = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local nextHighestChunk = -1
|
|
local nextHighestScore = highestScore
|
|
local nextHighestDirection
|
|
|
|
if (highestChunk ~= -1) then
|
|
neighborDirectionChunks = getNeighborChunks(map, highestChunk.x, highestChunk.y)
|
|
for x=1,8 do
|
|
local neighborChunk = neighborDirectionChunks[x]
|
|
|
|
if ((neighborChunk ~= -1) and ((chunk == -1) or (neighborChunk.id ~= chunk.id)) and
|
|
canMoveChunkDirection(map, x, highestChunk, neighborChunk)) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > nextHighestScore) then
|
|
nextHighestScore = score
|
|
nextHighestChunk = neighborChunk
|
|
nextHighestDirection = x
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if (nextHighestChunk == nil) then
|
|
nextHighestChunk = -1
|
|
end
|
|
|
|
return highestChunk, highestDirection, nextHighestChunk, nextHighestDirection
|
|
end
|
|
|
|
|
|
--[[
|
|
Expects all neighbors adjacent to a chunk
|
|
--]]
|
|
function movementUtils.scoreNeighborsForFormation(neighborChunks, validFunction, scoreFunction, map)
|
|
local highestChunk = -1
|
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
local highestDirection
|
|
for x=1,8 do
|
|
local neighborChunk = neighborChunks[x]
|
|
if (neighborChunk ~= -1) and validFunction(map, neighborChunk) then
|
|
local score = scoreFunction(map, neighborChunk)
|
|
if (score > highestScore) then
|
|
highestScore = score
|
|
highestChunk = neighborChunk
|
|
highestDirection = x
|
|
end
|
|
end
|
|
end
|
|
|
|
return highestChunk, highestDirection
|
|
end
|
|
|
|
movementUtilsG = movementUtils
|
|
return movementUtils
|