Closed tillmas closed 1 year ago
table.sort(distances)
. distances
appears to be an associative array (of the form { [non-sequential integer key]: value }), so the sort function doesn't know what it's sorting.Instead the distances array should contain pairs of the form [zoneName, distanceToReferenceUnit], then use the sorting function
function(a, b)
return a[2] < b[2]
end
For a complete example:
local zoneList = {}
local output = {}
for _, z in pairs(mist.DBs.zonesByName) do
zoneList[#zoneList+1] = z
end
local distances = {}
for i = 1, #zoneList do
local zoneCoords = mist.getRandomPointInZone(zoneList[i].name, 0)
local bluePlatoons = {"[g]C1-1", "[g]C2-1"}
local refCoords = mist.getAvgPos(mist.makeUnitTable(bluePlatoons))
distances[i] = {zoneList[i].name, mist.utils.get2DDist(refCoords, zoneCoords)}
end
table.sort(distances, function(a, b) return a[2] < b[2] end)
for i = 1, 3 do
output[i] = distances[i][1]
end
return output
-- output
--[
-- "1-7",
-- "1-5",
-- "1-10"
--]
I'll work a bit on structuring that, but basically I think it works out to be something like:
-- returns [numZones] zones from a list of [targetZones] that are closes to a specified [referencePoint]
function assignMission(targetZones, referencePoint, numZones)
which we can call with the structure...
-- determine zone states
local attackZones = {}
local defenseZones = {}
-- something that sorts out zone control states
-- for each battalion commander...
-- assign attack missions
local attackMissions = assignMission(attackZones, referencePoint, numAttackZones)
-- assign defense missions
local defenseMissions = assignMission(defenseZones, referencePoint, numDefenseZones)
Then the commander logic can work out force allocation for attack and defense separately
Am I correct that this bit of code is simply creating a list of all of the zones specified in the mission editor? Likely the end of this is the right place to pick the arbitrary number of zones over which to fight.
local zoneList = {}
local output = {}
for _, z in pairs(mist.DBs.zonesByName) do
zoneList[#zoneList+1] = z
end
I wonder if splitting the function at this point makes sense. We are going to run everything above this once per mission load, and everything below this once per commander.
Yes, correct. The example I provided needs to be organized. Putting my two examples together results in something like what's shown below. This may not be the correct logic, but it should be (close to) the right overall structure.
-- 1. Zone Control
-- this could be done a little easier/simpler with the included zone handling in MIST
local zonePrefix = "1-" -- string prefix used to select zones
local numTargetZones = 10 -- set by the mission designer
local zoneList = {} -- list of all zones the script might select as a target
local targetZones = {} -- list of zones selected as targets
-- 1a. Get all zones with specified prefix in name
local zoneList = getAllZonesWithPrefix(zonePrefix)
-- 1b. Choose zones of interest for the mission
local targetZones = getTargetZones(zoneList, numTargetZones)
-- determine zone states
local attackZones = {}
local defenseZones = {}
-- something that sorts out zones by control status
for z in targetZones do
if z.controlledBy == "blue" then
defenseZones[#defenseZones+1] = z.name
else
attackZones[#attackZones +1] = z.name
end
end
-- for each battalion commander...
-- assign attack missions
local attackMissions = assignMission(attackZones, referencePoint, numAttackZones)
-- assign defense missions
local defenseMissions = assignMission(defenseZones, referencePoint, numDefenseZones)
I'm going to close this issue because it has really split into two non-related things. For now, I replaced the zoneList section of the code with your much better code. I totally agree with the first half of your design above, I hadn't thought of the need for a prefix or label on the fighting zones to separate them from normal trigger zones - that is a great catch.
I am trying to get this function to take the inputs, sort the unfriendly target zones by distance from the reference unit, and then push out the n closest. It is throwing an error right now, and I am having a hard time troubleshooting it. I think that there must be a simpler way to do it. Perhaps splitting the function up into attack and defend.
function assignMission(TargetZones,UnfriendlyZones,FriendlyZones,ReferenceUnits,numAttack,numDefend)
end