FMD: misc
FOX v0.3.0 improvements
RANGE v2.1.1 fixed bugs
SCORING added option to reload csv file
WAREHOUSE v0.7.1 added AssedSpawned FMS event.
This commit is contained in:
Frank
2019-05-13 21:57:09 +02:00
parent b795d2fd09
commit 8e92b8045b
6 changed files with 539 additions and 249 deletions
@@ -145,7 +145,7 @@ function FMD:New()
self:AddTransition("*", "Status", "*") -- Start FMD script.
-- Start FMD.
FMD:Start()
self:Start()
return self
end
@@ -239,28 +239,33 @@ end
-- @param Wrapper.Unit#UNIT unit
-- @return #FMD.DataPoint Datapoint.
function FMD:_GetDataPoint(unit)
if unit and unit:IsAlive() then
-- Current coordinate.
local coord=unit:GetCoordinate()
local dp={} --#FMD.DataPoint
dp.a={}
dp.Alt=coord.y
dp.AoA=unit:GetAoA()
dp.Atot=nil
dp.P=coord:GetPressure()
dp.Pitch=unit:GetPitch()
dp.Roll=unit:GetRoll()
dp.time=timer.getAbsTime()
dp.T=coord:GetTemperature()
dp.v=unit:GetVelocityVec3()
dp.Vtot=UTILS.VecNorm(dp.v)
dp.Yaw=unit:GetYaw()
dp.o=unit:GetOrientationX()
dp.Hdg=unit:GetHeading()
return dp
-- Current coordinate.
local coord=unit:GetCoordinate()
local dp={} --#FMD.DataPoint
dp.a={}
dp.Alt=coord.y
dp.AoA=unit:GetAoA()
dp.Atot=nil
dp.P=coord:GetPressure()
dp.Pitch=unit:GetPitch()
dp.Roll=unit:GetRoll()
dp.time=timer.getAbsTime()
dp.T=coord:GetTemperature()
dp.v=unit:GetVelocityVec3()
dp.Vtot=UTILS.VecNorm(dp.v)
dp.Yaw=unit:GetYaw()
dp.o=unit:GetOrientationX()
dp.Hdg=unit:GetHeading()
return dp
else
return nil
end
end
--- Get data of unit.
@@ -292,9 +297,32 @@ function FMD:_Derivative(playerData)
dpi.a.z=numderiv(dpm.v.z, dpp.v.z, dt)
dpi.DPitch=numderiv(dpm.Pitch, dpp.Pitch, dt)
dpi.DRoll=numderiv(dpm.Roll, dpp.Roll, dt)
--dpi.DRoll=numderiv(dpm.Roll, dpp.Roll, dt)
dpi.DYaw=numderiv(dpm.Yaw, dpp.Yaw, dt)
-- Roll shortcuts.
local r1=dpm.Roll
local r2=dpp.Roll
-- Put roll in [0,360)
if (r1<0) then
r1=r1+360
end
if (r2<0) then
r2=r2+360
end
-- Handle case where 360 deg periodicity strikes.
if r1<90 and r2>270 then
r1=r1+360
end
if r1>270 and r2<90 then
r2=r2+360
end
--
dpi.DRoll=numderiv(r1, r2, dt)
local ang=UTILS.VecAngle(dpm.o, dpp.o)
dpi.omega=numderiv(0, ang, dt)
@@ -317,12 +345,20 @@ function FMD:_RecordData(playerData)
-- Activate recording switch.
playerData.recording=true
end
-- Get data point.
local dp=self:_GetDataPoint(playerData.unit)
-- Add data point to player table.
table.insert(playerData.data, dp)
-- Check if unit is alive.
if playerData.unit and playerData.unit:IsAlive() then
-- Get data point.
local dp=self:_GetDataPoint(playerData.unit)
-- Add data point to player table.
table.insert(playerData.data, dp)
else
-- Stop recording if player unit is not alive.
self:_StopRecording(playerData.unitname)
end
end
@@ -374,7 +410,7 @@ function FMD:_SaveData(playerData)
self:I(self.lid..text)
-- Header line
local data="#Time,Altitude,Temperature,Pressure,Vtot,Vx,Vy,Vz,Atot,ax,ay,az,AoA,Pitch,dPitch/dt,Roll,dRoll/dt,Yaw,dYaw/dt\n"
local data="#Time,Altitude,Temperature,Pressure,Vtot,Vx,Vy,Vz,Atot,ax,ay,az,AoA,Pitch,dPitch/dt,Roll,dRoll/dt,Yaw,dYaw/dt,Turn Rate\n"
local g0=playerData.data[1] --#FMD.DataPoint
local T0=g0.time
@@ -404,7 +440,11 @@ function FMD:_SaveData(playerData)
local l=dp.AoA or 0
local m=dp.Pitch or 0
local n=dp.DPitch or 0
local o=dp.Roll or 0
local roll=dp.Roll or 0
if roll<0 then
roll=roll+360
end
local o=roll --dp.Roll or 0
local p=dp.DRoll or 0
local q=dp.Yaw or 0
local r=dp.DYaw or 0
@@ -510,13 +550,16 @@ function FMD:_AddF10Commands(_unitName)
missionCommands.addCommandForGroup(gid, "Delta t=30 s", _timePath, self._SetTimeInterval, self, _unitName, 30.0)
missionCommands.addCommandForGroup(gid, "Delta t=60 s", _timePath, self._SetTimeInterval, self, _unitName, 60.0)
-------------------------------
-- F10/F<X> FMD/F1 Rec Duration
-------------------------------
local _durPath=missionCommands.addSubMenuForGroup(gid, "Rec Duration", _rootPath)
-- F10/FMD/F1 Rec Duration/
missionCommands.addCommandForGroup(gid, "T=10 s", _timePath, self._SetRecDuration, self, _unitName, 10)
missionCommands.addCommandForGroup(gid, "T=30 s", _timePath, self._SetRecDuration, self, _unitName, 30)
missionCommands.addCommandForGroup(gid, "T=60 s", _timePath, self._SetRecDuration, self, _unitName, 60)
missionCommands.addCommandForGroup(gid, "T=5 min", _timePath, self._SetRecDuration, self, _unitName, 5*60)
missionCommands.addCommandForGroup(gid, "T=10 min", _timePath, self._SetRecDuration, self, _unitName, 10*60)
missionCommands.addCommandForGroup(gid, "T=10 s", _durPath, self._SetRecDuration, self, _unitName, 10)
missionCommands.addCommandForGroup(gid, "T=30 s", _durPath, self._SetRecDuration, self, _unitName, 30)
missionCommands.addCommandForGroup(gid, "T=60 s", _durPath, self._SetRecDuration, self, _unitName, 60)
missionCommands.addCommandForGroup(gid, "T=5 min", _durPath, self._SetRecDuration, self, _unitName, 5*60)
missionCommands.addCommandForGroup(gid, "T=10 min", _durPath, self._SetRecDuration, self, _unitName, 10*60)
--------------------------------
-- F10/F<X> FMD/
@@ -536,7 +579,7 @@ end
-- @param #FMD self
-- @param #string _unitName Name of player unit.
-- @param #number rd Recording duration in sec.
function FMD:_SetTimeInterval(_unitName, rd)
function FMD:_SetRecDuration(_unitName, rd)
-- Get player unit and name.
local _unit, _playername = self:_GetPlayerUnitAndName(_unitName)
@@ -610,7 +653,7 @@ function FMD:_StartRecording(_unitName)
playerData.SID=playerData.scheduler:Schedule(nil, self._RecordData, {self, playerData}, delay, playerData.dt, 0.0)
-- Stop scheduler once.
playerData.scheduler:ScheduleOnce(playerData.rd+delay, self._StopRecording, {self,_unitName})
playerData.scheduler:ScheduleOnce(playerData.rd+delay, self._StopRecording, self,_unitName)
end
end
+266 -165
View File
@@ -18,12 +18,12 @@
-- ===
--
-- ### Author: **funkyfranky**
-- @module Functional.FOX2
-- @image Functional_FOX2.png
-- @module Functional.FOX
-- @image Functional_FOX.png
--- FOX2 class.
-- @type FOX2
--- FOX class.
-- @type FOX
-- @field #string ClassName Name of the class.
-- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #string lid Class id string for output to DCS log file.
@@ -40,24 +40,25 @@
-- @field #number dt05 Time step [sec] for missile position updates if distance to target > 5 km and < 10 km. Default 0.5 sec.
-- @field #number dt01 Time step [sec] for missile position updates if distance to target > 1 km and < 5 km. Default 0.1 sec.
-- @field #number dt00 Time step [sec] for missile position updates if distance to target < 1 km. Default 0.01 sec.
-- @field #boolean
-- @extends Core.Fsm#FSM
--- Fox 2!
--- Fox 3!
--
-- ===
--
-- ![Banner Image](..\Presentations\FOX2\FOX2_Main.png)
-- ![Banner Image](..\Presentations\FOX\FOX_Main.png)
--
-- # The FOX2 Concept
-- # The FOX Concept
--
-- As you probably know [Fox](https://en.wikipedia.org/wiki/Fox_(code_word)) is a NATO bevity code for launching air-to-air munition. Therefore, the class name is not 100% accurate as this
-- script handles air-to-air and surface-to-air missiles. Furthermore, it handles not only Fox **2**, i.e. IR, missiles but also radar guided missiles.
-- As you probably know [Fox](https://en.wikipedia.org/wiki/Fox_(code_word)) is a NATO brevity code for launching air-to-air munition. Therefore, the class name is not 100% accurate as this
-- script handles air-to-air and surface-to-air missiles.
--
--
--
-- @field #FOX2
FOX2 = {
ClassName = "FOX2",
-- @field #FOX
FOX = {
ClassName = "FOX",
Debug = false,
lid = nil,
menuadded = {},
@@ -78,7 +79,7 @@ FOX2 = {
--- Player data table holding all important parameters of each player.
-- @type FOX2.PlayerData
-- @type FOX.PlayerData
-- @field Wrapper.Unit#UNIT unit Aircraft of the player.
-- @field #string unitname Name of the unit.
-- @field Wrapper.Client#CLIENT client Client object of player.
@@ -92,9 +93,10 @@ FOX2 = {
-- @field #boolean marklaunch Mark position of launched missile on F10 map.
-- @field #number defeated Number of missiles defeated.
-- @field #number dead Number of missiles not defeated.
-- @field #boolean inzone Player is inside a protected zone.
--- Missile data table.
-- @type FOX2.MissileData
-- @type FOX.MissileData
-- @field Wrapper.Unit#UNIT weapon Missile weapon unit.
-- @field #boolean active If true the missile is active.
-- @field #string missileType Type of missile.
@@ -106,132 +108,175 @@ FOX2 = {
-- @field #number shotTime Abs mission time in seconds the missile was fired.
-- @field Core.Point#COORDINATE shotCoord Coordinate where the missile was fired.
-- @field Wrapper.Unit#UNIT targetUnit Unit that was targeted.
-- @field #FOX2.PlayerData targetPlayer Player that was targeted or nil.
-- @field #FOX.PlayerData targetPlayer Player that was targeted or nil.
--- Main radio menu on group level.
-- @field #table MenuF10 Root menu table on group level.
FOX2.MenuF10={}
FOX.MenuF10={}
--- Main radio menu on mission level.
-- @field #table MenuF10Root Root menu on mission level.
FOX2.MenuF10Root=nil
FOX.MenuF10Root=nil
--- FOX2 class version.
--- FOX class version.
-- @field #string version
FOX2.version="0.1.4"
FOX.version="0.3.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list:
-- TODO: safe zones
-- TODO: mark shooter on F10
-- DONE: safe zones
-- DONE: mark shooter on F10
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Create a new FOX2 class object.
-- @param #FOX2 self
-- @return #FOX2 self.
function FOX2:New()
--- Create a new FOX class object.
-- @param #FOX self
-- @return #FOX self.
function FOX:New()
self.lid="FOX2 | "
self.lid="FOX | "
-- Inherit everthing from FSM class.
local self=BASE:Inherit(self, FSM:New()) -- #FOX2
local self=BASE:Inherit(self, FSM:New()) -- #FOX
-- Start State.
self:SetStartState("Stopped")
-- Add FSM transitions.
-- From State --> Event --> To State
self:AddTransition("Stopped", "Start", "Running") -- Start FOX2 script.
self:AddTransition("*", "Status", "*") -- Start FOX2 script.
self:AddTransition("*", "MissileLaunch", "*") -- Start FOX2 script.
self:AddTransition("*", "MissileDestroyed", "*") -- Start FOX2 script.
self:AddTransition("Stopped", "Start", "Running") -- Start FOX script.
self:AddTransition("*", "Status", "*") -- Status update.
self:AddTransition("*", "MissileLaunch", "*") -- Missile was launched.
self:AddTransition("*", "MissileDestroyed", "*") -- Missile was destroyed before impact.
self:AddTransition("*", "EnterSafeZone", "*") -- Player enters a safe zone.
self:AddTransition("*", "ExitSafeZone", "*") -- Player exists a safe zone.
------------------------
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Start". Starts the FOX2. Initializes parameters and starts event handlers.
-- @function [parent=#FOX2] Start
-- @param #FOX2 self
--- Triggers the FSM event "Start". Starts the FOX. Initializes parameters and starts event handlers.
-- @function [parent=#FOX] Start
-- @param #FOX self
--- Triggers the FSM event "Start" after a delay. Starts the FOX2. Initializes parameters and starts event handlers.
-- @function [parent=#FOX2] __Start
-- @param #FOX2 self
--- Triggers the FSM event "Start" after a delay. Starts the FOX. Initializes parameters and starts event handlers.
-- @function [parent=#FOX] __Start
-- @param #FOX self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Stop". Stops the FOX2 and all its event handlers.
-- @param #FOX2 self
--- Triggers the FSM event "Stop". Stops the FOX and all its event handlers.
-- @param #FOX self
--- Triggers the FSM event "Stop" after a delay. Stops the FOX2 and all its event handlers.
-- @function [parent=#FOX2] __Stop
-- @param #FOX2 self
--- Triggers the FSM event "Stop" after a delay. Stops the FOX and all its event handlers.
-- @function [parent=#FOX] __Stop
-- @param #FOX self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Status".
-- @function [parent=#FOX2] Status
-- @param #FOX2 self
-- @function [parent=#FOX] Status
-- @param #FOX self
--- Triggers the FSM event "Status" after a delay.
-- @function [parent=#FOX2] __Status
-- @param #FOX2 self
-- @function [parent=#FOX] __Status
-- @param #FOX self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "MissileLaunch".
-- @function [parent=#FOX2] MissileLaunch
-- @param #FOX2 self
-- @param #FOX2.MissileData missile Data of the fired missile.
-- @function [parent=#FOX] MissileLaunch
-- @param #FOX self
-- @param #FOX.MissileData missile Data of the fired missile.
--- Triggers the FSM delayed event "MissileLaunch".
-- @function [parent=#FOX2] __MissileLaunch
-- @param #FOX2 self
-- @function [parent=#FOX] __MissileLaunch
-- @param #FOX self
-- @param #number delay Delay in seconds before the function is called.
-- @param #FOX2.MissileData missile Data of the fired missile.
-- @param #FOX.MissileData missile Data of the fired missile.
--- On after "MissileLaunch" event user function. Called when a missile was launched.
-- @function [parent=#FOX2] OnAfterMissileLaunch
-- @param #RECOVERYTANKER self
-- @function [parent=#FOX] OnAfterMissileLaunch
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FOX2.MissileData missile Data of the fired missile.
-- @param #FOX.MissileData missile Data of the fired missile.
--- Triggers the FSM event "MissileDestroyed".
-- @function [parent=#FOX2] MissileDestroyed
-- @param #FOX2 self
-- @param #FOX2.MissileData missile Data of the destroyed missile.
-- @function [parent=#FOX] MissileDestroyed
-- @param #FOX self
-- @param #FOX.MissileData missile Data of the destroyed missile.
--- Triggers the FSM delayed event "MissileDestroyed".
-- @function [parent=#FOX2] __MissileDestroyed
-- @param #FOX2 self
-- @function [parent=#FOX] __MissileDestroyed
-- @param #FOX self
-- @param #number delay Delay in seconds before the function is called.
-- @param #FOX2.MissileData missile Data of the destroyed missile.
-- @param #FOX.MissileData missile Data of the destroyed missile.
--- On after "MissileLaunch" event user function. Called when a missile was launched.
-- @function [parent=#FOX2] OnAfterMissileLaunch
-- @param #RECOVERYTANKER self
--- On after "MissileDestroyed" event user function. Called when a missile was destroyed.
-- @function [parent=#FOX] OnAfterMissileDestroyed
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FOX2.MissileData missile Data of the fired missile.
-- @param #FOX.MissileData missile Data of the destroyed missile.
--- Triggers the FSM event "EnterSafeZone".
-- @function [parent=#FOX] EnterSafeZone
-- @param #FOX self
-- @param #FOX.PlayerData player Player data.
--- Triggers the FSM delayed event "EnterSafeZone".
-- @function [parent=#FOX] __EnterSafeZone
-- @param #FOX self
-- @param #number delay Delay in seconds before the function is called.
-- @param #FOX.PlayerData player Player data.
--- On after "EnterSafeZone" event user function. Called when a player enters a safe zone.
-- @function [parent=#FOX] OnAfterEnterSafeZone
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FOX.PlayerData player Player data.
--- Triggers the FSM event "ExitSafeZone".
-- @function [parent=#FOX] ExitSafeZone
-- @param #FOX self
-- @param #FOX.PlayerData player Player data.
--- Triggers the FSM delayed event "ExitSafeZone".
-- @function [parent=#FOX] __ExitSafeZone
-- @param #FOX self
-- @param #number delay Delay in seconds before the function is called.
-- @param #FOX.PlayerData player Player data.
--- On after "ExitSafeZone" event user function. Called when a player exists a safe zone.
-- @function [parent=#FOX] OnAfterExitSafeZone
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FOX.PlayerData player Player data.
return self
end
--- On after Start event. Starts the missile trainer and adds event handlers.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FOX2:onafterStart(From, Event, To)
function FOX:onafterStart(From, Event, To)
-- Short info.
local text=string.format("Starting FOX2 Missile Trainer %s", FOX2.version)
local text=string.format("Starting FOX Missile Trainer %s", FOX.version)
env.info(text)
-- Handle events:
@@ -247,14 +292,14 @@ function FOX2:onafterStart(From, Event, To)
end
--- On after Stop event. Stops the missile trainer and unhandles events.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FOX2:onafterStop(From, Event, To)
function FOX:onafterStop(From, Event, To)
-- Short info.
local text=string.format("Stopping FOX2 Missile Trainer v0.0.1")
local text=string.format("Stopping FOX Missile Trainer %s", FOX.version)
env.info(text)
-- Handle events:
@@ -268,10 +313,10 @@ end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Add a training zone. Players in the zone are safe.
-- @param #FOX2 self
-- @param #FOX self
-- @param Core.Zone#ZONE zone Training zone.
-- @return #FOX2 self
function FOX2:AddSafeZone(zone)
-- @return #FOX self
function FOX:AddSafeZone(zone)
table.insert(self.safezones, zone)
@@ -279,10 +324,10 @@ function FOX2:AddSafeZone(zone)
end
--- Add a launch zone. Only missiles launched within these zones will be tracked.
-- @param #FOX2 self
-- @param #FOX self
-- @param Core.Zone#ZONE zone Training zone.
-- @return #FOX2 self
function FOX2:AddLaunchZone(zone)
-- @return #FOX self
function FOX:AddLaunchZone(zone)
table.insert(self.launchzones, zone)
@@ -290,10 +335,10 @@ function FOX2:AddLaunchZone(zone)
end
--- Set debug mode on/off.
-- @param #FOX2 self
-- @param #FOX self
-- @param #boolean switch If true debug mode on. If false/nil debug mode off
-- @return #FOX2 self
function FOX2:SetDebugOnOff(switch)
-- @return #FOX self
function FOX:SetDebugOnOff(switch)
if switch==nil then
self.Debug=false
@@ -305,17 +350,17 @@ function FOX2:SetDebugOnOff(switch)
end
--- Set debug mode on.
-- @param #FOX2 self
-- @return #FOX2 self
function FOX2:SetDebugOn()
-- @param #FOX self
-- @return #FOX self
function FOX:SetDebugOn()
self:SetDebugOnOff(true)
return self
end
--- Set debug mode off.
-- @param #FOX2 self
-- @return #FOX2 self
function FOX2:SetDebugOff()
-- @param #FOX self
-- @return #FOX self
function FOX:SetDebugOff()
self:SetDebugOff(false)
return self
end
@@ -325,26 +370,77 @@ end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Check spawn queue and spawn aircraft if necessary.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function FOX2:onafterStatus(From, Event, To)
function FOX:onafterStatus(From, Event, To)
self:I(self.lid..string.format("Missile trainer status: %s", self:GetState()))
local fsmstate=self:GetState()
self:I(self.lid..string.format("Missile trainer status: %s", fsmstate))
self:_CheckMissileStatus()
self:__Status(-30)
if fsmstate=="Running" then
self:__Status(-10)
end
end
--- Check status of players.
-- @param #FOX self
-- @param #string _unitName Name of player unit.
function FOX:_CheckPlayers()
for playername,_playersettings in pairs(self.players) do
local playersettings=_playersettings --#FOX.PlayerData
local unitname=playersettings.unitname
local unit=UNIT:FindByName(unitname)
if unit and unit:IsAlive() then
local coord=unit:GetCoordinate()
local issafe=self:_CheckCoordSafe(coord)
if issafe then
-----------------------------
-- Player INSIDE Safe Zone --
-----------------------------
if not playersettings.inzone then
self:EnterSafeZone(playersettings)
playersettings.inzone=true
end
else
------------------------------
-- Player OUTSIDE Safe Zone --
------------------------------
if playersettings.inzone==true then
self:ExitSafeZone(playersettings)
playersettings.inzone=false
end
end
end
end
end
--- Missile status
-- @param #FOX2 self
function FOX2:_CheckMissileStatus()
-- @param #FOX self
function FOX:_CheckMissileStatus()
local text="Missiles:"
for i,_missile in pairs(self.missiles) do
local missile=_missile --#FOX2.MissileData
local missile=_missile --#FOX.MissileData
local targetname="unkown"
if missile.targetUnit then
@@ -368,19 +464,19 @@ function FOX2:_CheckMissileStatus()
end
--- Missle launch.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #FOX2.MissileData missile Fired missile
function FOX2:onafterMissileLaunch(From, Event, To, missile)
-- @param #FOX.MissileData missile Fired missile
function FOX:onafterMissileLaunch(From, Event, To, missile)
-- Tracking info and init of last bomb position.
self:I(FOX2.lid..string.format("FOX2: Tracking %s - %s.", missile.missileType, missile.missileName))
self:I(FOX.lid..string.format("FOX: Tracking %s - %s.", missile.missileType, missile.missileName))
-- Loop over players.
for _,_player in pairs(self.players) do
local player=_player --#FOX2.PlayerData
local player=_player --#FOX.PlayerData
-- Player position.
local playerUnit=player.unit
@@ -406,7 +502,7 @@ function FOX2:onafterMissileLaunch(From, Event, To, missile)
local text=string.format("Missile launch detected! Distance %.1f NM, bearing %03d°.", UTILS.MetersToNM(distance), bearing)
text=text..string.format("\nNotching heading %03d or %03d", nr, nl)
--TODO: ALERT or INFO depending on wether this is a direct target.
--TODO: ALERT or INFO depending on whether this is a direct target.
--TODO: lauchalertall option.
MESSAGE:New(text, 5, "ALERT"):ToClient(player.client)
@@ -482,7 +578,7 @@ function FOX2:onafterMissileLaunch(From, Event, To, missile)
-- Loop over players.
for _,_player in pairs(self.players) do
local player=_player --#FOX2.PlayerData
local player=_player --#FOX.PlayerData
-- Check that player was not the one who launched the missile.
if player.unitname~=missile.shooterName then
@@ -588,7 +684,7 @@ function FOX2:onafterMissileLaunch(From, Event, To, missile)
missile.active=false
--Terminate the timer.
self:T(FOX2.lid..string.format("Terminating missile track timer."))
self:T(FOX.lid..string.format("Terminating missile track timer."))
return nil
end -- _status check
@@ -596,7 +692,7 @@ function FOX2:onafterMissileLaunch(From, Event, To, missile)
end -- end function trackBomb
-- Weapon is not yet "alife" just yet. Start timer with a little delay.
self:T(FOX2.lid..string.format("Tracking of missile starts in 0.1 seconds."))
self:T(FOX.lid..string.format("Tracking of missile starts in 0.1 seconds."))
timer.scheduleFunction(trackMissile, missile.weapon, timer.getTime()+0.0001)
end
@@ -605,10 +701,10 @@ end
-- Event Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- FOX2 event handler for event birth.
-- @param #FOX2 self
--- FOX event handler for event birth.
-- @param #FOX self
-- @param Core.Event#EVENTDATA EventData
function FOX2:OnEventBirth(EventData)
function FOX:OnEventBirth(EventData)
self:F3({eventbirth = EventData})
-- Nil checks.
@@ -649,7 +745,7 @@ function FOX2:OnEventBirth(EventData)
SCHEDULER:New(nil, self._AddF10Commands, {self,_unitName}, 0.1)
-- Player data.
local playerData={} --#FOX2.PlayerData
local playerData={} --#FOX.PlayerData
-- Player unit, client and callsign.
playerData.unit = playerunit
@@ -677,10 +773,10 @@ function FOX2:OnEventBirth(EventData)
end
end
--- FOX2 event handler for event shot (when a unit releases a rocket or bomb (but not a fast firing gun).
-- @param #FOX2 self
--- FOX event handler for event shot (when a unit releases a rocket or bomb (but not a fast firing gun).
-- @param #FOX self
-- @param Core.Event#EVENTDATA EventData
function FOX2:OnEventShot(EventData)
function FOX:OnEventShot(EventData)
self:I({eventshot = EventData})
if EventData.Weapon==nil then
@@ -712,13 +808,13 @@ function FOX2:OnEventShot(EventData)
end
-- Debug info.
self:E(FOX2.lid.."EVENT SHOT: FOX2")
self:E(FOX2.lid..string.format("EVENT SHOT: Ini unit = %s", tostring(EventData.IniUnitName)))
self:E(FOX2.lid..string.format("EVENT SHOT: Ini group = %s", tostring(EventData.IniGroupName)))
self:E(FOX2.lid..string.format("EVENT SHOT: Weapon type = %s", tostring(_weapon)))
self:E(FOX2.lid..string.format("EVENT SHOT: Weapon categ = %s", tostring(weaponcategory)))
self:E(FOX2.lid..string.format("EVENT SHOT: Missil categ = %s", tostring(missilecategory)))
self:E(FOX2.lid..string.format("EVENT SHOT: Missil range = %s", tostring(missilerange)))
self:E(FOX.lid.."EVENT SHOT: FOX")
self:E(FOX.lid..string.format("EVENT SHOT: Ini unit = %s", tostring(EventData.IniUnitName)))
self:E(FOX.lid..string.format("EVENT SHOT: Ini group = %s", tostring(EventData.IniGroupName)))
self:E(FOX.lid..string.format("EVENT SHOT: Weapon type = %s", tostring(_weapon)))
self:E(FOX.lid..string.format("EVENT SHOT: Weapon categ = %s", tostring(weaponcategory)))
self:E(FOX.lid..string.format("EVENT SHOT: Missil categ = %s", tostring(missilecategory)))
self:E(FOX.lid..string.format("EVENT SHOT: Missil range = %s", tostring(missilerange)))
-- Check if fired in launch zone.
@@ -734,7 +830,7 @@ function FOX2:OnEventShot(EventData)
--_targetUnit=UNIT:FindByName(_targetName)
_targetUnit=UNIT:Find(_target)
end
self:E(FOX2.lid..string.format("EVENT SHOT: Target name = %s", tostring(_targetName)))
self:E(FOX.lid..string.format("EVENT SHOT: Target name = %s", tostring(_targetName)))
-- Track missiles of type AAM=1, SAM=2 or OTHER=6
local _track = weaponcategory==1 and missilecategory and (missilecategory==1 or missilecategory==2 or missilecategory==6)
@@ -742,7 +838,7 @@ function FOX2:OnEventShot(EventData)
-- Only track missiles
if _track then
local missile={} --#FOX2.MissileData
local missile={} --#FOX.MissileData
missile.active=true
missile.weapon=EventData.weapon
@@ -758,10 +854,15 @@ function FOX2:OnEventShot(EventData)
missile.targetUnit=_targetUnit
missile.targetPlayer=self:_GetPlayerFromUnit(missile.targetUnit)
-- Add missile table.
table.insert(self.missiles, missile)
-- TODO: or in protected set!
if missile.targetPlayer then
self:__MissileLaunch(0.1, missile)
-- Add missile table.
table.insert(self.missiles, missile)
self:__MissileLaunch(0.1, missile)
end
end --if _track
@@ -773,9 +874,9 @@ end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Add menu commands for player.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string _unitName Name of player unit.
function FOX2:_AddF10Commands(_unitName)
function FOX:_AddF10Commands(_unitName)
self:F(_unitName)
-- Get player unit and name.
@@ -797,40 +898,40 @@ function FOX2:_AddF10Commands(_unitName)
-- Set menu root path.
local _rootPath=nil
if FOX2.MenuF10Root then
if FOX.MenuF10Root then
------------------------
-- MISSON LEVEL MENUE --
------------------------
-- F10/FOX2/...
_rootPath=FOX2.MenuF10Root
-- F10/FOX/...
_rootPath=FOX.MenuF10Root
else
------------------------
-- GROUP LEVEL MENUES --
------------------------
-- Main F10 menu: F10/FOX2/
if FOX2.MenuF10[gid]==nil then
FOX2.MenuF10[gid]=missionCommands.addSubMenuForGroup(gid, "FOX2")
-- Main F10 menu: F10/FOX/
if FOX.MenuF10[gid]==nil then
FOX.MenuF10[gid]=missionCommands.addSubMenuForGroup(gid, "FOX")
end
-- F10/FOX2/...
_rootPath=FOX2.MenuF10[gid]
-- F10/FOX/...
_rootPath=FOX.MenuF10[gid]
end
--------------------------------
-- F10/F<X> FOX2/F1 Help
-- F10/F<X> FOX/F1 Help
--------------------------------
local _helpPath=missionCommands.addSubMenuForGroup(gid, "Help", _rootPath)
-- F10/FOX2/F1 Help/
-- F10/FOX/F1 Help/
--missionCommands.addCommandForGroup(gid, "Subtitles On/Off", _helpPath, self._SubtitlesOnOff, self, _unitName) -- F7
--missionCommands.addCommandForGroup(gid, "Trapsheet On/Off", _helpPath, self._TrapsheetOnOff, self, _unitName) -- F8
-------------------------
-- F10/F<X> FOX2/
-- F10/F<X> FOX/
-------------------------
missionCommands.addCommandForGroup(gid, "Launch Alerts On/Off", _rootPath, self._ToggleLaunchAlert, self, _unitName) -- F2
@@ -848,9 +949,9 @@ end
--- Turn player's launch alert on/off.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string _unitname Name of the player unit.
function FOX2:_MyStatus(_unitname)
function FOX:_MyStatus(_unitname)
self:F2(_unitname)
-- Get player unit and player name.
@@ -860,7 +961,7 @@ function FOX2:_MyStatus(_unitname)
if unit and playername then
-- Player data.
local playerData=self.players[playername] --#FOX2.PlayerData
local playerData=self.players[playername] --#FOX.PlayerData
if playerData then
@@ -877,9 +978,9 @@ end
--- Turn player's launch alert on/off.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string _unitname Name of the player unit.
function FOX2:_ToggleLaunchAlert(_unitname)
function FOX:_ToggleLaunchAlert(_unitname)
self:F2(_unitname)
-- Get player unit and player name.
@@ -889,7 +990,7 @@ function FOX2:_ToggleLaunchAlert(_unitname)
if unit and playername then
-- Player data.
local playerData=self.players[playername] --#FOX2.PlayerData
local playerData=self.players[playername] --#FOX.PlayerData
if playerData then
@@ -910,9 +1011,9 @@ function FOX2:_ToggleLaunchAlert(_unitname)
end
--- Turn player's
-- @param #FOX2 self
-- @param #FOX self
-- @param #string _unitname Name of the player unit.
function FOX2:_ToggleDestroyMissiles(_unitname)
function FOX:_ToggleDestroyMissiles(_unitname)
self:F2(_unitname)
-- Get player unit and player name.
@@ -922,7 +1023,7 @@ function FOX2:_ToggleDestroyMissiles(_unitname)
if unit and playername then
-- Player data.
local playerData=self.players[playername] --#FOX2.PlayerData
local playerData=self.players[playername] --#FOX.PlayerData
if playerData then
@@ -948,9 +1049,9 @@ end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- Get a random text message in case you die.
-- @param #FOX2 self
-- @param #FOX self
-- @return #string Text in case you die.
function FOX2:_DeadText()
function FOX:_DeadText()
local texts={}
texts[1]="You're dead!"
@@ -967,10 +1068,10 @@ end
--- Check if a coordinate lies within a safe training zone.
-- @param #FOX2 self
-- @param #FOX self
-- @param Core.Point#COORDINATE coord Coordinate to check.
-- @return #boolean True if safe.
function FOX2:_CheckCoordSafe(coord)
function FOX:_CheckCoordSafe(coord)
-- No safe zones defined ==> Everything is safe.
if #self.safezones==0 then
@@ -990,10 +1091,10 @@ function FOX2:_CheckCoordSafe(coord)
end
--- Check if a coordinate lies within a launch zone.
-- @param #FOX2 self
-- @param #FOX self
-- @param Core.Point#COORDINATE coord Coordinate to check.
-- @return #boolean True if in launch zone.
function FOX2:_CheckCoordLaunch(coord)
function FOX:_CheckCoordLaunch(coord)
-- No safe zones defined ==> Everything is safe.
if #self.launchzones==0 then
@@ -1013,10 +1114,10 @@ function FOX2:_CheckCoordLaunch(coord)
end
--- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned.
-- @param #FOX2 self
-- @param #DCS.Weapon weapon The weapon.
-- @param #FOX self
-- @param DCS#Weapon weapon The weapon.
-- @return #number Heading of weapon in degrees or -1.
function FOX2:_GetWeapongHeading(weapon)
function FOX:_GetWeapongHeading(weapon)
if weapon and weapon:isExist() then
@@ -1037,11 +1138,11 @@ function FOX2:_GetWeapongHeading(weapon)
end
--- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned.
-- @param #FOX2 self
-- @param #DCS.Weapon weapon The weapon.
-- @param #FOX self
-- @param DCS#Weapon weapon The weapon.
-- @return #number Notching heading right, i.e. missile heading +90
-- @return #number Notching heading left, i.e. missile heading -90.
function FOX2:_GetNotchingHeadings(weapon)
function FOX:_GetNotchingHeadings(weapon)
if weapon then
@@ -1064,13 +1165,13 @@ function FOX2:_GetNotchingHeadings(weapon)
end
--- Returns the player data from a unit name.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string unitName Name of the unit.
-- @return #FOX2.PlayerData Player data.
function FOX2:_GetPlayerFromUnitname(unitName)
-- @return #FOX.PlayerData Player data.
function FOX:_GetPlayerFromUnitname(unitName)
for _,_player in pairs(self.players) do
local player=_player --#FOX2.PlayerData
local player=_player --#FOX.PlayerData
if player.unitname==unitName then
return player
@@ -1081,10 +1182,10 @@ function FOX2:_GetPlayerFromUnitname(unitName)
end
--- Retruns the player data from a unit.
-- @param #FOX2 self
-- @param #FOX self
-- @param Wrapper.Unit#UNIT unit
-- @return #FOX2.PlayerData Player data.
function FOX2:_GetPlayerFromUnit(unit)
-- @return #FOX.PlayerData Player data.
function FOX:_GetPlayerFromUnit(unit)
if unit and unit:IsAlive() then
@@ -1092,7 +1193,7 @@ function FOX2:_GetPlayerFromUnit(unit)
local unitname=unit:GetName()
for _,_player in pairs(self.players) do
local player=_player --#FOX2.PlayerData
local player=_player --#FOX.PlayerData
if player.unitname==unitname then
return player
@@ -1105,11 +1206,11 @@ function FOX2:_GetPlayerFromUnit(unit)
end
--- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned.
-- @param #FOX2 self
-- @param #FOX self
-- @param #string _unitName Name of the player unit.
-- @return Wrapper.Unit#UNIT Unit of player or nil.
-- @return #string Name of the player or nil.
function FOX2:_GetPlayerUnitAndName(_unitName)
function FOX:_GetPlayerUnitAndName(_unitName)
self:F2(_unitName)
if _unitName ~= nil then
+3 -3
View File
@@ -340,7 +340,7 @@ RANGE.MenuF10Root=nil
--- Range script version.
-- @field #string version
RANGE.version="2.1.0"
RANGE.version="2.1.1"
--TODO list:
--TODO: Verbosity level for messages.
@@ -532,7 +532,7 @@ function RANGE:onafterStart()
end
if self.location==nil then
local text=string.format("ERROR! No range location found. Number of strafe targets = %d. Number of bomb targets = %d.", self.rangename, self.nstrafetargets, self.nbombtargets)
local text=string.format("ERROR! No range location found. Number of strafe targets = %d. Number of bomb targets = %d.", self.nstrafetargets, self.nbombtargets)
self:E(self.id..text)
return
end
@@ -1095,7 +1095,7 @@ function RANGE:AddBombingTargetUnit(unit, goodhitrange, randommove)
local target={} --#RANGE.BombTarget
target.name=name
target.target=target
target.target=unit
target.goodhitrange=goodhitrange
target.move=randommove
target.speed=speed
+159 -42
View File
@@ -151,7 +151,7 @@
--
-- When a player commits too much damage to friendlies, his penalty score will reach a certain level.
-- Use the method @{#SCORING.SetFratricide}() to define the level when a player gets kicked.
-- By default, the fratricide level is the default penalty mutiplier * 2 for the penalty score.
-- By default, the fratricide level is the default penalty multiplier * 2 for the penalty score.
--
-- # Penalty score when a player changes the coalition.
--
@@ -227,10 +227,12 @@ SCORING = {
ClassName = "SCORING",
ClassID = 0,
Players = {},
CSVdata = {},
}
local _SCORINGCoalition =
{
[0] = "Neutral",
[1] = "Red",
[2] = "Blue",
}
@@ -247,13 +249,15 @@ local _SCORINGCategory =
--- Creates a new SCORING object to administer the scoring achieved by players.
-- @param #SCORING self
-- @param #string GameName The name of the game. This name is also logged in the CSV score file.
-- @param #string FileName (Optional) Name of the CSV file for saving results. If the file exists, player scores are read.
-- @param #boolean MenuOff (Optional) Done create player menus.
-- @return #SCORING self
-- @usage
--
-- -- Define a new scoring object for the mission Gori Valley.
-- ScoringObject = SCORING:New( "Gori Valley" )
--
function SCORING:New( GameName )
function SCORING:New( GameName, FileName, MenuOff )
-- Inherits from BASE
local self = BASE:Inherit( self, BASE:New() ) -- #SCORING
@@ -264,6 +268,10 @@ function SCORING:New( GameName )
error( "A game name must be given to register the scoring results" )
end
if FileName then
self.FileName = FileName
end
-- Additional Object scores
self.ScoringObjects = {}
@@ -290,6 +298,9 @@ function SCORING:New( GameName )
self:SetDisplayMessagePrefix()
-- No player menus.
self.MenuOff=MenuOff
-- Event handlers
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
@@ -312,7 +323,7 @@ function SCORING:New( GameName )
-- Create the CSV file.
self:OpenCSV( GameName )
self:OpenCSV( GameName, FileName )
return self
@@ -600,11 +611,13 @@ end
-- @param #SCORING self
-- @return #SCORING
function SCORING:SetScoringMenu( ScoringGroup )
if not self.MenuOff then
local Menu = MENU_GROUP:New( ScoringGroup, 'Scoring and Statistics' )
local ReportGroupSummary = MENU_GROUP_COMMAND:New( ScoringGroup, 'Summary report players in group', Menu, SCORING.ReportScoreGroupSummary, self, ScoringGroup )
local ReportGroupDetailed = MENU_GROUP_COMMAND:New( ScoringGroup, 'Detailed report players in group', Menu, SCORING.ReportScoreGroupDetailed, self, ScoringGroup )
local ReportToAllSummary = MENU_GROUP_COMMAND:New( ScoringGroup, 'Summary report all players', Menu, SCORING.ReportScoreAllSummary, self, ScoringGroup )
self:SetState( ScoringGroup, "ScoringMenu", Menu )
end
return self
end
@@ -1758,47 +1771,49 @@ function SCORING:ReportScoreAllSummary( PlayerGroup )
end
function SCORING:SecondsToClock(sSeconds)
local nSeconds = sSeconds
if nSeconds == 0 then
--return nil;
return "00:00:00";
else
nHours = string.format("%02.f", math.floor(nSeconds/3600));
nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60)));
nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60));
return nHours..":"..nMins..":"..nSecs
end
end
--- Opens a score CSV file to log the scores.
-- @param #SCORING self
-- @param #string ScoringCSV
-- @param #string FileName Name of the csv file.
-- @return #SCORING self
-- @usage
-- -- Open a new CSV file to log the scores of the game Gori Valley. Let the name of the CSV file begin with "Player Scores".
-- ScoringObject = SCORING:New( "Gori Valley" )
-- ScoringObject:OpenCSV( "Player Scores" )
function SCORING:OpenCSV( ScoringCSV )
function SCORING:OpenCSV( ScoringCSV, FileName )
self:F( ScoringCSV )
if lfs and io and os then
if ScoringCSV then
self.ScoringCSV = ScoringCSV
local fdir = lfs.writedir() .. [[Logs\]] .. self.ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
self.CSVFile, self.err = io.open( fdir, "w+" )
if not self.CSVFile then
error( "Error: Cannot open CSV file in " .. lfs.writedir() )
-- File name.
local fdir = lfs.writedir() .. [[Logs\]] .. ScoringCSV .. " " .. os.date( "%Y-%m-%d %H-%M-%S" ) .. ".csv"
if FileName then
fdir=lfs.writedir() .. [[Logs\]] .. FileName
end
if UTILS.FileExists(fdir) then
self:LoadCSV(fdir)
self.CSVFile, self.err = io.open( fdir, "a+" )
if not self.CSVFile then
error( "Error: Cannot open CSV file in " .. lfs.writedir() )
end
else
self.CSVFile, self.err = io.open( fdir, "w+" )
if not self.CSVFile then
error( "Error: Cannot open CSV file in " .. lfs.writedir() )
end
self.CSVFile:write( '"GameName","RunTime","Time","PlayerName","TargetPlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
end
self.CSVFile:write( '"GameName","RunTime","Time","PlayerName","TargetPlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' )
self.RunTime = os.date("%y-%m-%d_%H-%M-%S")
else
error( "A string containing the CSV file name must be given." )
end
else
self:F( "The MissionScripting.lua file has not been changed to allow lfs, io and os modules to be used..." )
end
@@ -1806,6 +1821,101 @@ function SCORING:OpenCSV( ScoringCSV )
end
--- Load player data from file.
-- @param #SCORING self
-- @param #string filename File name containing player scoring data.
function SCORING:LoadCSV(filename)
--- Function that load data from a file.
local function _loadfile(filename)
local f=io.open(filename, "rb")
if f then
local data=f:read("*all")
f:close()
return data
else
self:E(self.id..string.format("ERROR: Could not load player results from file %s", tostring(filename)))
return nil
end
end
-- Info message.
local text=string.format("Loading player scoring from file %s", filename)
self:I(text)
-- Load asset data from file.
local data=_loadfile(filename)
if data then
-- Split by line break.
local results=UTILS.Split(data,"\n")
-- Remove first header line.
table.remove(results, 1)
-- Init player scores table.
self.CSVdata=self.CSVdata or {}
-- Loop over all lines.
for _,_result in pairs(results) do
-- Parameters are separated by commata.
local resultdata=UTILS.Split(_result, ",")
-- Grade table
local result={}
--'"GameName","RunTime","Time","PlayerName","TargetPlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition",
-- "TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n'
local PlayerName=tostring(resultdata[4])
-- Results data.
result.GameName=tostring(resultdata[1])
result.RunTime=tostring(resultdata[2])
result.Time=tonumber(resultdata[3])
result.PlayerName=tostring(resultdata[4])
result.TargetPlayerName=tostring(resultdata[5])
result.ScoreType=tostring(resultdata[6])
result.PlayerUnitCoaltion=tostring(resultdata[7])
result.PlayerUnitCategory=tostring(resultdata[8])
result.PlayerUnitType=tostring(resultdata[9])
result.PlayerUnitName=tostring(resultdata[10])
result.TargetUnitCoalition=tostring(resultdata[11])
result.TargetUnitCategory=tostring(resultdata[12])
result.TargetUnitType=tostring(resultdata[13])
result.TargetUnitName=tostring(resultdata[14])
result.Times=tonumber(resultdata[15])
result.Score=tonumber(resultdata[16])
self:E(result.Score)
-- Create player array if necessary.
self.CSVdata[result.PlayerName]=self.CSVdata[result.PlayerName] or {}
if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ...
self.Players[PlayerName] = {}
self.Players[PlayerName].Hit = {}
self.Players[PlayerName].Destroy = {}
self.Players[PlayerName].Goals = {}
self.Players[PlayerName].Mission = {}
self.Players[PlayerName].HitPlayers = {}
self.Players[PlayerName].Score = 0
self.Players[PlayerName].Penalty = 0
self.Players[PlayerName].PenaltyCoalition = 0
self.Players[PlayerName].PenaltyWarning = 0
end
--self.Players[PlayerName].Score=self.Players[PlayerName].Score+result.Score
-- Add result to table.
table.insert(self.CSVdata[result.PlayerName], result)
end
end
end
--- Registers a score for a player.
-- @param #SCORING self
-- @param #string PlayerName The name of the player.
@@ -1823,11 +1933,17 @@ end
-- @param #string TargetUnitType The type of the target unit.
-- @return #SCORING self
function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
--write statistic information to file
local ScoreTime = self:SecondsToClock( timer.getTime() )
--local ScoreTime = self:SecondsToClock( timer.getTime() )
local ScoreTime = UTILS.SecondsToClock(timer.getAbsTime())
-- Player name
PlayerName = PlayerName:gsub( '"', '_' )
TargetPlayerName = TargetPlayerName or ""
-- Target NAme
TargetPlayerName = TargetPlayerName or "n/a"
TargetPlayerName = TargetPlayerName:gsub( '"', '_' )
if PlayerUnitName and PlayerUnitName ~= '' then
@@ -1847,22 +1963,22 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
PlayerUnitType = PlayerUnit:getTypeName()
end
else
PlayerUnitName = ''
PlayerUnitCategory = ''
PlayerUnitCoalition = ''
PlayerUnitType = ''
PlayerUnitName = 'n/a'
PlayerUnitCategory = 'n/a'
PlayerUnitCoalition = 'n/a'
PlayerUnitType = 'n/a'
end
else
PlayerUnitName = ''
PlayerUnitCategory = ''
PlayerUnitCoalition = ''
PlayerUnitType = ''
PlayerUnitName = 'n/a'
PlayerUnitCategory = 'n/a'
PlayerUnitCoalition = 'n/a'
PlayerUnitType = 'n/a'
end
TargetUnitCoalition = TargetUnitCoalition or ""
TargetUnitCategory = TargetUnitCategory or ""
TargetUnitType = TargetUnitType or ""
TargetUnitName = TargetUnitName or ""
TargetUnitCoalition = TargetUnitCoalition or "n/a"
TargetUnitCategory = TargetUnitCategory or "n/a"
TargetUnitType = TargetUnitType or "n/a"
TargetUnitName = TargetUnitName or "n/a"
if lfs and io and os then
self.CSVFile:write(
@@ -1881,14 +1997,15 @@ function SCORING:ScoreCSV( PlayerName, TargetPlayerName, ScoreType, ScoreTimes,
'"' .. TargetUnitType .. '"' .. ',' ..
'"' .. TargetUnitName .. '"' .. ',' ..
'' .. ScoreTimes .. '' .. ',' ..
'' .. ScoreAmount
'' .. ScoreAmount
)
self.CSVFile:write( "\n" )
end
end
--- Close csv file.
-- @param #SCORING self
function SCORING:CloseCSV()
if lfs and io and os then
self.CSVFile:close()
@@ -1733,7 +1733,7 @@ _WAREHOUSEDB = {
--- Warehouse class version.
-- @field #string version
WAREHOUSE.version="0.7.0"
WAREHOUSE.version="0.7.1"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Warehouse todo list.
@@ -1876,6 +1876,7 @@ function WAREHOUSE:New(warehouse, alias)
self:AddTransition("Running", "Request", "*") -- Process a request. Only in running mode.
self:AddTransition("Attacked", "Request", "*") -- Process a request. Only in running mode.
self:AddTransition("*", "Unloaded", "*") -- Cargo has been unloaded from the carrier (unused ==> unnecessary?).
self:AddTransition("*", "AssetSpawned", "*") -- Asset has been spawned into the world.
self:AddTransition("*", "Arrived", "*") -- Cargo or transport group has arrived.
self:AddTransition("*", "Delivered", "*") -- All cargo groups of a request have been delivered to the requesting warehouse.
self:AddTransition("Running", "SelfRequest", "*") -- Request to warehouse itself. Requested assets are only spawned but not delivered anywhere.
@@ -2301,6 +2302,29 @@ function WAREHOUSE:New(warehouse, alias)
-- @param #string To To state.
--- Triggers the FSM event "AssetSpawned" when the warehouse has spawned an asset.
-- @function [parent=#WAREHOUSE] AssetSpawned
-- @param #WAREHOUSE self
-- @param Wrapper.Group#GROUP group the group that was spawned.
-- @param #WAREHOUSE.Assetitem asset The asset that was spawned.
--- Triggers the FSM event "AssetSpawned" with a delay when the warehouse has spawned an asset.
-- @function [parent=#WAREHOUSE] __AssetSpawned
-- @param #WAREHOUSE self
-- @param #number delay Delay in seconds.
-- @param Wrapper.Group#GROUP group the group that was spawned.
-- @param #WAREHOUSE.Assetitem asset The asset that was spawned.
--- On after "AssetSpawned" event user function. Called when the warehouse has spawned an asset.
-- @function [parent=#WAREHOUSE] OnAfterAssetSpawned
-- @param #WAREHOUSE self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Wrapper.Group#GROUP group the group that was spawned.
-- @param #WAREHOUSE.Assetitem asset The asset that was spawned.
--- Triggers the FSM event "Save" when the warehouse assets are saved to file on disk.
-- @function [parent=#WAREHOUSE] Save
-- @param #WAREHOUSE self
@@ -4259,6 +4283,9 @@ function WAREHOUSE:onafterRequest(From, Event, To, Request)
-- Add transport assets.
table.insert(_transportassets,_assetitem)
-- Asset spawned FSM function.
self:__AssetSpawned(1, spawngroup, _assetitem)
end
end
@@ -5195,6 +5222,9 @@ function WAREHOUSE:_SpawnAssetRequest(Request)
if _group then
_groupset:AddGroup(_group)
table.insert(_assets, _assetitem)
-- Call FSM function.
self:__AssetSpawned(1,_group,_assetitem)
else
self:E(self.wid.."ERROR: Cargo asset could not be spawned!")
end
-1
View File
@@ -8320,7 +8320,6 @@ end
--- Airboss event handler for event that a unit takes off.
-- @param #AIRBOSS self
-- @param Core.Event#EVENTDATA EventData
--function AIRBOSS:OnEventPlayerLeaveUnit(EventData)
function AIRBOSS:OnEventTakeoff(EventData)
self:F3({eventtakeoff=EventData})