diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index cf59f2958..24f6a283b 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -373,9 +373,58 @@ do -- Zones end end + -- Drawings as zones + if env.mission.drawings and env.mission.drawings.layers then + + -- Loop over layers. + for layerID, layerData in pairs(env.mission.drawings.layers or {}) do + + -- Loop over objects in layers. + for objectID, objectData in pairs(layerData.objects or {}) do + + -- Check for polygon which has at least 4 points (we would need 3 but the origin seems to be there twice) + if objectData.polygonMode=="free" and objectData.points and #objectData.points>=4 then + + -- Name of the zone. + local ZoneName=objectData.name or "Unknown Drawing Zone" + + -- Reference point. All other points need to be translated by this. + local vec2={x=objectData.mapX, y=objectData.mapY} + + -- Copy points array. + local points=UTILS.DeepCopy(objectData.points) + + -- Translate points. + for i,_point in pairs(points) do + local point=_point --DCS#Vec2 + points[i]=UTILS.Vec2Add(point, vec2) + end + + -- Remove last point. + table.remove(points, #points) + + -- Debug output + self:I(string.format("Register ZONE: %s (Polygon drawing with %d verticies)", ZoneName, #points)) + + -- Create new polygon zone. + local Zone=ZONE_POLYGON:NewFromPointsArray(ZoneName, points) + + -- Set color. + Zone:SetColor({1, 0, 0}, 0.15) + + -- Store in DB. + self.ZONENAMES[ZoneName] = ZoneName + + -- Add zone. + self:AddZone(ZoneName, Zone) + + end + end + end + + end + end - - end -- zone do -- Zone_Goal diff --git a/Moose Development/Moose/Core/MarkerOps_Base.lua b/Moose Development/Moose/Core/MarkerOps_Base.lua index 5e5aa273f..2cdb2afb6 100644 --- a/Moose Development/Moose/Core/MarkerOps_Base.lua +++ b/Moose Development/Moose/Core/MarkerOps_Base.lua @@ -5,6 +5,12 @@ -- * Create an easy way to tap into markers added to the F10 map by users. -- * Recognize own tag and list of keywords. -- * Matched keywords are handed down to functions. +-- ##Listen for your tag +-- myMarker = MARKEROPS_BASE:New("tag", {}, false) +-- function myMarker:OnAfterMarkChanged(From, Event, To, Text, Keywords, Coord, idx) +-- +-- end +-- Make sure to use the "MarkChanged" event as "MarkAdded" comes in right after the user places a blank marker and your callback will never be called. -- -- === -- diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index a4166b27f..07ce932d5 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -32,20 +32,21 @@ -- * [USS George Washington](https://en.wikipedia.org/wiki/USS_George_Washington_(CVN-73\)) (CVN-73) [Super Carrier Module] -- * [USS Harry S. Truman](https://en.wikipedia.org/wiki/USS_Harry_S._Truman) (CVN-75) [Super Carrier Module] -- * [USS Forrestal](https://en.wikipedia.org/wiki/USS_Forrestal_(CV-59\)) (CV-59) [Heatblur Carrier Module] --- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12\)) (R12) [**WIP**] --- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_(R05\)) (R05) [**WIP**] --- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1\)) (LHA-1) [**WIP**] --- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6\)) (LHA-6) [**WIP**] --- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) [**WIP**] --- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02\)) (L02) [**WIP**] +-- * [HMS Hermes](https://en.wikipedia.org/wiki/HMS_Hermes_(R12\)) (R12) +-- * [HMS Invincible](https://en.wikipedia.org/wiki/HMS_Invincible_(R05\)) (R05) +-- * [USS Tarawa](https://en.wikipedia.org/wiki/USS_Tarawa_(LHA-1\)) (LHA-1) +-- * [USS America](https://en.wikipedia.org/wiki/USS_America_(LHA-6\)) (LHA-6) +-- * [Juan Carlos I](https://en.wikipedia.org/wiki/Spanish_amphibious_assault_ship_Juan_Carlos_I) (L61) +-- * [HMAS Canberra](https://en.wikipedia.org/wiki/HMAS_Canberra_(L02\)) (L02) -- -- **Supported Aircraft:** -- -- * [F/A-18C Hornet Lot 20](https://forums.eagle.ru/forumdisplay.php?f=557) (Player & AI) -- * [F-14A/B Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI) -- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI) --- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI) [**WIP**] --- * [T-45C Goshawk](https://www.vnao-cvw-7.com/t-45-goshawk) (VNAO)(Player & AI) [**WIP**] +-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI) +-- * [T-45C Goshawk](https://www.vnao-cvw-7.com/t-45-goshawk) (VNAO mod) (Player & AI) +-- * [FE/A-18E/F/G Superhornet](https://forum.dcs.world/topic/316971-cjs-super-hornet-community-mod-v20-official-thread/) (CJS mod) (Player & AI) -- * F/A-18C Hornet (AI) -- * F-14A Tomcat (AI) -- * E-2D Hawkeye (AI) @@ -1278,7 +1279,10 @@ AIRBOSS = { -- @field #string S3BTANKER Lockheed S-3B Viking tanker. -- @field #string E2D Grumman E-2D Hawkeye AWACS. -- @field #string C2A Grumman C-2A Greyhound from Military Aircraft Mod. --- @field #string T45C T-45C by VNAO +-- @field #string T45C T-45C by VNAO. +-- @field #string RHINOE F/A-18E Superhornet (mod). +-- @field #string RHINOF F/A-18F Superhornet (mod). +-- @field #string GROWLER FEA-18G Superhornet (mod). AIRBOSS.AircraftCarrier={ AV8B="AV8BNA", HORNET="FA-18C_hornet", @@ -1292,6 +1296,9 @@ AIRBOSS.AircraftCarrier={ S3BTANKER="S-3B Tanker", E2D="E-2C", C2A="C2A_Greyhound", + RHINOE="FA-18E", + RHINOF="FA-18F", + GROWLER="EA-18G", } --- Carrier types. @@ -1302,7 +1309,7 @@ AIRBOSS.AircraftCarrier={ -- @field #string STENNIS USS John C. Stennis (CVN-74) -- @field #string TRUMAN USS Harry S. Truman (CVN-75) [Super Carrier Module] -- @field #string FORRESTAL USS Forrestal (CV-59) [Heatblur Carrier Module] --- @field #string VINSON USS Carl Vinson (CVN-70) [Obsolete] +-- @field #string VINSON USS Carl Vinson (CVN-70) [Deprecated!] -- @field #string HERMES HMS Hermes (R12) [V/STOL Carrier] -- @field #string INVINCIBLE HMS Invincible (R05) [V/STOL Carrier] -- @field #string TARAWA USS Tarawa (LHA-1) [V/STOL Carrier] @@ -5177,7 +5184,10 @@ end function AIRBOSS:_GetAircraftAoA( playerData ) -- Get AC type. - local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF + or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B @@ -5340,7 +5350,10 @@ function AIRBOSS:_GetAircraftParameters( playerData, step ) step = step or playerData.step -- Get AC type. - local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF + or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B @@ -6251,6 +6264,9 @@ function AIRBOSS:_RefuelAI( flight ) actype==AIRBOSS.AircraftCarrier.F14B or actype==AIRBOSS.AircraftCarrier.F14A_AI or actype==AIRBOSS.AircraftCarrier.HORNET or + actype==AIRBOSS.AircraftCarrier.RHINOE or + actype==AIRBOSS.AircraftCarrier.RHINOF or + actype==AIRBOSS.AircraftCarrier.GROWLER or actype==AIRBOSS.AircraftCarrier.FA18C or actype==AIRBOSS.AircraftCarrier.S3B or actype==AIRBOSS.AircraftCarrier.S3BTANKER then @@ -6348,7 +6364,11 @@ function AIRBOSS:_LandAI( flight ) -- Aircraft speed when flying the pattern. local Speed = UTILS.KnotsToKmph( 200 ) - if flight.actype == AIRBOSS.AircraftCarrier.HORNET or flight.actype == AIRBOSS.AircraftCarrier.FA18C then + if flight.actype == AIRBOSS.AircraftCarrier.HORNET + or flight.actype == AIRBOSS.AircraftCarrier.FA18C + or flight.actype == AIRBOSS.AircraftCarrier.RHINOE + or flight.actype == AIRBOSS.AircraftCarrier.RHINOF + or flight.actype == AIRBOSS.AircraftCarrier.GROWLER then Speed = UTILS.KnotsToKmph( 200 ) elseif flight.actype == AIRBOSS.AircraftCarrier.E2D then Speed = UTILS.KnotsToKmph( 150 ) @@ -9172,7 +9192,13 @@ function AIRBOSS:_DirtyUp( playerData ) self:_PlayerHint( playerData ) -- Radio call "Say/Fly needles". Delayed by 10/15 seconds. - if playerData.actype == AIRBOSS.AircraftCarrier.HORNET or playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then + if playerData.actype == AIRBOSS.AircraftCarrier.HORNET + or playerData.actype == AIRBOSS.AircraftCarrier.F14A + or playerData.actype == AIRBOSS.AircraftCarrier.F14B + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF + or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER + then local callsay = self:_NewRadioCall( self.MarshalCall.SAYNEEDLES, nil, nil, 5, playerData.onboard ) local callfly = self:_NewRadioCall( self.MarshalCall.FLYNEEDLES, nil, nil, 5, playerData.onboard ) self:RadioTransmission( self.MarshalRadio, callsay, false, 55, nil, true ) @@ -10263,7 +10289,10 @@ function AIRBOSS:_Trapped( playerData ) -- Get current wire (estimate). This now based on the position where the player comes to a standstill which should reflect the trapped wire better. local dcorr = 100 - if playerData.actype == AIRBOSS.AircraftCarrier.HORNET then + if playerData.actype == AIRBOSS.AircraftCarrier.HORNET + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF + or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER then dcorr = 100 elseif playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then -- TODO: Check Tomcat. @@ -12463,7 +12492,10 @@ function AIRBOSS:_PlayerHint( playerData, delay, soundoff ) if playerData.step == AIRBOSS.PatternStep.BULLSEYE then -- Hint follow the needles. if playerData.difficulty == AIRBOSS.Difficulty.EASY then - if playerData.actype == AIRBOSS.AircraftCarrier.HORNET then + if playerData.actype == AIRBOSS.AircraftCarrier.HORNET + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOE + or playerData.actype == AIRBOSS.AircraftCarrier.RHINOF + or playerData.actype == AIRBOSS.AircraftCarrier.GROWLER then hint = hint .. string.format( "\nIntercept glideslope and follow the needles." ) else hint = hint .. string.format( "\nIntercept glideslope." ) @@ -13957,6 +13989,10 @@ function AIRBOSS:_GetACNickname( actype ) nickname = "Tomcat" elseif actype == AIRBOSS.AircraftCarrier.FA18C or actype == AIRBOSS.AircraftCarrier.HORNET then nickname = "Hornet" + elseif actype == AIRBOSS.AircraftCarrier.RHINOE or actype == AIRBOSS.AircraftCarrier.RHINOF then + nickname = "Rhino" + elseif actype == AIRBOSS.AircraftCarrier.GROWLER then + nickname = "Growler" elseif actype == AIRBOSS.AircraftCarrier.S3B or actype == AIRBOSS.AircraftCarrier.S3BTANKER then nickname = "Viking" end diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 575a7ad37..b01e0dee5 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -26,11 +26,11 @@ -- -- === -- --- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing) +-- ### Author: **Applevangelist** (Moose Version), ***Ciribob*** (original), Thanks to: Shadowze, Cammel (testing), The Chosen One (Persistence) -- @module Ops.CSAR -- @image OPS_CSAR.jpg --- Date: November 2022 +-- Date: January 2023 ------------------------------------------------------------------------- --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM @@ -197,6 +197,26 @@ -- -- --Create a casualty and CASEVAC request from a "Point" (VEC2) for the blue coalition --shagrat -- my_csar:SpawnCASEVAC(Point, coalition.side.BLUE) +-- +-- ## 6. Save and load downed pilots - Persistance +-- +-- You can save and later load back downed pilots to make your mission persistent. +-- For this to work, you need to de-sanitize **io** and **lfs** in your MissionScripting.lua, which is located in your DCS installtion folder under Scripts. +-- There is a risk involved in doing that; if you do not know what that means, this is possibly not for you. +-- +-- Use the following options to manage your saves: +-- +-- mycsar.enableLoadSave = true -- allow auto-saving and loading of files +-- mycsar.saveinterval = 600 -- save every 10 minutes +-- mycsar.filename = "missionsave.csv" -- example filename +-- mycsar.filepath = "C:\\Users\\myname\\Saved Games\\DCS\Missions\\MyMission" -- example path +-- +-- Then use an initial load at the beginning of your mission: +-- +-- mycsar:__Load(10) +-- +-- **Caveat:** +-- Dropped troop noMessage and forcedesc parameters aren't saved. -- -- @field #CSAR CSAR = { @@ -296,6 +316,8 @@ function CSAR:New(Coalition, Template, Alias) -- Inherit everything from FSM class. local self=BASE:Inherit(self, FSM:New()) -- #CSAR + BASE:T({Coalition, Prefixes, Alias}) + --set Coalition if Coalition and type(Coalition)=="string" then if Coalition=="blue" then @@ -346,6 +368,8 @@ function CSAR:New(Coalition, Template, Alias) self:AddTransition("*", "Returning", "*") -- CSAR able to return to base. self:AddTransition("*", "Rescued", "*") -- Pilot at MASH. self:AddTransition("*", "KIA", "*") -- Pilot killed in action. + self:AddTransition("*", "Load", "*") -- CSAR load event. + self:AddTransition("*", "Save", "*") -- CSAR save event. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. -- tables, mainly for tracking actions @@ -442,6 +466,14 @@ function CSAR:New(Coalition, Template, Alias) self.SRSVolume = 1.0 -- volume 0.0 to 1.0 self.SRSGender = "male" -- male or female + local AliaS = string.gsub(self.alias," ","_") + self.filename = string.format("CSAR_%s_Persist.csv",AliaS) + + -- load and save downed pilots + self.enableLoadSave = false + self.filepath = nil + self.saveinterval = 600 + ------------------------ --- Pseudo Functions --- ------------------------ @@ -471,6 +503,24 @@ function CSAR:New(Coalition, Template, Alias) -- @function [parent=#CSAR] __Status -- @param #CSAR self -- @param #number delay Delay in seconds. + -- + -- --- Triggers the FSM event "Load". + -- @function [parent=#CSAR] Load + -- @param #CSAR self + + --- Triggers the FSM event "Load" after a delay. + -- @function [parent=#CSAR] __Load + -- @param #CSAR self + -- @param #number delay Delay in seconds. + + --- Triggers the FSM event "Save". + -- @function [parent=#CSAR] Load + -- @param #CSAR self + + --- Triggers the FSM event "Save" after a delay. + -- @function [parent=#CSAR] __Save + -- @param #CSAR self + -- @param #number delay Delay in seconds. --- On After "PilotDown" event. Downed Pilot detected. -- @function [parent=#CSAR] OnAfterPilotDown @@ -538,6 +588,24 @@ function CSAR:New(Coalition, Template, Alias) -- @param #string To To state. -- @param #string Pilotname Name of the pilot KIA. + --- FSM Function OnAfterLoad. + -- @function [parent=#CSAR] OnAfterLoad + -- @param #CSAR self + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + -- @param #string path (Optional) Path where the file is located. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if the lfs module is desanitized. + -- @param #string filename (Optional) File name for loading. Default is "CSAR__Persist.csv". + + --- FSM Function OnAfterSave. + -- @function [parent=#CSAR] OnAfterSave + -- @param #CSAR self + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + -- @param #string path (Optional) Path where the file is saved. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if the lfs module is desanitized. + -- @param #string filename (Optional) File name for saving. Default is "CSAR__Persist.csv". + return self end @@ -2220,7 +2288,16 @@ function CSAR:onafterStart(From, Event, To) self.msrs:SetLabel("CSAR") self.SRSQueue = MSRSQUEUE:New("CSAR") end + self:__Status(-10) + + if self.enableLoadSave then + local interval = self.saveinterval + local filename = self.filename + local filepath = self.filepath + self:__Save(interval,filepath,filename) + end + return self end @@ -2453,6 +2530,240 @@ function CSAR:onbeforeLanded(From, Event, To, HeliName, Airbase) self:T({From, Event, To, HeliName, Airbase}) return self end + +--- On before "Save" event. Checks if io and lfs are available. +-- @param #CSAR self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #string path (Optional) Path where the file is saved. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if the lfs module is desanitized. +-- @param #string filename (Optional) File name for saving. Default is "CSAR__Persist.csv". +function CSAR:onbeforeSave(From, Event, To, path, filename) + self:T({From, Event, To, path, filename}) + if not self.enableLoadSave then + return self + end + -- Thanks to @FunkyFranky + -- Check io module is available. + if not io then + self:E(self.lid.."ERROR: io not desanitized. Can't save current state.") + return false + end + + -- Check default path. + if path==nil and not lfs then + self:E(self.lid.."WARNING: lfs not desanitized. State will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") + end + + return true +end + +--- On after "Save" event. Player data is saved to file. +-- @param #CSAR self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #string path Path where the file is saved. If nil, file is saved in the DCS root installtion directory or your "Saved Games" folder if lfs was desanitized. +-- @param #string filename (Optional) File name for saving. Default is Default is "CSAR__Persist.csv". +function CSAR:onafterSave(From, Event, To, path, filename) + self:T({From, Event, To, path, filename}) + -- Thanks to @FunkyFranky + if not self.enableLoadSave then + return self + end + --- Function that saves data to file + local function _savefile(filename, data) + local f = assert(io.open(filename, "wb")) + f:write(data) + f:close() + end + + -- Set path or default. + if lfs then + path=self.filepath or lfs.writedir() + end + + -- Set file name. + filename=filename or self.filename + + -- Set path. + if path~=nil then + filename=path.."\\"..filename + end + + local pilots = self.downedPilots + + --local data = "LoadedData = {\n" + local data = "playerName,x,y,z,coalition,country,description,typeName,unitName,freq\n" + local n = 0 + for _,_grp in pairs(pilots) do + local DownedPilot = _grp -- Wrapper.Group#GROUP + if DownedPilot and DownedPilot.alive then + -- get downed pilot data for saving + local playerName = DownedPilot.player + local group = DownedPilot.group + local coalition = group:GetCoalition() + local country = group:GetCountry() + local description = DownedPilot.desc + local typeName = DownedPilot.typename + local freq = DownedPilot.frequency + local location = group:GetVec3() + local unitName = DownedPilot.originalUnit + local txt = string.format("%s,%d,%d,%d,%s,%s,%s,%s,%s,%d\n",playerName,location.x,location.y,location.z,coalition,country,description,typeName,unitName,freq) + + self:I(self.lid.."Saving to CSAR File: " .. txt) + + data = data .. txt + end + end + + _savefile(filename, data) + + -- AutoSave + if self.enableLoadSave then + local interval = self.saveinterval + local filename = self.filename + local filepath = self.filepath + self:__Save(interval,filepath,filename) + end + return self +end + +--- On before "Load" event. Checks if io and lfs and the file are available. +-- @param #CSAR self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #string path (Optional) Path where the file is located. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if the lfs module is desanitized. +-- @param #string filename (Optional) File name for loading. Default is "CSAR__Persist.csv". +function CSAR:onbeforeLoad(From, Event, To, path, filename) + self:T({From, Event, To, path, filename}) + if not self.enableLoadSave then + return self + end + --- Function that check if a file exists. + local function _fileexists(name) + local f=io.open(name,"r") + if f~=nil then + io.close(f) + return true + else + return false + end + end + + -- Set file name and path + filename=filename or self.filename + path = path or self.filepath + + -- Check io module is available. + if not io then + self:E(self.lid.."WARNING: io not desanitized. Cannot load file.") + return false + end + + -- Check default path. + if path==nil and not lfs then + self:E(self.lid.."WARNING: lfs not desanitized. State will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") + end + + -- Set path or default. + if lfs then + path=path or lfs.writedir() + end + + -- Set path. + if path~=nil then + filename=path.."\\"..filename + end + + -- Check if file exists. + local exists=_fileexists(filename) + + if exists then + return true + else + self:E(self.lid..string.format("WARNING: State file %s might not exist.", filename)) + return false + --return self + end + +end + +--- On after "Load" event. Loads dropped units from file. +-- @param #CSAR self +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +-- @param #string path (Optional) Path where the file is located. Default is the DCS root installation folder or your "Saved Games\\DCS" folder if the lfs module is desanitized. +-- @param #string filename (Optional) File name for loading. Default is "CSAR__Persist.csv". +function CSAR:onafterLoad(From, Event, To, path, filename) + self:T({From, Event, To, path, filename}) + if not self.enableLoadSave then + return self + end + --- Function that loads data from a file. + local function _loadfile(filename) + local f=assert(io.open(filename, "rb")) + local data=f:read("*all") + f:close() + return data + end + + -- Set file name and path + filename=filename or self.filename + path = path or self.filepath + + -- Set path or default. + if lfs then + path=path or lfs.writedir() + end + + -- Set path. + if path~=nil then + filename=path.."\\"..filename + end + + -- Info message. + local text=string.format("Loading CSAR state from file %s", filename) + MESSAGE:New(text,10):ToAllIf(self.Debug) + self:I(self.lid..text) + + local file=assert(io.open(filename, "rb")) + + local loadeddata = {} + for line in file:lines() do + loadeddata[#loadeddata+1] = line + end + file:close() + + -- remove header + table.remove(loadeddata, 1) + + for _id,_entry in pairs (loadeddata) do + local dataset = UTILS.Split(_entry,",") + -- 1=playerName,2=x,3=y,4=z,5=coalition,6=country,7=description,8=typeName,9=unitName,10=freq\n + local playerName = dataset[1] + + local vec3 = {} + vec3.x = tonumber(dataset[2]) + vec3.y = tonumber(dataset[3]) + vec3.z = tonumber(dataset[4]) + local point = COORDINATE:NewFromVec3(vec3) + + local coalition = dataset[5] + local country = dataset[6] + local description = dataset[7] + local typeName = dataset[8] + local unitName = dataset[9] + local freq = dataset[10] + + self:_AddCsar(coalition, country, point, typeName, unitName, playerName, freq, nil, description, nil) + end + + return self +end + -------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- End Ops.CSAR -------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/Moose Development/Moose/Wrapper/Marker.lua b/Moose Development/Moose/Wrapper/Marker.lua index 21936ae46..4bb7f9c7b 100644 --- a/Moose Development/Moose/Wrapper/Marker.lua +++ b/Moose Development/Moose/Wrapper/Marker.lua @@ -58,18 +58,16 @@ -- If the maker should be visible to a specific coalition, you can use the :ToCoalition() function. -- -- mymarker = MARKER:New( Coordinate , "I am Batumi Airfield" ):ToCoalition( coalition.side.BLUE ) --- --- ### To Blue Coalition --- --- ### To Red Coalition --- +-- -- This would show the marker only to the Blue coalition. -- -- ## For a Group -- +-- mymarker = MARKER:New( Coordinate , "Target Location" ):ToGroup( tankGroup ) -- -- # Removing a Marker --- +-- mymarker:Remove(60) +-- This removes the marker after 60 seconds -- -- # Updating a Marker -- @@ -175,8 +173,6 @@ function MARKER:New( Coordinate, Text ) -- Inherit everything from FSM class. local self = BASE:Inherit( self, FSM:New() ) -- #MARKER - local self=BASE:Inherit(self, FSM:New()) -- #MARKER - self.coordinate=UTILS.DeepCopy(Coordinate) self.text = Text @@ -307,7 +303,7 @@ end -- User API Functions ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Marker is readonly. Text cannot be changed and marker cannot be removed. +--- Marker is readonly. Text cannot be changed and marker cannot be removed. The will not update the marker in the game, Call MARKER:Refresh to update state. -- @param #MARKER self -- @return #MARKER self function MARKER:ReadOnly() @@ -317,7 +313,7 @@ function MARKER:ReadOnly() return self end ---- Marker is readonly. Text cannot be changed and marker cannot be removed. +--- Marker is read and write. Text cannot be changed and marker cannot be removed. The will not update the marker in the game, Call MARKER:Refresh to update state. -- @param #MARKER self -- @return #MARKER self function MARKER:ReadWrite()