mirror of
https://github.com/akaAgar/the-universal-mission-for-dcs-world.git
synced 2025-11-25 19:31:01 +00:00
They are defined in `TUM.administrativeSettings`. They have a default value in `TUM.administrativeSettingsDefaultValues`. They can be overloaded either: - by script (with a call like `TUM.administrativeSettings.setValue(TUM.administrativeSettings.USE_SPECIFIC_RADIOMENU, true)` - by a parameter named after the setting in a trigger zone called `TUM_Administrative_Settings` Settings that are already implemented: - USE_SPECIFIC_RADIOMENU: use a specific radio menu for the mission commands, or use the main one? - INITIALIZE_AUTOMATICALLY: automatically initialize the mission when the script is loaded. If false, you must call TUM.initialize() manually. - IGNORE_ZONES_STARTINGWITH: if set, ignore all zones starting with this string. This is useful to avoid conflicts with other scripts that use the same zone names. - ONLY_ZONES_STARTINGWITH: if set, only adds zones starting with this string. This is useful to avoid conflicts with other scripts that use the same zone names.
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.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.logLevel.ERROR)
|
|
return false
|
|
end
|
|
|
|
if #missionZones > 10 then
|
|
TUM.log("Too many mission zones, extra zones removed.", TUM.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.logLevel.ERROR)
|
|
-- return false
|
|
-- elseif not zones[coalition.side.RED] then
|
|
-- TUM.log("REDFOR zone not found.", TUM.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
|