mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
AIRBOSS v0.9.8
This commit is contained in:
parent
48c7254c84
commit
b6a19d34c6
@ -842,7 +842,10 @@
|
|||||||
-- a naval unit (i.e. the carrier).
|
-- a naval unit (i.e. the carrier).
|
||||||
--
|
--
|
||||||
-- As a workaround, you can put an aircraft, e.g. a Helicopter on the deck of the carrier or another ship of the strike group. The aircraft should be set to
|
-- As a workaround, you can put an aircraft, e.g. a Helicopter on the deck of the carrier or another ship of the strike group. The aircraft should be set to
|
||||||
-- uncontrolled and maybe even to immortal. With the @{#AIRBOSS.SetRadioUnit}(*unitname*) function you can use this unit as "radio repeater".
|
-- uncontrolled and maybe even to immortal. With the @{#AIRBOSS.SetRadioUnitName}(*unitname*) function you can use this unit as "radio repeater" for both Marshal and LSO
|
||||||
|
-- radio channels. However, this might lead to interruptions in the transmission if both channels transmit simultaniously. Therefore, it is better to assign a unit for
|
||||||
|
-- each radio via the @{#AIRBOSS.SetRadioRelayLSO}(unitname) and @{#AIRBOSS.SetRadioRelayMarshal}(unitname) functions.
|
||||||
|
--
|
||||||
-- Of course you can also use any other aircraft in the vicinity of the carrier, e.g. a rescue helo or a recovery tanker. It is just important that this
|
-- Of course you can also use any other aircraft in the vicinity of the carrier, e.g. a rescue helo or a recovery tanker. It is just important that this
|
||||||
-- unit is and stays close the the boat as the distance from the sender to the receiver is modeled in DCS. So messages from too far away might not reach the players.
|
-- unit is and stays close the the boat as the distance from the sender to the receiver is modeled in DCS. So messages from too far away might not reach the players.
|
||||||
--
|
--
|
||||||
@ -880,6 +883,27 @@
|
|||||||
--
|
--
|
||||||
-- If no AI handling is desired, this can be turned off via the @{#AIRBOSS.SetHandleAIOFF} function.
|
-- If no AI handling is desired, this can be turned off via the @{#AIRBOSS.SetHandleAIOFF} function.
|
||||||
--
|
--
|
||||||
|
-- In case only specifc AI groups shall be excluded, it can be done by adding the groups to a set, e.g.
|
||||||
|
--
|
||||||
|
-- -- AI groups explicitly excluded from handling by the Airboss
|
||||||
|
-- local CarrierExcludeSet=SET_GROUP:New():FilterPrefixes("E-2D Wizard Group"):FilterStart()
|
||||||
|
-- AirbossStennis:SetExcludeAI(CarrierExcludeSet)
|
||||||
|
--
|
||||||
|
-- Similarly, to the @{#AIRBOSS.SetExcludeAI} function, AI groups can be explicitly *included* via the @{#AIRBOSS.SetSquadronAI} function. If this is used, only the *included* groups are handled
|
||||||
|
-- by the AIRBOSS.
|
||||||
|
--
|
||||||
|
-- ## Refueling
|
||||||
|
--
|
||||||
|
-- AI groups in the marshal pattern can be send to refuel at the recovery tanker or if none is defined to the nearest divert airfield. This can be enabled by the @{AIRBOSS.SetRefuelAI}(*lowfuelthreshold*).
|
||||||
|
-- The parameter *lowfuelthreshold* is the threshold of fuel in percent. If the fuel drops below this value, the group will go for refueling. If refueling is performed at the recovery tanker,
|
||||||
|
-- the group will return to the marshal stack when done. The aircraft will not return from the divert airfield however.
|
||||||
|
--
|
||||||
|
-- ## Respawning - DCS Landing Bug
|
||||||
|
--
|
||||||
|
-- AI groups that enter the CCA are usually guided to Marshal stack. However, due to DCS limitations they might not obey the landing task if they have another airfield as departure and/or destination in
|
||||||
|
-- their mission task. Therefore, AI groups can be respawned when detected in the CCA. This should clear all other airfields and allow the aircraft to land on the carrier.
|
||||||
|
-- This is achieved by the @{AIRBOSS.SetRespawnAI}() function.
|
||||||
|
--
|
||||||
-- ## Known Issues
|
-- ## Known Issues
|
||||||
--
|
--
|
||||||
-- Dealing with the DCS AI is a big challenge and there is only so much one can do. Please bear this in mind!
|
-- Dealing with the DCS AI is a big challenge and there is only so much one can do. Please bear this in mind!
|
||||||
@ -1362,7 +1386,6 @@ AIRBOSS.Difficulty={
|
|||||||
-- @field #number LUE Lineup error in degrees.
|
-- @field #number LUE Lineup error in degrees.
|
||||||
-- @field #number Roll Roll angle.
|
-- @field #number Roll Roll angle.
|
||||||
-- @field #number Rhdg Relative heading player to carrier. 0=parallel, +-90=perpendicular.
|
-- @field #number Rhdg Relative heading player to carrier. 0=parallel, +-90=perpendicular.
|
||||||
-- @field #number TGroove Time stamp when pilot entered the groove.
|
|
||||||
-- @field #string FlyThrough Fly through up "/" or fly through down "\\".
|
-- @field #string FlyThrough Fly through up "/" or fly through down "\\".
|
||||||
|
|
||||||
--- LSO grade data.
|
--- LSO grade data.
|
||||||
@ -1416,6 +1439,7 @@ AIRBOSS.Difficulty={
|
|||||||
-- @field #table elements Flight group elements.
|
-- @field #table elements Flight group elements.
|
||||||
-- @field #number Tcharlie Charlie (abs) time in seconds.
|
-- @field #number Tcharlie Charlie (abs) time in seconds.
|
||||||
-- @field #string name Player name or name of first AI unit.
|
-- @field #string name Player name or name of first AI unit.
|
||||||
|
-- @field #boolean refueling Flight is refueling.
|
||||||
|
|
||||||
--- Parameters of an element in a flight group.
|
--- Parameters of an element in a flight group.
|
||||||
-- @type AIRBOSS.FlightElement
|
-- @type AIRBOSS.FlightElement
|
||||||
@ -1707,7 +1731,7 @@ function AIRBOSS:New(carriername, alias)
|
|||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
-- Debug trace.
|
-- Debug trace.
|
||||||
if true then
|
if false then
|
||||||
--self.Debug=true
|
--self.Debug=true
|
||||||
BASE:TraceOnOff(true)
|
BASE:TraceOnOff(true)
|
||||||
BASE:TraceClass(self.ClassName)
|
BASE:TraceClass(self.ClassName)
|
||||||
@ -1715,17 +1739,20 @@ function AIRBOSS:New(carriername, alias)
|
|||||||
self.dTstatus=0.1
|
self.dTstatus=0.1
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:_GetZoneGroove():SmokeZone(SMOKECOLOR.Red, 5)
|
|
||||||
|
|
||||||
-- Smoke zones.
|
-- Smoke zones.
|
||||||
if self.Debug and false then
|
if self.Debug and false then
|
||||||
local case=2
|
local case=2
|
||||||
|
self.holdingoffset=30
|
||||||
|
self:_GetZoneGroove():SmokeZone(SMOKECOLOR.Red, 5)
|
||||||
self:_GetZoneBullseye(case):SmokeZone(SMOKECOLOR.White, 45)
|
self:_GetZoneBullseye(case):SmokeZone(SMOKECOLOR.White, 45)
|
||||||
self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45)
|
self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45)
|
||||||
self:_GetZoneArcIn(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
self:_GetZoneArcIn(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
||||||
self:_GetZoneArcOut(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
self:_GetZoneArcOut(case):SmokeZone(SMOKECOLOR.Blue, 45)
|
||||||
self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Red, 45)
|
self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Red, 45)
|
||||||
self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45)
|
self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45)
|
||||||
|
self:_GetZoneHolding(case, 1):SmokeZone(SMOKECOLOR.White, 45)
|
||||||
|
self:_GetZoneInitial(case):SmokeZone(SMOKECOLOR.Orange, 45)
|
||||||
|
self:_GetZoneCommence(1):SmokeZone(SMOKECOLOR.Red, 45)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Carrier parameter debug tests.
|
-- Carrier parameter debug tests.
|
||||||
@ -2280,6 +2307,15 @@ function AIRBOSS:SetRespawnAI(switch)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Give AI aircraft the refueling task if a recovery tanker is present or send them to the nearest divert airfield.
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #number lowfuelthreshold Low fuel threshold in percent. AI will go refueling if their fuel level drops below this value. Default 10 %.
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:SetRefuelAI(lowfuelthreshold)
|
||||||
|
self.lowfuelAI=lowfuelthreshold or 10
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set folder where the airboss sound files are located **within you mission (miz) file**.
|
--- Set folder where the airboss sound files are located **within you mission (miz) file**.
|
||||||
-- The default path is "l10n/DEFAULT/" but sound files simply copied there will be removed by DCS the next time you save the mission.
|
-- The default path is "l10n/DEFAULT/" but sound files simply copied there will be removed by DCS the next time you save the mission.
|
||||||
@ -3002,11 +3038,16 @@ function AIRBOSS:_CheckAIStatus()
|
|||||||
-- Only AI!
|
-- Only AI!
|
||||||
if flight.ai then
|
if flight.ai then
|
||||||
|
|
||||||
-- TODO: Check that aircraft can be refueled.
|
-- Get fuel amount in %.
|
||||||
local fuel=flight.group:GetFuelMin()*100
|
local fuel=flight.group:GetFuelMin()*100
|
||||||
|
|
||||||
if self.lowfuelAI and fuel<self.lowfuelAI then
|
-- Debug text.
|
||||||
--self:_RefuelAI(flight)
|
local text=string.format("Group %s fuel=%.1f %%", flight.groupname, fuel)
|
||||||
|
self:T3(self.lid..text)
|
||||||
|
|
||||||
|
-- Send AI for refueling at tanker or divert field.
|
||||||
|
if self.lowfuelAI and fuel<self.lowfuelAI and not flight.refueling then
|
||||||
|
self:_RefuelAI(flight)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -5267,9 +5308,9 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn)
|
|||||||
self:_AddMarshalGroup(flight, nstack)
|
self:_AddMarshalGroup(flight, nstack)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Explot unit.
|
-- Explode unit for testing. Worked!
|
||||||
local u1=flight.group:GetUnit(1) --Wrapper.Unit#UNIT
|
--local u1=flight.group:GetUnit(1) --Wrapper.Unit#UNIT
|
||||||
u1:Explode(500, 10)
|
--u1:Explode(500, 10)
|
||||||
|
|
||||||
-- Recovery case.
|
-- Recovery case.
|
||||||
local case=flight.case
|
local case=flight.case
|
||||||
@ -5420,7 +5461,26 @@ function AIRBOSS:_RefuelAI(flight)
|
|||||||
-- Current positon.
|
-- Current positon.
|
||||||
wp[#wp+1]=flight.group:GetCoordinate():WaypointAirTurningPoint(nil, CurrentSpeed, {}, "Current position")
|
wp[#wp+1]=flight.group:GetCoordinate():WaypointAirTurningPoint(nil, CurrentSpeed, {}, "Current position")
|
||||||
|
|
||||||
if self.tanker then
|
-- Check if aircraft can be refueled.
|
||||||
|
-- TODO: This should also depend on the tanker type AC.
|
||||||
|
local refuelac=false
|
||||||
|
local actype=flight.group:GetTypeName()
|
||||||
|
if actype==AIRBOSS.AircraftCarrier.AV8B or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.F14A or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.F14B or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.F14A_AI or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.HORNET or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.FA18C or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.S3B or
|
||||||
|
actype==AIRBOSS.AircraftCarrier.S3BTANKER then
|
||||||
|
refuelac=true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Message.
|
||||||
|
local text=""
|
||||||
|
|
||||||
|
-- Refuel or divert?
|
||||||
|
if self.tanker and refuelac then
|
||||||
|
|
||||||
-- Current Tanker position.
|
-- Current Tanker position.
|
||||||
local tankerpos=self.tanker.tanker:GetCoordinate()
|
local tankerpos=self.tanker.tanker:GetCoordinate()
|
||||||
@ -5434,6 +5494,9 @@ function AIRBOSS:_RefuelAI(flight)
|
|||||||
-- Waypoint with tasks.
|
-- Waypoint with tasks.
|
||||||
wp[#wp+1]=tankerpos:WaypointAirTurningPoint(nil, CurrentSpeed, {TaskRefuel, TaskMarshal}, "Refueling")
|
wp[#wp+1]=tankerpos:WaypointAirTurningPoint(nil, CurrentSpeed, {TaskRefuel, TaskMarshal}, "Refueling")
|
||||||
|
|
||||||
|
-- Message.
|
||||||
|
text="going to recovery tanker for some gas."
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
------------------------------
|
------------------------------
|
||||||
@ -5449,14 +5512,24 @@ function AIRBOSS:_RefuelAI(flight)
|
|||||||
-- Landing waypoint.
|
-- Landing waypoint.
|
||||||
wp[#wp+1]=divertcoord:WaypointAirLanding(UTILS.KnotsToKmph(200), divertfield, {}, "Divert Field")
|
wp[#wp+1]=divertcoord:WaypointAirLanding(UTILS.KnotsToKmph(200), divertfield, {}, "Divert Field")
|
||||||
|
|
||||||
|
-- Message
|
||||||
|
text=string.format("going to divert field %s to get some gas.", divertfield:GetName())
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Message to marshal.
|
||||||
|
self:MessageToMarshal(text, flight.onboard, nil, self.Tmessage)
|
||||||
|
self:I(self.lid..flight.groupname.." "..text)
|
||||||
|
|
||||||
-- Reinit waypoints.
|
-- Reinit waypoints.
|
||||||
flight.group:WayPointInitialize(wp)
|
flight.group:WayPointInitialize(wp)
|
||||||
|
|
||||||
-- Route group.
|
-- Route group.
|
||||||
flight.group:Route(wp, 0)
|
flight.group:Route(wp, 0)
|
||||||
|
|
||||||
|
-- Set refueling switch.
|
||||||
|
flight.refueling=true
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Tell AI to land on the carrier.
|
--- Tell AI to land on the carrier.
|
||||||
@ -6138,6 +6211,7 @@ function AIRBOSS:_CreateFlightGroup(group)
|
|||||||
flight.seclead=flight.group:GetUnit(1):GetName() -- Sec lead is first unitname of group but player name for players.
|
flight.seclead=flight.group:GetUnit(1):GetName() -- Sec lead is first unitname of group but player name for players.
|
||||||
flight.section={}
|
flight.section={}
|
||||||
flight.ballcall=false
|
flight.ballcall=false
|
||||||
|
flight.refueling=false
|
||||||
flight.holding=nil
|
flight.holding=nil
|
||||||
flight.name=flight.group:GetUnit(1):GetName() --Will be overwritten in _Newplayer with player name if human player in the group.
|
flight.name=flight.group:GetUnit(1):GetName() --Will be overwritten in _Newplayer with player name if human player in the group.
|
||||||
|
|
||||||
@ -6278,6 +6352,7 @@ function AIRBOSS:_InitPlayer(playerData, step)
|
|||||||
playerData.debrief={}
|
playerData.debrief={}
|
||||||
playerData.warning=nil
|
playerData.warning=nil
|
||||||
playerData.holding=nil
|
playerData.holding=nil
|
||||||
|
playerData.refueling=false
|
||||||
playerData.valid=false
|
playerData.valid=false
|
||||||
playerData.lig=false
|
playerData.lig=false
|
||||||
playerData.patternwo=false
|
playerData.patternwo=false
|
||||||
@ -6496,12 +6571,12 @@ function AIRBOSS:_CheckSectionRecovered(flight)
|
|||||||
|
|
||||||
-- Just for now, check if it is in other queues as well.
|
-- Just for now, check if it is in other queues as well.
|
||||||
if self:_InQueue(self.Qmarshal, lead.group) then
|
if self:_InQueue(self.Qmarshal, lead.group) then
|
||||||
self:E("ERROR: flight group should not be in marshal queue")
|
self:E(self.lid..string.format("ERROR: lead flight group %s should not be in marshal queue", lead.groupname))
|
||||||
self:_RemoveFlightFromMarshalQueue(lead, true)
|
self:_RemoveFlightFromMarshalQueue(lead, true)
|
||||||
end
|
end
|
||||||
-- Just for now, check if it is in other queues as well.
|
-- Just for now, check if it is in other queues as well.
|
||||||
if self:_InQueue(self.Qwaiting, lead.group) then
|
if self:_InQueue(self.Qwaiting, lead.group) then
|
||||||
self:E("ERROR: flight group should not be in pattern queue")
|
self:E(self.lid..string.format("ERROR: lead flight group %s should not be in pattern queue", lead.groupname))
|
||||||
self:_RemoveFlightFromQueue(self.Qwaiting, lead)
|
self:_RemoveFlightFromQueue(self.Qwaiting, lead)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -7056,18 +7131,7 @@ end
|
|||||||
-- @param #AIRBOSS.PlayerData playerData Player data.
|
-- @param #AIRBOSS.PlayerData playerData Player data.
|
||||||
function AIRBOSS:_SetTimeInGroove(playerData)
|
function AIRBOSS:_SetTimeInGroove(playerData)
|
||||||
|
|
||||||
--[[
|
-- Set time in the groove
|
||||||
|
|
||||||
-- Get time in the groove.
|
|
||||||
local gdataX0=playerData.groove.X0 --#AIRBOSS.GrooveData
|
|
||||||
if gdataX0 then
|
|
||||||
playerData.Tgroove=timer.getTime()-gdataX0.TGroove
|
|
||||||
else
|
|
||||||
playerData.Tgroove=9999
|
|
||||||
end
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
if playerData.TIG0 then
|
if playerData.TIG0 then
|
||||||
playerData.Tgroove=timer.getTime()-playerData.TIG0
|
playerData.Tgroove=timer.getTime()-playerData.TIG0
|
||||||
else
|
else
|
||||||
@ -7084,16 +7148,7 @@ function AIRBOSS:_GetTimeInGroove(playerData)
|
|||||||
|
|
||||||
local Tgroove=999
|
local Tgroove=999
|
||||||
|
|
||||||
--[[
|
|
||||||
|
|
||||||
-- Get time in the groove.
|
-- Get time in the groove.
|
||||||
local gdataX0=playerData.groove.X0 --#AIRBOSS.GrooveData
|
|
||||||
if gdataX0 then
|
|
||||||
Tgroove=timer.getTime()-gdataX0.TGroove
|
|
||||||
end
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
if playerData.TIG0 then
|
if playerData.TIG0 then
|
||||||
Tgroove=timer.getTime()-playerData.TIG0
|
Tgroove=timer.getTime()-playerData.TIG0
|
||||||
end
|
end
|
||||||
@ -7215,7 +7270,7 @@ function AIRBOSS:OnEventLand(EventData)
|
|||||||
|
|
||||||
-- Check if playerData is okay.
|
-- Check if playerData is okay.
|
||||||
if playerData==nil then
|
if playerData==nil then
|
||||||
self:E(self.lid.."ERROR: playerData nil in landing event.")
|
self:E(self.lid..string.format("ERROR: playerData nil in landing event. unit=%s player=%s", tostring(_unitName), tostring(_playername)))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -7234,6 +7289,8 @@ function AIRBOSS:OnEventLand(EventData)
|
|||||||
-- Clear queues just in case.
|
-- Clear queues just in case.
|
||||||
self:_RemoveFlightFromMarshalQueue(playerData, true)
|
self:_RemoveFlightFromMarshalQueue(playerData, true)
|
||||||
self:_RemoveFlightFromQueue(self.Qpattern, playerData)
|
self:_RemoveFlightFromQueue(self.Qpattern, playerData)
|
||||||
|
self:_RemoveFlightFromQueue(self.Qwaiting, playerData)
|
||||||
|
self:_RemoveFlightFromQueue(self.Qspinning, playerData)
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -7297,7 +7354,8 @@ function AIRBOSS:OnEventLand(EventData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
-- TODO: Handle case where player did not land on the carrier.
|
-- Handle case where player did not land on the carrier.
|
||||||
|
-- Well, I guess, he leaves the slot or ejects. Both should be handled.
|
||||||
if playerData then
|
if playerData then
|
||||||
self:E(self.lid..string.format("Player %s did not land in carrier box zone. Maybe in the water near the carrier?", playerData.name))
|
self:E(self.lid..string.format("Player %s did not land in carrier box zone. Maybe in the water near the carrier?", playerData.name))
|
||||||
end
|
end
|
||||||
@ -8375,7 +8433,6 @@ function AIRBOSS:_Final(playerData, nocheck)
|
|||||||
groovedata.LUE=self:_Lineup(playerData.unit, true)
|
groovedata.LUE=self:_Lineup(playerData.unit, true)
|
||||||
groovedata.Roll=roll
|
groovedata.Roll=roll
|
||||||
groovedata.Rhdg=relhead
|
groovedata.Rhdg=relhead
|
||||||
groovedata.TGroove=timer.getTime()
|
|
||||||
groovedata.FlyThrough=nil
|
groovedata.FlyThrough=nil
|
||||||
|
|
||||||
-- TODO: could add angled approach if lineup<5 and relhead>5. This would mean the player has not turned in correctly!
|
-- TODO: could add angled approach if lineup<5 and relhead>5. This would mean the player has not turned in correctly!
|
||||||
@ -9177,8 +9234,6 @@ function AIRBOSS:_GetZoneGroove(l, w)
|
|||||||
-- Stern coordinate.
|
-- Stern coordinate.
|
||||||
local st=self:_GetSternCoord()
|
local st=self:_GetSternCoord()
|
||||||
|
|
||||||
-- TODO: optimize for Tarawa. shift port.
|
|
||||||
|
|
||||||
-- Zone points.
|
-- Zone points.
|
||||||
local c1=st:Translate(self.carrierparam.totwidthstarboard, fbi-90)
|
local c1=st:Translate(self.carrierparam.totwidthstarboard, fbi-90)
|
||||||
local c2=st:Translate(UTILS.NMToMeters(0.10), fbi-90):Translate(UTILS.NMToMeters(0.3), fbi)
|
local c2=st:Translate(UTILS.NMToMeters(0.10), fbi-90):Translate(UTILS.NMToMeters(0.3), fbi)
|
||||||
@ -9252,7 +9307,7 @@ end
|
|||||||
-- @return Core.Zone#ZONE_RADIUS Arc in zone.
|
-- @return Core.Zone#ZONE_RADIUS Arc in zone.
|
||||||
function AIRBOSS:_GetZoneArcOut(case)
|
function AIRBOSS:_GetZoneArcOut(case)
|
||||||
|
|
||||||
-- Radius = 1 NM.
|
-- Radius = 1.25 NM.
|
||||||
local radius=UTILS.NMToMeters(1.25)
|
local radius=UTILS.NMToMeters(1.25)
|
||||||
|
|
||||||
-- Distance = 12 NM
|
-- Distance = 12 NM
|
||||||
@ -9276,7 +9331,7 @@ end
|
|||||||
-- @return Core.Zone#ZONE_RADIUS Arc in zone.
|
-- @return Core.Zone#ZONE_RADIUS Arc in zone.
|
||||||
function AIRBOSS:_GetZoneArcIn(case)
|
function AIRBOSS:_GetZoneArcIn(case)
|
||||||
|
|
||||||
-- Radius = 1 NM.
|
-- Radius = 1.25 NM.
|
||||||
local radius=UTILS.NMToMeters(1.25)
|
local radius=UTILS.NMToMeters(1.25)
|
||||||
|
|
||||||
-- Zone depends on Case recovery.
|
-- Zone depends on Case recovery.
|
||||||
@ -9286,8 +9341,7 @@ function AIRBOSS:_GetZoneArcIn(case)
|
|||||||
local alpha=math.rad(self.holdingoffset)
|
local alpha=math.rad(self.holdingoffset)
|
||||||
|
|
||||||
-- 14+x NM from carrier
|
-- 14+x NM from carrier
|
||||||
-- TODO
|
local x=14 --/math.cos(alpha)
|
||||||
local x=14/math.cos(alpha)
|
|
||||||
|
|
||||||
-- Distance = 14 NM
|
-- Distance = 14 NM
|
||||||
local distance=UTILS.NMToMeters(x)
|
local distance=UTILS.NMToMeters(x)
|
||||||
@ -9342,8 +9396,8 @@ function AIRBOSS:_GetZoneCorridor(case)
|
|||||||
-- Angle between radial and offset in rad.
|
-- Angle between radial and offset in rad.
|
||||||
local alpha=math.rad(self.holdingoffset)
|
local alpha=math.rad(self.holdingoffset)
|
||||||
|
|
||||||
-- Distance shift ahead of carrier to allow for some space to bolter
|
-- Distance shift ahead of carrier to allow for some space to bolter.
|
||||||
local dx=2
|
local dx=5
|
||||||
|
|
||||||
-- Width of the box in NM.
|
-- Width of the box in NM.
|
||||||
local w=2
|
local w=2
|
||||||
@ -9382,9 +9436,12 @@ function AIRBOSS:_GetZoneCorridor(case)
|
|||||||
self:T3(string.format("FF Q = %.1f NM", Q))
|
self:T3(string.format("FF Q = %.1f NM", Q))
|
||||||
|
|
||||||
local c={}
|
local c={}
|
||||||
c[1]=self:GetCoordinate():Translate(-UTILS.NMToMeters(dx), radial) --Carrier coordinate translated 2 NM in direction of travel to allow for bolter space.
|
local cv=self:GetCoordinate()
|
||||||
|
c[1]=cv:Translate(-UTILS.NMToMeters(dx), radial) --Carrier coordinate translated 2 NM in direction of travel to allow for bolter space.
|
||||||
|
|
||||||
if math.abs(self.holdingoffset)>1 then
|
if math.abs(self.holdingoffset)>=5 then
|
||||||
|
|
||||||
|
--[[
|
||||||
-- Complicated case with an angle.
|
-- Complicated case with an angle.
|
||||||
c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90) -- 1 Right of carrier.
|
c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90) -- 1 Right of carrier.
|
||||||
c[3]=c[2]:Translate( UTILS.NMToMeters(d+dx+w2), radial) -- 13 "south" @ 1 right
|
c[3]=c[2]:Translate( UTILS.NMToMeters(d+dx+w2), radial) -- 13 "south" @ 1 right
|
||||||
@ -9394,10 +9451,22 @@ function AIRBOSS:_GetZoneCorridor(case)
|
|||||||
c[9]=c[1]:Translate( UTILS.NMToMeters(w2), radial+90) -- 1 left of carrier.
|
c[9]=c[1]:Translate( UTILS.NMToMeters(w2), radial+90) -- 1 left of carrier.
|
||||||
c[8]=c[9]:Translate( UTILS.NMToMeters(d+dx-w2), radial) -- 1 left and 11 behind of carrier.
|
c[8]=c[9]:Translate( UTILS.NMToMeters(d+dx-w2), radial) -- 1 left and 11 behind of carrier.
|
||||||
c[7]=c[8]:Translate( UTILS.NMToMeters(P), radial+90)
|
c[7]=c[8]:Translate( UTILS.NMToMeters(P), radial+90)
|
||||||
|
]]
|
||||||
|
|
||||||
|
c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90) -- 1 Right of carrier, dx ahead.
|
||||||
|
c[3]=c[2]:Translate( UTILS.NMToMeters(d+dx+w2), radial) -- 13 "south" @ 1 right
|
||||||
|
|
||||||
|
c[4]=cv:Translate(UTILS.NMToMeters(15), offset):Translate(UTILS.NMToMeters(1), offset-90)
|
||||||
|
c[5]=cv:Translate(UTILS.NMToMeters(31), offset):Translate(UTILS.NMToMeters(1), offset-90)
|
||||||
|
c[6]=cv:Translate(UTILS.NMToMeters(31), offset):Translate(UTILS.NMToMeters(1), offset+90)
|
||||||
|
c[7]=cv:Translate(UTILS.NMToMeters(13), offset):Translate(UTILS.NMToMeters(1), offset+90)
|
||||||
|
c[8]=cv:Translate(UTILS.NMToMeters(11), radial):Translate(UTILS.NMToMeters(1), radial+90)
|
||||||
|
c[9]=c[1]:Translate(UTILS.NMToMeters(w2), radial+90)
|
||||||
|
|
||||||
|
|
||||||
-- Translate these points a bit for a smoother turn.
|
-- Translate these points a bit for a smoother turn.
|
||||||
c[4]=c[4]:Translate(UTILS.NMToMeters(2), offset)
|
--c[4]=c[4]:Translate(UTILS.NMToMeters(2), offset)
|
||||||
c[7]=c[7]:Translate(UTILS.NMToMeters(2), offset)
|
--c[7]=c[7]:Translate(UTILS.NMToMeters(2), offset)
|
||||||
else
|
else
|
||||||
-- Easy case of a long box.
|
-- Easy case of a long box.
|
||||||
c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90)
|
c[2]=c[1]:Translate( UTILS.NMToMeters(w2), radial-90)
|
||||||
@ -9958,9 +10027,10 @@ end
|
|||||||
--- Get wind direction and speed at carrier position.
|
--- Get wind direction and speed at carrier position.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #number alt Altitude ASL in meters. Default 50 m.
|
-- @param #number alt Altitude ASL in meters. Default 50 m.
|
||||||
|
-- @param #boolean magnetic Direction including magnetic declination.
|
||||||
-- @return #number Direction the wind is blowing **from** in degrees.
|
-- @return #number Direction the wind is blowing **from** in degrees.
|
||||||
-- @return #number Wind speed in m/s.
|
-- @return #number Wind speed in m/s.
|
||||||
function AIRBOSS:GetWind(alt)
|
function AIRBOSS:GetWind(alt, magnetic)
|
||||||
|
|
||||||
-- Current position of the carrier
|
-- Current position of the carrier
|
||||||
local cv=self:GetCoordinate()
|
local cv=self:GetCoordinate()
|
||||||
@ -9968,6 +10038,15 @@ function AIRBOSS:GetWind(alt)
|
|||||||
-- Wind direction and speed. By default at 50 meters ASL.
|
-- Wind direction and speed. By default at 50 meters ASL.
|
||||||
local Wdir, Wspeed=cv:GetWind(alt or 50)
|
local Wdir, Wspeed=cv:GetWind(alt or 50)
|
||||||
|
|
||||||
|
-- Include magnetic declination.
|
||||||
|
if magnetic then
|
||||||
|
Wdir=Wdir-self.magvar
|
||||||
|
-- Adjust negative values.
|
||||||
|
if Wdir<0 then
|
||||||
|
Wdir=Wdir+360
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return Wdir, Wspeed
|
return Wdir, Wspeed
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -10279,7 +10358,6 @@ function AIRBOSS:_LSOadvice(playerData, glideslopeError, lineupError)
|
|||||||
local advice=0
|
local advice=0
|
||||||
|
|
||||||
-- Glideslope high/low calls.
|
-- Glideslope high/low calls.
|
||||||
--TODO: introduce GSE enumerator values.
|
|
||||||
if glideslopeError>self.gle.HIGH then --1.5 then
|
if glideslopeError>self.gle.HIGH then --1.5 then
|
||||||
-- "You're high!"
|
-- "You're high!"
|
||||||
self:RadioTransmission(self.LSORadio, self.LSOCall.HIGH, true, nil, nil, true)
|
self:RadioTransmission(self.LSORadio, self.LSOCall.HIGH, true, nil, nil, true)
|
||||||
@ -10293,7 +10371,6 @@ function AIRBOSS:_LSOadvice(playerData, glideslopeError, lineupError)
|
|||||||
self:RadioTransmission(self.LSORadio, self.LSOCall.POWER, true, nil, nil, true)
|
self:RadioTransmission(self.LSORadio, self.LSOCall.POWER, true, nil, nil, true)
|
||||||
advice=advice+self.LSOCall.POWER.duration
|
advice=advice+self.LSOCall.POWER.duration
|
||||||
elseif glideslopeError<self.gle.Low then -- -0.6 then
|
elseif glideslopeError<self.gle.Low then -- -0.6 then
|
||||||
--TODO CHECK THIS NUMBER. -0.3 vs -0.6!
|
|
||||||
-- "Power."
|
-- "Power."
|
||||||
self:RadioTransmission(self.LSORadio, self.LSOCall.POWER, false, nil, nil, true)
|
self:RadioTransmission(self.LSORadio, self.LSOCall.POWER, false, nil, nil, true)
|
||||||
advice=advice+self.LSOCall.POWER.duration
|
advice=advice+self.LSOCall.POWER.duration
|
||||||
@ -10303,7 +10380,6 @@ function AIRBOSS:_LSOadvice(playerData, glideslopeError, lineupError)
|
|||||||
|
|
||||||
|
|
||||||
-- Lineup left/right calls.
|
-- Lineup left/right calls.
|
||||||
-- TODO: introduce LUE enumerator values.
|
|
||||||
if lineupError<self.lue.LEFT then
|
if lineupError<self.lue.LEFT then
|
||||||
-- "Come left!"
|
-- "Come left!"
|
||||||
self:RadioTransmission(self.LSORadio, self.LSOCall.COMELEFT, true, nil, nil, true)
|
self:RadioTransmission(self.LSORadio, self.LSOCall.COMELEFT, true, nil, nil, true)
|
||||||
@ -10490,6 +10566,7 @@ function AIRBOSS:_LSOgrade(playerData)
|
|||||||
grade="WOFD"
|
grade="WOFD"
|
||||||
points=-1.0
|
points=-1.0
|
||||||
end
|
end
|
||||||
|
G="n/a"
|
||||||
elseif playerData.waveoff then
|
elseif playerData.waveoff then
|
||||||
-- Wave Off
|
-- Wave Off
|
||||||
if playerData.landed then
|
if playerData.landed then
|
||||||
@ -11427,7 +11504,7 @@ function AIRBOSS:_Debrief(playerData)
|
|||||||
|
|
||||||
-- Unit does not seem to be alive!
|
-- Unit does not seem to be alive!
|
||||||
-- TODO: What now?
|
-- TODO: What now?
|
||||||
self:T2(self.lid..string.format("Player unit not alive!"))
|
self:E(self.lid..string.format("ERROR: Player unit not alive!"))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -12168,6 +12245,9 @@ function AIRBOSS._TaskFunctionMarshalAI(group, airboss, flight)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Not refueling any more in case it was.
|
||||||
|
flight.refueling=false
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -13362,6 +13442,9 @@ function AIRBOSS:_MarshalCallRecoveryStopped(case)
|
|||||||
-- Subtitle.
|
-- Subtitle.
|
||||||
local text=string.format("Case %d recovery ops are stopped. Deck is closed.", case)
|
local text=string.format("Case %d recovery ops are stopped. Deck is closed.", case)
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call to display complete subtitle.
|
-- Create new call to display complete subtitle.
|
||||||
local call=self:_NewRadioCall(self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99")
|
local call=self:_NewRadioCall(self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99")
|
||||||
|
|
||||||
@ -13400,6 +13483,9 @@ function AIRBOSS:_MarshalCallRecoveryPausedResumedAt(clock)
|
|||||||
-- Subtitle.
|
-- Subtitle.
|
||||||
local text=string.format("aircraft recovery is paused and will be resumed at %s.", clock)
|
local text=string.format("aircraft recovery is paused and will be resumed at %s.", clock)
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call=self:_NewRadioCall(self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99")
|
local call=self:_NewRadioCall(self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99")
|
||||||
|
|
||||||
@ -13425,6 +13511,9 @@ function AIRBOSS:_MarshalCallClearedForRecovery(modex, case)
|
|||||||
-- Subtitle.
|
-- Subtitle.
|
||||||
local text=string.format("you're cleared for Case %d recovery.", case)
|
local text=string.format("you're cleared for Case %d recovery.", case)
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call=self:_NewRadioCall(self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex)
|
local call=self:_NewRadioCall(self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex)
|
||||||
|
|
||||||
@ -13460,6 +13549,9 @@ function AIRBOSS:_MarshalCallNewFinalBearing(FB)
|
|||||||
-- Subtitle.
|
-- Subtitle.
|
||||||
local text=string.format("new final bearing %03d°.", FB)
|
local text=string.format("new final bearing %03d°.", FB)
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call=self:_NewRadioCall(self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99")
|
local call=self:_NewRadioCall(self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99")
|
||||||
|
|
||||||
@ -13480,6 +13572,9 @@ function AIRBOSS:_MarshalCallCarrierTurnTo(hdg)
|
|||||||
-- Subtitle.
|
-- Subtitle.
|
||||||
local text=string.format("starting turn to heading %03d°.", hdg)
|
local text=string.format("starting turn to heading %03d°.", hdg)
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call=self:_NewRadioCall(self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99")
|
local call=self:_NewRadioCall(self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99")
|
||||||
|
|
||||||
@ -13508,6 +13603,9 @@ function AIRBOSS:_MarshalCallStackFull(modex, nwaiting)
|
|||||||
text=text..string.format("You are next in line.")
|
text=text..string.format("You are next in line.")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call with full subtitle.
|
-- Create new call with full subtitle.
|
||||||
local call=self:_NewRadioCall(self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex)
|
local call=self:_NewRadioCall(self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex)
|
||||||
|
|
||||||
@ -13560,7 +13658,7 @@ end
|
|||||||
-- @param #string charlie Charlie Time estimate.
|
-- @param #string charlie Charlie Time estimate.
|
||||||
-- @param #string qfe Alitmeter inHg.
|
-- @param #string qfe Alitmeter inHg.
|
||||||
function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe)
|
function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe)
|
||||||
self:E({modex=modex,case=case,brc=brc,altitude=altitude,charlie=charlie,qfe=qfe})
|
self:F({modex=modex,case=case,brc=brc,altitude=altitude,charlie=charlie,qfe=qfe})
|
||||||
|
|
||||||
-- Split strings etc.
|
-- Split strings etc.
|
||||||
local angels=self:_GetAngels(altitude)
|
local angels=self:_GetAngels(altitude)
|
||||||
@ -13572,6 +13670,9 @@ function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe)
|
|||||||
local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s.\n", case, brc, angels, charlie)
|
local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s.\n", case, brc, angels, charlie)
|
||||||
text=text..string.format("Altimeter %.2f. Report see me.", qfe)
|
text=text..string.format("Altimeter %.2f. Report see me.", qfe)
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Create new call to display complete subtitle.
|
-- Create new call to display complete subtitle.
|
||||||
local casecall=self:_NewRadioCall(self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex)
|
local casecall=self:_NewRadioCall(self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex)
|
||||||
|
|
||||||
@ -13705,10 +13806,10 @@ function AIRBOSS:_AddF10Commands(_unitName)
|
|||||||
-- F10/Airboss/<Carrier>/F1 Help/F2 Skill Level
|
-- F10/Airboss/<Carrier>/F1 Help/F2 Skill Level
|
||||||
local _skillPath=missionCommands.addSubMenuForGroup(gid, "Skill Level", _helpPath)
|
local _skillPath=missionCommands.addSubMenuForGroup(gid, "Skill Level", _helpPath)
|
||||||
-- F10/Airboss/<Carrier>/F1 Help/F2 Skill Level/
|
-- F10/Airboss/<Carrier>/F1 Help/F2 Skill Level/
|
||||||
missionCommands.addCommandForGroup(gid, "Flight Student", _skillPath, self._SetDifficulty, self, playername, AIRBOSS.Difficulty.EASY) -- F1
|
missionCommands.addCommandForGroup(gid, "Flight Student", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.EASY) -- F1
|
||||||
missionCommands.addCommandForGroup(gid, "Naval Aviator", _skillPath, self._SetDifficulty, self, playername, AIRBOSS.Difficulty.NORMAL) -- F2
|
missionCommands.addCommandForGroup(gid, "Naval Aviator", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.NORMAL) -- F2
|
||||||
missionCommands.addCommandForGroup(gid, "TOPGUN Graduate", _skillPath, self._SetDifficulty, self, playername, AIRBOSS.Difficulty.HARD) -- F3
|
missionCommands.addCommandForGroup(gid, "TOPGUN Graduate", _skillPath, self._SetDifficulty, self, _unitName, AIRBOSS.Difficulty.HARD) -- F3
|
||||||
missionCommands.addCommandForGroup(gid, "Hints On/Off", _skillPath, self._SetHintsOnOff, self, playername) -- F4
|
missionCommands.addCommandForGroup(gid, "Hints On/Off", _skillPath, self._SetHintsOnOff, self, _unitName) -- F4
|
||||||
-- F10/Airboss/<Carrier>/F1 Help/
|
-- F10/Airboss/<Carrier>/F1 Help/
|
||||||
missionCommands.addCommandForGroup(gid, "My Status", _helpPath, self._DisplayPlayerStatus, self, _unitName) -- F3
|
missionCommands.addCommandForGroup(gid, "My Status", _helpPath, self._DisplayPlayerStatus, self, _unitName) -- F3
|
||||||
missionCommands.addCommandForGroup(gid, "Attitude Monitor", _helpPath, self._DisplayAttitude, self, _unitName) -- F4
|
missionCommands.addCommandForGroup(gid, "Attitude Monitor", _helpPath, self._DisplayAttitude, self, _unitName) -- F4
|
||||||
@ -14187,7 +14288,7 @@ function AIRBOSS:_RequestRefueling(_unitName)
|
|||||||
|
|
||||||
elseif self.tanker:IsReturning() then
|
elseif self.tanker:IsReturning() then
|
||||||
-- Tanker is RTB.
|
-- Tanker is RTB.
|
||||||
text="Tanker is RTB. Request denied!\nWait for the tanker to be back on station if you can."
|
text="negative, tanker is RTB. Request denied!\nWait for the tanker to be back on station if you can."
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -14847,11 +14948,18 @@ end
|
|||||||
|
|
||||||
--- Set difficulty level.
|
--- Set difficulty level.
|
||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #string playername Player name.
|
-- @param #string _unitname Name of the player unit.
|
||||||
-- @param #AIRBOSS.Difficulty difficulty Difficulty level.
|
-- @param #AIRBOSS.Difficulty difficulty Difficulty level.
|
||||||
function AIRBOSS:_SetDifficulty(playername, difficulty)
|
function AIRBOSS:_SetDifficulty(_unitname, difficulty)
|
||||||
self:T2({difficulty=difficulty, playername=playername})
|
self:T2({difficulty=difficulty, unitname=_unitname})
|
||||||
|
|
||||||
|
-- Get player unit and player name.
|
||||||
|
local unit, playername = self:_GetPlayerUnitAndName(_unitname)
|
||||||
|
|
||||||
|
-- Check if we have a player.
|
||||||
|
if unit and playername then
|
||||||
|
|
||||||
|
-- Player data.
|
||||||
local playerData=self.players[playername] --#AIRBOSS.PlayerData
|
local playerData=self.players[playername] --#AIRBOSS.PlayerData
|
||||||
|
|
||||||
if playerData then
|
if playerData then
|
||||||
@ -14869,6 +14977,7 @@ function AIRBOSS:_SetDifficulty(playername, difficulty)
|
|||||||
playerData.showhints=true
|
playerData.showhints=true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Turn player's aircraft attitude display on or off.
|
--- Turn player's aircraft attitude display on or off.
|
||||||
@ -14887,13 +14996,15 @@ function AIRBOSS:_SetHintsOnOff(_unitname)
|
|||||||
local playerData=self.players[playername] --#AIRBOSS.PlayerData
|
local playerData=self.players[playername] --#AIRBOSS.PlayerData
|
||||||
|
|
||||||
if playerData then
|
if playerData then
|
||||||
|
|
||||||
|
-- Invert hints.
|
||||||
playerData.showhints=not playerData.showhints
|
playerData.showhints=not playerData.showhints
|
||||||
|
|
||||||
-- Inform player.
|
-- Inform player.
|
||||||
local text=""
|
local text=""
|
||||||
if playerData.showhints==true then
|
if playerData.showhints==true then
|
||||||
text=string.format("hints are now ON.")
|
text=string.format("hints are now ON.")
|
||||||
elseif playerData.showhints==false then
|
else
|
||||||
text=string.format("hints are now OFF.")
|
text=string.format("hints are now OFF.")
|
||||||
end
|
end
|
||||||
self:MessageToPlayer(playerData, text, nil, playerData.name, 5)
|
self:MessageToPlayer(playerData, text, nil, playerData.name, 5)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user