mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'FF/Ops' into FF/OpsDev
This commit is contained in:
commit
91e80bf1a6
@ -1054,28 +1054,55 @@ do -- COORDINATE
|
||||
return heading
|
||||
end
|
||||
|
||||
--- Returns the 3D wind direction vector. Note that vector points into the direction the wind in blowing to.
|
||||
-- @param #COORDINATE self
|
||||
-- @param #number height (Optional) parameter specifying the height ASL in meters. The minimum height will be always be the land height since the wind is zero below the ground.
|
||||
-- @param #boolean turbulence (Optional) If `true`, include turbulence.
|
||||
-- @return DCS#Vec3 Wind 3D vector. Components in m/s.
|
||||
function COORDINATE:GetWindVec3(height, turbulence)
|
||||
|
||||
-- We at 0.1 meters to be sure to be above ground since wind is zero below ground level.
|
||||
local landheight=self:GetLandHeight()+0.1
|
||||
|
||||
local point={x=self.x, y=math.max(height or self.y, landheight), z=self.z}
|
||||
|
||||
-- Get wind velocity vector.
|
||||
local wind = nil --DCS#Vec3
|
||||
|
||||
if turbulence then
|
||||
wind = atmosphere.getWindWithTurbulence(point)
|
||||
else
|
||||
wind = atmosphere.getWind(point)
|
||||
end
|
||||
|
||||
return wind
|
||||
end
|
||||
|
||||
--- Returns the wind direction (from) and strength.
|
||||
-- @param #COORDINATE self
|
||||
-- @param height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
|
||||
-- @return Direction the wind is blowing from in degrees.
|
||||
-- @return Wind strength in m/s.
|
||||
function COORDINATE:GetWind(height)
|
||||
local landheight=self:GetLandHeight()+0.1 -- we at 0.1 meters to be sure to be above ground since wind is zero below ground level.
|
||||
local point={x=self.x, y=math.max(height or self.y, landheight), z=self.z}
|
||||
-- get wind velocity vector
|
||||
local wind = atmosphere.getWind(point)
|
||||
local direction = math.deg(math.atan2(wind.z, wind.x))
|
||||
if direction < 0 then
|
||||
direction = 360 + direction
|
||||
end
|
||||
-- Convert to direction to from direction
|
||||
-- @param #number height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
|
||||
-- @param #boolean turbulence If `true`, include turbulence. If `false` or `nil`, wind without turbulence.
|
||||
-- @return #number Direction the wind is blowing from in degrees.
|
||||
-- @return #number Wind strength in m/s.
|
||||
function COORDINATE:GetWind(height, turbulence)
|
||||
|
||||
-- Get wind velocity vector
|
||||
local wind = self:GetWindVec3(height, turbulence)
|
||||
|
||||
-- Calculate the direction of the vector.
|
||||
local direction=UTILS.VecHdg(wind)
|
||||
|
||||
-- Invert "to" direction to "from" direction.
|
||||
if direction > 180 then
|
||||
direction = direction-180
|
||||
else
|
||||
direction = direction+180
|
||||
end
|
||||
local strength=math.sqrt((wind.x)^2+(wind.z)^2)
|
||||
-- Return wind direction and strength km/h.
|
||||
|
||||
-- Wind strength in m/s.
|
||||
local strength=UTILS.VecNorm(wind) -- math.sqrt((wind.x)^2+(wind.z)^2)
|
||||
|
||||
-- Return wind direction and strength.
|
||||
return direction, strength
|
||||
end
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
|
||||
--
|
||||
-- * Spot for a defined duration.
|
||||
-- * Updates of laer spot position every 0.2 seconds for moving targets.
|
||||
-- * Updates of laser spot position every 0.2 seconds for moving targets.
|
||||
-- * Wiggle the spot at the target.
|
||||
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
|
||||
-- * Implement a status machine, LaseOn, LaseOff.
|
||||
@ -13,18 +13,8 @@
|
||||
-- ===
|
||||
--
|
||||
-- # Demo Missions
|
||||
--
|
||||
-- ### [SPOT Demo Missions source code]()
|
||||
--
|
||||
-- ### [SPOT Demo Missions, only for beta testers]()
|
||||
--
|
||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # YouTube Channel
|
||||
--
|
||||
-- ### [SPOT YouTube Channel]()
|
||||
-- ### [Demo Missions on GitHub](https://github.com/FlightControl-Master/MOOSE_MISSIONS)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -50,14 +40,14 @@ do
|
||||
--- Implements the target spotting or marking functionality, but adds additional luxury to be able to:
|
||||
--
|
||||
-- * Mark targets for a defined duration.
|
||||
-- * Updates of laer spot position every 0.2 seconds for moving targets.
|
||||
-- * Updates of laser spot position every 0.25 seconds for moving targets.
|
||||
-- * Wiggle the spot at the target.
|
||||
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
|
||||
-- * Implement a status machine, LaseOn, LaseOff.
|
||||
--
|
||||
-- ## 1. SPOT constructor
|
||||
--
|
||||
-- * @{#SPOT.New}(..\Presentations\SPOT\Dia2.JPG): Creates a new SPOT object.
|
||||
-- * @{#SPOT.New}(): Creates a new SPOT object.
|
||||
--
|
||||
-- ## 2. SPOT is a FSM
|
||||
--
|
||||
@ -217,6 +207,8 @@ do
|
||||
|
||||
|
||||
self.Recce = Recce
|
||||
|
||||
self.RecceName = self.Recce:GetName()
|
||||
|
||||
self.LaseScheduler = SCHEDULER:New( self )
|
||||
|
||||
@ -243,6 +235,9 @@ do
|
||||
end
|
||||
|
||||
self.Target = Target
|
||||
|
||||
self.TargetName = Target:GetName()
|
||||
|
||||
self.LaserCode = LaserCode
|
||||
|
||||
self.Lasing = true
|
||||
@ -302,12 +297,18 @@ do
|
||||
function SPOT:OnEventDead(EventData)
|
||||
self:F( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
|
||||
if self.Target then
|
||||
if EventData.IniDCSUnitName == self.Target:GetName() then
|
||||
self:F( {"Target dead ", self.Target:GetName() } )
|
||||
if EventData.IniDCSUnitName == self.TargetName then
|
||||
self:F( {"Target dead ", self.TargetName } )
|
||||
self:Destroyed()
|
||||
self:LaseOff()
|
||||
end
|
||||
end
|
||||
if self.Recce then
|
||||
if EventData.IniDCSUnitName == self.RecceName then
|
||||
self:F( {"Recce dead ", self.RecceName } )
|
||||
self:LaseOff()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #SPOT self
|
||||
@ -382,4 +383,4 @@ do
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@ -1369,6 +1369,13 @@ PLAYERTASKCONTROLLER.Messages = {
|
||||
AIRDEFENSE = "Airdefense",
|
||||
SAM = "SAM",
|
||||
GROUP = "Group",
|
||||
UNARMEDSHIP = "Merchant",
|
||||
LIGHTARMEDSHIP = "Light Boat",
|
||||
CORVETTE = "Corvette",
|
||||
FRIGATE = "Frigate",
|
||||
CRUISER = "Cruiser",
|
||||
DESTROYER = "Destroyer",
|
||||
CARRIER = "Aircraft Carrier",
|
||||
},
|
||||
DE = {
|
||||
TASKABORT = "Auftrag abgebrochen!",
|
||||
@ -1441,12 +1448,19 @@ PLAYERTASKCONTROLLER.Messages = {
|
||||
AIRDEFENSE = "Flak",
|
||||
SAM = "Luftabwehr",
|
||||
GROUP = "Einheit",
|
||||
UNARMEDSHIP = "Handelsschiff",
|
||||
LIGHTARMEDSHIP = "Tender",
|
||||
CORVETTE = "Korvette",
|
||||
FRIGATE = "Fregatte",
|
||||
CRUISER = "Kreuzer",
|
||||
DESTROYER = "Zerstörer",
|
||||
CARRIER = "Flugzeugträger",
|
||||
},
|
||||
}
|
||||
|
||||
--- PLAYERTASK class version.
|
||||
-- @field #string version
|
||||
PLAYERTASKCONTROLLER.version="0.1.56"
|
||||
PLAYERTASKCONTROLLER.version="0.1.58"
|
||||
|
||||
--- Create and run a new TASKCONTROLLER instance.
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
@ -2231,35 +2245,60 @@ function PLAYERTASKCONTROLLER:_CheckTargetQueue()
|
||||
end
|
||||
end
|
||||
|
||||
if self.UseTypeNames and object:IsGround() then
|
||||
-- * Threat level 0: Unit is unarmed.
|
||||
-- * Threat level 1: Unit is infantry.
|
||||
-- * Threat level 2: Unit is an infantry vehicle.
|
||||
-- * Threat level 3: Unit is ground artillery.
|
||||
-- * Threat level 4: Unit is a tank.
|
||||
-- * Threat level 5: Unit is a modern tank or ifv with ATGM.
|
||||
-- * Threat level 6: Unit is a AAA.
|
||||
-- * Threat level 7: Unit is a SAM or manpad, IR guided.
|
||||
-- * Threat level 8: Unit is a Short Range SAM, radar guided.
|
||||
-- * Threat level 9: Unit is a Medium Range SAM, radar guided.
|
||||
-- * Threat level 10: Unit is a Long Range SAM, radar guided.
|
||||
local threat = object:GetThreatLevel()
|
||||
local typekey = "INFANTRY"
|
||||
if threat == 0 or threat == 2 then
|
||||
typekey = "TECHNICAL"
|
||||
elseif threat == 3 then
|
||||
typekey = "ARTILLERY"
|
||||
elseif threat == 4 or threat == 5 then
|
||||
typekey = "TANKS"
|
||||
elseif threat == 6 or threat == 7 then
|
||||
typekey = "AIRDEFENSE"
|
||||
elseif threat >= 8 then
|
||||
typekey = "SAM"
|
||||
if object:IsInstanceOf("UNIT") or object:IsInstanceOf("GROUP") then
|
||||
|
||||
if self.UseTypeNames and object:IsGround() then
|
||||
-- * Threat level 0: Unit is unarmed.
|
||||
-- * Threat level 1: Unit is infantry.
|
||||
-- * Threat level 2: Unit is an infantry vehicle.
|
||||
-- * Threat level 3: Unit is ground artillery.
|
||||
-- * Threat level 4: Unit is a tank.
|
||||
-- * Threat level 5: Unit is a modern tank or ifv with ATGM.
|
||||
-- * Threat level 6: Unit is a AAA.
|
||||
-- * Threat level 7: Unit is a SAM or manpad, IR guided.
|
||||
-- * Threat level 8: Unit is a Short Range SAM, radar guided.
|
||||
-- * Threat level 9: Unit is a Medium Range SAM, radar guided.
|
||||
-- * Threat level 10: Unit is a Long Range SAM, radar guided.
|
||||
local threat = object:GetThreatLevel()
|
||||
local typekey = "INFANTRY"
|
||||
if threat == 0 or threat == 2 then
|
||||
typekey = "TECHNICAL"
|
||||
elseif threat == 3 then
|
||||
typekey = "ARTILLERY"
|
||||
elseif threat == 4 or threat == 5 then
|
||||
typekey = "TANKS"
|
||||
elseif threat == 6 or threat == 7 then
|
||||
typekey = "AIRDEFENSE"
|
||||
elseif threat >= 8 then
|
||||
typekey = "SAM"
|
||||
end
|
||||
local typename = self.gettext:GetEntry(typekey,self.locale)
|
||||
local gname = self.gettext:GetEntry("GROUP",self.locale)
|
||||
target.TypeName = string.format("%s %s",typename,gname)
|
||||
--self:T(self.lid.."Target TypeName = "..target.TypeName)
|
||||
end
|
||||
local typename = self.gettext:GetEntry(typekey,self.locale)
|
||||
local gname = self.gettext:GetEntry("GROUP",self.locale)
|
||||
target.TypeName = string.format("%s %s",typename,gname)
|
||||
--self:T(self.lid.."Target TypeName = "..target.TypeName)
|
||||
|
||||
if self.UseTypeNames and object:IsShip() then
|
||||
local threat = object:GetThreatLevel()
|
||||
local typekey = "UNARMEDSHIP"
|
||||
if threat == 1 then
|
||||
typekey = "LIGHTARMEDSHIP"
|
||||
elseif threat == 2 then
|
||||
typekey = "CORVETTE"
|
||||
elseif threat == 3 or threat == 4 then
|
||||
typekey = "FRIGATE"
|
||||
elseif threat == 5 or threat == 6 then
|
||||
typekey = "CRUISER"
|
||||
elseif threat == 7 or threat == 8 then
|
||||
typekey = "DESTROYER"
|
||||
elseif threat >= 9 then
|
||||
typekey = "CARRIER"
|
||||
end
|
||||
local typename = self.gettext:GetEntry(typekey,self.locale)
|
||||
target.TypeName = typename
|
||||
--self:T(self.lid.."Target TypeName = "..target.TypeName)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self:_AddTask(target)
|
||||
|
||||
@ -489,6 +489,31 @@ UTILS.hPa2inHg = function( hPa )
|
||||
return hPa * 0.0295299830714
|
||||
end
|
||||
|
||||
--- Convert indicated airspeed (IAS) to true airspeed (TAS) for a given altitude above main sea level.
|
||||
-- The conversion is based on the approximation that TAS is ~2% higher than IAS with every 1000 ft altitude above sea level.
|
||||
-- @param #number ias Indicated air speed in any unit (m/s, km/h, knots, ...)
|
||||
-- @param #number altitude Altitude above main sea level in meters.
|
||||
-- @param #number oatcorr (Optional) Outside air temperature correction factor. Default 0.017.
|
||||
-- @return #number True airspeed in the same unit the IAS has been given.
|
||||
UTILS.IasToTas = function( ias, altitude, oatcorr )
|
||||
oatcorr=oatcorr or 0.017
|
||||
local tas=ias + (ias * oatcorr * UTILS.MetersToFeet(altitude) / 1000)
|
||||
return tas
|
||||
end
|
||||
|
||||
--- Convert true airspeed (TAS) to indicated airspeed (IAS) for a given altitude above main sea level.
|
||||
-- The conversion is based on the approximation that TAS is ~2% higher than IAS with every 1000 ft altitude above sea level.
|
||||
-- @param #number tas True air speed in any unit (m/s, km/h, knots, ...)
|
||||
-- @param #number altitude Altitude above main sea level in meters.
|
||||
-- @param #number oatcorr (Optional) Outside air temperature correction factor. Default 0.017.
|
||||
-- @return #number Indicated airspeed in the same unit the TAS has been given.
|
||||
UTILS.TasToIas = function( tas, altitude, oatcorr )
|
||||
oatcorr=oatcorr or 0.017
|
||||
local ias=tas/(1+oatcorr*UTILS.MetersToFeet(altitude)/1000)
|
||||
return ias
|
||||
end
|
||||
|
||||
|
||||
--- Convert knots to altitude corrected KIAS, e.g. for tankers.
|
||||
-- @param #number knots Speed in knots.
|
||||
-- @param #number altitude Altitude in feet
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
--- **Wrapper** - GROUP wraps the DCS Class Group objects.
|
||||
----- **Wrapper** - GROUP wraps the DCS Class Group objects.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -2810,7 +2810,7 @@ function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations)
|
||||
if self:IsAlive() then
|
||||
local IsPlayer = self:IsPlayer()
|
||||
local shortcallsign = self:GetCallsign() or "unknown91" -- e.g.Uzi91, but we want Uzi 9 1
|
||||
local callsignroot = string.match(shortcallsign, '(%a+)') -- Uzi
|
||||
local callsignroot = string.match(shortcallsign, '(%a+)') or "Ghost" -- Uzi
|
||||
--self:I("CallSign = " .. callsignroot)
|
||||
local groupname = self:GetName()
|
||||
local callnumber = string.match(shortcallsign, "(%d+)$" ) or "91" -- 91
|
||||
|
||||
@ -16,14 +16,27 @@ do
|
||||
-- @type NET
|
||||
-- @field #string ClassName
|
||||
-- @field #string Version
|
||||
-- @extends Core.Base#BASE
|
||||
-- @field #string lid
|
||||
-- @field #number BlockTime
|
||||
-- @field #table BlockedPilots
|
||||
-- @field #table KnownPilots
|
||||
-- @field #string BlockMessage
|
||||
-- @field #string UnblockMessage
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- Encapsules multiplayer environment scripting functions from [net](https://wiki.hoggitworld.com/view/DCS_singleton_net)
|
||||
-- with some added FSM functions and options to block/unblock players in MP environments.
|
||||
--
|
||||
-- @field #NET
|
||||
NET = {
|
||||
ClassName = "NET",
|
||||
Version = "0.0.2"
|
||||
Version = "0.0.3",
|
||||
BlockTime = 600,
|
||||
BlockedPilots = {},
|
||||
KnownPilots = {},
|
||||
BlockMessage = nil,
|
||||
UnblockMessage = nil,
|
||||
lid = nil,
|
||||
}
|
||||
|
||||
--- Instantiate a new NET object.
|
||||
@ -31,7 +44,218 @@ NET = {
|
||||
-- @return #NET self
|
||||
function NET:New()
|
||||
-- Inherit base.
|
||||
local self = BASE:Inherit(self, BASE:New()) -- #NET
|
||||
local self = BASE:Inherit(self, FSM:New()) -- #NET
|
||||
|
||||
self.BlockTime = 600
|
||||
self.BlockedPilots = {}
|
||||
self.KnownPilots = {}
|
||||
self:SetBlockMessage()
|
||||
self:SetUnblockMessage()
|
||||
|
||||
self:HandleEvent(EVENTS.PlayerEnterUnit,self._EventHandler)
|
||||
self:HandleEvent(EVENTS.PlayerEnterAircraft,self._EventHandler)
|
||||
self:HandleEvent(EVENTS.PlayerLeaveUnit,self._EventHandler)
|
||||
self:HandleEvent(EVENTS.PilotDead,self._EventHandler)
|
||||
self:HandleEvent(EVENTS.Ejection,self._EventHandler)
|
||||
self:HandleEvent(EVENTS.Crash,self._EventHandler)
|
||||
self:HandleEvent(EVENTS.SelfKillPilot,self._EventHandler)
|
||||
|
||||
-- Start State.
|
||||
self:SetStartState("Running")
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
self:AddTransition("*", "Run", "Running") -- Start FSM.
|
||||
self:AddTransition("*", "PlayerJoined", "*")
|
||||
self:AddTransition("*", "PlayerLeft", "*")
|
||||
self:AddTransition("*", "PlayerDied", "*")
|
||||
self:AddTransition("*", "PlayerEjected", "*")
|
||||
self:AddTransition("*", "PlayerBlocked", "*")
|
||||
self:AddTransition("*", "PlayerUnblocked", "*")
|
||||
|
||||
self.lid = string.format("NET %s | ",self.Version)
|
||||
|
||||
--- FSM Function OnAfterPlayerJoined.
|
||||
-- @function [parent=#NET] OnAfterPlayerJoined
|
||||
-- @param #NET self
|
||||
-- @param #string From State.
|
||||
-- @param #string Event Trigger.
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Unit#UNIT Client Unit Object.
|
||||
-- @param #string Name Name of joining Pilot.
|
||||
-- @return #NET self
|
||||
|
||||
--- FSM Function OnAfterPlayerLeft.
|
||||
-- @function [parent=#NET] OnAfterPlayerLeft
|
||||
-- @param #NET self
|
||||
-- @param #string From State.
|
||||
-- @param #string Event Trigger.
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Unit#UNIT Client Unit Object.
|
||||
-- @param #string Name Name of leaving Pilot.
|
||||
-- @return #NET self
|
||||
|
||||
--- FSM Function OnAfterPlayerEjected.
|
||||
-- @function [parent=#NET] OnAfterPlayerEjected
|
||||
-- @param #NET self
|
||||
-- @param #string From State.
|
||||
-- @param #string Event Trigger.
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Unit#UNIT Client Unit Object.
|
||||
-- @param #string Name Name of leaving Pilot.
|
||||
-- @return #NET self
|
||||
|
||||
--- FSM Function OnAfterPlayerDied.
|
||||
-- @function [parent=#NET] OnAfterPlayerDied
|
||||
-- @param #NET self
|
||||
-- @param #string From State.
|
||||
-- @param #string Event Trigger.
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Unit#UNIT Client Unit Object.
|
||||
-- @param #string Name Name of dead Pilot.
|
||||
-- @return #NET self
|
||||
|
||||
--- FSM Function OnAfterPlayerBlocked.
|
||||
-- @function [parent=#NET] OnAfterPlayerBlocked
|
||||
-- @param #NET self
|
||||
-- @param #string From State.
|
||||
-- @param #string Event Trigger.
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Client#CLIENT Client Client Object.
|
||||
-- @param #string Name Name of blocked Pilot.
|
||||
-- @param #number Seconds Blocked for this number of seconds
|
||||
-- @return #NET self
|
||||
|
||||
--- FSM Function OnAfterPlayerUnblocked.
|
||||
-- @function [parent=#NET] OnAfterPlayerUnblocked
|
||||
-- @param #NET self
|
||||
-- @param #string From State.
|
||||
-- @param #string Event Trigger.
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Client#CLIENT Client Client Object.
|
||||
-- @param #string Name Name of unblocked Pilot.
|
||||
-- @return #NET self
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] Event Handler
|
||||
-- @param #NET self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
-- @return #NET self
|
||||
function NET:_EventHandler(EventData)
|
||||
self:T(self.lid .. " _EventHandler")
|
||||
self:T2({Event = EventData.id})
|
||||
local data = EventData -- Core.Event#EVENTDATA EventData
|
||||
if data.id and data.IniUnit and (data.IniPlayerName or data.IniUnit:GetPlayerName()) then
|
||||
-- Get PlayerName
|
||||
local name = data.IniPlayerName and data.IniPlayerName or data.IniUnit:GetPlayerName()
|
||||
self:T(self.lid.."Event for: "..name)
|
||||
-- Joining
|
||||
if data.id == EVENTS.PlayerEnterUnit or data.id == EVENTS.PlayerEnterAircraft then
|
||||
-- Check for known pilots
|
||||
local TNow = timer.getTime()
|
||||
if self.BlockedPilots[name] and TNow < self.BlockedPilots[name] then
|
||||
-- block pilot
|
||||
self:ReturnToSpectators(data.IniUnit)
|
||||
else
|
||||
self.KnownPilots[name] = true
|
||||
self.BlockedPilots[name] = nil
|
||||
self:__PlayerJoined(1,data.IniUnit,name)
|
||||
return self
|
||||
end
|
||||
end
|
||||
-- Leaving
|
||||
if data.id == EVENTS.PlayerLeaveUnit and self.KnownPilots[name] then
|
||||
self:__PlayerLeft(1,data.IniUnit,name)
|
||||
self.KnownPilots[name] = false
|
||||
return self
|
||||
end
|
||||
-- Ejected
|
||||
if data.id == EVENTS.Ejection and self.KnownPilots[name] then
|
||||
self:__PlayerEjected(1,data.IniUnit,name)
|
||||
self.KnownPilots[name] = false
|
||||
return self
|
||||
end
|
||||
-- Dead, Crash, Suicide
|
||||
if (data.id == EVENTS.PilotDead or data.id == EVENTS.SelfKillPilot or data.id == EVENTS.Crash) and self.KnownPilots[name] then
|
||||
self:__PlayerDied(1,data.IniUnit,name)
|
||||
self.KnownPilots[name] = false
|
||||
return self
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Block a player.
|
||||
-- @param #NET self
|
||||
-- @param Wrapper.Client#CLIENT Client CLIENT object.
|
||||
-- @param #string PlayerName (optional) Name of the player.
|
||||
-- @param #number Seconds (optional) Number of seconds the player has to wait before rejoining.
|
||||
-- @param #string Message (optional) Message to be sent via chat.
|
||||
-- @return #NET self
|
||||
function NET:BlockPlayer(Client,PlayerName,Seconds,Message)
|
||||
local name
|
||||
if Client then
|
||||
name = CLIENT:GetPlayerName()
|
||||
elseif PlayerName then
|
||||
name = PlayerName
|
||||
else
|
||||
self:F(self.lid.."Block: No PlayerName given or not found!")
|
||||
return self
|
||||
end
|
||||
local addon = Seconds or self.BlockTime
|
||||
self.BlockedPilots[name] = timer.getTime()+addon
|
||||
local message = Message or self.BlockMessage
|
||||
if Client then
|
||||
self:SendChatToPlayer(message,Client)
|
||||
else
|
||||
self:SendChat(name..": "..message)
|
||||
end
|
||||
self:__PlayerBlocked(1,Client,name,Seconds)
|
||||
self:ReturnToSpectators(Client)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Unblock a player.
|
||||
-- @param #NET self
|
||||
-- @param Wrapper.Client#CLIENT Client CLIENT object
|
||||
-- @param #string PlayerName (optional) Name of the player.
|
||||
-- @param #string Message (optional) Message to be sent via chat.
|
||||
-- @return #NET self
|
||||
function NET:UnblockPlayer(Client,PlayerName,Message)
|
||||
local name
|
||||
if Client then
|
||||
name = CLIENT:GetPlayerName()
|
||||
elseif PlayerName then
|
||||
name = PlayerName
|
||||
else
|
||||
self:F(self.lid.."Unblock: No PlayerName given or not found!")
|
||||
return self
|
||||
end
|
||||
self.BlockedPilots[name] = nil
|
||||
local message = Message or self.UnblockMessage
|
||||
if Client then
|
||||
self:SendChatToPlayer(message,Client)
|
||||
else
|
||||
self:SendChat(name..": "..message)
|
||||
end
|
||||
self:__PlayerUnblocked(1,Client,name)
|
||||
return self
|
||||
end
|
||||
|
||||
function NET:SetBlockMessage(Text)
|
||||
self.BlockMessage = Text or "You are blocked from joining. Wait time is: "..self.BlockTime.." seconds!"
|
||||
return self
|
||||
end
|
||||
|
||||
function NET:SetBlockTime(Seconds)
|
||||
self.BlockTime = Seconds or 600
|
||||
return self
|
||||
end
|
||||
|
||||
function NET:SetUnblockMessage(Text)
|
||||
self.UnblockMessage = Text or "You are unblocked now and can join again."
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@ -845,6 +845,78 @@ function POSITIONABLE:GetVelocityKNOTS()
|
||||
return UTILS.MpsToKnots( self:GetVelocityMPS() )
|
||||
end
|
||||
|
||||
--- Returns the true airspeed (TAS). This is calculated from the current velocity minus wind in 3D.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @return #number TAS in m/s. Returns 0 if the POSITIONABLE does not exist.
|
||||
function POSITIONABLE:GetAirspeedTrue()
|
||||
|
||||
-- TAS
|
||||
local tas=0
|
||||
|
||||
-- Get current coordinate.
|
||||
local coord=self:GetCoord()
|
||||
|
||||
if coord then
|
||||
|
||||
-- Altitude in meters.
|
||||
local alt=coord.y
|
||||
|
||||
-- Wind velocity vector.
|
||||
local wvec3=coord:GetWindVec3(alt, false)
|
||||
|
||||
-- Velocity vector.
|
||||
local vvec3=self:GetVelocityVec3()
|
||||
|
||||
--GS=TAS+WIND ==> TAS=GS-WIND
|
||||
local tasvec3=UTILS.VecSubstract(vvec3, wvec3)
|
||||
|
||||
-- True airspeed in m/s
|
||||
tas=UTILS.VecNorm(tasvec3)
|
||||
|
||||
end
|
||||
|
||||
return tas
|
||||
end
|
||||
|
||||
--- Returns the indicated airspeed (IAS).
|
||||
-- The IAS is calculated from the TAS under the approximation that TAS increases by ~2% with every 1000 feet altitude ASL.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #number oatcorr (Optional) Outside air temperature (OAT) correction factor. Default 0.017 (=1.7%).
|
||||
-- @return #number IAS in m/s. Returns 0 if the POSITIONABLE does not exist.
|
||||
function POSITIONABLE:GetAirspeedIndicated(oatcorr)
|
||||
|
||||
-- Get true airspeed.
|
||||
local tas=self:GetAirspeedTrue()
|
||||
|
||||
-- Get altitude.
|
||||
local altitude=self:GetAltitude()
|
||||
|
||||
-- Convert TAS to IAS.
|
||||
local ias=UTILS.TasToIas(tas, altitude, oatcorr)
|
||||
|
||||
return ias
|
||||
end
|
||||
|
||||
--- Returns the horizonal speed relative to eath's surface. The vertical component of the velocity vector is projected out (set to zero).
|
||||
-- @param #POSITIONABLE self
|
||||
-- @return #number Ground speed in m/s. Returns 0 if the POSITIONABLE does not exist.
|
||||
function POSITIONABLE:GetGroundSpeed()
|
||||
|
||||
local gs=0
|
||||
|
||||
local vel=self:GetVelocityVec3()
|
||||
|
||||
if vel then
|
||||
|
||||
local vec2={x=vel.x, y=vel.z}
|
||||
|
||||
gs=UTILS.Vec2Norm(vel)
|
||||
|
||||
end
|
||||
|
||||
return gs
|
||||
end
|
||||
|
||||
--- Returns the Angle of Attack of a POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @return #number Angle of attack in degrees.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user