Cap rework (#48)
- Refactored all CAP classes. - Improved timing - Zones are now not tied to MissionStages - CAPROUTE_<routeID>_<free> - routeID is now what is used in the naming convention. - Units taxi back to their spawn parking space and rearm there. (Units destroyed while in the Rearming or Repairing state are not taken into account)
This commit is contained in:
+104
-10
@@ -36,15 +36,15 @@ do -- INIT UTIL
|
||||
|
||||
---@param orig table
|
||||
---@return table copy
|
||||
function UTIL.copyTable(orig)
|
||||
function UTIL.deepCopyTable(orig)
|
||||
local orig_type = type(orig)
|
||||
local copy
|
||||
if orig_type == 'table' then
|
||||
copy = {}
|
||||
for orig_key, orig_value in next, orig, nil do
|
||||
copy[UTIL.copyTable(orig_key)] = UTIL.copyTable(orig_value)
|
||||
copy[UTIL.deepCopyTable(orig_key)] = UTIL.deepCopyTable(orig_value)
|
||||
end
|
||||
setmetatable(copy, UTIL.copyTable(getmetatable(orig)))
|
||||
setmetatable(copy, UTIL.deepCopyTable(getmetatable(orig)))
|
||||
else -- number, string, boolean, etc
|
||||
copy = orig
|
||||
end
|
||||
@@ -88,15 +88,15 @@ do -- INIT UTIL
|
||||
table.insert(sb, string.rep(" ", indent)) -- indent it
|
||||
if type(value) == "table" and not done[value] then
|
||||
done[value] = true
|
||||
table.insert(sb, key .. " = {\n");
|
||||
table.insert(sb, "[\"" ..key .. "\"]" .. " = {\n");
|
||||
table.insert(sb, table_print(value, indent + 2, done))
|
||||
table.insert(sb, string.rep(" ", indent)) -- indent it
|
||||
table.insert(sb, "}\n");
|
||||
table.insert(sb, "},\n");
|
||||
elseif "number" == type(key) then
|
||||
table.insert(sb, string.format("\"%s\"\n", tostring(value)))
|
||||
table.insert(sb, string.format("\"%s\",\n", tostring(value)))
|
||||
else
|
||||
table.insert(sb, string.format(
|
||||
"%s = \"%s\"\n", tostring(key), tostring(value)))
|
||||
"[\"%s\"] = \"%s\",\n", tostring(key), tostring(value)))
|
||||
end
|
||||
end
|
||||
return table.concat(sb)
|
||||
@@ -172,6 +172,54 @@ do -- INIT UTIL
|
||||
return (vec.x ^ 2 + vec.y ^ 2 + vec.z ^ 2) ^ 0.5
|
||||
end
|
||||
|
||||
---@param vec Vec3
|
||||
---@return Vec3
|
||||
function UTIL.vectorNormalize(vec)
|
||||
local magnitude = UTIL.vectorMagnitude(vec)
|
||||
if magnitude == 0 then
|
||||
return { x = 0, y = 0, z = 0 }
|
||||
end
|
||||
return { x = vec.x / magnitude, y = vec.y / magnitude, z = vec.z / magnitude }
|
||||
end
|
||||
|
||||
---@param vec Vec2
|
||||
---@param direction number @in degrees
|
||||
---@param distance number
|
||||
---@return Vec2
|
||||
function UTIL.vectorMove(vec, direction, distance)
|
||||
local rad = math.rad(direction)
|
||||
local x = vec.x + (math.cos(rad) * distance)
|
||||
local y = vec.y + (math.sin(rad) * distance)
|
||||
|
||||
return { x = x, y = y}
|
||||
end
|
||||
|
||||
---comment
|
||||
---@param vec1 Vec2
|
||||
---@param vec2 Vec2
|
||||
---@return number in degrees
|
||||
function UTIL.vectorHeadingFromTo(vec1, vec2)
|
||||
local dx = vec2.x - vec1.x
|
||||
local dy = vec2.y - vec1.y
|
||||
local heading = math.deg(math.atan2(dy, dx))
|
||||
if heading < 0 then
|
||||
heading = heading + 360
|
||||
end
|
||||
return heading
|
||||
end
|
||||
|
||||
|
||||
|
||||
---@param vec1 Vec3
|
||||
---@param vec2 Vec3
|
||||
---@return number alignment a number in range [-1,1]. > 0 same direction. < 0 opposite direction
|
||||
function UTIL.vectorAlignment(vec1, vec2)
|
||||
local vec1Norm = UTIL.vectorNormalize(vec1)
|
||||
local vec2Norm = UTIL.vectorNormalize(vec2)
|
||||
|
||||
return ((vec1Norm.x * vec2Norm.x) + (vec1Norm.y * vec2Norm.y) + (vec1Norm.z * vec2Norm.z))
|
||||
end
|
||||
|
||||
local function isInComplexPolygon(polygon, x, y)
|
||||
local function getEdges(poly)
|
||||
local result = {}
|
||||
@@ -706,7 +754,7 @@ do -- INIT DCS_UTIL
|
||||
---@param groupName string
|
||||
function DCS_UTIL.IsGroupStatic(groupName)
|
||||
if DCS_UTIL.__miz_groups[groupName] then
|
||||
return DCS_UTIL.__miz_groups[groupName].category == DCS_UTIL.GroupCategory.STATIC;
|
||||
return DCS_UTIL.__miz_groups[groupName].category == DCS_UTIL.GroupCategory.STATIC
|
||||
end
|
||||
|
||||
return StaticObject.getByName(groupName) ~= nil
|
||||
@@ -1255,9 +1303,10 @@ do -- INIT DCS_UTIL
|
||||
---@param route table? route of the group. If nil wil be the default route.
|
||||
---@param uncontrolled boolean? Sets the group to be uncontrolled on spawn
|
||||
---@param countryId CountryID? Overwrites the country
|
||||
---@param emptyLoadouts boolean? If true, the group will spawn with empty loadouts
|
||||
---@return table? new_group the Group class that was spawned
|
||||
---@return boolean? isStatic whether the group is a static or not
|
||||
function DCS_UTIL.SpawnGroupTemplate(groupName, location, route, uncontrolled, countryId)
|
||||
function DCS_UTIL.SpawnGroupTemplate(groupName, location, route, uncontrolled, countryId, emptyLoadouts)
|
||||
if groupName == nil then
|
||||
return nil, nil
|
||||
end
|
||||
@@ -1280,7 +1329,7 @@ do -- INIT DCS_UTIL
|
||||
return object, true
|
||||
end
|
||||
else
|
||||
local spawn_template = template.group_template
|
||||
local spawn_template = Spearhead.Util.deepCopyTable(template.group_template)
|
||||
if location ~= nil then
|
||||
local x_offset
|
||||
if location.x ~= nil then x_offset = spawn_template.x - location.x end
|
||||
@@ -1298,6 +1347,26 @@ do -- INIT DCS_UTIL
|
||||
end
|
||||
end
|
||||
|
||||
if spawn_template.units then
|
||||
for _, unit in pairs(spawn_template.units) do
|
||||
if unit["parking"] then
|
||||
unit["parking_landing"] = unit["parking"]
|
||||
end
|
||||
|
||||
if unit["parking_id"] then
|
||||
unit["parking_landing_id"] = unit["parking_id"]
|
||||
end
|
||||
end
|
||||
|
||||
if emptyLoadouts == true then
|
||||
for _, unit in pairs(spawn_template.units) do
|
||||
if unit["payload"] and unit["payload"]["pylons"] then
|
||||
unit["payload"]["pylons"] = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if route ~= nil then
|
||||
spawn_template.route = route
|
||||
end
|
||||
@@ -1305,6 +1374,7 @@ do -- INIT DCS_UTIL
|
||||
if uncontrolled ~= nil then
|
||||
spawn_template.uncontrolled = uncontrolled
|
||||
end
|
||||
|
||||
local country = countryId or template.country_id
|
||||
local new_group = coalition.addGroup(country, template.category, spawn_template)
|
||||
return new_group, false
|
||||
@@ -1320,6 +1390,30 @@ do -- INIT DCS_UTIL
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function DCS_UTIL.NeedsRTBInTen(groupName, fuelOffset)
|
||||
|
||||
local isBingo = Spearhead.DcsUtil.IsBingoFuel(groupName, fuelOffset)
|
||||
if isBingo then return true end
|
||||
|
||||
local aliveUnits = 0
|
||||
local group = Group.getByName(groupName)
|
||||
if group then
|
||||
for _ , unit in pairs(group:getUnits()) do
|
||||
if unit and unit:isExist() == true and unit:inAir() == true then
|
||||
aliveUnits = aliveUnits + 1
|
||||
end
|
||||
end
|
||||
|
||||
if aliveUnits / group:getInitialSize() <= 0.5 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
---@return boolean
|
||||
function DCS_UTIL.IsBingoFuel(groupName, offset)
|
||||
if offset == nil then offset = 0 end
|
||||
local bingoSetting = 0.20
|
||||
|
||||
Reference in New Issue
Block a user