Merge branch 'FF/Ops' into FF/OpsDev

This commit is contained in:
Frank 2022-05-17 23:00:29 +02:00
commit 23733bb1a6
13 changed files with 669 additions and 252 deletions

View File

@ -874,6 +874,11 @@ do -- COORDINATE
-- Get the vector from A to B
local vec=UTILS.VecSubstract(ToCoordinate, self)
if f>1 then
local norm=UTILS.VecNorm(vec)
f=Fraction/norm
end
-- Scale the vector.
vec.x=f*vec.x
@ -883,7 +888,9 @@ do -- COORDINATE
-- Move the vector to start at the end of A.
vec=UTILS.VecAdd(self, vec)
-- Create a new coordiante object.
local coord=COORDINATE:New(vec.x,vec.y,vec.z)
return coord
end
@ -2769,8 +2776,9 @@ do -- COORDINATE
-- @param #COORDINATE FromCoordinate The coordinate to measure the distance and the bearing from.
-- @param #boolean Bogey Add "Bogey" at the end if true (not yet declared hostile or friendly)
-- @param #boolean Spades Add "Spades" at the end if true (no IFF/VID ID yet known)
-- @param #boolean SSML Add SSML tags speaking aspect as 0 1 2 and "brah" instead of BRAA
-- @return #string The BRAA text.
function COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades)
function COORDINATE:ToStringBRAANATO(FromCoordinate,Bogey,Spades,SSML)
-- Thanks to @Pikey
local BRAANATO = "Merged."
@ -2791,22 +2799,39 @@ do -- COORDINATE
local track = UTILS.BearingToCardinal(bearing) or "North"
if rangeNM > 3 then
if aspect == "" then
BRAANATO = string.format("BRA, %03d, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
if SSML then
if aspect == "" then
BRAANATO = string.format("brah <say-as interpret-as='characters'>%03d</say-as>, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
else
BRAANATO = string.format("brah <say-as interpret-as='characters'>%03d</say-as>, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
end
if Bogey and Spades then
BRAANATO = BRAANATO..", Bogey, Spades."
elseif Bogey then
BRAANATO = BRAANATO..", Bogey."
elseif Spades then
BRAANATO = BRAANATO..", Spades."
else
BRAANATO = BRAANATO.."."
end
else
BRAANATO = string.format("BRAA, %03d, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
end
if Bogey and Spades then
BRAANATO = BRAANATO..", Bogey, Spades."
elseif Bogey then
BRAANATO = BRAANATO..", Bogey."
elseif Spades then
BRAANATO = BRAANATO..", Spades."
else
BRAANATO = BRAANATO.."."
if aspect == "" then
BRAANATO = string.format("BRA %03d, %d miles, Angels %d, Track %s",bearing, rangeNM, alt, track)
else
BRAANATO = string.format("BRAA %03d, %d miles, Angels %d, %s, Track %s",bearing, rangeNM, alt, aspect, track)
end
if Bogey and Spades then
BRAANATO = BRAANATO..", Bogey, Spades."
elseif Bogey then
BRAANATO = BRAANATO..", Bogey."
elseif Spades then
BRAANATO = BRAANATO..", Spades."
else
BRAANATO = BRAANATO.."."
end
end
end
return BRAANATO
end

View File

@ -1005,32 +1005,65 @@ end
-- @param #number Formation Formation of the group.
function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
-- Debug info.
local text=string.format("Update route state=%s: n=%s, N=%s, Speed=%s, Formation=%s", self:GetState(), tostring(n), tostring(N), tostring(Speed), tostring(Formation))
self:T(self.lid..text)
-- Update route from this waypoint number onwards.
n=n or self:GetWaypointIndexNext(self.adinfinitum)
-- Max index.
N=N or #self.waypoints
N=N or #self.waypoints
N=math.min(N, #self.waypoints)
-- Debug info.
local text=string.format("Update route state=%s: n=%s, N=%s, Speed=%s, Formation=%s", self:GetState(), tostring(n), tostring(N), tostring(Speed), tostring(Formation))
self:T(self.lid..text)
-- Waypoints.
-- Waypoints including addtional wp onroad.
local waypoints={}
local formationlast=nil
for i=n, #self.waypoints do
-- Next waypoint.
local wp=self.waypoints[n] --Ops.OpsGroup#OPSGROUP.Waypoint
-- Formation at the current position.
local formation0=wp.action
if formation0==ENUMS.Formation.Vehicle.OnRoad then
if wp.roadcoord then
if wp.roaddist>10 then
formation0=ENUMS.Formation.Vehicle.OffRoad
end
else
formation0=ENUMS.Formation.Vehicle.OffRoad
end
end
-- Current point.
local current=self:GetCoordinate():WaypointGround(UTILS.MpsToKmph(self.speedWp), formation0) --ENUMS.Formation.Vehicle.OffRoad)
table.insert(waypoints, 1, current)
-- Loop over waypoints.
for j=n, N do
-- Index of previous waypoint.
local i=j-1
-- If we go to the first waypoint j=1 ==> i=0, so we take the last waypoint passed. E.g. when adinfinitum and passed final waypoint.
if i==0 then
i=self.currentwp
end
-- Next waypoint.
local wp=UTILS.DeepCopy(self.waypoints[i]) --Ops.OpsGroup#OPSGROUP.Waypoint
local wp=UTILS.DeepCopy(self.waypoints[j]) --Ops.OpsGroup#OPSGROUP.Waypoint
-- Previous waypoint. Index is i and not i-1 because we added the current position.
local wp0=self.waypoints[i] --Ops.OpsGroup#OPSGROUP.Waypoint
--local text=string.format("FF Update: i=%d, wp[i]=%s, wp[i-1]=%s", i, wp.action, wp0.action)
--env.info(text)
-- Speed.
if Speed then
wp.speed=UTILS.KnotsToMps(tonumber(Speed))
else
-- Take default waypoint speed. But make sure speed>0 if patrol ad infinitum.
if wp.speed<0.1 then --self.adinfinitum and
-- Take default waypoint speed. But make sure speed>0 if patrol ad infinitum.
if wp.speed<0.1 then
wp.speed=UTILS.KmphToMps(self.speedCruise)
end
end
@ -1041,9 +1074,23 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
elseif Formation then
wp.action=Formation
end
-- Add waypoint in between because this waypoint is "On Road" but lies "Off Road".
if wp.action==ENUMS.Formation.Vehicle.OnRoad and wp.roaddist>10 then
if wp.action==ENUMS.Formation.Vehicle.OnRoad and wp0.roaddist>=0 then
--env.info("FF adding waypoint0 on road #"..i)
-- Add "On Road" waypoint in between.
local wproad=wp0.roadcoord:WaypointGround(UTILS.MpsToKmph(wp.speed), ENUMS.Formation.Vehicle.OnRoad) --Ops.OpsGroup#OPSGROUP.Waypoint
-- Insert road waypoint.
table.insert(waypoints, wproad)
end
-- Add waypoint in between because this waypoint is "On Road" but lies "Off Road".
if wp.action==ENUMS.Formation.Vehicle.OnRoad and wp.roaddist>=0 then
--env.info("FF adding waypoint on road #"..i)
-- The real waypoint is actually off road.
wp.action=ENUMS.Formation.Vehicle.OffRoad
@ -1053,13 +1100,11 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
-- Insert road waypoint.
table.insert(waypoints, wproad)
end
end
-- Add waypoint.
table.insert(waypoints, wp)
-- Last formation.
formationlast=wp.action
table.insert(waypoints, wp)
end
-- First (next wp).
@ -1069,29 +1114,18 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
self.option.Formation=wp.action
-- Current set speed in m/s.
self.speedWp=wp.speed
local formation0=wp.action==ENUMS.Formation.Vehicle.OnRoad and ENUMS.Formation.Vehicle.OnRoad or wp.action
-- Current point.
local current=self:GetCoordinate():WaypointGround(UTILS.MpsToKmph(self.speedWp), formation0)
table.insert(waypoints, 1, current)
-- Insert a point on road.
if wp.action==ENUMS.Formation.Vehicle.OnRoad and (wp.coordinate or wp.roadcoord) then
current=self:GetClosestRoad():WaypointGround(UTILS.MpsToKmph(self.speedWp), ENUMS.Formation.Vehicle.OnRoad)
table.insert(waypoints, 2, current)
end
self.speedWp=wp.speed
-- Debug output.
if self.verbose>=10 then
--if true then
for i,_wp in pairs(waypoints) do
local wp=_wp --Ops.OpsGroup#OPSGROUP.Waypoint
local text=string.format("WP #%d UID=%d type=%s: Speed=%d m/s, alt=%d m, Action=%s", i, wp.uid and wp.uid or -1, wp.type, wp.speed, wp.alt, wp.action)
local text=string.format("WP #%d UID=%d Formation=%s: Speed=%d m/s, Alt=%d m, Type=%s", i, wp.uid and wp.uid or -1, wp.action, wp.speed, wp.alt, wp.type)
local coord=COORDINATE:NewFromWaypoint(wp):MarkToAll(text)
self:I(text)
end
end
@ -1722,7 +1756,10 @@ end
-- @param #boolean Updateroute If true or nil, call UpdateRoute. If false, no call.
-- @return Ops.OpsGroup#OPSGROUP.Waypoint Waypoint table.
function ARMYGROUP:AddWaypoint(Coordinate, Speed, AfterWaypointWithID, Formation, Updateroute)
-- Debug info.
self:T(self.lid..string.format("AddWaypoint Formation = %s",tostring(Formation) or "none"))
-- Create coordinate.
local coordinate=self:_CoordinateFromObject(Coordinate)

View File

@ -2112,6 +2112,10 @@ function AUFTRAG:_NewRELOCATECOHORT(Legion, Cohort)
mission.DCStask=mission:GetDCSMissionTask()
if Cohort.isGround then
mission.optionFormation=ENUMS.Formation.Vehicle.OnRoad
end
mission.DCStask.params.legion=Legion
mission.DCStask.params.cohort=Cohort

File diff suppressed because it is too large Load Diff

View File

@ -732,9 +732,12 @@ function COMMANDER:RelocateCohort(Cohort, Legion, Delay, NcarriersMin, Ncarriers
else
for _,legion in pairs(self.legions) do
mission:AssignTransportLegion(legion)
end
end
end
-- Set mission range very large. Mission designer should know...
mission:SetMissionRange(10000)
-- Add mission.
self:AddMission(mission)

View File

@ -65,7 +65,10 @@ function FLOTILLA:New(TemplateGroupName, Ngroups, FlotillaName)
local self=BASE:Inherit(self, COHORT:New(TemplateGroupName, Ngroups, FlotillaName)) -- #FLOTILLA
-- All flotillas get mission type Nothing.
self:AddMissionCapability(AUFTRAG.Type.NOTHING, 50)
self:AddMissionCapability(AUFTRAG.Type.NOTHING, 50)
-- Is naval.
self.isNaval=true
-- Get initial ammo.
self.ammo=self:_CheckAmmo()

View File

@ -499,6 +499,9 @@ function LEGION:RelocateCohort(Cohort, Legion, Delay, NcarriersMin, NcarriersMax
end
end
-- Set mission range very large. Mission designer should know...
mission:SetMissionRange(10000)
-- Add mission.
self:AddMission(mission)
end

View File

@ -541,6 +541,10 @@ function NAVYGROUP:_CreateTurnIntoWind(starttime, stoptime, speed, uturn, offset
-- Set start time.
local Tstart=UTILS.ClockToSeconds(starttime)
if uturn==nil then
uturn=true
end
-- Set stop time.
local Tstop=Tstart+90*60
@ -1241,8 +1245,8 @@ function NAVYGROUP:onafterTurnIntoWind(From, Event, To, IntoWind)
IntoWind.Open=true
IntoWind.Coordinate=self:GetCoordinate()
IntoWind.Coordinate=self:GetCoordinate(true)
self.intowind=IntoWind
-- Wind speed in m/s.

View File

@ -2823,7 +2823,7 @@ end
--- Get next waypoint index.
-- @param #OPSGROUP self
-- @param #boolean cyclic If true, return first waypoint if last waypoint was reached. Default is patrol ad infinitum value set.
-- @param #boolean cyclic If `true`, return first waypoint if last waypoint was reached. Default is patrol ad infinitum value set.
-- @param #number i Waypoint index from which the next index is returned. Default is the last waypoint passed.
-- @return #number Next waypoint index.
function OPSGROUP:GetWaypointIndexNext(cyclic, i)
@ -4095,11 +4095,14 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
local wp=nil --#OPSGROUP.Waypoint
if self.isArmygroup then
self:T2(self.lid.."Routing group to spawn zone of new legion")
wp=ARMYGROUP.AddWaypoint(self, Coordinate, Speed, currUID, Formation)
wp=ARMYGROUP.AddWaypoint(self, Coordinate, UTILS.KmphToKnots(self.speedCruise), currUID, Mission.optionFormation)
elseif self.isFlightgroup then
self:T2(self.lid.."Routing group to intermediate point near new legion")
Coordinate=self:GetCoordinate():GetIntermediateCoordinate(Coordinate, 0.8)
wp=FLIGHTGROUP.AddWaypoint(self, Coordinate, UTILS.KmphToKnots(self.speedCruise), currUID, UTILS.MetersToFeet(self.altitudeCruise))
elseif self.isNavygroup then
self:T2(self.lid.."Routing group to spawn zone of new legion")
wp=NAVYGROUP.AddWaypoint(self, Coordinate, UTILS.KmphToKnots(self.speedCruise), currUID)
else
end
@ -5016,9 +5019,9 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
-- Emission to default.
if Mission.optionEmission then
self:SwitchEmission()
end
end
-- Formation to default.
if Mission.optionFormation then
if Mission.optionFormation and self:IsFlightgroup() then
self:SwitchFormation()
end
-- Radio freq and modu to default.
@ -5130,6 +5133,17 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Ingress waypoint coordinate where the mission is executed.
local waypointcoord=nil --Core.Point#COORDINATE
-- Current coordinate of the group.
local currentcoord=self:GetCoordinate()
-- Road connection.
local roadcoord=currentcoord:GetClosestPointToRoad()
local roaddist=nil
if roadcoord then
roaddist=currentcoord:Get2DDistance(roadcoord)
end
-- Target zone.
local targetzone=nil --Core.Zone#ZONE
@ -5215,14 +5229,23 @@ function OPSGROUP:RouteToMission(mission, delay)
---
-- Roughly go to the new legion.
local ToCoordinate=mission.DCStask.params.legion:GetCoordinate()
local ToCoordinate=mission.DCStask.params.legion:GetCoordinate()
if self.isFlightgroup then
waypointcoord=self:GetCoordinate():GetIntermediateCoordinate(ToCoordinate, 0.2):SetAltitude(self.altitudeCruise)
-- Get mission waypoint coord in direction of the
waypointcoord=currentcoord:GetIntermediateCoordinate(ToCoordinate, 0.2):SetAltitude(self.altitudeCruise)
elseif self.isArmygroup then
-- Army group: check for road connection.
if roadcoord then
waypointcoord=roadcoord
else
waypointcoord=currentcoord:GetIntermediateCoordinate(ToCoordinate, 100)
end
else
waypointcoord=self:GetCoordinate():GetIntermediateCoordinate(ToCoordinate, 0.05)
-- Navy group: Route into direction of the target.
waypointcoord=currentcoord:GetIntermediateCoordinate(ToCoordinate, 0.05)
end
elseif mission.type==AUFTRAG.Type.RECOVERYTANKER then
---
-- Recoverytanker
@ -5356,12 +5379,16 @@ function OPSGROUP:RouteToMission(mission, delay)
end
-- Add waypoint.
-- Add mission execution (ingress) waypoint.
local waypoint=nil --#OPSGROUP.Waypoint
if self:IsFlightgroup() then
waypoint=FLIGHTGROUP.AddWaypoint(self, waypointcoord, SpeedToMission, uid, UTILS.MetersToFeet(mission.missionAltitude or self.altitudeCruise), false)
elseif self:IsArmygroup() then
waypoint=ARMYGROUP.AddWaypoint(self, waypointcoord, SpeedToMission, uid, mission.optionFormation, false)
local formation=mission.optionFormation
if mission.type==AUFTRAG.Type.RELOCATECOHORT then
formation=ENUMS.Formation.Vehicle.OffRoad
end
waypoint=ARMYGROUP.AddWaypoint(self, waypointcoord, SpeedToMission, uid, formation, false)
elseif self:IsNavygroup() then
waypoint=NAVYGROUP.AddWaypoint(self, waypointcoord, SpeedToMission, uid, UTILS.MetersToFeet(mission.missionAltitude or self.altitudeCruise), false)
end
@ -5380,8 +5407,6 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Add egress waypoint.
local egresscoord=mission:GetMissionEgressCoord()
if egresscoord then
--egresscoord:MarkToAll(string.format("Egress Mission %s alt=%d m", mission:GetName(), waypointcoord.y))
-- Add waypoint.
local Ewaypoint=nil --#OPSGROUP.Waypoint
if self:IsFlightgroup() then
Ewaypoint=FLIGHTGROUP.AddWaypoint(self, egresscoord, SpeedToMission, waypoint.uid, UTILS.MetersToFeet(mission.missionAltitude or self.altitudeCruise), false)
@ -5394,12 +5419,9 @@ function OPSGROUP:RouteToMission(mission, delay)
mission:SetGroupEgressWaypointUID(self, Ewaypoint.uid)
end
-- Get current pos.
local coord=self:GetCoordinate()
-- Distance to waypoint coordinate.
local d=coord:Get2DDistance(waypointcoord)
local d=currentcoord:Get2DDistance(waypointcoord)
-- Debug info.
self:T(self.lid..string.format("FF distance to ingress waypoint=%.1f m", d))
@ -5787,6 +5809,8 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
self:_PassedFinalWaypoint(true, "PassingWaypoint: adinfinitum but only ONE WAYPOINT left")
else
--[[ Solved now!
-- Looks like the passing waypoint function is triggered over and over again if the group is near the final waypoint.
-- So the only good solution is to guide the group away from that waypoint and then update the route.
@ -5795,9 +5819,19 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
-- Get a waypoint
local Coordinate=Waypoint.coordinate:GetIntermediateCoordinate(wp1.coordinate, 0.1)
-- Detour to the temp waypoint. When reached, the normal route is resumed.
self:Detour(Coordinate, self.speedCruise, nil, true)
local formation=nil
if self.isArmygroup then
formation=ENUMS.Formation.Vehicle.OffRoad
end
self:Detour(Coordinate, self.speedCruise, formation, true)
]]
-- Send
self:__UpdateRoute(-0.01, 1, 1)
end
end
@ -5809,6 +5843,27 @@ function OPSGROUP:onafterPassingWaypoint(From, Event, To, Waypoint)
-- Final waypoint reached.
self:_PassedFinalWaypoint(true, "PassingWaypoint: wpindex=#self.waypoints (or wpindex=nil)")
end
elseif wpindex==1 then
-- Ad infinitum and not mission waypoint?
if self.adinfinitum then
---
-- Ad Infinitum
---
if #self.waypoints<=1 then
-- Only one waypoint. Ad infinitum does not really make sense. However, another waypoint could be added later...
self:_PassedFinalWaypoint(true, "PassingWaypoint: adinfinitum but only ONE WAYPOINT left")
else
if not Waypoint.missionUID then
-- Redo the route until the end.
self:__UpdateRoute(-0.01, 2)
end
end
end
end
@ -9709,6 +9764,11 @@ function OPSGROUP:_CheckStuck()
-- Debug warning.
self:T(self.lid..string.format("WARNING: Group came to an unexpected standstill. Speed=%.1f<%.1f m/s expected for %d sec", speed, ExpectedSpeed, holdtime))
if self.legion then
self:T(self.lid..string.format("Asset is returned to its legion after being stuck!"))
self:ReturnToLegion()
end
end

View File

@ -65,6 +65,9 @@ function PLATOON:New(TemplateGroupName, Ngroups, PlatoonName)
-- All platoons get mission type Nothing.
self:AddMissionCapability(AUFTRAG.Type.NOTHING, 50)
-- Is ground.
self.isGround=true
-- Get ammo.
self.ammo=self:_CheckAmmo()

View File

@ -102,6 +102,9 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
-- Everyone can ORBIT.
self:AddMissionCapability(AUFTRAG.Type.ORBIT)
-- Is air.
self.isAir=true
-- Refueling system.
self.refuelSystem=select(2, self.templategroup:GetUnit(1):IsRefuelable())

View File

@ -96,6 +96,14 @@
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
--
-- **NOTE on using GOOGLE TTS with SRS:** You need to have the C# library installed in your SRS folder for Google to work.
-- You can obtain it e.g. here: [NuGet](https://www.nuget.org/packages/Grpc.Core)
--
-- **Pro-Tipp** - use the command line with power shell to call DCS-SR-ExternalAudio.exe - it will tell you what is missing.
-- and also the Google Console error, in case you have missed a step in setting up your Google TTS.
-- E.g. `.\DCS-SR-ExternalAudio.exe -t "Text Message" -f 255 -m AM -c 2 -s 2 -z -G "Path_To_You_Google.Json"`
-- Plays a message on 255AM for the blue coalition in-game.
--
-- ## Set Voice
--
-- Use a specifc voice with the @{#MSRS.SetVoice} function, e.g, `:SetVoice("Microsoft Hedda Desktop")`.

View File

@ -1625,6 +1625,10 @@ do -- Cargo
["Ural-4320T"] = 14,
["ZBD04A"] = 7, -- new by kappa
["VAB_Mephisto"] = 8, -- new by Apple
["tt_KORD"] = 6, -- 2.7.1 HL/TT
["tt_DSHK"] = 6,
["HL_KORD"] = 6,
["HL_DSHK"] = 6,
}
-- Assuming that each passenger weighs 95 kg on average.