This commit is contained in:
Frank
2020-05-07 00:00:35 +02:00
parent 853989bfc9
commit c30d9f3472
3 changed files with 145 additions and 57 deletions
+125 -44
View File
@@ -438,9 +438,6 @@ function FLIGHTCONTROL:OnEventBirth(EventData)
-- We delay this, to have all elements of the group in the game. -- We delay this, to have all elements of the group in the game.
if unit:IsAir() then if unit:IsAir() then
-- Coordinate.
local coordinate=unit:GetCoordinate()
self:ScheduleOnce(0.5, self._CreateFlightGroup, self, EventData.IniGroup) self:ScheduleOnce(0.5, self._CreateFlightGroup, self, EventData.IniGroup)
self:SpawnParkingGuard(unit) self:SpawnParkingGuard(unit)
@@ -608,13 +605,15 @@ function FLIGHTCONTROL:_CheckQueues()
-- Takeoff flight -- -- Takeoff flight --
-------------------- --------------------
-- No other flight is taking of or landing. -- No other flight is taking off or landing.
if ntakeoff==0 and nlanding==0 then if ntakeoff==0 and nlanding==0 then
-- Check if flight is AI. Humans have to request taxi via F10 menu. -- Check if flight is AI. Humans have to request taxi via F10 menu.
if flight.ai then if flight.ai then
-- NOTE that AI will start taxiing once they started their engine. ---
-- AI
---
-- Message. -- Message.
local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname) local text=string.format("Flight %s, you are cleared to taxi to runway.", flight.groupname)
@@ -628,8 +627,21 @@ function FLIGHTCONTROL:_CheckQueues()
-- Add flight to takeoff queue. -- Add flight to takeoff queue.
self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAKEOFF) self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.TAKEOFF)
-- Remove parking guards.
for _,_element in pairs(flight.elements) do
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
if element and element.parking then
local spot=self:GetParkingSpotByID(element.parking.TerminalID)
self:RemoveParkingGuard(spot)
end
end
else else
---
-- PLAYER
---
local text=string.format("HUMAN Flight %s, you are cleared for takeoff.", flight.groupname) local text=string.format("HUMAN Flight %s, you are cleared for takeoff.", flight.groupname)
self:I(self.lid..text) self:I(self.lid..text)
@@ -637,15 +649,6 @@ function FLIGHTCONTROL:_CheckQueues()
end end
-- Remove parking guards.
for _,_element in pairs(flight.elements) do
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
if element and element.parking then
local spot=self:GetParkingSpotByID(element.parking.TerminalID)
self:RemoveParkingGuard(spot)
end
end
else else
self:I(self.lid..string.format("FYI: Take of for flight %s denied as other flights are taking off (N=%d) or landing (N=%d).", flight.groupname, ntakeoff, nlanding)) self:I(self.lid..string.format("FYI: Take of for flight %s denied as other flights are taking off (N=%d) or landing (N=%d).", flight.groupname, ntakeoff, nlanding))
end end
@@ -774,15 +777,16 @@ end
-- @return Ops.FlightGroup#FLIGHTGROUP Marshal flight next in line and ready to enter the pattern. Or nil if no flight is ready. -- @return Ops.FlightGroup#FLIGHTGROUP Marshal flight next in line and ready to enter the pattern. Or nil if no flight is ready.
function FLIGHTCONTROL:_GetNextFightParking() function FLIGHTCONTROL:_GetNextFightParking()
-- Get flights taxiing to runway for takeoff. -- Get flights ready for take off.
local Qtaxiout=self:GetFlights(FLIGHTCONTROL.FlightStatus.TAXIOUT) local QreadyTO=self:GetFlights(FLIGHTCONTROL.FlightStatus.READYTO)
-- First check human players. -- First check human players.
if #Qtaxiout>0 then if #QreadyTO>0 then
-- TODO: Could be sorted by distance to active runway! Take the runway spawn point for distance measure. -- TODO: Could be sorted by distance to active runway! Take the runway spawn point for distance measure.
-- First come, first serve. -- First come, first serve.
return Qtaxiout[1] return QreadyTO[1]
end end
@@ -792,8 +796,6 @@ function FLIGHTCONTROL:_GetNextFightParking()
-- Check special cases where only up to one flight is waiting for takeoff. -- Check special cases where only up to one flight is waiting for takeoff.
if #Qparking==0 then if #Qparking==0 then
return nil return nil
elseif #Qparking==1 then
return Qparking[1]
end end
-- Sort flights parking time. -- Sort flights parking time.
@@ -806,12 +808,23 @@ function FLIGHTCONTROL:_GetNextFightParking()
-- Return flight waiting longest. -- Return flight waiting longest.
table.sort(Qparking, _sortByTparking) table.sort(Qparking, _sortByTparking)
-- Debug.
local text="Parking flights:"
for i,_flight in pairs(Qparking) do for i,_flight in pairs(Qparking) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
env.info(string.format("%d %s %.1f", i, flight.groupname, flight.Tparking)) text=text..string.format("\n[%d] %s %.1f", i, flight.groupname, flight.Tparking)
end
self:I(self.lid..text)
-- Get the first AI flight.
for i,_flight in pairs(Qparking) do
local flight=_flight --Ops.FlightGroup#FLIGHTGROUP
if flight.ai then
return flight
end
end end
return Qparking[1] return nil
end end
--- Print queue. --- Print queue.
@@ -1066,15 +1079,45 @@ function FLIGHTCONTROL:_InitParkingSpots()
spot.Marker.tocoaliton=true spot.Marker.tocoaliton=true
spot.Marker.coalition=self:GetCoalition() spot.Marker.coalition=self:GetCoalition()
-- Set spot to occupied. -- Check if spot is initially free or occupied.
if spot.Free then if spot.Free then
-- Parking spot is free.
self:SetParkingFree(spot) self:SetParkingFree(spot)
else else
-- Scan for the unit sitting here.
local unit=spot.Coordinate:FindClosestUnit(20) local unit=spot.Coordinate:FindClosestUnit(20)
if unit and unit:IsAlive() then
if unit then
local unitname=unit and unit:GetName() or "unknown" local unitname=unit and unit:GetName() or "unknown"
self:SetParkingOccupied(spot, unitname)
self:SpawnParkingGuard(unit) local isalive=unit:IsAlive()
env.info(string.format("FF parking spot %d is occupied by unit %s alive=%s", spot.TerminalID, unitname, tostring(isalive)))
if isalive then
self:SetParkingOccupied(spot, unitname)
self:SpawnParkingGuard(unit)
else
-- TODO
env.info(string.format("FF parking spot %d is occupied by NOT ALIVE unit %s", spot.TerminalID, unitname))
-- Parking spot is free.
self:SetParkingFree(spot)
end
else
self:I(self.lid..string.format("ERROR: Parking spot is NOT FREE but no unit could be found there!"))
end end
end end
@@ -1337,7 +1380,7 @@ function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
local rootmenu=atcmenu[airbasename].root --Core.Menu#MENU_GROUP_DELAYED local rootmenu=atcmenu[airbasename].root --Core.Menu#MENU_GROUP_DELAYED
-- Some info. -- Help Menu.
local helpmenu=MENU_GROUP_DELAYED:New(group, "Help", rootmenu):SetTime(Tnow):SetTag(Tag) local helpmenu=MENU_GROUP_DELAYED:New(group, "Help", rootmenu):SetTime(Tnow):SetTag(Tag)
-- Some info. -- Some info.
@@ -1346,30 +1389,57 @@ function FLIGHTCONTROL:_CreatePlayerMenu(flight, atcmenu)
MENU_GROUP_COMMAND_DELAYED:New(group, "Queues", infomenu, self._PlayerRequestInfoQueues, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Queues", infomenu, self._PlayerRequestInfoQueues, self, groupname):SetTime(Tnow):SetTag(Tag)
MENU_GROUP_COMMAND_DELAYED:New(group, "ATIS", infomenu, self._PlayerRequestInfoATIS, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "ATIS", infomenu, self._PlayerRequestInfoATIS, self, groupname):SetTime(Tnow):SetTag(Tag)
-- Root Commands -- Root Commands.
if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then
---
-- FC is controlling this flight
---
if flight:IsParking() then if flight:IsParking() then
---
-- Parking
---
MENU_GROUP_COMMAND_DELAYED:New(group, "Request Taxi", rootmenu, self._PlayerRequestTaxi, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Request Taxi", rootmenu, self._PlayerRequestTaxi, self, groupname):SetTime(Tnow):SetTag(Tag)
elseif flight:IsTaxiing() then elseif flight:IsTaxiing() then
---
-- Taxiing
---
MENU_GROUP_COMMAND_DELAYED:New(group, "Request Takeoff", rootmenu, self._PlayerRequestTakeoff, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Request Takeoff", rootmenu, self._PlayerRequestTakeoff, self, groupname):SetTime(Tnow):SetTag(Tag)
MENU_GROUP_COMMAND_DELAYED:New(group, "Abort Takeoff", rootmenu, self._PlayerAbortTakeoff, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Abort Takeoff", rootmenu, self._PlayerAbortTakeoff, self, groupname):SetTime(Tnow):SetTag(Tag)
elseif flight:IsAirborne() then elseif flight:IsAirborne() then
---
-- Airborne
---
end end
if flight:IsInbound() or flight:IsHolding() or flight:IsLanding() or flight:IsLanded() then if flight:IsInbound() or flight:IsHolding() or flight:IsLanding() or flight:IsLanded() then
MENU_GROUP_COMMAND_DELAYED:New(group, "Request Parking", rootmenu, self._PlayerRequestParking, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Request Parking", rootmenu, self._PlayerRequestParking, self, groupname):SetTime(Tnow):SetTag(Tag)
end end
else else
---
-- FC is NOT controlling this flight
---
if flight:IsAirborne() then if flight:IsAirborne() then
if self:GetFlightStatus(flight)==FLIGHTCONTROL.FlightStatus.INBOUND then if self:GetFlightStatus(flight)==FLIGHTCONTROL.FlightStatus.INBOUND then
MENU_GROUP_COMMAND_DELAYED:New(group, "Holding", rootmenu, self._PlayerInbound, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Holding", rootmenu, self._PlayerInbound, self, groupname):SetTime(Tnow):SetTag(Tag)
else else
MENU_GROUP_COMMAND_DELAYED:New(group, "Inbound", rootmenu, self._PlayerHolding, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "Inbound", rootmenu, self._PlayerHolding, self, groupname):SetTime(Tnow):SetTag(Tag)
end end
end end
end end
if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then if flight.flightcontrol and flight.flightcontrol.airbasename==self.airbasename then
MENU_GROUP_COMMAND_DELAYED:New(group, "My Status", rootmenu, self._PlayerMyStatus, self, groupname):SetTime(Tnow):SetTag(Tag) MENU_GROUP_COMMAND_DELAYED:New(group, "My Status", rootmenu, self._PlayerMyStatus, self, groupname):SetTime(Tnow):SetTag(Tag)
end end
@@ -1572,11 +1642,13 @@ function FLIGHTCONTROL:_PlayerMyStatus(groupname)
local flight=_DATABASE:GetFlightGroup(groupname) local flight=_DATABASE:GetFlightGroup(groupname)
if flight then if flight then
local fc=flight.flightcontrol
local text=string.format("My Status:") local text=string.format("My Status:")
text=text..string.format("\nFlight control: %s", tostring(flight.flightcontrol and flight.flightcontrol.airbasename or "N/A"))
text=text..string.format("\nFlight status: %s", tostring(flight:GetState())) text=text..string.format("\nFlight status: %s", tostring(flight:GetState()))
text=text..string.format("\nFlight control: %s status=%s", tostring(fc and fc.airbasename or "N/A"), tostring(fc and fc:GetFlightStatus(flight) or "N/A"))
MESSAGE:New(text, 5):ToGroup(flight.group) MESSAGE:New(text, 5):ToGroup(flight.group)
else else
@@ -1607,9 +1679,13 @@ function FLIGHTCONTROL:_PlayerRequestTaxi(groupname)
local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element local element=_element --Ops.FlightGroup#FLIGHTGROUP.Element
if element.parking then if element.parking then
local spot=self:GetParkingSpotByID(element.parking.TerminalID) local spot=self:GetParkingSpotByID(element.parking.TerminalID)
self:RemoveParkingGuard(spot) if element.ai then
self:RemoveParkingGuard(spot, 30)
else
self:RemoveParkingGuard(spot, 3)
end
end end
flight:ElementTaxiing(element) --flight:ElementTaxiing(element)
end end
else else
@@ -1649,8 +1725,6 @@ function FLIGHTCONTROL:_PlayerRequestTakeoff(groupname)
self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.READYTO) self:SetFlightStatus(flight, FLIGHTCONTROL.FlightStatus.READYTO)
end end
else else
MESSAGE:New(string.format("Negative, you must request TAXI before you can request TAKEOFF!"), 5):ToAll() MESSAGE:New(string.format("Negative, you must request TAXI before you can request TAKEOFF!"), 5):ToAll()
end end
@@ -1958,7 +2032,7 @@ end
--- Add parking guard in front of a parking aircraft. --- Add parking guard in front of a parking aircraft.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param Wrapper.Unit#UNIT Unit The aircraft. -- @param Wrapper.Unit#UNIT unit The aircraft.
function FLIGHTCONTROL:SpawnParkingGuard(unit) function FLIGHTCONTROL:SpawnParkingGuard(unit)
if unit and self.parkingGuard then if unit and self.parkingGuard then
@@ -1975,10 +2049,10 @@ function FLIGHTCONTROL:SpawnParkingGuard(unit)
-- Length of the unit + 3 meters. -- Length of the unit + 3 meters.
local size, x, y, z=unit:GetObjectSize() local size, x, y, z=unit:GetObjectSize()
self:I(self.lid..string.format("Parking guard for %s: heading=%d, distance size=%s x=%s y=%s z=%s", unit:GetName(), heading, tostring(size), tostring(x), tostring(y), tostring(z))) self:I(self.lid..string.format("Parking guard for %s: heading=%d, distance x=%.1f m", unit:GetName(), heading, x))
-- Coordinate for the guard. -- Coordinate for the guard.
local Coordinate=coordinate:Translate(x+3, heading) local Coordinate=coordinate:Translate(0.75*x+3, heading)
-- Let him face the aircraft. -- Let him face the aircraft.
local lookat=heading-180 local lookat=heading-180
@@ -1996,11 +2070,18 @@ end
--- Remove parking guard. --- Remove parking guard.
-- @param #FLIGHTCONTROL self -- @param #FLIGHTCONTROL self
-- @param #FLIGHTCONTROL.ParkingSpot spot -- @param #FLIGHTCONTROL.ParkingSpot spot
function FLIGHTCONTROL:RemoveParkingGuard(spot) -- @param #number delay Delay in seconds.
function FLIGHTCONTROL:RemoveParkingGuard(spot, delay)
if spot.ParkingGuard then if delay and delay>0 then
spot.ParkingGuard:Destroy() self:ScheduleOnce(delay, FLIGHTCONTROL.RemoveParkingGuard, self, spot)
spot.ParkingGuard=nil else
if spot.ParkingGuard then
spot.ParkingGuard:Destroy()
spot.ParkingGuard=nil
end
end end
end end
+15 -8
View File
@@ -831,12 +831,13 @@ end
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFlightControl(flightcontrol) function FLIGHTGROUP:SetFlightControl(flightcontrol)
-- Remove flight from previous FC. -- Check if there is already a FC.
if self.flightcontrol then if self.flightcontrol then
if self.flightcontrol.airbasename==flightcontrol.airbasename then if self.flightcontrol.airbasename==flightcontrol.airbasename then
-- Flight control is already controlling this flight! -- Flight control is already controlling this flight!
return return
else else
-- Remove flight from previous FC.
self.flightcontrol:_RemoveFlight(self) self.flightcontrol:_RemoveFlight(self)
end end
end end
@@ -2283,7 +2284,7 @@ function FLIGHTGROUP:onafterElementTakeoff(From, Event, To, Element, airbase)
self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAKEOFF, airbase) self:_UpdateStatus(Element, FLIGHTGROUP.ElementStatus.TAKEOFF, airbase)
-- Trigger element airborne event. -- Trigger element airborne event.
self:__ElementAirborne(10, Element) self:__ElementAirborne(2, Element)
end end
--- On after "ElementAirborne" event. --- On after "ElementAirborne" event.
@@ -2367,9 +2368,8 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function FLIGHTGROUP:onafterFlightSpawned(From, Event, To) function FLIGHTGROUP:onafterFlightSpawned(From, Event, To)
self:T(self.lid..string.format("Flight spawned!")) self:I(self.lid..string.format("Flight spawned!"))
if self.ai then if self.ai then
-- Set default ROE and ROT options. -- Set default ROE and ROT options.
@@ -2461,6 +2461,8 @@ function FLIGHTGROUP:onafterFlightTaxiing(From, Event, To)
else else
-- Human flights go to TAXI OUT queue. They will go to the ready for takeoff queue when they request it. -- Human flights go to TAXI OUT queue. They will go to the ready for takeoff queue when they request it.
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIOUT) self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIOUT)
-- Update menu.
self:_UpdateMenu()
end end
end end
@@ -2626,6 +2628,11 @@ function FLIGHTGROUP:onbeforeUpdateRoute(From, Event, To, n)
-- Not good, because mission will never start. Better only check if there is a current task! -- Not good, because mission will never start. Better only check if there is a current task!
--if self.currentmission then --if self.currentmission then
--end --end
-- Only AI flights.
if not self.ai then
allowed=false
end
-- Debug info. -- Debug info.
self:T2(self.lid..string.format("Onbefore Updateroute allowed=%s state=%s repeat in %s", tostring(allowed), self:GetState(), tostring(trepeat))) self:T2(self.lid..string.format("Onbefore Updateroute allowed=%s state=%s repeat in %s", tostring(allowed), self:GetState(), tostring(trepeat)))
@@ -2792,7 +2799,7 @@ end
-- @param #number delay Delay in seconds. -- @param #number delay Delay in seconds.
function FLIGHTGROUP:_CheckFlightDone(delay) function FLIGHTGROUP:_CheckFlightDone(delay)
if self:IsAlive() then if self:IsAlive() and not self.ai then
if delay and delay>0 then if delay and delay>0 then
-- Delayed call. -- Delayed call.
@@ -2824,10 +2831,10 @@ function FLIGHTGROUP:_CheckFlightDone(delay)
-- Send flight to destination. -- Send flight to destination.
if self.destbase then if self.destbase then
self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTB!") self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTB!")
self:__RTB(-1, self.destbase) self:__RTB(-3, self.destbase)
elseif self.destzone then elseif self.destzone then
self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTZ!") self:I(self.lid.."Passed Final WP and No current and/or future missions/task ==> RTZ!")
self:__RTZ(-1, self.destzone) self:__RTZ(-3, self.destzone)
else else
self:I(self.lid.."Passed Final WP and NO Tasks/Missions left. No DestBase or DestZone ==> Wait!") self:I(self.lid.."Passed Final WP and NO Tasks/Missions left. No DestBase or DestZone ==> Wait!")
self:__Wait(-1) self:__Wait(-1)
+5 -5
View File
@@ -74,10 +74,10 @@
-- --
-- # Updating a Marker -- # Updating a Marker
-- --
-- The marker text and/coordinate can be updated easily as shown below. -- The marker text and coordinate can be updated easily as shown below.
-- --
-- However, note that updateing involves to remove and recreate the marker if either text or its coordinate is changed. -- However, note that **updateing involves to remove and recreate the marker if either text or its coordinate is changed**.
-- This is a DCS scripting engine limitation. -- *This is a DCS scripting engine limitation.*
-- --
-- ## Update Text -- ## Update Text
-- --
@@ -101,7 +101,7 @@
-- --
-- # Retrieve Data -- # Retrieve Data
-- --
-- The important data as the displayed text and the coordinate of the marker can be retrieved quite easily. -- The important data as the displayed text and the coordinate of the marker can be retrieved easily.
-- --
-- ## Text -- ## Text
-- --
@@ -588,7 +588,7 @@ end
--- Set text that is displayed in the marker panel. Note this does not show the marker. --- Set text that is displayed in the marker panel. Note this does not show the marker.
-- @param #MARKER self -- @param #MARKER self
-- @param #string Text Marker text. -- @param #string Text Marker text. Default is an empty sting "".
-- @return #MARKER self -- @return #MARKER self
function MARKER:SetText(Text) function MARKER:SetText(Text)
self.text=Text and tostring(Text) or "" self.text=Text and tostring(Text) or ""