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
|
return heading
|
||||||
end
|
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.
|
--- Returns the wind direction (from) and strength.
|
||||||
-- @param #COORDINATE self
|
-- @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.
|
-- @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.
|
||||||
-- @return Direction the wind is blowing from in degrees.
|
-- @param #boolean turbulence If `true`, include turbulence. If `false` or `nil`, wind without turbulence.
|
||||||
-- @return Wind strength in m/s.
|
-- @return #number Direction the wind is blowing from in degrees.
|
||||||
function COORDINATE:GetWind(height)
|
-- @return #number Wind strength in m/s.
|
||||||
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.
|
function COORDINATE:GetWind(height, turbulence)
|
||||||
local point={x=self.x, y=math.max(height or self.y, landheight), z=self.z}
|
|
||||||
-- get wind velocity vector
|
-- Get wind velocity vector
|
||||||
local wind = atmosphere.getWind(point)
|
local wind = self:GetWindVec3(height, turbulence)
|
||||||
local direction = math.deg(math.atan2(wind.z, wind.x))
|
|
||||||
if direction < 0 then
|
-- Calculate the direction of the vector.
|
||||||
direction = 360 + direction
|
local direction=UTILS.VecHdg(wind)
|
||||||
end
|
|
||||||
-- Convert to direction to from direction
|
-- Invert "to" direction to "from" direction.
|
||||||
if direction > 180 then
|
if direction > 180 then
|
||||||
direction = direction-180
|
direction = direction-180
|
||||||
else
|
else
|
||||||
direction = direction+180
|
direction = direction+180
|
||||||
end
|
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
|
return direction, strength
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
|
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
|
||||||
--
|
--
|
||||||
-- * Spot for a defined duration.
|
-- * 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.
|
-- * Wiggle the spot at the target.
|
||||||
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
|
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
|
||||||
-- * Implement a status machine, LaseOn, LaseOff.
|
-- * Implement a status machine, LaseOn, LaseOff.
|
||||||
@ -13,18 +13,8 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- # Demo Missions
|
-- # 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)
|
-- ### [Demo Missions on GitHub](https://github.com/FlightControl-Master/MOOSE_MISSIONS)
|
||||||
--
|
|
||||||
-- ===
|
|
||||||
--
|
|
||||||
-- # YouTube Channel
|
|
||||||
--
|
|
||||||
-- ### [SPOT YouTube Channel]()
|
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -50,14 +40,14 @@ do
|
|||||||
--- Implements the target spotting or marking functionality, but adds additional luxury to be able to:
|
--- Implements the target spotting or marking functionality, but adds additional luxury to be able to:
|
||||||
--
|
--
|
||||||
-- * Mark targets for a defined duration.
|
-- * 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.
|
-- * Wiggle the spot at the target.
|
||||||
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
|
-- * Provide a @{Wrapper.Unit} as a target, instead of a point.
|
||||||
-- * Implement a status machine, LaseOn, LaseOff.
|
-- * Implement a status machine, LaseOn, LaseOff.
|
||||||
--
|
--
|
||||||
-- ## 1. SPOT constructor
|
-- ## 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
|
-- ## 2. SPOT is a FSM
|
||||||
--
|
--
|
||||||
@ -217,6 +207,8 @@ do
|
|||||||
|
|
||||||
|
|
||||||
self.Recce = Recce
|
self.Recce = Recce
|
||||||
|
|
||||||
|
self.RecceName = self.Recce:GetName()
|
||||||
|
|
||||||
self.LaseScheduler = SCHEDULER:New( self )
|
self.LaseScheduler = SCHEDULER:New( self )
|
||||||
|
|
||||||
@ -243,6 +235,9 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.Target = Target
|
self.Target = Target
|
||||||
|
|
||||||
|
self.TargetName = Target:GetName()
|
||||||
|
|
||||||
self.LaserCode = LaserCode
|
self.LaserCode = LaserCode
|
||||||
|
|
||||||
self.Lasing = true
|
self.Lasing = true
|
||||||
@ -302,12 +297,18 @@ do
|
|||||||
function SPOT:OnEventDead(EventData)
|
function SPOT:OnEventDead(EventData)
|
||||||
self:F( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
|
self:F( { Dead = EventData.IniDCSUnitName, Target = self.Target } )
|
||||||
if self.Target then
|
if self.Target then
|
||||||
if EventData.IniDCSUnitName == self.Target:GetName() then
|
if EventData.IniDCSUnitName == self.TargetName then
|
||||||
self:F( {"Target dead ", self.Target:GetName() } )
|
self:F( {"Target dead ", self.TargetName } )
|
||||||
self:Destroyed()
|
self:Destroyed()
|
||||||
self:LaseOff()
|
self:LaseOff()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if self.Recce then
|
||||||
|
if EventData.IniDCSUnitName == self.RecceName then
|
||||||
|
self:F( {"Recce dead ", self.RecceName } )
|
||||||
|
self:LaseOff()
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SPOT self
|
--- @param #SPOT self
|
||||||
@ -382,4 +383,4 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1369,6 +1369,13 @@ PLAYERTASKCONTROLLER.Messages = {
|
|||||||
AIRDEFENSE = "Airdefense",
|
AIRDEFENSE = "Airdefense",
|
||||||
SAM = "SAM",
|
SAM = "SAM",
|
||||||
GROUP = "Group",
|
GROUP = "Group",
|
||||||
|
UNARMEDSHIP = "Merchant",
|
||||||
|
LIGHTARMEDSHIP = "Light Boat",
|
||||||
|
CORVETTE = "Corvette",
|
||||||
|
FRIGATE = "Frigate",
|
||||||
|
CRUISER = "Cruiser",
|
||||||
|
DESTROYER = "Destroyer",
|
||||||
|
CARRIER = "Aircraft Carrier",
|
||||||
},
|
},
|
||||||
DE = {
|
DE = {
|
||||||
TASKABORT = "Auftrag abgebrochen!",
|
TASKABORT = "Auftrag abgebrochen!",
|
||||||
@ -1441,12 +1448,19 @@ PLAYERTASKCONTROLLER.Messages = {
|
|||||||
AIRDEFENSE = "Flak",
|
AIRDEFENSE = "Flak",
|
||||||
SAM = "Luftabwehr",
|
SAM = "Luftabwehr",
|
||||||
GROUP = "Einheit",
|
GROUP = "Einheit",
|
||||||
|
UNARMEDSHIP = "Handelsschiff",
|
||||||
|
LIGHTARMEDSHIP = "Tender",
|
||||||
|
CORVETTE = "Korvette",
|
||||||
|
FRIGATE = "Fregatte",
|
||||||
|
CRUISER = "Kreuzer",
|
||||||
|
DESTROYER = "Zerstörer",
|
||||||
|
CARRIER = "Flugzeugträger",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- PLAYERTASK class version.
|
--- PLAYERTASK class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
PLAYERTASKCONTROLLER.version="0.1.56"
|
PLAYERTASKCONTROLLER.version="0.1.58"
|
||||||
|
|
||||||
--- Create and run a new TASKCONTROLLER instance.
|
--- Create and run a new TASKCONTROLLER instance.
|
||||||
-- @param #PLAYERTASKCONTROLLER self
|
-- @param #PLAYERTASKCONTROLLER self
|
||||||
@ -2231,35 +2245,60 @@ function PLAYERTASKCONTROLLER:_CheckTargetQueue()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.UseTypeNames and object:IsGround() then
|
if object:IsInstanceOf("UNIT") or object:IsInstanceOf("GROUP") then
|
||||||
-- * Threat level 0: Unit is unarmed.
|
|
||||||
-- * Threat level 1: Unit is infantry.
|
if self.UseTypeNames and object:IsGround() then
|
||||||
-- * Threat level 2: Unit is an infantry vehicle.
|
-- * Threat level 0: Unit is unarmed.
|
||||||
-- * Threat level 3: Unit is ground artillery.
|
-- * Threat level 1: Unit is infantry.
|
||||||
-- * Threat level 4: Unit is a tank.
|
-- * Threat level 2: Unit is an infantry vehicle.
|
||||||
-- * Threat level 5: Unit is a modern tank or ifv with ATGM.
|
-- * Threat level 3: Unit is ground artillery.
|
||||||
-- * Threat level 6: Unit is a AAA.
|
-- * Threat level 4: Unit is a tank.
|
||||||
-- * Threat level 7: Unit is a SAM or manpad, IR guided.
|
-- * Threat level 5: Unit is a modern tank or ifv with ATGM.
|
||||||
-- * Threat level 8: Unit is a Short Range SAM, radar guided.
|
-- * Threat level 6: Unit is a AAA.
|
||||||
-- * Threat level 9: Unit is a Medium Range SAM, radar guided.
|
-- * Threat level 7: Unit is a SAM or manpad, IR guided.
|
||||||
-- * Threat level 10: Unit is a Long Range SAM, radar guided.
|
-- * Threat level 8: Unit is a Short Range SAM, radar guided.
|
||||||
local threat = object:GetThreatLevel()
|
-- * Threat level 9: Unit is a Medium Range SAM, radar guided.
|
||||||
local typekey = "INFANTRY"
|
-- * Threat level 10: Unit is a Long Range SAM, radar guided.
|
||||||
if threat == 0 or threat == 2 then
|
local threat = object:GetThreatLevel()
|
||||||
typekey = "TECHNICAL"
|
local typekey = "INFANTRY"
|
||||||
elseif threat == 3 then
|
if threat == 0 or threat == 2 then
|
||||||
typekey = "ARTILLERY"
|
typekey = "TECHNICAL"
|
||||||
elseif threat == 4 or threat == 5 then
|
elseif threat == 3 then
|
||||||
typekey = "TANKS"
|
typekey = "ARTILLERY"
|
||||||
elseif threat == 6 or threat == 7 then
|
elseif threat == 4 or threat == 5 then
|
||||||
typekey = "AIRDEFENSE"
|
typekey = "TANKS"
|
||||||
elseif threat >= 8 then
|
elseif threat == 6 or threat == 7 then
|
||||||
typekey = "SAM"
|
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
|
end
|
||||||
local typename = self.gettext:GetEntry(typekey,self.locale)
|
|
||||||
local gname = self.gettext:GetEntry("GROUP",self.locale)
|
if self.UseTypeNames and object:IsShip() then
|
||||||
target.TypeName = string.format("%s %s",typename,gname)
|
local threat = object:GetThreatLevel()
|
||||||
--self:T(self.lid.."Target TypeName = "..target.TypeName)
|
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
|
end
|
||||||
|
|
||||||
self:_AddTask(target)
|
self:_AddTask(target)
|
||||||
|
|||||||
@ -489,6 +489,31 @@ UTILS.hPa2inHg = function( hPa )
|
|||||||
return hPa * 0.0295299830714
|
return hPa * 0.0295299830714
|
||||||
end
|
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.
|
--- Convert knots to altitude corrected KIAS, e.g. for tankers.
|
||||||
-- @param #number knots Speed in knots.
|
-- @param #number knots Speed in knots.
|
||||||
-- @param #number altitude Altitude in feet
|
-- @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
|
if self:IsAlive() then
|
||||||
local IsPlayer = self:IsPlayer()
|
local IsPlayer = self:IsPlayer()
|
||||||
local shortcallsign = self:GetCallsign() or "unknown91" -- e.g.Uzi91, but we want Uzi 9 1
|
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)
|
--self:I("CallSign = " .. callsignroot)
|
||||||
local groupname = self:GetName()
|
local groupname = self:GetName()
|
||||||
local callnumber = string.match(shortcallsign, "(%d+)$" ) or "91" -- 91
|
local callnumber = string.match(shortcallsign, "(%d+)$" ) or "91" -- 91
|
||||||
|
|||||||
@ -16,14 +16,27 @@ do
|
|||||||
-- @type NET
|
-- @type NET
|
||||||
-- @field #string ClassName
|
-- @field #string ClassName
|
||||||
-- @field #string Version
|
-- @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)
|
--- 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
|
-- @field #NET
|
||||||
NET = {
|
NET = {
|
||||||
ClassName = "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.
|
--- Instantiate a new NET object.
|
||||||
@ -31,7 +44,218 @@ NET = {
|
|||||||
-- @return #NET self
|
-- @return #NET self
|
||||||
function NET:New()
|
function NET:New()
|
||||||
-- Inherit base.
|
-- 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
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -845,6 +845,78 @@ function POSITIONABLE:GetVelocityKNOTS()
|
|||||||
return UTILS.MpsToKnots( self:GetVelocityMPS() )
|
return UTILS.MpsToKnots( self:GetVelocityMPS() )
|
||||||
end
|
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.
|
--- Returns the Angle of Attack of a POSITIONABLE.
|
||||||
-- @param #POSITIONABLE self
|
-- @param #POSITIONABLE self
|
||||||
-- @return #number Angle of attack in degrees.
|
-- @return #number Angle of attack in degrees.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user