jeudi 15 avril 2010

FC2 : Installation de Tacview et modification proposée

Le tacview black shark fonctionne très bien pour FC2, toutefois le fichier généré est énorme car sont stockés :
- les  même objets que pour FC1
- les éclats et trajectoires obus !!!!
 voici le film pour l'install

http://www.youtube.com/watch?v=gOYJ33oFbTo

en complément ci dessous le fichier tacview modifié :





-- Tacview ACMI - Universal Flight Analysis Tool 0.94
-- Export script for DCS: Black Shark
-- Copyright (C) 2006-2009 - Stra Software
-- See http://lomac.strasoftware.com/lomac-acmi.php for more info

-- ACMI text files are exported to [/Black Shark/Temp/] folder

-- TO ENABLE THIS SCRIPT:
--        Set [EnableExportScript = true] in [/Black Shark/Config/export/config.lua]
--        Add [dofile("./Config/Export/TacviewExportBlackShark.lua")] at the end of [/Black Shark/Config/Export/Export.lua]

-- Headers
dofile("./Config/World/World.lua")                -- Required to get mission date
dofile("./Scripts/Database/wsTypes.lua")        -- Required to get object types definitions

-- Debug tools
function table.val_to_str ( v )
    if "string" == type( v ) then
        v = string.gsub( v, "\n", "\\n" )
        if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
            return "'" .. v .. "'"
        end
        return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
    else
        return "table" == type( v ) and table.tostring( v ) or tostring( v )
    end
end

function table.key_to_str ( k )
    if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
        return k
    else
        return "[" .. table.val_to_str( k ) .. "]"
    end
end

