mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
CT v0.0.2
This commit is contained in:
parent
46882ed192
commit
eda359e20f
@ -50,12 +50,12 @@ CARRIERTRAINER = {
|
|||||||
carrier = nil,
|
carrier = nil,
|
||||||
startZone = nil,
|
startZone = nil,
|
||||||
giantZone = nil,
|
giantZone = nil,
|
||||||
players = nil,
|
players = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Carrier trainer class version.
|
--- Carrier trainer class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CARRIERTRAINER.version="0.0.1"
|
CARRIERTRAINER.version="0.0.2"
|
||||||
|
|
||||||
--- Player data table holding all important parameters for each player.
|
--- Player data table holding all important parameters for each player.
|
||||||
-- @type CARRIERTRAINER.PlayerData
|
-- @type CARRIERTRAINER.PlayerData
|
||||||
@ -146,14 +146,13 @@ end
|
|||||||
function CARRIERTRAINER:onafterStart(From, Event, To)
|
function CARRIERTRAINER:onafterStart(From, Event, To)
|
||||||
|
|
||||||
-- Events are handled my MOOSE.
|
-- Events are handled my MOOSE.
|
||||||
self:I(self.lid..string.format"Starting Carrier Training %s for carrier unit %s.", CARRIERTRAINER.version, self.carrier:GetName())
|
self:I(self.lid..string.format("Starting Carrier Training %s for carrier unit %s.", CARRIERTRAINER.version, self.carrier:GetName()))
|
||||||
|
|
||||||
-- Handle events.
|
-- Handle events.
|
||||||
self:HandleEvent(EVENTS.Birth)
|
self:HandleEvent(EVENTS.Birth)
|
||||||
|
|
||||||
|
-- Init status check
|
||||||
-- Init status checkss
|
self:__Status(5)
|
||||||
self:__Status(-1)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after Status event. Checks player status.
|
--- On after Status event. Checks player status.
|
||||||
@ -167,7 +166,7 @@ function CARRIERTRAINER:onafterStatus(From, Event, To)
|
|||||||
self:_CheckPlayerStatus()
|
self:_CheckPlayerStatus()
|
||||||
|
|
||||||
-- Call status again in one second.
|
-- Call status again in one second.
|
||||||
self:_Status(-1)
|
self:__Status(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after Stop event. Unhandle events and stop status updates.
|
--- On after Stop event. Unhandle events and stop status updates.
|
||||||
@ -208,25 +207,13 @@ function CARRIERTRAINER:OnEventBirth(EventData)
|
|||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
MESSAGE:New(text, 5):ToAllIf(self.Debug)
|
MESSAGE:New(text, 5):ToAllIf(self.Debug)
|
||||||
|
|
||||||
local playerdata={} --#CARRIERTRAINER.PlayerData
|
--
|
||||||
|
if self.players[_playername]==nil then
|
||||||
playerdata.callsign=_callsign
|
self.players[_playername]=self:_InitNewPlayer(_unitName)
|
||||||
|
|
||||||
if self.player[_playername]==nil then
|
|
||||||
self:_InitNewPlayer(_unitName)
|
|
||||||
else
|
else
|
||||||
self:_InitNewRound(self.player[_playername])
|
self:_InitNewRound(self.players[_playername])
|
||||||
end
|
end
|
||||||
|
|
||||||
-- By default, some bomb impact points and do not flare each hit on target.
|
|
||||||
self.players[_playername]=playerdata
|
|
||||||
|
|
||||||
-- Start check in zone timer.
|
|
||||||
if self.planes[_uid] ~= true then
|
|
||||||
SCHEDULER:New(nil, self._CheckInZone, {self, EventData.IniUnitName}, 1, 1)
|
|
||||||
self.planes[_uid] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -239,8 +226,8 @@ function CARRIERTRAINER:_InitNewPlayer(unitname)
|
|||||||
local playerData={} --#CARRIERTRAINER.PlayerData
|
local playerData={} --#CARRIERTRAINER.PlayerData
|
||||||
|
|
||||||
playerData.unit = UNIT:FindByName(unitname)
|
playerData.unit = UNIT:FindByName(unitname)
|
||||||
playerData.client = CLIENT:FindByName(self.unit.UnitName, nil, true)
|
playerData.client = CLIENT:FindByName(playerData.unit.UnitName, nil, true)
|
||||||
playerData.callsign = self.unit:GetCallsign()
|
playerData.callsign = playerData.unit:GetCallsign()
|
||||||
playerData.totalScore = 0
|
playerData.totalScore = 0
|
||||||
playerData.passes = 0
|
playerData.passes = 0
|
||||||
playerData.collectedResultString = ""
|
playerData.collectedResultString = ""
|
||||||
@ -294,19 +281,26 @@ end
|
|||||||
-- @param #CARRIERTRAINER self
|
-- @param #CARRIERTRAINER self
|
||||||
function CARRIERTRAINER:_CheckPlayerStatus()
|
function CARRIERTRAINER:_CheckPlayerStatus()
|
||||||
|
|
||||||
|
if self.players==nil then
|
||||||
|
self:I(self.lid.."No players yet.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Loop over all players.
|
-- Loop over all players.
|
||||||
for _playerName,_playerData in pairs(self.Player) do
|
for _playerName,_playerData in pairs(self.players) do
|
||||||
local playerData = _playerData --#CARRIERTRAINER.PlayerData
|
local playerData = _playerData --#CARRIERTRAINER.PlayerData
|
||||||
|
|
||||||
if playerData then
|
if playerData then
|
||||||
|
|
||||||
|
self:I("player "..playerData.callsign)
|
||||||
|
|
||||||
-- Player unit.
|
-- Player unit.
|
||||||
local unit = playerData.unit
|
local unit = playerData.unit
|
||||||
|
|
||||||
if unit:IsAlive() then
|
if unit:IsAlive() then
|
||||||
|
|
||||||
if unit:IsInZone(self.giantZone) then
|
if unit:IsInZone(self.giantZone) then
|
||||||
--Tick(playerData)
|
self:_DetailedPlayerStatus(playerData)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check long down wind leg.
|
-- Check long down wind leg.
|
||||||
@ -314,8 +308,8 @@ function CARRIERTRAINER:_CheckPlayerStatus()
|
|||||||
self:_CheckForLongDownwind(playerData)
|
self:_CheckForLongDownwind(playerData)
|
||||||
end
|
end
|
||||||
|
|
||||||
if playerData.step==0 and unit:IsInZone(self.giantZone and unit:InAir()) then
|
if playerData.step==0 and unit:IsInZone(self.giantZone) and unit:InAir() then
|
||||||
self:_NewRound(unitname)
|
self:_NewRound(playerData)
|
||||||
elseif playerData.step == 1 and unit:IsInZone(self.startZone) then
|
elseif playerData.step == 1 and unit:IsInZone(self.startZone) then
|
||||||
self:_Start(playerData)
|
self:_Start(playerData)
|
||||||
elseif playerData.step == 2 and unit:IsInZone(self.giantZone) then
|
elseif playerData.step == 2 and unit:IsInZone(self.giantZone) then
|
||||||
@ -343,6 +337,34 @@ function CARRIERTRAINER:_CheckPlayerStatus()
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Provide info about player status on the fly.
|
||||||
|
-- @param #CARRIERTRAINER self
|
||||||
|
-- @param #CARRIERTRAINER.PlayerData playerData Player data.
|
||||||
|
function CARRIERTRAINER:_DetailedPlayerStatus(playerData)
|
||||||
|
|
||||||
|
local unit=playerData.unit
|
||||||
|
|
||||||
|
local aoa=unit:GetAoA()
|
||||||
|
local dist=playerData.unit:GetCoordinate():Get2DDistance(self.carrier:GetCoordinate())
|
||||||
|
local dz,dx=self:_GetDistances(unit)
|
||||||
|
|
||||||
|
local text=string.format("%s, current AoA=%.1f\n", playerData.callsign, aoa)
|
||||||
|
text=text..string.format("Carrier distance: d=%d m\n", dist)
|
||||||
|
text=text..string.format("Carrier distance: z=%d m x=%d m sum=%d", dz, dx, math.abs(dz)+math.abs(dx))
|
||||||
|
|
||||||
|
-- Player and carrier position vector.
|
||||||
|
local playerPosition = playerData.unit:GetVec3()
|
||||||
|
local carrierPosition = self.carrier:GetVec3()
|
||||||
|
|
||||||
|
local diffZ = playerPosition.z - carrierPosition.z
|
||||||
|
local diffX = playerPosition.x - carrierPosition.x
|
||||||
|
|
||||||
|
-- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier)
|
||||||
|
diffZ, diffX = self:_GetDistances(playerData.unit)
|
||||||
|
|
||||||
|
MESSAGE:New(text, 5, nil ,true):ToClient(playerData.client)
|
||||||
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- CARRIER TRAINING functions
|
-- CARRIER TRAINING functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -351,9 +373,10 @@ end
|
|||||||
-- @param #CARRIERTRAINER self
|
-- @param #CARRIERTRAINER self
|
||||||
-- @param #CARRIERTRAINER.PlayerData playerData Player data.
|
-- @param #CARRIERTRAINER.PlayerData playerData Player data.
|
||||||
function CARRIERTRAINER:_NewRound(playerData)
|
function CARRIERTRAINER:_NewRound(playerData)
|
||||||
local playerData = nil
|
|
||||||
|
|
||||||
MessageToAll( "Welcome back, " .. playerData.callsign .. "! Cleared for approach! TCN 1X, BRC 354 (MAG HDG).", 5, "InitZoneMessage" )
|
local text=string.format("Welcome back, %s! Cleared for approach. TCN 1X, BRC 354 (MAG HDG).", playerData.callsign)
|
||||||
|
MESSAGE:New(text, 5):ToClient(playerData.client)
|
||||||
|
--MessageToAll( "Welcome back, " .. playerData.callsign .. "! Cleared for approach! TCN 1X, BRC 354 (MAG HDG).", 5, "InitZoneMessage" )
|
||||||
|
|
||||||
self:_InitNewRound(playerData)
|
self:_InitNewRound(playerData)
|
||||||
playerData.step = 1
|
playerData.step = 1
|
||||||
@ -423,8 +446,7 @@ function CARRIERTRAINER:_Upwind(playerData)
|
|||||||
|
|
||||||
self:_PrintAltitudeFeedback(altitude, idealAltitude, playerData)
|
self:_PrintAltitudeFeedback(altitude, idealAltitude, playerData)
|
||||||
self:_PrintScore(score, playerData, true)
|
self:_PrintScore(score, playerData, true)
|
||||||
|
|
||||||
|
|
||||||
self:_AddToSummary(playerData, hint)
|
self:_AddToSummary(playerData, hint)
|
||||||
|
|
||||||
-- Set step.
|
-- Set step.
|
||||||
@ -443,7 +465,7 @@ function CARRIERTRAINER:_GetDistances(unit)
|
|||||||
local x=self.carrier:GetOrientationX()
|
local x=self.carrier:GetOrientationX()
|
||||||
local dz=UTILS.VecDot(x,c)
|
local dz=UTILS.VecDot(x,c)
|
||||||
local alpha=math.acos(UTILS.VecDot(c,x)/UTILS.VecNorm(c))
|
local alpha=math.acos(UTILS.VecDot(c,x)/UTILS.VecNorm(c))
|
||||||
local dx=c*math.sin(alpha)
|
local dx=UTILS.VecNorm(c)*math.sin(alpha)
|
||||||
return dz,dx
|
return dz,dx
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -526,7 +548,7 @@ function CARRIERTRAINER:_Abeam(playerData)
|
|||||||
-- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier)
|
-- Get distances between carrier and player unit (parallel and perpendicular to direction of movement of carrier)
|
||||||
diffZ, diffX = self:_GetDistances(playerData.unit)
|
diffZ, diffX = self:_GetDistances(playerData.unit)
|
||||||
|
|
||||||
if(diffZ > -1000 or diffZ < -3700) then
|
if (diffZ > -1000 or diffZ < -3700) then
|
||||||
self:_AbortPattern(playerData)
|
self:_AbortPattern(playerData)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -617,10 +639,10 @@ function CARRIERTRAINER:_CheckForLongDownwind(playerData)
|
|||||||
--TODO if diffX
|
--TODO if diffX
|
||||||
|
|
||||||
if carrierPosition.x - playerPosition.x > limit then
|
if carrierPosition.x - playerPosition.x > limit then
|
||||||
--local heading = math.deg(mist.getHeading(playerData.mistUnit))
|
|
||||||
local heading = playerData.unit:GetHeading()
|
local heading = playerData.unit:GetHeading()
|
||||||
|
|
||||||
if(heading > 170) then
|
if (heading > 170) then
|
||||||
local hint = "Too long downwind. Turn final earlier next time."
|
local hint = "Too long downwind. Turn final earlier next time."
|
||||||
self:_SendMessageToPlayer( hint, 8, playerData )
|
self:_SendMessageToPlayer( hint, 8, playerData )
|
||||||
local score = -40
|
local score = -40
|
||||||
@ -777,7 +799,7 @@ function CARRIERTRAINER:_Groove(playerData)
|
|||||||
local hint = "You're too far left and never reached the groove."
|
local hint = "You're too far left and never reached the groove."
|
||||||
self:_SendMessageToPlayer( hint, 8, playerData )
|
self:_SendMessageToPlayer( hint, 8, playerData )
|
||||||
self:_PrintScore(0, playerData, true)
|
self:_PrintScore(0, playerData, true)
|
||||||
playerData:AddToSummary(hint)
|
self:_AddToSummary(playerData, hint)
|
||||||
playerData.step = 9
|
playerData.step = 9
|
||||||
else
|
else
|
||||||
local limitDeg = 8.0
|
local limitDeg = 8.0
|
||||||
@ -893,7 +915,7 @@ function CARRIERTRAINER:_Trap(playerData)
|
|||||||
|
|
||||||
local fullHint = "Trapped catching the " .. wire .. "-wire."
|
local fullHint = "Trapped catching the " .. wire .. "-wire."
|
||||||
|
|
||||||
playerData:AddToSummary(fullHint)
|
self:_AddToSummary(playerData, fullHint)
|
||||||
|
|
||||||
self:_PrintFinalScore(playerData, 60, wire)
|
self:_PrintFinalScore(playerData, 60, wire)
|
||||||
self:_HandleCollectedResult(playerData, wire)
|
self:_HandleCollectedResult(playerData, wire)
|
||||||
@ -916,7 +938,7 @@ function CARRIERTRAINER:_Trap(playerData)
|
|||||||
self:_SendMessageToPlayer( hint, 8, playerData )
|
self:_SendMessageToPlayer( hint, 8, playerData )
|
||||||
self:_PrintScore(score, playerData, true)
|
self:_PrintScore(score, playerData, true)
|
||||||
|
|
||||||
playerData:AddToSummary(hint)
|
self:_AddToSummary(playerData, hint)
|
||||||
|
|
||||||
self:_PrintFinalScore(playerData, 60, wire)
|
self:_PrintFinalScore(playerData, 60, wire)
|
||||||
self:_HandleCollectedResult(playerData, wire)
|
self:_HandleCollectedResult(playerData, wire)
|
||||||
@ -1064,7 +1086,7 @@ end
|
|||||||
-- @param #CARRIERTRAINER.PlayerData playerData Player data.
|
-- @param #CARRIERTRAINER.PlayerData playerData Player data.
|
||||||
function CARRIERTRAINER:_AbortPattern(playerData)
|
function CARRIERTRAINER:_AbortPattern(playerData)
|
||||||
self:_SendMessageToPlayer( "You're too far from where you should be. Abort approach!", 15, playerData )
|
self:_SendMessageToPlayer( "You're too far from where you should be. Abort approach!", 15, playerData )
|
||||||
playerData:AddToSummary("Approach aborted.")
|
self:_AddToSummary(playerData, "Approach aborted.")
|
||||||
self:_PrintFinalScore(playerData, 30, -2)
|
self:_PrintFinalScore(playerData, 30, -2)
|
||||||
self:_HandleCollectedResult(playerData, -2)
|
self:_HandleCollectedResult(playerData, -2)
|
||||||
playerData.step = 0
|
playerData.step = 0
|
||||||
@ -657,24 +657,24 @@ function UTILS.Randomize(value, fac, lower, upper)
|
|||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Calculate the dot (scalar) product of two vectors.
|
--- Calculate the [dot product](https://en.wikipedia.org/wiki/Dot_product) of two vectors. The result is a number.
|
||||||
-- @param DCS#Vec3 a Vector in 3D with x,y,z components.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
-- @param DCS#Vec3 b Vector in 3D with x,y,z components.
|
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||||
-- @return #number Scalar product of the two vectors a*b.
|
-- @return #number Scalar product of the two vectors a*b.
|
||||||
function UTILS.VecDot(a, b)
|
function UTILS.VecDot(a, b)
|
||||||
return a.x*b.x + a.y*b.y + a.z*b.z
|
return a.x*b.x + a.y*b.y + a.z*b.z
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Calculate the eucledian norm (length) of a 3D vector.
|
--- Calculate the [euclidean norm](https://en.wikipedia.org/wiki/Euclidean_distance) (length) of a 3D vector.
|
||||||
-- @param DCS#Vec3 a Vector in 3D with x,y,z components.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
-- @return #number Norm of the vector.
|
-- @return #number Norm of the vector.
|
||||||
function UTILS.VecNorm(a)
|
function UTILS.VecNorm(a)
|
||||||
return math.sqrt(UTILS.DotProduct(a, a))
|
return math.sqrt(UTILS.VecDot(a, a))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Calculate the cross product of two 3D vectors.
|
--- Calculate the [cross product](https://en.wikipedia.org/wiki/Cross_product) of two 3D vectors. The result is a 3D vector.
|
||||||
-- @param DCS#Vec3 a Vector in 3D with x,y,z components.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
-- @param DCS#Vec3 b Vector in 3D with x,y,z components.
|
-- @param DCS#Vec3 b Vector in 3D with x, y, z components.
|
||||||
-- @return DCS#Vec3 Vector
|
-- @return DCS#Vec3 Vector
|
||||||
function UTILS.VecCross(a, b)
|
function UTILS.VecCross(a, b)
|
||||||
return {x=a.y*b.z - a.z*b.y, y=a.z*b.x - a.x*b.z, z=a.x*b.y - a.y*b.x}
|
return {x=a.y*b.z - a.z*b.y, y=a.z*b.x - a.x*b.z, z=a.x*b.y - a.y*b.x}
|
||||||
|
|||||||
@ -667,7 +667,7 @@ function POSITIONABLE:GetAoA()
|
|||||||
if unitpos then
|
if unitpos then
|
||||||
|
|
||||||
-- Get velocity vector of the unit.
|
-- Get velocity vector of the unit.
|
||||||
local unitvel = self:GetVelocity()
|
local unitvel = self:GetVelocityVec3()
|
||||||
|
|
||||||
if unitvel and UTILS.VecNorm(unitvel)~=0 then
|
if unitvel and UTILS.VecNorm(unitvel)~=0 then
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user