From eab28abc86e5cb01aca5a8d8666305ea7e8eb2c6 Mon Sep 17 00:00:00 2001 From: Ismael Date: Fri, 19 Nov 2021 01:11:49 +0100 Subject: [PATCH 1/2] Subject: Add Player and AI Inbound radio calls to better inmersion in Airboss #16311 This commit enhances Airboss class functionality to provide with the inbound calls both from Players requesting marshal and AI sent to marshal: - "Marshal, [MODEX], marking mom's [BEARING] for [DISTANCE], angels [HEIGHT], state [FUEL_STATE] Two new boolean fields have been added to Airboss class to trigger or not the inbound calls: - inRadioCall - inRadioCallAI These fields can be modified trough methods: - AIRBOSS:SetInboundMessagesPlayer(false) - AIRBOSS:SetInboundMessagesAI(false) Note. At the moment both methods initialize to "false" at Airboss:NEW, so in case you want to have this functionality activated, you need to call the methods with (true) when initializing your Airboss class. This enhacement of the Airboss class requires 5 new sound files (.ogg) to be included to folder "\Airboss Soundfiles" in your .miz file: - PILOT-Angels.ogg - PILOT-For.ogg - PILOT-MarkingMoms.ogg - PILOT-Marshal.ogg - PILOT-State.ogg To get them, please refer to the SOUNDS MOOSE repository or the discord channel. Where they will be available. --- Moose Development/Moose/Ops/Airboss.lua | 126 +++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index becd99218..d9afeb81f 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -1201,6 +1201,8 @@ AIRBOSS = { NmaxSection = nil, NmaxStack = nil, handleai = nil, + inbRadioCall = nil, + inbRadioCallAI = nil, tanker = nil, Corientation = nil, Corientlast = nil, @@ -1900,6 +1902,12 @@ function AIRBOSS:New(carriername, alias) -- Set AI handling On. self:SetHandleAION() + -- No Inbound messages from Player by default + self:SetInboundMessagesPlayer(false) + + -- No Inbound messages from AI by default + self:SetInboundMessagesAI(false) + -- Airboss is a nice guy. self:SetAirbossNiceGuy() @@ -3215,6 +3223,24 @@ function AIRBOSS:SetHandleAION() return self end +--- Will simulate the inbound call from the player when requesteing marshal +-- @param #AIRBOSS self +-- @param #AIRBOSS status Boolean to activate (true) / deactivate (false) the radio inbound calls (default is ON) +-- @return #AIRBOSS self +function AIRBOSS:SetInboundMessagesPlayer(status) + self.inbRadioCall=status + return self +end + +--- Will simulate the inbound call from the AI when sending to marshal (as if they have called for it) +-- @param #AIRBOSS self +-- @param #AIRBOSS status Boolean to activate (true) / deactivate (false) the radio inbound calls (default is ON) +-- @return #AIRBOSS self +function AIRBOSS:SetInboundMessagesAI(status) + self.inbRadioCallAI=status + return self +end + --- Do not handle AI aircraft. -- @param #AIRBOSS self -- @return #AIRBOSS self @@ -5299,6 +5325,41 @@ function AIRBOSS:_InitVoiceOvers() subtitle="", duration=1.95, }, + MARSHAL={ + file="PILOT-Marshal", + suffix="ogg", + loud=false, + subtitle="", + duration=0.50, + }, + MARKINGMOMS={ + file="PILOT-MarkingMoms", + suffix="ogg", + loud=false, + subtitle="", + duration=0.90, + }, + FOR={ + file="PILOT-For", + suffix="ogg", + loud=false, + subtitle="", + duration=0.29, + }, + ANGELS={ + file="PILOT-Angels", + suffix="ogg", + loud=false, + subtitle="", + duration=0.50, + }, + STATE={ + file="PILOT-State", + suffix="ogg", + loud=false, + subtitle="", + duration=0.40, + }, } ------------------- @@ -6545,6 +6606,11 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn) -- Check if flight is already in Marshal queue. if not self:_InQueue(self.Qmarshal,flight.group) then + -- Simulate inbound call + if self.inbRadioCallAI then + local leader = flight.group:GetUnits()[1] + self:_MarshallInboundCall(leader, flight.onboard) + end -- Add group to marshal stack queue. self:_AddMarshalGroup(flight, nstack) end @@ -15722,6 +15788,60 @@ function AIRBOSS:_Number2Radio(radio, number, delay, interval, pilotcall) return wait end +--- Aircraft request marshal (Inbound call). +-- @param #AIRBOSS self +-- @return Wrapper.Unit#UNIT Unit of player or nil. +-- @param #string modex Tail number. +function AIRBOSS:_MarshallInboundCall(unit, modex) + + -- Calculate + local vectorCarrier = self:GetCoordinate():GetDirectionVec3(unit:GetCoordinate()) + local bearing = UTILS.Round(unit:GetCoordinate():GetAngleDegrees( vectorCarrier ), 0) + local distance = UTILS.Round(UTILS.MetersToNM(unit:GetCoordinate():Get2DDistance(self:GetCoordinate())),0) + local angels = UTILS.Round(UTILS.MetersToFeet(unit:GetHeight()/1000),0) + local state = UTILS.Round(self:_GetFuelState(unit)/1000,1) + + -- Pilot: "Marshall, [modex], marking mom's [bearing] for [distance], angels [XX], state [X.X]" + local text=string.format("Marshal, %s, marking mom's %d for %d, angels %d, state %.1f", modex, bearing, distance, angels, state) + -- Debug message. + self:I(self.lid..text) + + -- Fuel state. + local FS=UTILS.Split(string.format("%.1f", state), ".") + + -- Create new call to display complete subtitle. + local inboundcall=self:_NewRadioCall(self.MarshalCall.CLICK, unit.UnitName:upper() , text, self.Tmessage, nil, unit.UnitName:upper()) + + -- CLICK! + self:RadioTransmission(self.MarshalRadio, inboundcall) + -- Marshal .. + self:RadioTransmission(self.MarshalRadio, self.PilotCall.MARSHAL, nil, nil, nil, nil, true) + -- Modex.. + self:_Number2Radio(self.MarshalRadio, modex, nil, nil, true) + -- Marking Mom's, + self:RadioTransmission(self.MarshalRadio, self.PilotCall.MARKINGMOMS, nil, nil, nil, nil, true) + -- Bearing .. + self:_Number2Radio(self.MarshalRadio, tostring(bearing), nil, nil, true) + -- For .. + self:RadioTransmission(self.MarshalRadio, self.PilotCall.FOR, nil, nil, nil, nil, true) + -- Distance .. + self:_Number2Radio(self.MarshalRadio, tostring(distance), nil, nil, true) + -- Angels .. + self:RadioTransmission(self.MarshalRadio, self.PilotCall.ANGELS, nil, nil, nil, nil, true) + -- Angels Number .. + self:_Number2Radio(self.MarshalRadio, tostring(angels), nil, nil, true) + -- State .. + self:RadioTransmission(self.MarshalRadio, self.PilotCall.STATE, nil, nil, nil, nil, true) + -- X.. + self:_Number2Radio(self.MarshalRadio, FS[1], nil, nil, true) + -- Point.. + self:RadioTransmission(self.MarshalRadio, self.PilotCall.POINT, nil, nil, nil, nil, true) + -- Y. + self:_Number2Radio(self.MarshalRadio, FS[2], nil, nil, true) + -- CLICK! + self:RadioTransmission(self.MarshalRadio, self.MarshalRadio.CLICK, nil, nil, nil, nil, true) + +end --- AI aircraft calls the ball. -- @param #AIRBOSS self @@ -16478,7 +16598,11 @@ function AIRBOSS:_RequestMarshal(_unitName) -- Get player unit and name. local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - + + if self.inbRadioCall then + self:_MarshallInboundCall(_unit, "202") + end + -- Check if we have a unit which is a player. if _unit and _playername then local playerData=self.players[_playername] --#AIRBOSS.PlayerData From 397ab77105d3b516c31c229523dd07c018a07f54 Mon Sep 17 00:00:00 2001 From: Ismael Date: Fri, 19 Nov 2021 15:31:49 +0100 Subject: [PATCH 2/2] This pull request enhances Airboss class functionality to provide with the 1) Inbound calls both from Players requesting marshal and AI sent to marshal: "Marshal, [MODEX], marking mom's [BEARING] for [DISTANCE], angels [HEIGHT], state [FUEL_STATE] 2) Commencing call and voiceover (both AI and Players) For that, two boolean fields have been added to Airboss class to trigger or not extra voice overs: xtVoiceOvers xtVoiceOversAI These fields can be modified trough methods: AIRBOSS:SetExtraVoiceOvers(true/false) AIRBOSS:SetExtraVoiceOversAI(true/false) Note. At the moment both methods initialize to "false" at Airboss:NEW, so in case you want to have this functionality activated, you need to call the methods with (true) when initializing your Airboss class. The new methods in charge of creating the radio calls are AIRBOSS:_MarshalAI: for AI flights send to marshal AIRBOSS:_RequestMarshal: for player flighs requesting marshal from F10 menu 2) AIRBOSS:_CommencingCall(unit, modex), which is called from AIRBOSS:_ClearForLanding: for AI flights cleared for landing AIRBOSS:_RequestCommence: for player flights requesting commencing from F10 menu (disregarding if the player call is right or not) This enhacement of the Airboss class requires 5 new sound files (.ogg) to be included to folder "\Airboss Soundfiles" in your .miz file: PILOT-Angels.ogg PILOT-For.ogg PILOT-MarkingMoms.ogg PILOT-Marshal.ogg PILOT-State.ogg PILOT-Commencing.ogg --- Moose Development/Moose/Ops/Airboss.lua | 88 ++++++++++++++++++------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index d9afeb81f..d720e8803 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -1201,8 +1201,8 @@ AIRBOSS = { NmaxSection = nil, NmaxStack = nil, handleai = nil, - inbRadioCall = nil, - inbRadioCallAI = nil, + xtVoiceOvers = nil, + xtVoiceOversAI = nil, tanker = nil, Corientation = nil, Corientlast = nil, @@ -1902,11 +1902,11 @@ function AIRBOSS:New(carriername, alias) -- Set AI handling On. self:SetHandleAION() - -- No Inbound messages from Player by default - self:SetInboundMessagesPlayer(false) + -- No extra voiceover/calls from player by default + self:SetExtraVoiceOvers(false) - -- No Inbound messages from AI by default - self:SetInboundMessagesAI(false) + -- No extra voiceover/calls from AI by default + self:SetExtraVoiceOversAI(false) -- Airboss is a nice guy. self:SetAirbossNiceGuy() @@ -3223,21 +3223,21 @@ function AIRBOSS:SetHandleAION() return self end ---- Will simulate the inbound call from the player when requesteing marshal +--- Will play the inbound calls, commencing, initial, etc. from the player when requesteing marshal -- @param #AIRBOSS self -- @param #AIRBOSS status Boolean to activate (true) / deactivate (false) the radio inbound calls (default is ON) -- @return #AIRBOSS self -function AIRBOSS:SetInboundMessagesPlayer(status) - self.inbRadioCall=status +function AIRBOSS:SetExtraVoiceOvers(status) + self.xtVoiceOvers=status return self end ---- Will simulate the inbound call from the AI when sending to marshal (as if they have called for it) +--- Will simulate the inbound call, commencing, initial, etc from the AI when requested by Airboss -- @param #AIRBOSS self -- @param #AIRBOSS status Boolean to activate (true) / deactivate (false) the radio inbound calls (default is ON) -- @return #AIRBOSS self -function AIRBOSS:SetInboundMessagesAI(status) - self.inbRadioCallAI=status +function AIRBOSS:SetExtraVoiceOversAI(status) + self.xtVoiceOversAI=status return self end @@ -5359,7 +5359,14 @@ function AIRBOSS:_InitVoiceOvers() loud=false, subtitle="", duration=0.40, - }, + }, + COMMENCING={ + file="PILOT-Commencing", + suffix="ogg", + loud=false, + subtitle="", + duration=0.45, + }, } ------------------- @@ -6235,6 +6242,12 @@ function AIRBOSS:_ClearForLanding(flight) -- Cleared for Case X recovery. self:_MarshalCallClearedForRecovery(flight.onboard, flight.case) + -- Voice over of the commencing simulated call from AI + if self.xtVoiceOversAI then + local leader = flight.group:GetUnits()[1] + self:_CommencingCall(leader, flight.onboard) + end + else -- Cleared for Case X recovery. @@ -6607,7 +6620,7 @@ function AIRBOSS:_MarshalAI(flight, nstack, respawn) -- Check if flight is already in Marshal queue. if not self:_InQueue(self.Qmarshal,flight.group) then -- Simulate inbound call - if self.inbRadioCallAI then + if self.xtVoiceOversAI then local leader = flight.group:GetUnits()[1] self:_MarshallInboundCall(leader, flight.onboard) end @@ -15788,7 +15801,7 @@ function AIRBOSS:_Number2Radio(radio, number, delay, interval, pilotcall) return wait end ---- Aircraft request marshal (Inbound call). +--- Aircraft request marshal (Inbound call both for players and AI). -- @param #AIRBOSS self -- @return Wrapper.Unit#UNIT Unit of player or nil. -- @param #string modex Tail number. @@ -15843,6 +15856,31 @@ function AIRBOSS:_MarshallInboundCall(unit, modex) end +--- Aircraft commencing call (both for players and AI). +-- @param #AIRBOSS self +-- @return Wrapper.Unit#UNIT Unit of player or nil. +-- @param #string modex Tail number. +function AIRBOSS:_CommencingCall(unit, modex) + + -- Pilot: "[modex], commencing" + local text=string.format("%s, commencing", modex) + -- Debug message. + self:I(self.lid..text) + + -- Create new call to display complete subtitle. + local commencingCall=self:_NewRadioCall(self.MarshalCall.CLICK, unit.UnitName:upper() , text, self.Tmessage, nil, unit.UnitName:upper()) + + -- Click + self:RadioTransmission(self.MarshalRadio, commencingCall) + -- Modex.. + self:_Number2Radio(self.MarshalRadio, modex, nil, nil, true) + -- Commencing + self:RadioTransmission(self.MarshalRadio, self.PilotCall.COMMENCING, nil, nil, nil, nil, true) + -- CLICK! + self:RadioTransmission(self.MarshalRadio, self.MarshalRadio.CLICK, nil, nil, nil, nil, true) + +end + --- AI aircraft calls the ball. -- @param #AIRBOSS self -- @param #string modex Tail number. @@ -16598,17 +16636,18 @@ function AIRBOSS:_RequestMarshal(_unitName) -- Get player unit and name. local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - - if self.inbRadioCall then - self:_MarshallInboundCall(_unit, "202") - end - + -- Check if we have a unit which is a player. if _unit and _playername then local playerData=self.players[_playername] --#AIRBOSS.PlayerData if playerData then + -- Voice over of inbound call (regardless of airboss rejecting it or not) + if self.xtVoiceOvers then + self:_MarshallInboundCall(_unit, playerData.onboard) + end + -- Check if player is in CCA local inCCA=playerData.unit:IsInZone(self.zoneCCA) @@ -16850,13 +16889,18 @@ function AIRBOSS:_RequestCommence(_unitName) -- Get player unit and name. local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - + -- Check if we have a unit which is a player. if _unit and _playername then local playerData=self.players[_playername] --#AIRBOSS.PlayerData if playerData then - + + -- Voice over of Commencing call (regardless of Airboss will rejected or not) + if self.xtVoiceOvers then + self:_CommencingCall(_unit, playerData.onboard) + end + -- Check if unit is in CCA. local text="" local cleared=false