mirror of
https://github.com/akaAgar/the-universal-mission-for-dcs-world.git
synced 2025-11-25 19:31:01 +00:00
197 lines
7.5 KiB
Lua
197 lines
7.5 KiB
Lua
-- ====================================================================================
|
|
-- TUM.TERRITORIES - HANDLES THE MISSION SPECIAL ZONES (COALITION TERRITORIES, WATER AND BATTLE ZONES)
|
|
-- ====================================================================================
|
|
-- (local) assignTerritoryToZone(coalitionID, zone)
|
|
-- TUM.territories.getCenter(side)
|
|
-- TUM.territories.getPointOwner(point)
|
|
-- TUM.territories.getRandomPoint(side, surfaceType)
|
|
-- TUM.territories.getSurfaceArea(side)
|
|
-- TUM.territories.onInitialize()
|
|
-- ====================================================================================
|
|
|
|
TUM.territories = {}
|
|
|
|
do
|
|
local coalitionZones = { {}, {} }
|
|
local missionZones = {}
|
|
local waterZones = {}
|
|
|
|
local function addZoneToCoalition(zone, side)
|
|
table.insert(coalitionZones[side], zone)
|
|
local airbases = world.getAirbases()
|
|
|
|
for _,ab in pairs(airbases) do
|
|
local airbasePoint2 = DCSEx.math.vec3ToVec2(ab:getPoint())
|
|
|
|
if DCSEx.zones.isPointInside(zone, airbasePoint2) then
|
|
if ab:getDesc().category ~= Airbase.Category.SHIP then -- Ignore ships
|
|
ab:setCoalition(side)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function TUM.territories.getMissionZones()
|
|
return DCSEx.table.deepCopy(missionZones)
|
|
end
|
|
|
|
function TUM.territories.getWaterZones()
|
|
return DCSEx.table.deepCopy(waterZones)
|
|
end
|
|
|
|
-------------------------------------
|
|
-- Returns the coalition to which belong a given point on the map.
|
|
-- Return coalition.side.NEUTRAL if the point isn't in any coalition territory.
|
|
-- @param point A vec2 or vec3
|
|
-- @return A value from the coalition.side enum
|
|
-------------------------------------
|
|
function TUM.territories.getPointOwner(point)
|
|
for side=1,2 do
|
|
for _,z in ipairs(coalitionZones[side]) do
|
|
if DCSEx.zones.isPointInside(z, point) then
|
|
return side
|
|
end
|
|
end
|
|
end
|
|
|
|
return coalition.side.NEUTRAL
|
|
end
|
|
|
|
function TUM.territories.getTerritoryZones(side)
|
|
return DCSEx.table.deepCopy(coalitionZones[side])
|
|
end
|
|
|
|
function TUM.territories.getTerritoryCenter(side)
|
|
local center = { x = 0, y = 0 }
|
|
|
|
if #coalitionZones[side] == 0 then return center end
|
|
|
|
for _,z in ipairs(coalitionZones[side]) do
|
|
center.x = center.x + z.x
|
|
center.y = center.y + z.y
|
|
end
|
|
|
|
-- TODO: bigger zones should skew the center in their favor
|
|
|
|
center.x = center.x / #coalitionZones[side]
|
|
center.y = center.y / #coalitionZones[side]
|
|
|
|
return center
|
|
end
|
|
|
|
-- function TUM.territories.getCenter(side)
|
|
-- return DCSEx.zones.getCenter(zones[side])
|
|
-- end
|
|
|
|
-- function TUM.territories.getSurfaceArea(side)
|
|
-- return DCSEx.zones.getSurfaceArea(zones[side])
|
|
-- end
|
|
|
|
-- function TUM.territories.getZone(side)
|
|
-- return DCSEx.table.deepCopy(zones[side])
|
|
-- end
|
|
|
|
function TUM.territories.getRandomPointInTerritory(side, surfaceType)
|
|
if #coalitionZones[side] == 0 then return nil end
|
|
|
|
local zone = DCSEx.table.getRandom(coalitionZones[side]) -- TODO: bigger zones should be selected more often
|
|
|
|
return DCSEx.zones.getRandomPointInside(zone, surfaceType)
|
|
end
|
|
|
|
-------------------------------------
|
|
-- Called on mission start up
|
|
-- @return True if started up properly, false if an error happened
|
|
-------------------------------------
|
|
function TUM.territories.onStartUp()
|
|
coalitionZones = { {}, {} }
|
|
missionZones = {}
|
|
waterZones = {}
|
|
|
|
-- Disable autocapture for all bases and give them to the neutral coalition
|
|
for _,ab in pairs(world.getAirbases()) do
|
|
ab:autoCapture(false)
|
|
if ab:getDesc().category ~= Airbase.Category.SHIP then -- Ignore ships
|
|
ab:setCoalition(coalition.side.NEUTRAL)
|
|
end
|
|
end
|
|
|
|
local zones = DCSEx.zones.getAll()
|
|
for _,z in ipairs(zones) do
|
|
if DCSEx.string.startsWith(z.name:lower(), "blufor") then
|
|
addZoneToCoalition(z, coalition.side.BLUE)
|
|
elseif DCSEx.string.startsWith(z.name:lower(), "redfor") then
|
|
addZoneToCoalition(z, coalition.side.RED)
|
|
elseif DCSEx.string.startsWith(z.name:lower(), "water") then
|
|
table.insert(waterZones, z)
|
|
else
|
|
local onlyZonesStartingWith = TUM.administrativeSettings.getValue(TUM.administrativeSettings.ONLY_ZONES_STARTINGWITH)
|
|
if onlyZonesStartingWith and #onlyZonesStartingWith > 0 then
|
|
if type(onlyZonesStartingWith) ~= "table" then
|
|
onlyZonesStartingWith = { onlyZonesStartingWith }
|
|
end
|
|
for _, zonePrefix in ipairs(onlyZonesStartingWith) do
|
|
if DCSEx.string.startsWith(z.name:lower(), zonePrefix:lower()) then
|
|
table.insert(missionZones, z)
|
|
break
|
|
end
|
|
end
|
|
else
|
|
local ignoreZonesStartingWith = TUM.administrativeSettings.getValue(TUM.administrativeSettings.IGNORE_ZONES_STARTINGWITH)
|
|
if ignoreZonesStartingWith then
|
|
if not DCSEx.string.startsWith(z.name:lower(), ignoreZonesStartingWith:lower()) then
|
|
table.insert(missionZones, z)
|
|
end
|
|
else
|
|
table.insert(missionZones, z)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for side=1,2 do
|
|
if #coalitionZones[side] == 0 or #coalition.getAirbases(side) == 0 then
|
|
local name = DCSEx.dcs.getCoalitionAsString(side)
|
|
local zoneName = "BLUFOR"
|
|
if side == 1 then zoneName = "REDFOR" end
|
|
|
|
TUM.log("Coalition "..name.." has no territory zones and/or controls no airfields. Please add zone with a name starting with "..zoneName.." in the mission editor and make sure at least one contains an airbase.", TUM.logger.logLevel.ERROR)
|
|
return false
|
|
end
|
|
end
|
|
|
|
if #missionZones == 0 then
|
|
TUM.log("No mission zones found. Create at least one mission zone in the mission editor.", TUM.logger.logLevel.ERROR)
|
|
return false
|
|
end
|
|
|
|
if #missionZones > 10 then
|
|
TUM.log("Too many mission zones, extra zones removed.", TUM.logger.logLevel.WARNING)
|
|
while #missionZones > 10 do
|
|
table.remove(missionZones, 11)
|
|
end
|
|
end
|
|
|
|
-- zones = {}
|
|
-- zones[coalition.side.BLUE] = DCSEx.zones.getByName("BLUFOR")
|
|
-- zones[coalition.side.RED] = DCSEx.zones.getByName("REDFOR")
|
|
|
|
-- if not zones[coalition.side.BLUE] then
|
|
-- TUM.log("BLUFOR zone not found.", TUM.logger.logLevel.ERROR)
|
|
-- return false
|
|
-- elseif not zones[coalition.side.RED] then
|
|
-- TUM.log("REDFOR zone not found.", TUM.logger.logLevel.ERROR)
|
|
-- return false
|
|
-- end
|
|
|
|
-- -- TODO: square kilometers if "metric system" enabled?
|
|
-- for side=1,2 do
|
|
-- TUM.log(
|
|
-- "Coalition "..DCSEx.dcs.getCoalitionAsString(side):upper().."'s territory is "..
|
|
-- DCSEx.string.toStringThousandsSeparator(math.floor(TUM.territories.getSurfaceArea(side) / 2589988.110336)).." squared miles.")
|
|
-- end
|
|
|
|
return true
|
|
end
|
|
end
|