function table.tostring( tbl )
    local result, done = {}, {}
    for k, v in ipairs( tbl ) do
        table.insert( result, table.val_to_str( v ) )
        done[ k ] = true
    end
    for k, v in pairs( tbl ) do
        if not done[ k ] then
            table.insert( result,
            table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
        end
    end
    return "{" .. table.concat( result, "," ) .. "}"
end

-- Terrain exporter
function ExportTerrain()

--[[
    -- ge (Black Shark)
    ExportSector(40,41);
    ExportSector(40,42);
    ExportSector(40,43);
    ExportSector(40,44);
    ExportSector(41,41);
    ExportSector(41,42);
    ExportSector(41,43);
    ExportSector(41,44);
    ExportSector(42,40);
    ExportSector(42,41);
    ExportSector(42,42);
    ExportSector(42,43);
    ExportSector(42,44);

    -- ru (Black Shark)
    ExportSector(43,39);
    ExportSector(43,40);
    ExportSector(43,41);
    ExportSector(43,42);
    ExportSector(43,43);
    ExportSector(43,44);
    ExportSector(44,37);
    ExportSector(44,38);
    ExportSector(44,39);
    ExportSector(44,40);
    ExportSector(44,41);
    ExportSector(44,42);
    ExportSector(44,43);
    ExportSector(44,44);
    ExportSector(45,37);
    ExportSector(45,38);
    ExportSector(45,39);
    ExportSector(45,40);

    -- ua (Flaming Cliffs)
    ExportSector(44,33);
    ExportSector(44,34);
    ExportSector(44,35);
    ExportSector(45,32);
    ExportSector(45,33);
    ExportSector(45,34);
    ExportSector(45,35);
    ExportSector(45,36);
--]]

end

function ExportSector(Latitude,Longitude)

    local TerrainFile=io.open(string.format("./Temp/N%02uE%03u.hgt.txt",Latitude,Longitude),"wb");

    for y=1200,0,-1 do

        local CurrentLatitude=Latitude+y/1200;

        for x=0,1200 do

            local CurrentLongitude=Longitude+x/1200;
            local DCSCoordinates=LoGeoCoordinatesToLoCoordinates(CurrentLongitude,CurrentLatitude);

            TerrainFile:write(LoGetAltitude(DCSCoordinates.x,DCSCoordinates.z).."\n");

        end
    end

    io.close(TerrainFile);
end

-- ACMI Log
AcmiData=
{
    -- Log parameters
    DefaultObjectsUpdatePeriod=1/10,    -- Delay between two log updates (in seconds) for default objects, use [0] to force update at each frame
    BallisticObjectsUpdatePeriod=1/2,    -- Delay between two log updates (in seconds) for ballistic objects, use [0] to force update at each frame
    LatitudeOffset=41,                    -- To improve log resolution
    LongitudeOffset=36,                    -- To improve log resolution

    -- Convert Lock-On Object_Type To Tacview Object_Type
    ObjectTypeLookupTable=
    {
        [wsType_Destroyed]                    =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
        [wsType_Air]=
        {
            [-1]                            =    0x10,    -- Aeroplanes (including fixed-wing drones)
            [wsType_Helicopter]                =    0x18,    -- Helicopters (including rotary-wing drones)
            [wsType_Airplane]=
            {
                [-1]                        =    0x10,    -- Aeroplanes (including fixed-wing drones)
                [wsType_Fighter]            =    0x10,    -- Aeroplanes (including fixed-wing drones)
                [wsType_F_Bomber]            =    0x10,    -- Aeroplanes (including fixed-wing drones)
                [wsType_Intercepter]        =    0x10,    -- Aeroplanes (including fixed-wing drones)
                [wsType_Intruder]            =    0x10,    -- Aeroplanes (including fixed-wing drones)
                [wsType_Cruiser]            =    0x10,    -- Aeroplanes (including fixed-wing drones)
                [wsType_Battleplane]        =    0x10,    -- Aeroplanes (including fixed-wing drones)
            },
            [wsType_Free_Fall]=
            {
                [-1]                        =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Snars]=
                {
                    [-1]                    =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                    [wsType_Chaff]            =    0x50,    -- Chaff (obviously a chaff cluster)
                    [wsType_Flare]            =    0x54,    -- Flare
                },
                [wsType_Parts]=
                {
                    [-1]                    =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                    [203]                    =    0x60,    -- Minor object (e.g. cartridge)
                },
                [wsType_FuelTank]            =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
            },
        },
        [wsType_Ground]=
        {
            [-1]                            =    0x28,    -- Light/Unarmed vehicles
            [wsType_Tank]=
            {
                [-1]                        =    0x24,    -- Armored fighting vehicle
                [wsType_NoWeapon]=
                {
                    [-1]                    =    0x28,    -- Light/Unarmed vehicles
                    [wsTypePredator_GCS]     =    0x28,    -- Light/Unarmed vehicles
                    [wsTypePredator_TrojanSpirit]=0x28,    -- Light/Unarmed vehicles
                },
                [wsType_Gun]=
                {
                    [-1]                    =    0x24,    -- Armored fighting vehicle
                    [wsTypeSandbox]            =    0x89,    -- Building
                    [wsTypeBunker]            =    0x89,    -- Building
                    [wsTypeAutogun]            =    0x2c,    -- Infantry
                    [wsTypeSoldier_AK]       =    0x2c,    -- Infantry
                },
                [wsType_MissGun]=
                {
                    [-1]                      =    0x24,    -- Armored fighting vehicle
                    [wsTypeRPG]                =    0x2c,    -- Infantry
                    [wsTypeSoldier_RPG]      =    0x2c,    -- Infantry
                },
            },
            [wsType_SAM]                    =    0x20,    -- Anti-aircraft warfare (usually: SAM and AAA)
            [wsType_Moving]=
            {
                [-1]                        =    0x28,    -- Light/Unarmed vehicles
                [wsType_NoWeapon]            =    0x28,    -- Light/Unarmed vehicles
                [wsType_Gun]                =    0x28,    -- Light/Unarmed vehicles
                [wsType_Miss]                =    0x24,    -- Armored fighting vehicle
                [wsType_ChildMiss]            =    0x24,    -- Armored fighting vehicle
                [wsType_MissGun]            =    0x24,    -- Armored fighting vehicle
                [wsType_Civil]                =    0x28,    -- Light/Unarmed vehicles
            },
            [wsType_Standing]=
            {
                [-1]                        =    0x89,    -- Building
                [wsType_NoWeapon]            =    0x89,    -- Building
                [wsType_Gun]                =    0x89,    -- Building
                [wsType_Miss]                =    0x20,    -- Anti-aircraft warfare (usually: SAM and AAA)
                [wsType_ChildMiss]            =    0x20,    -- Anti-aircraft warfare (usually: SAM and AAA)
                [wsType_MissGun]            =    0x20,    -- Anti-aircraft warfare (usually: SAM and AAA)
                [wsType_Civil]                =    0x89,    -- Building
            },
        },
        [wsType_Navy]=
        {
            [-1]                            =    0x30,    -- Armed Watercraft (including submarines)
            [wsType_Ship]=
            {
                [-1]                        =    0x30,    -- Armed Watercraft (including submarines)
                [wsType_AirCarrier]            =    0x34,    -- Aircraft carrier (including Helicopter carrier)
                [wsType_HCarrier]            =    0x34,    -- Aircraft carrier (including Helicopter carrier)
                [wsType_ArmedShip]            =    0x30,    -- Armed Watercraft (including submarines)
                [wsType_CivilShip]            =    0x38,    -- Light/Unarmed Watercraft
            },
        },
        [wsType_Weapon]=
        {
            [-1]                            =    0x40,    -- Missile (guided missiles)
            [wsType_Missile]=
            {
                [-1]                        =    0x40,    -- Missile (guided missiles)
                [wsType_AA_Missile]            =    0x40,    -- Missile (guided missiles)
                [wsType_AS_Missile]            =    0x40,    -- Missile (guided missiles)
                [wsType_SA_Missile]            =    0x40,    -- Missile (guided missiles)
                [wsType_SS_Missile]            =    0x40,    -- Missile (guided missiles)
                [wsType_AA_TRAIN_Missile]    =    0x40,    -- Missile (guided missiles)
                [wsType_AS_TRAIN_Missile]    =    0x40,    -- Missile (guided missiles)
            },
            [wsType_Bomb]=
            {
                [-1]                        =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_A]                =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_Guided]        =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_BetAB]            =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_Cluster]        =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_Antisubmarine]    =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_ODAB]            =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_Fire]            =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_Nuclear]        =    0x4c,    -- Bomb (guided and unguided)
                [wsType_Bomb_Lighter]        =    0x4c,    -- Bomb (guided and unguided)
            },
            [wsType_Shell]=
            {
                [-1]                        =    0x48,    -- Shell
                [wsType_Shell_A]            =    0x48,    -- Shell
            },
            [wsType_NURS]=
            {
                [-1]                        =    0x44,    -- Rocket (unguided missiles)
                [wsType_Container]            =    0x44,    -- Rocket (unguided missiles)
                [wsType_Rocket]                =    0x44,    -- Rocket (unguided missiles)
            },
        },
        [wsType_Static]=
        {
            [-1]                            =    0x89,    -- Building
            [wsType_AirdromePart]            =    0x89,    -- Building
            [wsType_WingPart]                =    0x89,    -- Building
            [wsType_Free_Fall]=
            {
                [-1]                        =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Parts]=
                {
                    [-1]                    =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                    [255]                    =    -1,        -- Particles (e.g. landing gear dust on runway)
                },
            },
            [wsType_Airdrome]=
            {
                [-1]                        =    0x81,    -- Aerodrome
                [wsType_RW1]                =    0x81,    -- Aerodrome
                [wsType_RW2]                =    0x81,    -- Aerodrome
                [wsType_Heliport]            =    0x81,    -- Aerodrome
            },
            [wsType_Explosion]=
            {
                [-1]                        =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_GroundExp]            =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
            },
            [wsType_GContainer]=
            {
                [-1]                        =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Control_Cont]        =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Jam_Cont]            =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Cannon_Cont]        =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Support]            =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Snare_Cont]            =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
                [wsType_Smoke_Cont]            =    0x46,    -- Shrapnel (e.g. Cluster-bomb fragments or exploded plane parts)
            },
        },
    },

    -- Convert Lock-On Coalition_ID To Tacview Coalition_ID
    CoalitionLookupTable=
    {
        ["Allies"]            =    0,
        ["Enemies"]            =    1,
    },

    -- Convert Lock-On Country_Name To ISO Country_Code
    CountryCodeLookupTable=
    {
        [ 0]                =    "ru",
        [ 1]                =    "ua",
        [ 2]                =    "us",
        [ 3]                =    "tr",
        [ 4]                =    "uk",
        [ 5]                =    "fr",
        [ 6]                =    "de",
--        [ 7]                =    "",
        [ 8]                =    "ca",
        [ 9]                =    "es",
        [10]                =    "nl",
        [11]                =    "be",
        [12]                =    "no",
        [13]                =    "dk",
--        [14]                =    "",
        [15]                =    "il",
        [16]                =    "ge",
        [17]                =    "xi",        -- [Insurgents] (free for use ISO code)
    },

    -- Reduce ID size (to compact text log)
    -- OptimizedID=ID^0x1000000  (free in C, hard to do with LUA...)
    GetOptimizedID=function(ID)

        if math.mod(math.floor(ID/0x1000000),2)==1 then
            return ID-0x1000000;    -- Clear bit
        end

        return ID+0x1000000;        -- Set bit
    end,

    -- Trim Given String
    Trim=function(StringToTrim)
        return string.gsub(StringToTrim,"^%s*(.-)%s*$","%1");
    end,

    -- Add escape characters
    DecorateName=function(Name)

        if Name then
            Name=string.gsub(Name,"\\","\\\\");
            Name=string.gsub(Name,",","\\,");
            Name=string.gsub(Name,"=","\\=");
            return Name;
        end

        return "";
    end,

    -- Trim and decorate name for log output
    CleanupName=function(Name)
        return AcmiData.DecorateName(AcmiData.Trim(Name));
    end,

    -- Convert Lock-On unit type to Tacview unit type
    ConvertObjectType=function(LockOnObjectType)

        local TacviewObjectType;

        TacviewObjectType=AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1];

        if not TacviewObjectType then
            return AcmiData.ObjectTypeLookupTable[-1];
        end

        if type(TacviewObjectType)~="table" then
            return TacviewObjectType;
        end

         TacviewObjectType=AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1][LockOnObjectType.level2];

        if not TacviewObjectType then
            return AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1][-1];
        end

        if TacviewObjectType and type(TacviewObjectType)~="table" then
            return TacviewObjectType;
        end

         TacviewObjectType=AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1][LockOnObjectType.level2][LockOnObjectType.level3];

        if not TacviewObjectType then
            return AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1][LockOnObjectType.level2][-1];
        end

        if TacviewObjectType and type(TacviewObjectType)~="table" then
            return TacviewObjectType;
        end

         TacviewObjectType=AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1][LockOnObjectType.level2][LockOnObjectType.level3][LockOnObjectType.level4];

        if not TacviewObjectType then
            return AcmiData.ObjectTypeLookupTable[LockOnObjectType.level1][LockOnObjectType.level2][LockOnObjectType.level3][-1];
        end

         return TacviewObjectType;
    end,

    -- Begin to log ACMI data
    BeginLog=function(self)

        -- Reset objects lists
        self.LastObjectsStatus={};        -- Last frame object status
        self.LoggedObjectsStatus={};    -- Last logged object status (usually older than LastObjectsStatus)

        -- Reset tools
        self.NextDefaultObjectsUpdateTime=0;
        self.NextBallisticObjectsUpdateTime=0;

        -- Create a new log file for each mission
        self.AcmiFile=io.open("./Temp/Tacview-"..os.date("%Y%m%d-%H%M%S")..".txt.acmi","wb");

        if not self.AcmiFile then
            return;
        end

        -- UTF-8 BOM header
        self.AcmiFile:write(string.char(0xEF,0xBB,0xBF));

        -- Core Header
        self.AcmiFile:write("FileType=text/acmi/tacview\n");
        self.AcmiFile:write("FileVersion=1.2\n");
        self.AcmiFile:write("Source=LOCK ON Flaming Cliff 2.0\n");
        self.AcmiFile:write("Recorder=Tacview 0.94\n");
        self.AcmiFile:write("RecordingTime="..os.date("!%Y-%m-%dT%H:%M:%SZ",now).."\n");

        local PlayerName=LoGetPilotName();

        if PlayerName then
            self.AcmiFile:write("Author="..self.CleanupName(PlayerName).."\n");
        end

        -- Declarations
        if MissionDate then

            -- Crimea Time Zone: Winter(UTC+2) Summer(DST=UTC+3)
            -- 3 hours time shift calculation (assume summer Crimea time shift)
            local LocalRefTime=os.time{year=2004,month=6,day=22,hour=0};
            local UTCRefTime=os.time{year=2004,month=6,day=21,hour=21};
            local TimeShift=LocalRefTime-UTCRefTime;

            -- Need to manualy apply DST bias because nothing is simple with LUA
            local CurrentDate=os.date("*t",now);
            local IsDst;

            if CurrentDate and CurrentDate.isdst==true then
                IsDst=true;
            else
                IsDst=false;
            end

            -- Substract 3 hours from the current mission time (not easy with lua)
            local LocalMissionTime=os.time{year=MissionDate.Year,month=MissionDate.Month,day=MissionDate.Day,hour=0,isdst=IsDst};
            local UTCMissionTime=LocalMissionTime-TimeShift+LoGetMissionStartTime();
            local MissionTimeTable=os.date("*t",UTCMissionTime);

            self.AcmiFile:write("MissionTime="..string.format("%04u-%02u-%02uT%02u:%02u:%02uZ",MissionTimeTable.year,MissionTimeTable.month,MissionTimeTable.day,MissionTimeTable.hour,MissionTimeTable.min,MissionTimeTable.sec).."\n");
        end

        self.AcmiFile:write("LatitudeOffset="..self.LatitudeOffset.."\n");
        self.AcmiFile:write("LongitudeOffset="..self.LongitudeOffset.."\n");
        self.AcmiFile:write("Coalition=Allies,Red\n");
        self.AcmiFile:write("Coalition=Enemies,Blue\n");
        self.AcmiFile:write("ProvidedEvents=Removed\n");

        -- Additional Information
        local PlayerID=LoGetPlayerPlaneId();

        if PlayerID then
            self.AcmiFile:write(string.format("MainAircraftID=%x\n",self.GetOptimizedID(PlayerID)));
        end
    end,

    -- Update ACMI log
    UpdateLog=function(self)

        -- Check parameters
        if not AcmiData.AcmiFile then
            return;
        end

        -- Format current frame time
        local CurrentTime=LoGetModelTime();
        local FormatedTime=string.format("#%.2f\n",CurrentTime);
        local ShouldUpdateLog=true;

        -- Add/Update default objects
        if CurrentTime>=self.NextDefaultObjectsUpdateTime then
            ShouldUpdateLog=true;
            self.NextDefaultObjectsUpdateTime=CurrentTime+self.DefaultObjectsUpdatePeriod;
        end

        local DefaultObjectsList=LoGetWorldObjects();    -- LoGetWorldObjects("units");

        if self:AddUpdateObjects(DefaultObjectsList,FormatedTime,ShouldUpdateLog)==true then
            FormatedTime=nil;
        end

        -- Add/Update ballistic objects
        if CurrentTime>=self.NextBallisticObjectsUpdateTime then
            ShouldUpdateLog=true;
            self.NextBallisticObjectsUpdateTime=CurrentTime+self.BallisticObjectsUpdatePeriod;
        end

        local BallisticObjectsList=LoGetWorldObjects("ballistic");

        if self:AddUpdateObjects(BallisticObjectsList,FormatedTime,ShouldUpdateLog)==true then
            FormatedTime=nil;
        end

        -- Remove destroyed objects
        self:RemoveObjects(DefaultObjectsList,BallisticObjectsList,FormatedTime);
    end,

    -- Add/Update objects
    AddUpdateObjects=function(self,CurrentObjectsList,FormatedTime,ShouldUpdateLog)

        -- Check parameters
        if not CurrentObjectsList then
            return false;
        end

        -- Dump objects
        local LogWasUpdated=false;

        for ID,Object in pairs(CurrentObjectsList) do

            -- Check Object Type
            local ObjectType=self.ConvertObjectType(Object.Type);

            if ObjectType~=-1 then    -- Ignore some objects (like particles clouds)

                -- Reduce ID size (to compact text log)
                local OptimizedID=self.GetOptimizedID(ID);

                -- Add new object
                if not self.LastObjectsStatus[ID] then

                    local LogLine;

                    -- Time prefix
                    if FormatedTime then
                        LogLine=FormatedTime;
                        FormatedTime=nil;
                    else
                        LogLine="";
                    end

                    -- Object/Pilot Name
                    local ObjectName=Object.Name;
                    local PilotName;

                    if Object.UnitName then
                        PilotName=Object.UnitName;
                    else
                        PilotName="";
                    end

                    -- Object Type
                    local ObjectTypeFormated;

                    if ObjectType and type(ObjectType)=="number" then
                        ObjectTypeFormated=string.format("%x",ObjectType);
                    else
                        -- This will help to track unknown types
                        ObjectTypeFormated=string.format("%s.%s.%s.%s",Object.Type.level1,Object.Type.level2,Object.Type.level3,Object.Type.level4);
                    end

                    -- Coalition
                    local CoalitionID;

                    if ObjectType==0x48 or ObjectType==0x50 or ObjectType==0x54 then
                        CoalitionID="?";            -- Chaff/Flare/Shell coalition is not reliable in DCS
                    else
                        if Object.Coalition then
                            CoalitionID=self.CoalitionLookupTable[Object.Coalition];

                            if not CoalitionID then
                                CoalitionID="?";
                            end
                        else
                            CoalitionID="?";
                        end
                    end

                    -- Country
                    local CountryCode;

                    if Object.Country then
                        CountryCode=self.CountryCodeLookupTable[Object.Country];

                        if not CountryCode then
                            CountryCode="?";
                        end
                    else
                        CountryCode="?";
                    end

                    -- Group Name
                    local GroupName;

                    if Object.GroupName then
                        GroupName=Object.GroupName;
                    else
                        GroupName="?";
                    end
                    -- modification yoann suppression des shrapnels
                    if ObjectType ~= 0x46 then
                        -- Declare new object
                        self.AcmiFile:write(LogLine..string.format("+%x,?,%s,%s,%s,%s,%s,%s,?\n",OptimizedID,ObjectTypeFormated,CoalitionID,CountryCode,self.CleanupName(ObjectName),self.CleanupName(PilotName),self.CleanupName(GroupName)));
                   
                    -- Done
                        LogWasUpdated=true;
                    end
                end

                -- Update object data as required
                --
                -- modification yoann suppression des shrapnels
               
                if ObjectType ~= 0x46 then
                    if self:UpdateObject(ID,Object,ObjectType,self.LoggedObjectsStatus[ID],FormatedTime,ShouldUpdateLog)==true then
                        FormatedTime=nil;
                        LogWasUpdated=true;
                    end
                end
            end
        end

        -- Completed
        return LogWasUpdated;
    end,

    -- Fix Yaw (because FC/BS map is a 2D projection, not a true 3D sphere)
    FixedYaw=function(Yaw,RefX,RefZ,Latitude,Longitude)

        local ToNorthPos=LoGeoCoordinatesToLoCoordinates(Longitude,Latitude+.001);

        local ToNorthX=ToNorthPos.z-RefZ;
        local ToNorthY=ToNorthPos.x-RefX;

        local ToNorthLength=math.sqrt(ToNorthX*ToNorthX+ToNorthY*ToNorthY);

        if ToNorthLength>0 then
            return Yaw-math.asin(ToNorthX/ToNorthLength);
        end

        return Yaw;
    end,

    -- Update one object
    UpdateObject=function(self,ID,CurrentObjectData,ObjectType,PrevObjectData,FormatedTime,ShouldUpdateLog)

        -- Log object dynamic properties
        local ChangeDetected=false;
        local LogWasUpdated=false;
        local Log="";

        -- Latitude
        if not PrevObjectData or CurrentObjectData.LatLongAlt.Lat~=PrevObjectData.LatLongAlt.Lat then
            Log=Log..string.format(",%.6f",CurrentObjectData.LatLongAlt.Lat-self.LatitudeOffset);
            ChangeDetected=true;
        else
            Log=Log..",";
        end

        -- Longitude
        if not PrevObjectData or CurrentObjectData.LatLongAlt.Long~=PrevObjectData.LatLongAlt.Long then
            Log=Log..string.format(",%.6f",CurrentObjectData.LatLongAlt.Long-self.LongitudeOffset);
            ChangeDetected=true;
        else
            Log=Log..",";
        end

        -- Altitude
        if not PrevObjectData or CurrentObjectData.LatLongAlt.Alt~=PrevObjectData.LatLongAlt.Alt then
            Log=Log..string.format(",%.2f",CurrentObjectData.LatLongAlt.Alt);
            ChangeDetected=true;
        else
            Log=Log..",";
        end

        -- Roll/Pitch/Yaw
        if ObjectType==0x48 or ObjectType==0x50 or ObjectType==0x54 then    -- flare/chaff/shell

            -- Do not log roll/pitch/yaw to reduce recording size
            if not PrevObjectData then
                Log=Log..",0,0,0\n";
            else
                Log=Log..",,,\n";
            end

        else

            if ObjectType==0x4c and CurrentObjectData.Name=="" then

                -- Emulate bomblets orientation
                if not PrevObjectData then
                    Log=Log..",?,?,?\n";
                else
                    Log=Log..",,,\n";
                end

            else

                -- Roll
                if not PrevObjectData or CurrentObjectData.Bank~=PrevObjectData.Bank then

                    local NewFormatedRoll=string.format(",%.1f",math.mod(math.deg(CurrentObjectData.Bank),360));
                    local RollIsDifferent=true;

                    if PrevObjectData then

                        local OldFormatedRoll=string.format(",%.1f",math.mod(math.deg(PrevObjectData.Bank),360));

                        if NewFormatedRoll==OldFormatedRoll then
                            RollIsDifferent=false;
                        end
                    end

                    if RollIsDifferent==true then
                        Log=Log..NewFormatedRoll;
                        ChangeDetected=true;
                    else
                        Log=Log..",";        -- not different enougth to be dumped
                    end

                else
                    Log=Log..",";
                end

                -- Pitch
                if not PrevObjectData or CurrentObjectData.Pitch~=PrevObjectData.Pitch then

                    local NewFormatedPitch=string.format(",%.1f",-math.mod(math.deg(-CurrentObjectData.Pitch),360));
                    local PitchIsDifferent=true;

                    if PrevObjectData then

                        local OldFormatedPitch=string.format(",%.1f",-math.mod(math.deg(-PrevObjectData.Pitch),360));

                        if NewFormatedPitch==OldFormatedPitch then
                            PitchIsDifferent=false;
                        end
                    end

                    if PitchIsDifferent==true then
                        Log=Log..NewFormatedPitch;
                        ChangeDetected=true;
                    else
                        Log=Log..",";        -- not different enougth to be dumped
                    end

                else
                    Log=Log..",";
                end

                -- Yaw
                if not PrevObjectData or CurrentObjectData.Heading~=PrevObjectData.Heading then

                    local NewFormatedYaw=string.format(",%.1f\n",math.mod(math.deg(AcmiData.FixedYaw(CurrentObjectData.Heading,CurrentObjectData.Position.x,CurrentObjectData.Position.z,CurrentObjectData.LatLongAlt.Lat,CurrentObjectData.LatLongAlt.Long)),360));
                    local YawIsDifferent=true;

                    if PrevObjectData then

                        local OldFormatedYaw=string.format(",%.1f\n",math.mod(math.deg(AcmiData.FixedYaw(PrevObjectData.Heading,PrevObjectData.Position.x,PrevObjectData.Position.z,PrevObjectData.LatLongAlt.Lat,PrevObjectData.LatLongAlt.Long)),360));

                        if NewFormatedYaw==OldFormatedYaw then
                            YawIsDifferent=false;
                        end
                    end

                    if YawIsDifferent==true then
                        Log=Log..NewFormatedYaw;
                        ChangeDetected=true;
                    else
                        Log=Log..",\n";        -- not different enougth to be dumped
                    end

                else
                    Log=Log..",\n";
                end
            end
        end

        -- Log data
        if not PrevObjectData or ( ChangeDetected==true and ShouldUpdateLog==true ) then

            local OptimizedID=self.GetOptimizedID(ID);

            if FormatedTime then
                self.AcmiFile:write(FormatedTime..string.format("%x",OptimizedID)..Log);
            else
                self.AcmiFile:write(string.format("%x",OptimizedID)..Log);
            end

            LogWasUpdated=true;

            -- Remember Last Logged Object Properties
            self.LoggedObjectsStatus[ID]=CurrentObjectData;
        end

        -- Remember Current Frame Object Properties
        self.LastObjectsStatus[ID]=CurrentObjectData;

        -- Complete
        return LogWasUpdated;
    end,

    -- Remove any destroyed objects
    RemoveObjects=function(self,DefaultObjectsList,BallisticObjectsList,FormatedTime)

        local Log;

        for ID,Object in pairs(self.LastObjectsStatus) do

            if (not DefaultObjectsList or not DefaultObjectsList[ID]) and (not BallisticObjectsList or not BallisticObjectsList[ID]) then

                -- Log last position if required
                local ObjectType=self.ConvertObjectType(Object.Type);

                if self:UpdateObject(ID,Object,ObjectType,self.LoggedObjectsStatus[ID],FormatedTime,true)==true then
                    FormatedTime=nil;
                end

                -- Prefix event with time if required
                if FormatedTime then
                    Log=FormatedTime;
                    FormatedTime=nil;
                else
                    Log="";
                end

                -- Log Event
                self.AcmiFile:write(Log..string.format("!20,%x\n",self.GetOptimizedID(ID)));

                -- Remove object from lists
                self.LoggedObjectsStatus[ID]=nil;
                self.LastObjectsStatus[ID]=nil;
            end
        end
    end,

    -- Stop ACMI logging
    EndLog=function(self)
        if self.AcmiFile then
            io.close(self.AcmiFile);
        end
    end,
}

-- (Hook) Works once right before mission start.
do
    local PrevLuaExportStart=LuaExportStart;

    LuaExportStart=function()

        ExportTerrain();

        AcmiData:BeginLog();

        if PrevLuaExportStart then
            PrevLuaExportStart();
        end
    end
end

-- (Hook) Works right after every simulation frame.
do
    local PrevLuaExportAfterNextFrame=LuaExportAfterNextFrame;

    LuaExportAfterNextFrame=function()
        AcmiData:UpdateLog();

        if PrevLuaExportAfterNextFrame then
            PrevLuaExportAfterNextFrame();
        end
    end
end

-- (Hook) Works once right after mission stop.
do
    local PrevLuaExportStop=LuaExportStop;

    LuaExportStop=function()
        AcmiData:EndLog();

        if PrevLuaExportStop then
            PrevLuaExportStop();
        end
    end
end

0 commentaires: