From fa3e387dd1c133d7e0ccead9d496aa1a8d89069e Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 30 Jun 2021 23:23:41 +0200 Subject: [PATCH] OPS --- Moose Development/Moose/Ops/ArmyGroup.lua | 17 -- Moose Development/Moose/Ops/FlightGroup.lua | 62 +---- Moose Development/Moose/Ops/NavyGroup.lua | 16 -- Moose Development/Moose/Ops/OpsGroup.lua | 258 +++++++++----------- 4 files changed, 120 insertions(+), 233 deletions(-) diff --git a/Moose Development/Moose/Ops/ArmyGroup.lua b/Moose Development/Moose/Ops/ArmyGroup.lua index fc82983ac..f2953ede0 100644 --- a/Moose Development/Moose/Ops/ArmyGroup.lua +++ b/Moose Development/Moose/Ops/ArmyGroup.lua @@ -1055,23 +1055,6 @@ function ARMYGROUP:onafterCruise(From, Event, To, Speed, Formation) end ---- On after "Stop" event. --- @param #ARMYGROUP self --- @param #string From From state. --- @param #string Event Event. --- @param #string To To state. -function ARMYGROUP:onafterStop(From, Event, To) - - -- Handle events: - self:UnHandleEvent(EVENTS.Birth) - self:UnHandleEvent(EVENTS.Dead) - self:UnHandleEvent(EVENTS.RemoveUnit) - - -- Call OPSGROUP function. - self:GetParent(self).onafterStop(self, From, Event, To) - -end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Routing ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 2ec865140..c68ae0edc 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -2079,26 +2079,6 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n) end ---- On after "Respawn" event. --- @param #FLIGHTGROUP self --- @param #string From From state. --- @param #string Event Event. --- @param #string To To state. --- @param #table Template The template used to respawn the group. -function FLIGHTGROUP:onafterRespawn(From, Event, To, Template) - - self:T(self.lid.."Respawning group!") - - local template=UTILS.DeepCopy(Template or self.template) - - if self.group and self.group:InAir() then - template.lateActivation=false - self.respawning=true - self.group=self.group:Respawn(template) - end - -end - --- On after "OutOfMissilesAA" event. -- @param #FLIGHTGROUP self -- @param #string From From state. @@ -2856,44 +2836,6 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To) end end ---- On after "Stop" event. --- @param #FLIGHTGROUP self --- @param #string From From state. --- @param #string Event Event. --- @param #string To To state. -function FLIGHTGROUP:onafterStop(From, Event, To) - - -- Check if group is still alive. - if self:IsAlive() then - - -- Set element parking spot to FREE (after arrived for example). - if self.flightcontrol then - for _,_element in pairs(self.elements) do - local element=_element --#FLIGHTGROUP.Element - self:_SetElementParkingFree(element) - end - end - - end - - self.currbase=nil - - -- Handle events: - self:UnHandleEvent(EVENTS.Birth) - self:UnHandleEvent(EVENTS.EngineStartup) - self:UnHandleEvent(EVENTS.Takeoff) - self:UnHandleEvent(EVENTS.Land) - self:UnHandleEvent(EVENTS.EngineShutdown) - self:UnHandleEvent(EVENTS.PilotDead) - self:UnHandleEvent(EVENTS.Ejection) - self:UnHandleEvent(EVENTS.Crash) - self:UnHandleEvent(EVENTS.RemoveUnit) - - -- Call OPSGROUP function. - self:GetParent(self).onafterStop(self, From, Event, To) - -end - ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Task functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -3433,14 +3375,14 @@ function FLIGHTGROUP:InitWaypoints() self.currbase=self:GetHomebaseFromWaypoints() -- Remove the landing waypoint. We use RTB for that. It makes adding new waypoints easier as we do not have to check if the last waypoint is the landing waypoint. - if self.destbase then + if self.destbase and #self.waypoints>1 then table.remove(self.waypoints, #self.waypoints) else self.destbase=self.homebase end -- Debug info. - self:T(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown")) + self:I(self.lid..string.format("Initializing %d waypoints. Homebase %s ==> %s Destination", #self.waypoints, self.homebase and self.homebase:GetName() or "unknown", self.destbase and self.destbase:GetName() or "uknown")) -- Update route. if #self.waypoints>0 then diff --git a/Moose Development/Moose/Ops/NavyGroup.lua b/Moose Development/Moose/Ops/NavyGroup.lua index fb836d489..d78b0a6a5 100644 --- a/Moose Development/Moose/Ops/NavyGroup.lua +++ b/Moose Development/Moose/Ops/NavyGroup.lua @@ -1062,22 +1062,6 @@ function NAVYGROUP:onafterCollisionWarning(From, Event, To, Distance) self.collisionwarning=true end ---- On after Start event. Starts the NAVYGROUP FSM and event handlers. --- @param #NAVYGROUP self --- @param #string From From state. --- @param #string Event Event. --- @param #string To To state. -function NAVYGROUP:onafterStop(From, Event, To) - - -- Handle events: - self:UnHandleEvent(EVENTS.Birth) - self:UnHandleEvent(EVENTS.Dead) - self:UnHandleEvent(EVENTS.RemoveUnit) - - -- Call OPSGROUP function. - self:GetParent(self).onafterStop(self, From, Event, To) - -end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Routing diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 13d1464e5..5273b0176 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -378,6 +378,7 @@ OPSGROUP.TaskType={ -- @field #boolean detour If true, this waypoint is not part of the normal route. -- @field #boolean intowind If true, this waypoint is a turn into wind route point. -- @field #boolean astar If true, this waypint was found by A* pathfinding algorithm. +-- @field #boolean temp If true, this is a temporary waypoint and will be deleted when passed. Also the passing waypoint FSM event is not triggered. -- @field #number npassed Number of times a groups passed this waypoint. -- @field Core.Point#COORDINATE coordinate Waypoint coordinate. -- @field Core.Point#COORDINATE roadcoord Closest point to road. @@ -2292,50 +2293,34 @@ function OPSGROUP:OnEventBirth(EventData) local group=EventData.IniGroup local unitname=EventData.IniUnitName - if self.respawning then - self:I(self.lid.."Respawning unit "..tostring(unitname)) + -- Set homebase if not already set. + if self.isFlightgroup then - local function reset() - self.respawning=nil - self:_CheckGroupDone() - end - - -- Reset switch in 1 sec. This should allow all birth events of n>1 groups to have passed. - -- TODO: Can I do this more rigorously? - self:ScheduleOnce(1, reset) - - else - - -- Set homebase if not already set. - if self.isFlightgroup then - - if EventData.Place then - self.homebase=self.homebase or EventData.Place - self.currbase=EventData.Place - else - self.currbase=nil - end - - if self.homebase and not self.destbase then - self.destbase=self.homebase - end - - self:T(self.lid..string.format("EVENT: Element %s born at airbase %s==> spawned", unitname, self.homebase and self.homebase:GetName() or "unknown")) + if EventData.Place then + self.homebase=self.homebase or EventData.Place + self.currbase=EventData.Place else - self:T3(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname)) + self.currbase=nil end - -- Get element. - local element=self:GetElementByName(unitname) - - -- Set element to spawned state. - self:ElementSpawned(element) + if self.homebase and not self.destbase then + self.destbase=self.homebase + end + self:I(self.lid..string.format("EVENT: Element %s born at airbase %s ==> spawned", unitname, self.homebase and self.homebase:GetName() or "unknown")) + else + self:T3(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname)) end - end + -- Get element. + local element=self:GetElementByName(unitname) + -- Set element to spawned state. + self:ElementSpawned(element) + + end + end --- Event function handling the crash of a unit. @@ -3755,7 +3740,7 @@ end -- FSM Events ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- On after "PassingWaypoint" event. +--- Check if group is currently waiting. -- @param #OPSGROUP self -- @param #boolean If true, group is currently waiting. function OPSGROUP:IsWaiting() @@ -3776,8 +3761,10 @@ function OPSGROUP:onafterWait(From, Event, To, Duration) -- Order Group to hold. self:FullStop() + -- Set time stamp. self.Twaiting=timer.getAbsTime() + -- Max waiting self.dTwait=Duration end @@ -4567,25 +4554,6 @@ function OPSGROUP:onafterElementDead(From, Event, To, Element) end end - -- Check cargo bay and declare cargo groups dead. - --[[ - for groupname, carriername in pairs(self.cargoBay or {}) do - if Element.name==carriername then - local opsgroup=_DATABASE:GetOpsGroup(groupname) - if opsgroup and not (opsgroup:IsDead() or opsgroup:IsStopped()) then - for _,element in pairs(opsgroup.elements) do - - -- Debug info. - self:T2(self.lid.."Cargo element dead "..element.name) - - -- Trigger dead event. - opsgroup:ElementDead(element) - - end - end - end - end - ]] -- Check cargo bay and declare cargo groups dead. for _,_element in pairs(self.elements) do @@ -4593,25 +4561,31 @@ function OPSGROUP:onafterElementDead(From, Event, To, Element) for _,_cargo in pairs(element.cargoBay) do local cargo=_cargo --#OPSGROUP.MyCargo if cargo.group and not (cargo.group:IsDead() or cargo.group:IsStopped()) then - for _,cargoelement in pairs(cargo.group.elements) do - - -- Debug info. - self:T2(self.lid.."Cargo element dead "..cargoelement.name) - - -- Trigger dead event. - cargo.group:ElementDead(cargoelement) - + + -- Remove my carrier + cargo.group:_RemoveMyCarrier() + + if cargo.reserved then + -- This group was not loaded yet ==> Not cargo any more. + cargo.group.cargoStatus=OPSGROUP.CargoStatus.NOTCARGO + else + + -- Carrier dead ==> cargo dead. + for _,cargoelement in pairs(cargo.group.elements) do + + -- Debug info. + self:T2(self.lid.."Cargo element dead "..cargoelement.name) + + -- Trigger dead event. + cargo.group:ElementDead(cargoelement) + + end end + end end end - if self:IsCarrier() then - if self.cargoTransport then - self.cargoTransport:DeadCarrierGroup(self) - end - end - end --- On after "Respawn" event. @@ -4713,6 +4687,10 @@ function OPSGROUP:_Respawn(Delay, Template, Reset) -- Debug output. self:I({Template=Template}) + + --if self:IsStopped() then + --self:InitWaypoints() + --end -- Spawn new group. _DATABASE:Spawn(Template) @@ -4720,6 +4698,7 @@ function OPSGROUP:_Respawn(Delay, Template, Reset) -- Set activation and controlled state. self.isLateActivated=Template.lateActivation self.isUncontrolled=Template.uncontrolled + -- Reset events. --self:ResetEvents() @@ -4772,20 +4751,45 @@ function OPSGROUP:onafterDead(From, Event, To) end + -- Delete waypoints so they are re-initialized at the next spawn. + self:ClearWaypoints() + self.groupinitialized=false + + -- Set cargo status to NOTCARGO. + self.cargoStatus=OPSGROUP.CargoStatus.NOTCARGO + self.carrierStatus=OPSGROUP.CarrierStatus.NOTCARRIER + + -- Remove from cargo bay of carrier. + local mycarrier=self:_GetMyCarrierGroup() + if mycarrier and not mycarrier:IsDead() then + mycarrier:_DelCargobay(self) + self:_RemoveMyCarrier() + end + -- Inform all transports in the queue that this carrier group is dead now. for i,_transport in pairs(self.cargoqueue) do local transport=_transport --Ops.OpsTransport#OPSTRANSPORT - transport:DeadCarrierGroup(self) + transport:__DeadCarrierGroup(1, self) end - - -- Delete waypoints so they are re-initialized at the next spawn. - self.waypoints=nil - self.groupinitialized=false -- Stop in a sec. self:__Stop(-5) end +--- On before "Stop" event. +-- @param #OPSGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function OPSGROUP:onbeforeStop(From, Event, To) + + if self:IsAlive() then + return false + end + + return true +end + --- On after "Stop" event. -- @param #OPSGROUP self -- @param #string From From state. @@ -4793,6 +4797,23 @@ end -- @param #string To To state. function OPSGROUP:onafterStop(From, Event, To) + -- Handle events: + self:UnHandleEvent(EVENTS.Birth) + self:UnHandleEvent(EVENTS.Dead) + self:UnHandleEvent(EVENTS.RemoveUnit) + + -- Handle events: + if self.isFlightgroup then + self:UnHandleEvent(EVENTS.EngineStartup) + self:UnHandleEvent(EVENTS.Takeoff) + self:UnHandleEvent(EVENTS.Land) + self:UnHandleEvent(EVENTS.EngineShutdown) + self:UnHandleEvent(EVENTS.PilotDead) + self:UnHandleEvent(EVENTS.Ejection) + self:UnHandleEvent(EVENTS.Crash) + self.currbase=nil + end + -- Stop check timers. self.timerCheckZone:Stop() self.timerQueueUpdate:Stop() @@ -4827,18 +4848,6 @@ function OPSGROUP:_CheckCargoTransport() local Time=timer.getAbsTime() -- Cargo bay debug info. - --[[ - if self.verbose>=3 then - local text="" - for cargogroupname, carriername in pairs(self.cargoBay) do - text=text..string.format("\n- %s in carrier %s", tostring(cargogroupname), tostring(carriername)) - end - if text~="" then - self:I(self.lid.."Cargo bay:"..text) - end - end - ]] - -- Check cargo bay and declare cargo groups dead. if self.verbose>=0 then local text="" @@ -5044,7 +5053,6 @@ function OPSGROUP:_AddCargobay(CargoGroup, CarrierElement, Reserved) table.insert(CarrierElement.cargoBay, cargo) end - -- Set my carrier. CargoGroup:_SetMyCarrier(self, CarrierElement, Reserved) @@ -5500,22 +5508,6 @@ function OPSGROUP:FindCarrierForCargo(CargoGroup) return nil end ---- Reserve cargo space for a cargo group. --- @param #OPSGROUP self --- @param #OPSGROUP CargoGroup Cargo group, which needs a carrier. --- @return #OPSGROUP.Element Carrier able to transport the cargo. -function OPSGROUP:ReserveCargoSpace(CargoGroup) - - local element=self:FindCarrierForCargo(CargoGroup) - - if element then - element.reservedCargo=element.reservedCargo or {} - table.insert(element.reservedCargo, CargoGroup) - end - - return nil -end - --- Set my carrier. -- @param #OPSGROUP self -- @param #OPSGROUP CarrierGroup Carrier group. @@ -5688,8 +5680,7 @@ function OPSGROUP:onafterPickup(From, Event, To) -- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone. Coordinate:SetAltitude(200) - local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate) - waypoint.detour=true + local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=true else self:E(self.lid.."ERROR: Carrier aircraft cannot land in Pickup zone! Specify a ZONE_AIRBASE as pickup zone") @@ -5733,26 +5724,6 @@ function OPSGROUP:onafterLoading(From, Event, To) -- Loading time stamp. self.Tloading=timer.getAbsTime() - -- Create a temp array and monitor the free cargo space for each element. - local cargobay={} - for _,_element in pairs(self.elements) do - local element=_element --#OPSGROUP.Element - cargobay[element.name]=element.weightMaxCargo-element.weightCargo - end - - - --- Find a carrier which can load a given weight. - local function _findCarrier(weight) - local carrier=nil --#OPSGROUP.Element - for _,_element in pairs(self.elements) do - local element=_element --#OPSGROUP.Element - if cargobay[element.name]>=weight then - return element - end - end - return nil - end - --TODO: sort cargos wrt weight. -- Loop over all cargos. @@ -5772,19 +5743,11 @@ function OPSGROUP:onafterLoading(From, Event, To) -- Cargo MUST be inside zone or it will not be loaded! if inzone then - -- Weight of cargo. - local weight=cargo.opsgroup:GetWeightTotal() - - -- Find a carrier that has enough free cargo bay for this group. - local carrier=_findCarrier(weight) - + -- Find a carrier for this cargo. local carrier=self:FindCarrierForCargo(cargo.opsgroup) if carrier then - -- Decrease free cargo bay. - cargobay[carrier.name]=cargobay[carrier.name]-weight - -- Set cargo status. cargo.opsgroup.cargoStatus=OPSGROUP.CargoStatus.ASSIGNED @@ -5918,6 +5881,23 @@ function OPSGROUP:onafterLoaded(From, Event, To) end +--- On before "Transport" event. +-- @param #OPSGROUP self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function OPSGROUP:onbeforeTransport(From, Event, To) + + if self.cargoTransport==nil then + return false + elseif self.cargoTransport:IsDelivered() then --could be if all cargo was dead on boarding + return false + end + + return true +end + + --- On after "Transport" event. -- @param #OPSGROUP self -- @param #string From From state. @@ -6011,8 +5991,7 @@ function OPSGROUP:onafterTransport(From, Event, To) -- If this is a helo and no ZONE_AIRBASE was given, we make the helo land in the pickup zone. Coordinate:SetAltitude(200) - local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate) - waypoint.detour=true + local waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=true else self:E(self.lid.."ERROR: Carrier aircraft cannot land in Deploy zone! Specify a ZONE_AIRBASE as deploy zone") @@ -6461,12 +6440,10 @@ function OPSGROUP:onafterBoard(From, Event, To, CarrierGroup, Carrier) self:ClearWaypoints() if self.isArmygroup then - local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate) - waypoint.detour=true + local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=0 self:Cruise() else - local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate) - waypoint.detour=true + local waypoint=NAVYGROUP.AddWaypoint(self, Coordinate) ; waypoint.detour=0 self:Cruise() end @@ -7322,6 +7299,7 @@ function OPSGROUP._PassingWaypoint(group, opsgroup, uid) opsgroup:Cruise() else opsgroup:E("ERROR: waypoint.detour should be 0 or 1") + opsgroup:FullStop() end end