diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index d25186b66..272dc386d 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -2423,8 +2423,7 @@ end -- @param #SPAWN self -- @param DCS#Vec3 Vec3 The Vec3 coordinates where to spawn the group. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil Nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. function SPAWN:SpawnFromVec3( Vec3, SpawnIndex ) self:F( { self.SpawnTemplatePrefix, Vec3, SpawnIndex } ) @@ -2493,8 +2492,7 @@ end -- @param #SPAWN self -- @param Core.Point#Coordinate Coordinate The Coordinate coordinates where to spawn the group. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil Nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. function SPAWN:SpawnFromCoordinate( Coordinate, SpawnIndex ) self:F( { self.SpawnTemplatePrefix, SpawnIndex } ) @@ -2510,8 +2508,7 @@ end -- @param #SPAWN self -- @param Core.Point#POINT_VEC3 PointVec3 The PointVec3 coordinates where to spawn the group. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil Nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. -- @usage -- -- local SpawnPointVec3 = ZONE:New( ZoneName ):GetPointVec3( 2000 ) -- Get the center of the ZONE object at 2000 meters from the ground. @@ -2535,8 +2532,7 @@ end -- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone. -- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil Nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. -- @usage -- -- local SpawnVec2 = ZONE:New( ZoneName ):GetVec2() @@ -2569,8 +2565,7 @@ end -- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone. -- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil Nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. -- @usage -- -- local SpawnPointVec2 = ZONE:New( ZoneName ):GetPointVec2() @@ -2626,8 +2621,7 @@ end -- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone. -- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil Nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. -- @usage -- -- local SpawnStatic = STATIC:FindByName( StaticName ) @@ -2658,8 +2652,7 @@ end -- @param #number MinHeight (optional) The minimum height to spawn an airborne group into the zone. -- @param #number MaxHeight (optional) The maximum height to spawn an airborne group into the zone. -- @param #number SpawnIndex (optional) The index which group to spawn within the given zone. --- @return Wrapper.Group#GROUP that was spawned. --- @return #nil when nothing was spawned. +-- @return Wrapper.Group#GROUP that was spawned or #nil if nothing was spawned. -- @usage -- -- local SpawnZone = ZONE:New( ZoneName ) diff --git a/Moose Development/Moose/Ops/NavyGroup.lua b/Moose Development/Moose/Ops/NavyGroup.lua index d78b0a6a5..0310292ac 100644 --- a/Moose Development/Moose/Ops/NavyGroup.lua +++ b/Moose Development/Moose/Ops/NavyGroup.lua @@ -1287,7 +1287,7 @@ function NAVYGROUP:_CheckFreePath(DistanceMax, dx) local los=LoS(x) -- Debug message. - self:I(self.lid..string.format("N=%d: xmin=%.1f xmax=%.1f x=%.1f d=%.3f los=%s", N, xmin, xmax, x, d, tostring(los))) + self:T(self.lid..string.format("N=%d: xmin=%.1f xmax=%.1f x=%.1f d=%.3f los=%s", N, xmin, xmax, x, d, tostring(los))) if los and d<=eps then return x diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 97fd17248..65060db9e 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -4675,7 +4675,8 @@ function OPSGROUP:_Respawn(Delay, Template, Reset) self:ScheduleOnce(Delay, OPSGROUP._Respawn, self, 0, Template, Reset) else - self:I(self.lid.."FF _Respawn") + -- Debug message. + self:T2(self.lid.."FF _Respawn") -- Given template or get old. Template=Template or UTILS.DeepCopy(self.template) @@ -5612,7 +5613,7 @@ end -- @param #OPSGROUP self -- @return #OPSGROUP self function OPSGROUP:_RemoveMyCarrier() - self:I(self.lid..string.format("Removing my carrier!")) + self:T(self.lid..string.format("Removing my carrier!")) self.mycarrier.group=nil self.mycarrier.element=nil self.mycarrier.reserved=nil @@ -5723,16 +5724,50 @@ function OPSGROUP:onafterPickup(From, Event, To) -- Navy Group - local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid) ; waypoint.detour=true + local cwp=self:GetWaypointCurrent() + local uid=cwp and cwp.uid or nil + -- Get a (random) pre-defined transport path. + local path=self.cargoTransport:_GetPathPickup() + + if path then + -- Loop over coordinates. + for i,coordinate in pairs(path) do + local waypoint=NAVYGROUP.AddWaypoint(self, coordinate, nil, uid) ; waypoint.temp=true + uid=waypoint.uid + --coordinate:MarkToAll(string.format("Path i=%d, UID=%d", i, uid)) + end + end + + -- NAVYGROUP + local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate, nil, uid) ; waypoint.detour=true + + -- Give cruise command. self:__Cruise(-2) + elseif self.isArmygroup then -- Army Group - local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid) ; waypoint.detour=true + local cwp=self:GetWaypointCurrent() + local uid=cwp and cwp.uid or nil + -- Get a (random) pre-defined transport path. + local path=self.cargoTransport:_GetPathPickup() + + if path then + -- Loop over coordinates. + for i,coordinate in pairs(path) do + local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, uid) ; waypoint.temp=true + uid=waypoint.uid + --coordinate:MarkToAll(string.format("Path i=%d, UID=%d", i, uid)) + end + end + + -- ARMYGROUP + local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, uid) ; waypoint.detour=true + self:__Cruise(-2) end @@ -5883,7 +5918,7 @@ function OPSGROUP:onafterLoad(From, Event, To, CargoGroup, Carrier) -- Trigger "Loaded" event for current cargo transport. if self.cargoTransport then - self.cargoTransport:Loaded(CargoGroup, carrier) + self.cargoTransport:Loaded(CargoGroup, self, carrier) else self:E(self.lid..string.format("WARNING: Loaded cargo but no current OPSTRANSPORT assignment!")) end @@ -6034,15 +6069,18 @@ function OPSGROUP:onafterTransport(From, Event, To) elseif self.isArmygroup then + local cwp=self:GetWaypointCurrent() + local uid=cwp and cwp.uid or nil + local path=self.cargoTransport:_GetPathTransport() + if path then - - for _,_zone in pairs(path.zones:GetSet()) do - local zone=_zone --Core.Zone#ZONE - local coordinate=zone:GetRandomCoordinate(nil, nil, nil) --TODO: surface type land - local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, self:GetWaypointCurrent().uid) ; waypoint.temp=true + -- Loop over coordinates. + for i,coordinate in pairs(path) do + local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, uid) ; waypoint.temp=true + uid=waypoint.uid + --coordinate:MarkToAll(string.format("Path i=%d, UID=%d", i, uid)) end - end -- ARMYGROUP @@ -6060,12 +6098,11 @@ function OPSGROUP:onafterTransport(From, Event, To) local path=self.cargoTransport:_GetPathTransport() if path then - -- Loop over zones + -- Loop over coordinates. for i,coordinate in pairs(path) do - local waypoint=NAVYGROUP.AddWaypoint(self, coordinate, nil, uid) - waypoint.temp=true + local waypoint=NAVYGROUP.AddWaypoint(self, coordinate, nil, uid) ; waypoint.temp=true uid=waypoint.uid - coordinate:MarkToAll(string.format("Path i=%d, UID=%d", i, uid)) + --coordinate:MarkToAll(string.format("Path i=%d, UID=%d", i, uid)) end end @@ -6184,7 +6221,7 @@ function OPSGROUP:onafterUnloading(From, Event, To) end -- Trigger "Unloaded" event for current cargo transport - self.cargoTransport:Unloaded(cargo.opsgroup) + self.cargoTransport:Unloaded(cargo.opsgroup, self) end @@ -7236,7 +7273,7 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid) -- Debug message. local text=string.format("Group passing waypoint uid=%d", uid) - opsgroup:I(opsgroup.lid..text) + opsgroup:T(opsgroup.lid..text) -- Trigger PassingWaypoint event. if waypoint.temp then diff --git a/Moose Development/Moose/Ops/OpsTransport.lua b/Moose Development/Moose/Ops/OpsTransport.lua index 816813ac7..0ef309150 100644 --- a/Moose Development/Moose/Ops/OpsTransport.lua +++ b/Moose Development/Moose/Ops/OpsTransport.lua @@ -50,7 +50,8 @@ -- @field #number Ncargo Total number of cargo groups. -- @field #number Ncarrier Total number of assigned carriers. -- @field #number Ndelivered Total number of cargo groups delivered. --- @field #table pathsTransport Paths of `#OPSGROUP.Path`. +-- @field #table pathsTransport Transport paths of `#OPSGROUP.Path`. +-- @field #table pathsPickup Pickup paths of `#OPSGROUP.Path`. -- @extends Core.Fsm#FSM --- *Victory is the beautiful, bright-colored flower. Transport is the stem without which it could never have blossomed.* -- Winston Churchill @@ -78,6 +79,7 @@ OPSTRANSPORT = { carrierTransportStatus = {}, conditionStart = {}, pathsTransport = {}, + pathsPickup = {}, requiredCargos = {}, } @@ -203,7 +205,7 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet) -- We got a single GROUP or OPSGROUP object. local cargo=self:_CreateCargoGroupData(GroupSet) - if cargo then --and self:CanCargo(cargo.opsgroup) + if cargo then table.insert(self.cargos, cargo) self.Ncargo=self.Ncargo+1 end @@ -530,10 +532,11 @@ end --- Add path used for transportation from the pickup to the deploy zone. If multiple paths are defined, a random one is chosen. -- @param #OPSTRANSPORT self -- @param Wrapper.Group#GROUP PathGroup A (late activated) GROUP defining a transport path by their waypoints. +-- @param #boolean Reversed If `true`, add waypoints of group in reversed order. -- @param #number Radius Randomization radius in meters. Default 0 m. -- @param #number Altitude Altitude in feet AGL. Only for aircraft. -- @return #OPSTRANSPORT self -function OPSTRANSPORT:AddPathTransport(PathGroup, Radius, Altitude) +function OPSTRANSPORT:AddPathTransport(PathGroup, Reversed, Radius, Altitude) local path={} --#OPSTRANSPORT.Path path.coords={} @@ -543,11 +546,21 @@ function OPSTRANSPORT:AddPathTransport(PathGroup, Radius, Altitude) -- Get route points. local waypoints=PathGroup:GetTaskRoute() - for _,wp in pairs(waypoints) do - local coord=COORDINATE:New(wp.x, wp.alt, wp.y) - table.insert(path.coords, coord) + if Reversed then + for i=#waypoints,1,-1 do + local wp=waypoints[i] + local coord=COORDINATE:New(wp.x, wp.alt, wp.y) + table.insert(path.coords, coord) + end + else + for i=1,#waypoints do + local wp=waypoints[i] + local coord=COORDINATE:New(wp.x, wp.alt, wp.y) + table.insert(path.coords, coord) + end end + -- Add path. table.insert(self.pathsTransport, path) @@ -580,6 +593,69 @@ function OPSTRANSPORT:_GetPathTransport() end +--- Add path used to go to the pickup zone. If multiple paths are defined, a random one is chosen. +-- @param #OPSTRANSPORT self +-- @param Wrapper.Group#GROUP PathGroup A (late activated) GROUP defining a transport path by their waypoints. +-- @param #boolean Reversed If `true`, add waypoints of group in reversed order. +-- @param #number Radius Randomization radius in meters. Default 0 m. +-- @param #number Altitude Altitude in feet AGL. Only for aircraft. +-- @return #OPSTRANSPORT self +function OPSTRANSPORT:AddPathPickup(PathGroup, Reversed, Radius, Altitude) + + local path={} --#OPSTRANSPORT.Path + path.coords={} + path.radius=Radius or 0 + path.altitude=Altitude + + -- Get route points. + local waypoints=PathGroup:GetTaskRoute() + + if Reversed then + for i=#waypoints,1,-1 do + local wp=waypoints[i] + local coord=COORDINATE:New(wp.x, wp.alt, wp.y) + table.insert(path.coords, coord) + end + else + for i=1,#waypoints do + local wp=waypoints[i] + local coord=COORDINATE:New(wp.x, wp.alt, wp.y) + table.insert(path.coords, coord) + end + end + + -- Add path. + table.insert(self.pathsPickup, path) + + return self +end + +--- Get a path for pickup. +-- @param #OPSTRANSPORT self +-- @return #table The path of COORDINATEs. +function OPSTRANSPORT:_GetPathPickup() + + if self.pathsPickup and #self.pathsPickup>0 then + + -- Get a random path for transport. + local path=self.pathsPickup[math.random(#self.pathsPickup)] --#OPSTRANSPORT.Path + + + local coordinates={} + for _,coord in ipairs(path.coords) do + + -- TODO: Add randomization. + + table.insert(coordinates, coord) + end + + return coordinates + end + + return nil +end + + --- Add a carrier assigned for this transport. -- @param #OPSTRANSPORT self -- @param Ops.OpsGroup#OPSGROUP CarrierGroup Carrier OPSGROUP.