diff --git a/CTLD.lua b/CTLD.lua index a4498a1..4fcaa5c 100644 --- a/CTLD.lua +++ b/CTLD.lua @@ -42,6 +42,547 @@ ctld.Trace = true ctld.dontInitialize = false -- if true, ctld.initialize() will not run; instead, you'll have to run it from your own code - it's useful when you want to override some functions/parameters before the initialization takes place +-- *************************************************************** +-- *************** Internationalization (I18N) ******************* +-- *************************************************************** + +-- If you want to change the language replace "en" with the language you want to use +-- i.e +-- ctld.i18n_lang = "fr" +ctld.i18n_lang = "en" + +-- This is the default language +-- If a string is not found in the current language then it will default to this language +-- Note that no translation is provided for this language (obviously) but that we'll maintain this table to help the translators. +ctld.i18n = {} +ctld.i18n["en"] = {} + +--- groups names +ctld.i18n["en"]["Standard Group"] = nil +ctld.i18n["en"]["Anti Air"] = nil +ctld.i18n["en"]["Anti Tank"] = nil +ctld.i18n["en"]["Mortar Squad"] = nil +ctld.i18n["en"]["JTAC Group"] = nil +ctld.i18n["en"]["Single JTAC"] = nil +ctld.i18n["en"]["2x - Standard Groups"] = nil +ctld.i18n["en"]["2x - Anti Air"] = nil +ctld.i18n["en"]["2x - Anti Tank"] = nil +ctld.i18n["en"]["2x - Standard Groups + 2x Mortar"] = nil +ctld.i18n["en"]["3x - Standard Groups"] = nil +ctld.i18n["en"]["3x - Anti Air"] = nil +ctld.i18n["en"]["3x - Anti Tank"] = nil +ctld.i18n["en"]["3x - Mortar Squad"] = nil +ctld.i18n["en"]["5x - Mortar Squad"] = nil +ctld.i18n["en"]["Mortar Squad Red"] = nil + +--- crates names +ctld.i18n["en"]["Humvee - MG"] = nil +ctld.i18n["en"]["Humvee - TOW"] = nil +ctld.i18n["en"]["Light Tank - MRAP"] = nil +ctld.i18n["en"]["Med Tank - LAV-25"] = nil +ctld.i18n["en"]["Heavy Tank - Abrams"] = nil +ctld.i18n["en"]["BTR-D"] = nil +ctld.i18n["en"]["BRDM-2"] = nil +ctld.i18n["en"]["Hummer - JTAC"] = nil +ctld.i18n["en"]["M-818 Ammo Truck"] = nil +ctld.i18n["en"]["M-978 Tanker"] = nil +ctld.i18n["en"]["SKP-11 - JTAC"] = nil +ctld.i18n["en"]["Ural-375 Ammo Truck"] = nil +ctld.i18n["en"]["KAMAZ Ammo Truck"] = nil +ctld.i18n["en"]["EWR Radar"] = nil +ctld.i18n["en"]["FOB Crate - Small"] = nil +ctld.i18n["en"]["MLRS"] = nil +ctld.i18n["en"]["SpGH DANA"] = nil +ctld.i18n["en"]["T155 Firtina"] = nil +ctld.i18n["en"]["Howitzer"] = nil +ctld.i18n["en"]["SPH 2S19 Msta"] = nil +ctld.i18n["en"]["M1097 Avenger"] = nil +ctld.i18n["en"]["M48 Chaparral"] = nil +ctld.i18n["en"]["Roland ADS"] = nil +ctld.i18n["en"]["Gepard AAA"] = nil +ctld.i18n["en"]["LPWS C-RAM"] = nil +ctld.i18n["en"]["9K33 Osa"] = nil +ctld.i18n["en"]["9P31 Strela-1"] = nil +ctld.i18n["en"]["9K35M Strela-10"] = nil +ctld.i18n["en"]["9K331 Tor"] = nil +ctld.i18n["en"]["2K22 Tunguska"] = nil +ctld.i18n["en"]["HAWK Launcher"] = nil +ctld.i18n["en"]["HAWK Search Radar"] = nil +ctld.i18n["en"]["HAWK Track Radar"] = nil +ctld.i18n["en"]["HAWK PCP"] = nil +ctld.i18n["en"]["HAWK CWAR"] = nil +ctld.i18n["en"]["HAWK Repair"] = nil +ctld.i18n["en"]["NASAMS Launcher 120C"] = nil +ctld.i18n["en"]["NASAMS Search/Track Radar"] = nil +ctld.i18n["en"]["NASAMS Command Post"] = nil +ctld.i18n["en"]["NASAMS Repair"] = nil +ctld.i18n["en"]["KUB Launcher"] = nil +ctld.i18n["en"]["KUB Radar"] = nil +ctld.i18n["en"]["KUB Repair"] = nil +ctld.i18n["en"]["BUK Launcher"] = nil +ctld.i18n["en"]["BUK Search Radar"] = nil +ctld.i18n["en"]["BUK CC Radar"] = nil +ctld.i18n["en"]["BUK Repair"] = nil +ctld.i18n["en"]["Patriot Launcher"] = nil +ctld.i18n["en"]["Patriot Radar"] = nil +ctld.i18n["en"]["Patriot ECS"] = nil +ctld.i18n["en"]["Patriot ICC"] = nil +ctld.i18n["en"]["Patriot EPP"] = nil +ctld.i18n["en"]["Patriot AMG (optional)"] = nil +ctld.i18n["en"]["Patriot Repair"] = nil +ctld.i18n["en"]["S-300 Grumble TEL C"] = nil +ctld.i18n["en"]["S-300 Grumble Flap Lid-A TR"] = nil +ctld.i18n["en"]["S-300 Grumble Clam Shell SR"] = nil +ctld.i18n["en"]["S-300 Grumble Big Bird SR"] = nil +ctld.i18n["en"]["S-300 Grumble C2"] = nil +ctld.i18n["en"]["S-300 Repair"] = nil + +--- mission design error messages +ctld.i18n["en"]["CTLD.lua ERROR: Can't find trigger called %1"] = nil +ctld.i18n["en"]["CTLD.lua ERROR: Can't find zone called %1"] = nil +ctld.i18n["en"]["CTLD.lua ERROR: Can't find zone or ship called %1"] = nil +ctld.i18n["en"]["CTLD.lua ERROR: Can't find crate with weight %1"] = nil + +--- runtime messages +ctld.i18n["en"]["You are not close enough to friendly logistics to get a crate!"] = nil +ctld.i18n["en"]["No more JTAC Crates Left!"] = nil +ctld.i18n["en"]["Sorry you must wait %1 seconds before you can get another crate"] = nil +ctld.i18n["en"]["A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock "] = nil +ctld.i18n["en"]["%1 fast-ropped troops from %2 into combat"] = nil +ctld.i18n["en"]["%1 dropped troops from %2 into combat"] = nil +ctld.i18n["en"]["%1 fast-ropped troops from %2 into %3"] = nil +ctld.i18n["en"]["%1 dropped troops from %2 into %3"] = nil +ctld.i18n["en"]["Too high or too fast to drop troops into combat! Hover below %1 feet or land."] = nil +ctld.i18n["en"]["%1 dropped vehicles from %2 into combat"] = nil +ctld.i18n["en"]["%1 loaded troops into %2"] = nil +ctld.i18n["en"]["%1 loaded %2 vehicles into %3"] = nil +ctld.i18n["en"]["%1 delivered a FOB Crate"] = nil +ctld.i18n["en"]["Delivered FOB Crate 60m at 6'oclock to you"] = nil +ctld.i18n["en"]["FOB Crate dropped back to base"] = nil +ctld.i18n["en"]["FOB Crate Loaded"] = nil +ctld.i18n["en"]["%1 loaded a FOB Crate ready for delivery!"] = nil +ctld.i18n["en"]["FOB Crate Loaded"] = nil +ctld.i18n["en"]["%1 loaded a FOB Crate ready for delivery!"] = nil +ctld.i18n["en"]["There are no friendly logistic units nearby to load a FOB crate from!"] = nil +ctld.i18n["en"]["You already have troops onboard."] = nil +ctld.i18n["en"]["You already have vehicles onboard."] = nil +ctld.i18n["en"]["This area has no more reinforcements available!"] = nil +ctld.i18n["en"]["You are not in a pickup zone and no one is nearby to extract"] = nil +ctld.i18n["en"]["You are not in a pickup zone"] = nil +ctld.i18n["en"]["No one to unload"] = nil +ctld.i18n["en"]["Dropped troops back to base"] = nil +ctld.i18n["en"]["Dropped vehicles back to base"] = nil +ctld.i18n["en"]["You already have troops onboard."] = nil +ctld.i18n["en"]["You already have vehicles onboard."] = nil +ctld.i18n["en"]["Sorry - The group of %1 is too large to fit. \n\nLimit is %2 for %3"] = nil +ctld.i18n["en"]["%1 extracted troops in %2 from combat"] = nil +ctld.i18n["en"]["No extractable troops nearby!"] = nil +ctld.i18n["en"]["%1 extracted vehicles in %2 from combat"] = nil +ctld.i18n["en"]["No extractable vehicles nearby!"] = nil +ctld.i18n["en"]["%1 troops onboard (%2 kg)\n"] = nil +ctld.i18n["en"]["%1 vehicles onboard (%2)\n"] = nil +ctld.i18n["en"]["1 FOB Crate oboard (%1 kg)\n"] = nil +ctld.i18n["en"]["%1 crate onboard (%2 kg)\n"] = nil +ctld.i18n["en"]["Total weight of cargo : %1 kg\n"] = nil +ctld.i18n["en"]["No cargo."] = nil +ctld.i18n["en"]["Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!"] = nil +ctld.i18n["en"]["Loaded %1 crate!"] = nil +ctld.i18n["en"]["Too low to hook %1 crate.\n\nHold hover for %2 seconds"] = nil +ctld.i18n["en"]["Too high to hook %1 crate.\n\nHold hover for %2 seconds"] = nil +ctld.i18n["en"]["You must land before you can load a crate!"] = nil +ctld.i18n["en"]["Loaded %1 crate!"] = nil +ctld.i18n["en"]["No Crates within 50m to load!"] = nil +ctld.i18n["en"]["Maximum number of crates are on board!"] = nil +ctld.i18n["en"]["%1\n%2 crate - kg %3 - %4 m - %5 o'clock"] = nil +ctld.i18n["en"]["FOB Crate - %1 m - %2 o'clock\n"] = nil +ctld.i18n["en"]["No Nearby Crates"] = nil +ctld.i18n["en"]["Nearby Crates:\n%1"] = nil +ctld.i18n["en"]["Nearby FOB Crates (Not Slingloadable):\n%1"] = nil +ctld.i18n["en"]["FOB Positions:"] = nil +ctld.i18n["en"]["%1\nFOB @ %2"] = nil +ctld.i18n["en"]["Sorry, there are no active FOBs!"] = nil +ctld.i18n["en"]["You can't unpack that here! Take it to where it's needed!"] = nil +ctld.i18n["en"]["Sorry you must move this crate before you unpack it!"] = nil +ctld.i18n["en"]["%1 successfully deployed %2 to the field"] = nil +ctld.i18n["en"]["No friendly crates close enough to unpack, or crate too close to aircraft."] = nil +ctld.i18n["en"]["You can't unpack that here! Take it to where it's needed!"] = nil +ctld.i18n["en"]["Finished building FOB! Crates and Troops can now be picked up."] = nil +ctld.i18n["en"]["Finished building FOB! Crates can now be picked up."] = nil +ctld.i18n["en"]["%1 started building FOB using %2 FOB crates, it will be finished in %3 seconds.\nPosition marked with smoke."] = nil +ctld.i18n["en"]["Cannot build FOB!\n\nIt requires %1 Large FOB crates ( 3 small FOB crates equal 1 large FOB Crate) and there are the equivalent of %2 large FOB crates nearby\n\nOr the crates are not within 750m of each other"] = nil +ctld.i18n["en"]["You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate or land and use F10 Crate Commands."] = nil +ctld.i18n["en"]["You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate."] = nil +ctld.i18n["en"]["You are not currently transporting any crates. \n\nTo Pickup a crate, land and use F10 Crate Commands to load one."] = nil +ctld.i18n["en"]["%1 crate has been safely unhooked and is at your %2 o'clock"] = nil +ctld.i18n["en"]["%1 crate has been safely dropped below you"] = nil +ctld.i18n["en"]["You were too high! The crate has been destroyed"] = nil +ctld.i18n["en"]["Radio Beacons:\n%1"] = nil +ctld.i18n["en"]["No Active Radio Beacons"] = nil +ctld.i18n["en"]["%1 deployed a Radio Beacon.\n\n%2"] = nil +ctld.i18n["en"]["You need to land before you can deploy a Radio Beacon!"] = nil +ctld.i18n["en"]["%1 removed a Radio Beacon.\n\n%2"] = nil +ctld.i18n["en"]["No Radio Beacons within 500m."] = nil +ctld.i18n["en"]["You need to land before remove a Radio Beacon"] = nil +ctld.i18n["en"]["%1 successfully rearmed a full %2 in the field"] = nil +ctld.i18n["en"]["Missing %1\n"] = nil +ctld.i18n["en"]["Out of parts for AA Systems. Current limit is %1\n"] = nil +ctld.i18n["en"]["Cannot build %1\n%2\n\nOr the crates are not close enough together"] = nil +ctld.i18n["en"]["%1 successfully deployed a full %2 in the field. \n\nAA Active System limit is: %3\nActive: %4"] = nil +ctld.i18n["en"]["%1 successfully repaired a full %2 in the field."] = nil +ctld.i18n["en"]["Cannot repair %1. No damaged %2 within 300m"] = nil +ctld.i18n["en"]["%1 successfully deployed %2 to the field using %3 crates."] = nil +ctld.i18n["en"]["Cannot build %1!\n\nIt requires %2 crates and there are %3 \n\nOr the crates are not within 300m of each other"] = nil +ctld.i18n["en"]["%1 dropped %2 smoke."] = nil + +--- JTAC messages +ctld.i18n["en"]["JTAC Group %1 KIA!"] = nil +ctld.i18n["en"]["%1, selected target reacquired, %2"] = nil +ctld.i18n["en"][". CODE: %1. POSITION: %2"] = nil +ctld.i18n["en"]["new target, "] = nil +ctld.i18n["en"]["standing by on %1"] = nil +ctld.i18n["en"]["lasing %1"] = nil +ctld.i18n["en"][", temporarily %1"] = nil +ctld.i18n["en"]["target lost"] = nil +ctld.i18n["en"]["target destroyed"] = nil +ctld.i18n["en"][", selected %1"] = nil +ctld.i18n["en"]["%1 %2 target lost."] = nil +ctld.i18n["en"]["%1 %2 target destroyed."] = nil +ctld.i18n["en"]["JTAC STATUS: \n\n"] = nil +ctld.i18n["en"][", available on %1 %2,"] = nil +ctld.i18n["en"]["UNKNOWN"] = nil +ctld.i18n["en"][" targeting "] = nil +ctld.i18n["en"][" targeting selected unit "] = nil +ctld.i18n["en"][" attempting to find selected unit, temporarily targeting "] = nil +ctld.i18n["en"]["(Laser OFF) "] = nil +ctld.i18n["en"]["Visual On: "] = nil +ctld.i18n["en"][" searching for targets %1\n"] = nil +ctld.i18n["en"]["No Active JTACs"] = nil +ctld.i18n["en"][", targeting selected unit, %1"] = nil +ctld.i18n["en"][". CODE: %1. POSITION: %2"] = nil +ctld.i18n["en"][", target selection reset."] = nil +ctld.i18n["en"]["%1, laser and smokes enabled"] = nil +ctld.i18n["en"]["%1, laser and smokes disabled"] = nil +ctld.i18n["en"]["%1, wind and target speed laser spot compensations enabled"] = nil +ctld.i18n["en"]["%1, wind and target speed laser spot compensations disabled"] = nil +ctld.i18n["en"]["%1, WHITE smoke deployed near target"] = nil + +-- These are the string translations +-- If you want to change the text then do so here +-- If you want to add a new language then create a new block +-- following the same format as the current ones + +ctld.i18n["fr"] = {} + +--- groups names +ctld.i18n["fr"]["Standard Group"] = "Groupe standard" +ctld.i18n["fr"]["Anti Air"] = "Défense aérienne" +ctld.i18n["fr"]["Anti Tank"] = "Anti Tank" +ctld.i18n["fr"]["Mortar Squad"] = "Groupe mortier" +ctld.i18n["fr"]["JTAC Group"] = "Group JTAC" +ctld.i18n["fr"]["Single JTAC"] = "JTAC seul" +ctld.i18n["fr"]["2x - Standard Groups"] = "2x - Groupes standards" +ctld.i18n["fr"]["2x - Anti Air"] = "2x - Défenses aériennes" +ctld.i18n["fr"]["2x - Anti Tank"] = "2x - Anti Tank" +ctld.i18n["fr"]["2x - Standard Groups + 2x Mortar"] = "2x - Groupes standards + 2x Groupes mortiers" +ctld.i18n["fr"]["3x - Standard Groups"] = "3x - Groupes standards" +ctld.i18n["fr"]["3x - Anti Air"] = "3x - Défenses aériennes" +ctld.i18n["fr"]["3x - Anti Tank"] = "3x - Anti Tank" +ctld.i18n["fr"]["3x - Mortar Squad"] = "3x - Groupes mortiers" +ctld.i18n["fr"]["5x - Mortar Squad"] = "5x - Groupes mortiers" +ctld.i18n["fr"]["Mortar Squad Red"] = "Groupe mortier rouge" + +--- crates names +ctld.i18n["fr"]["Humvee - MG"] = nil +ctld.i18n["fr"]["Humvee - TOW"] = nil +ctld.i18n["fr"]["Light Tank - MRAP"] = nil +ctld.i18n["fr"]["Med Tank - LAV-25"] = nil +ctld.i18n["fr"]["Heavy Tank - Abrams"] = nil +ctld.i18n["fr"]["BTR-D"] = nil +ctld.i18n["fr"]["BRDM-2"] = nil +ctld.i18n["fr"]["Hummer - JTAC"] = nil +ctld.i18n["fr"]["M-818 Ammo Truck"] = nil +ctld.i18n["fr"]["M-978 Tanker"] = nil +ctld.i18n["fr"]["SKP-11 - JTAC"] = nil +ctld.i18n["fr"]["Ural-375 Ammo Truck"] = nil +ctld.i18n["fr"]["KAMAZ Ammo Truck"] = nil +ctld.i18n["fr"]["EWR Radar"] = nil +ctld.i18n["fr"]["FOB Crate - Small"] = nil +ctld.i18n["fr"]["MLRS"] = nil +ctld.i18n["fr"]["SpGH DANA"] = nil +ctld.i18n["fr"]["T155 Firtina"] = nil +ctld.i18n["fr"]["Howitzer"] = nil +ctld.i18n["fr"]["SPH 2S19 Msta"] = nil +ctld.i18n["fr"]["M1097 Avenger"] = nil +ctld.i18n["fr"]["M48 Chaparral"] = nil +ctld.i18n["fr"]["Roland ADS"] = nil +ctld.i18n["fr"]["Gepard AAA"] = nil +ctld.i18n["fr"]["LPWS C-RAM"] = nil +ctld.i18n["fr"]["9K33 Osa"] = nil +ctld.i18n["fr"]["9P31 Strela-1"] = nil +ctld.i18n["fr"]["9K35M Strela-10"] = nil +ctld.i18n["fr"]["9K331 Tor"] = nil +ctld.i18n["fr"]["2K22 Tunguska"] = nil +ctld.i18n["fr"]["HAWK Launcher"] = nil +ctld.i18n["fr"]["HAWK Search Radar"] = nil +ctld.i18n["fr"]["HAWK Track Radar"] = nil +ctld.i18n["fr"]["HAWK PCP"] = nil +ctld.i18n["fr"]["HAWK CWAR"] = nil +ctld.i18n["fr"]["HAWK Repair"] = nil +ctld.i18n["fr"]["NASAMS Launcher 120C"] = nil +ctld.i18n["fr"]["NASAMS Search/Track Radar"] = nil +ctld.i18n["fr"]["NASAMS Command Post"] = nil +ctld.i18n["fr"]["NASAMS Repair"] = nil +ctld.i18n["fr"]["KUB Launcher"] = nil +ctld.i18n["fr"]["KUB Radar"] = nil +ctld.i18n["fr"]["KUB Repair"] = nil +ctld.i18n["fr"]["BUK Launcher"] = nil +ctld.i18n["fr"]["BUK Search Radar"] = nil +ctld.i18n["fr"]["BUK CC Radar"] = nil +ctld.i18n["fr"]["BUK Repair"] = nil +ctld.i18n["fr"]["Patriot Launcher"] = nil +ctld.i18n["fr"]["Patriot Radar"] = nil +ctld.i18n["fr"]["Patriot ECS"] = nil +ctld.i18n["fr"]["Patriot ICC"] = nil +ctld.i18n["fr"]["Patriot EPP"] = nil +ctld.i18n["fr"]["Patriot AMG (optional)"] = nil +ctld.i18n["fr"]["Patriot Repair"] = nil +ctld.i18n["fr"]["S-300 Grumble TEL C"] = nil +ctld.i18n["fr"]["S-300 Grumble Flap Lid-A TR"] = nil +ctld.i18n["fr"]["S-300 Grumble Clam Shell SR"] = nil +ctld.i18n["fr"]["S-300 Grumble Big Bird SR"] = nil +ctld.i18n["fr"]["S-300 Grumble C2"] = nil +ctld.i18n["fr"]["S-300 Repair"] = nil + +--- mission design error messages +ctld.i18n["fr"]["CTLD.lua ERROR: Can't find trigger called %1"] = nil +ctld.i18n["fr"]["CTLD.lua ERROR: Can't find zone called %1"] = nil +ctld.i18n["fr"]["CTLD.lua ERROR: Can't find zone or ship called %1"] = nil +ctld.i18n["fr"]["CTLD.lua ERROR: Can't find crate with weight %1"] = nil + +--- runtime messages +ctld.i18n["fr"]["You are not close enough to friendly logistics to get a crate!"] = nil +ctld.i18n["fr"]["No more JTAC Crates Left!"] = nil +ctld.i18n["fr"]["Sorry you must wait %1 seconds before you can get another crate"] = nil +ctld.i18n["fr"]["A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock "] = nil +ctld.i18n["fr"]["%1 fast-ropped troops from %2 into combat"] = nil +ctld.i18n["fr"]["%1 dropped troops from %2 into combat"] = nil +ctld.i18n["fr"]["%1 fast-ropped troops from %2 into %3"] = nil +ctld.i18n["fr"]["%1 dropped troops from %2 into %3"] = nil +ctld.i18n["fr"]["Too high or too fast to drop troops into combat! Hover below %1 feet or land."] = nil +ctld.i18n["fr"]["%1 dropped vehicles from %2 into combat"] = nil +ctld.i18n["fr"]["%1 loaded troops into %2"] = nil +ctld.i18n["fr"]["%1 loaded %2 vehicles into %3"] = nil +ctld.i18n["fr"]["%1 delivered a FOB Crate"] = nil +ctld.i18n["fr"]["Delivered FOB Crate 60m at 6'oclock to you"] = nil +ctld.i18n["fr"]["FOB Crate dropped back to base"] = nil +ctld.i18n["fr"]["FOB Crate Loaded"] = nil +ctld.i18n["fr"]["%1 loaded a FOB Crate ready for delivery!"] = nil +ctld.i18n["fr"]["FOB Crate Loaded"] = nil +ctld.i18n["fr"]["%1 loaded a FOB Crate ready for delivery!"] = nil +ctld.i18n["fr"]["There are no friendly logistic units nearby to load a FOB crate from!"] = nil +ctld.i18n["fr"]["You already have troops onboard."] = nil +ctld.i18n["fr"]["You already have vehicles onboard."] = nil +ctld.i18n["fr"]["This area has no more reinforcements available!"] = nil +ctld.i18n["fr"]["You are not in a pickup zone and no one is nearby to extract"] = nil +ctld.i18n["fr"]["You are not in a pickup zone"] = nil +ctld.i18n["fr"]["No one to unload"] = nil +ctld.i18n["fr"]["Dropped troops back to base"] = nil +ctld.i18n["fr"]["Dropped vehicles back to base"] = nil +ctld.i18n["fr"]["You already have troops onboard."] = nil +ctld.i18n["fr"]["You already have vehicles onboard."] = nil +ctld.i18n["fr"]["Sorry - The group of %1 is too large to fit. \n\nLimit is %2 for %3"] = nil +ctld.i18n["fr"]["%1 extracted troops in %2 from combat"] = nil +ctld.i18n["fr"]["No extractable troops nearby!"] = nil +ctld.i18n["fr"]["%1 extracted vehicles in %2 from combat"] = nil +ctld.i18n["fr"]["No extractable vehicles nearby!"] = nil +ctld.i18n["fr"]["%1 troops onboard (%2 kg)\n"] = nil +ctld.i18n["fr"]["%1 vehicles onboard (%2)\n"] = nil +ctld.i18n["fr"]["1 FOB Crate oboard (%1 kg)\n"] = nil +ctld.i18n["fr"]["%1 crate onboard (%2 kg)\n"] = nil +ctld.i18n["fr"]["Total weight of cargo : %1 kg\n"] = nil +ctld.i18n["fr"]["No cargo."] = nil +ctld.i18n["fr"]["Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!"] = nil +ctld.i18n["fr"]["Loaded %1 crate!"] = nil +ctld.i18n["fr"]["Too low to hook %1 crate.\n\nHold hover for %2 seconds"] = nil +ctld.i18n["fr"]["Too high to hook %1 crate.\n\nHold hover for %2 seconds"] = nil +ctld.i18n["fr"]["You must land before you can load a crate!"] = nil +ctld.i18n["fr"]["Loaded %1 crate!"] = nil +ctld.i18n["fr"]["No Crates within 50m to load!"] = nil +ctld.i18n["fr"]["Maximum number of crates are on board!"] = nil +ctld.i18n["fr"]["%1\n%2 crate - kg %3 - %4 m - %5 o'clock"] = nil +ctld.i18n["fr"]["FOB Crate - %1 m - %2 o'clock\n"] = nil +ctld.i18n["fr"]["No Nearby Crates"] = nil +ctld.i18n["fr"]["Nearby Crates:\n%1"] = nil +ctld.i18n["fr"]["Nearby FOB Crates (Not Slingloadable):\n%1"] = nil +ctld.i18n["fr"]["FOB Positions:"] = nil +ctld.i18n["fr"]["%1\nFOB @ %2"] = nil +ctld.i18n["fr"]["Sorry, there are no active FOBs!"] = nil +ctld.i18n["fr"]["You can't unpack that here! Take it to where it's needed!"] = nil +ctld.i18n["fr"]["Sorry you must move this crate before you unpack it!"] = nil +ctld.i18n["fr"]["%1 successfully deployed %2 to the field"] = nil +ctld.i18n["fr"]["No friendly crates close enough to unpack, or crate too close to aircraft."] = nil +ctld.i18n["fr"]["You can't unpack that here! Take it to where it's needed!"] = nil +ctld.i18n["fr"]["Finished building FOB! Crates and Troops can now be picked up."] = nil +ctld.i18n["fr"]["Finished building FOB! Crates can now be picked up."] = nil +ctld.i18n["fr"]["%1 started building FOB using %2 FOB crates, it will be finished in %3 seconds.\nPosition marked with smoke."] = nil +ctld.i18n["fr"]["Cannot build FOB!\n\nIt requires %1 Large FOB crates ( 3 small FOB crates equal 1 large FOB Crate) and there are the equivalent of %2 large FOB crates nearby\n\nOr the crates are not within 750m of each other"] = nil +ctld.i18n["fr"]["You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate or land and use F10 Crate Commands."] = nil +ctld.i18n["fr"]["You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate."] = nil +ctld.i18n["fr"]["You are not currently transporting any crates. \n\nTo Pickup a crate, land and use F10 Crate Commands to load one."] = nil +ctld.i18n["fr"]["%1 crate has been safely unhooked and is at your %2 o'clock"] = nil +ctld.i18n["fr"]["%1 crate has been safely dropped below you"] = nil +ctld.i18n["fr"]["You were too high! The crate has been destroyed"] = nil +ctld.i18n["fr"]["Radio Beacons:\n%1"] = nil +ctld.i18n["fr"]["No Active Radio Beacons"] = nil +ctld.i18n["fr"]["%1 deployed a Radio Beacon.\n\n%2"] = nil +ctld.i18n["fr"]["You need to land before you can deploy a Radio Beacon!"] = nil +ctld.i18n["fr"]["%1 removed a Radio Beacon.\n\n%2"] = nil +ctld.i18n["fr"]["No Radio Beacons within 500m."] = nil +ctld.i18n["fr"]["You need to land before remove a Radio Beacon"] = nil +ctld.i18n["fr"]["%1 successfully rearmed a full %2 in the field"] = nil +ctld.i18n["fr"]["Missing %1\n"] = nil +ctld.i18n["fr"]["Out of parts for AA Systems. Current limit is %1\n"] = nil +ctld.i18n["fr"]["Cannot build %1\n%2\n\nOr the crates are not close enough together"] = nil +ctld.i18n["fr"]["%1 successfully deployed a full %2 in the field. \n\nAA Active System limit is: %3\nActive: %4"] = nil +ctld.i18n["fr"]["%1 successfully repaired a full %2 in the field."] = nil +ctld.i18n["fr"]["Cannot repair %1. No damaged %2 within 300m"] = nil +ctld.i18n["fr"]["%1 successfully deployed %2 to the field using %3 crates."] = nil +ctld.i18n["fr"]["Cannot build %1!\n\nIt requires %2 crates and there are %3 \n\nOr the crates are not within 300m of each other"] = nil +ctld.i18n["fr"]["%1 dropped %2 smoke."] = nil + +--- JTAC messages +ctld.i18n["fr"]["JTAC Group %1 KIA!"] = nil +ctld.i18n["fr"]["%1, selected target reacquired, %2"] = nil +ctld.i18n["fr"][". CODE: %1. POSITION: %2"] = nil +ctld.i18n["fr"]["new target, "] = nil +ctld.i18n["fr"]["standing by on %1"] = nil +ctld.i18n["fr"]["lasing %1"] = nil +ctld.i18n["fr"][", temporarily %1"] = nil +ctld.i18n["fr"]["target lost"] = nil +ctld.i18n["fr"]["target destroyed"] = nil +ctld.i18n["fr"][", selected %1"] = nil +ctld.i18n["fr"]["%1 %2 target lost."] = nil +ctld.i18n["fr"]["%1 %2 target destroyed."] = nil +ctld.i18n["fr"]["JTAC STATUS: \n\n"] = nil +ctld.i18n["fr"][", available on %1 %2,"] = nil +ctld.i18n["fr"]["UNKNOWN"] = nil +ctld.i18n["fr"][" targeting "] = nil +ctld.i18n["fr"][" targeting selected unit "] = nil +ctld.i18n["fr"][" attempting to find selected unit, temporarily targeting "] = nil +ctld.i18n["fr"]["(Laser OFF) "] = nil +ctld.i18n["fr"]["Visual On: "] = nil +ctld.i18n["fr"][" searching for targets %1\n"] = nil +ctld.i18n["fr"]["No Active JTACs"] = nil +ctld.i18n["fr"][", targeting selected unit, %1"] = nil +ctld.i18n["fr"][". CODE: %1. POSITION: %2"] = nil +ctld.i18n["fr"][", target selection reset."] = nil +ctld.i18n["fr"]["%1, laser and smokes enabled"] = nil +ctld.i18n["fr"]["%1, laser and smokes disabled"] = nil +ctld.i18n["fr"]["%1, wind and target speed laser spot compensations enabled"] = nil +ctld.i18n["fr"]["%1, wind and target speed laser spot compensations disabled"] = nil +ctld.i18n["fr"]["%1, WHITE smoke deployed near target"] = nil + +--- Translates a string (text) with parameters (parameters) to the language defined in ctld.i18n_lang +---@param text string The text to translate, with the parameters as %1, %2, etc. (all strings!!!!) +---@param ... any (list) The parameters to replace in the text, in order (all paremeters will be converted to string) +---@return string the translated and formatted text +function ctld.i18n_translate(text, ...) + local function p(o, level) + local MAX_LEVEL = 20 + if level == nil then level = 0 end + if level > MAX_LEVEL then + return "" + end + local text = "" + if (type(o) == "table") then + text = "\n" + for key,value in pairs(o) do + for i=0, level do + text = text .. " " + end + text = text .. ".".. key.."="..p(value, level+1) .. "\n" + end + elseif (type(o) == "function") then + text = "[function]" + elseif (type(o) == "boolean") then + if o == true then + text = "[true]" + else + text = "[false]" + end + else + if o == nil then + text = "[nil]" + else + text = tostring(o) + end + end + return text + end + local function formatText(text, ...) + if not text then + return "" + end + if type(text) ~= 'string' then + text = p(text) + else + local args = ... + if args and args.n and args.n > 0 then + local pArgs = {} + for i=1,args.n do + pArgs[i] = p(args[i]) + end + text = text:format(unpack(pArgs)) + end + end + local fName = nil + local cLine = nil + if debug and debug.getinfo then + local dInfo = debug.getinfo(3) + fName = dInfo.name + cLine = dInfo.currentline + end + if fName and cLine then + return fName .. '|' .. cLine .. ': ' .. text + elseif cLine then + return cLine .. ': ' .. text + else + return ' ' .. text + end + end + local function logTrace(message, ...) + message = formatText(message, arg) + env.info(" T - " .. ctld.Id .. message) + end + + logTrace("ctld.i18n_translate(lang=%s, text=%s", p(ctld.i18n_lang), p(text)) + local _text = ctld.i18n[ctld.i18n_lang][text] + logTrace("_text=%s", p(_text)) + + -- default to english + if _text == nil then + _text = ctld.i18n["en"][text] + end + + -- default to the provided text + if _text == nil then + _text = text + end + + if arg and arg.n and arg.n > 0 then + local _args = {} + for i=1,arg.n do + _args[i] = p(arg[i]) + end + for i = 1, #_args do + _text = string.gsub(_text, "%%" .. i, _args[i]) + end + end + + logTrace("returning %s", p(_text)) + return _text +end + -- ************************************************************************ -- ********************* USER CONFIGURATION ****************************** -- ************************************************************************ @@ -70,7 +611,7 @@ ctld.maximumMoveDistance = 2000 -- max distance for troops to move from drop poi ctld.minimumDeployDistance = 1000 -- minimum distance from a friendly pickup zone where you can deploy a crate -ctld.numberOfTroops = 10 -- default number of troops to load on a transport heli or C-130 +ctld.numberOfTroops = 10 -- default number of troops to load on a transport heli or C-130 -- also works as maximum size of group that'll fit into a helicopter unless overridden ctld.enableFastRopeInsertion = true -- allows you to drop troops by fast rope ctld.fastRopeMaximumHeight = 18.28 -- in meters which is 60 ft max fast rope (not rappell) safe height @@ -261,7 +802,7 @@ ctld.aircraftTypeTable = { --"SK-60", --"UH-60L", --"T-45", - + --%%%%% CHOPPERS %%%%% --"Ka-50", --"Ka-50_3", @@ -273,7 +814,7 @@ ctld.aircraftTypeTable = { --"SA342Minigun", "UH-1H", "CH-47Fbl1", - + --%%%%% AIRCRAFTS %%%%% --"C-101EB", --"C-101CC", @@ -676,22 +1217,22 @@ ctld.JTAC_WEIGHT = 15 -- kg -- You can also add an optional coalition side to limit the group to one side -- for the side - 2 is BLUE and 1 is RED ctld.loadableGroups = { - {name = "Standard Group", inf = 6, mg = 2, at = 2 }, -- will make a loadable group with 6 infantry, 2 MGs and 2 anti-tank for both coalitions - {name = "Anti Air", inf = 2, aa = 3 }, - {name = "Anti Tank", inf = 2, at = 6 }, - {name = "Mortar Squad", mortar = 6 }, - {name = "JTAC Group", inf = 4, jtac = 1 }, -- will make a loadable group with 4 infantry and a JTAC soldier for both coalitions - {name = "Single JTAC", jtac = 1 }, -- will make a loadable group witha single JTAC soldier for both coalitions - {name = "2x - Standard Groups", inf = 12, mg = 4, at = 4 }, - {name = "2x - Anti Air", inf = 4, aa = 6 }, - {name = "2x - Anti Tank", inf = 4, at = 12 }, - {name = "2x - Standard Groups + 2x Mortar", inf = 12, mg = 4, at = 4, mortar = 12 }, - {name = "3x - Standard Groups", inf = 18, mg = 6, at = 6 }, - {name = "3x - Anti Air", inf = 6, aa = 9 }, - {name = "3x - Anti Tank", inf = 6, at = 18 }, - {name = "3x - Mortar Squad", mortar = 18}, - {name = "5x - Mortar Squad", mortar = 30}, - -- {name = "Mortar Squad Red", inf = 2, mortar = 5, side =1 }, --would make a group loadable by RED only + {name = ctld.i18n_translate("Standard Group"), inf = 6, mg = 2, at = 2 }, -- will make a loadable group with 6 infantry, 2 MGs and 2 anti-tank for both coalitions + {name = ctld.i18n_translate("Anti Air"), inf = 2, aa = 3 }, + {name = ctld.i18n_translate("Anti Tank"), inf = 2, at = 6 }, + {name = ctld.i18n_translate("Mortar Squad"), mortar = 6 }, + {name = ctld.i18n_translate("JTAC Group"), inf = 4, jtac = 1 }, -- will make a loadable group with 4 infantry and a JTAC soldier for both coalitions + {name = ctld.i18n_translate("Single JTAC"), jtac = 1 }, -- will make a loadable group witha single JTAC soldier for both coalitions + {name = ctld.i18n_translate("2x - Standard Groups"), inf = 12, mg = 4, at = 4 }, + {name = ctld.i18n_translate("2x - Anti Air"), inf = 4, aa = 6 }, + {name = ctld.i18n_translate("2x - Anti Tank"), inf = 4, at = 12 }, + {name = ctld.i18n_translate("2x - Standard Groups + 2x Mortar"), inf = 12, mg = 4, at = 4, mortar = 12 }, + {name = ctld.i18n_translate("3x - Standard Groups"), inf = 18, mg = 6, at = 6 }, + {name = ctld.i18n_translate("3x - Anti Air"), inf = 6, aa = 9 }, + {name = ctld.i18n_translate("3x - Anti Tank"), inf = 6, at = 18 }, + {name = ctld.i18n_translate("3x - Mortar Squad"), mortar = 18}, + {name = ctld.i18n_translate("5x - Mortar Squad"), mortar = 30}, + -- {name = ctld.i18n_translate("Mortar Squad Red"), inf = 2, mortar = 5, side =1 }, --would make a group loadable by RED only } -- ************** SPAWNABLE CRATES ****************** @@ -711,110 +1252,110 @@ ctld.spawnableCrates = { -- Some descriptions are filtered to determine if JTAC or not! --- BLUE - { weight = 1000.01, desc = "Humvee - MG", unit = "M1043 HMMWV Armament", side = 2 }, --careful with the names as the script matches the desc to JTAC types - { weight = 1000.02, desc = "Humvee - TOW", unit = "M1045 HMMWV TOW", side = 2, cratesRequired = 2 }, - { weight = 1000.03, desc = "Light Tank - MRAP", unit="MaxxPro_MRAP", side = 2, cratesRequired = 2 }, - { weight = 1000.04, desc = "Med Tank - LAV-25", unit="LAV-25", side = 2, cratesRequired = 3 }, - { weight = 1000.05, desc = "Heavy Tank - Abrams", unit="M1A2C_SEP_V3", side = 2, cratesRequired = 4 }, + { weight = 1000.01, desc = ctld.i18n_translate("Humvee - MG"), unit = "M1043 HMMWV Armament", side = 2 }, --careful with the names as the script matches the desc to JTAC types + { weight = 1000.02, desc = ctld.i18n_translate("Humvee - TOW"), unit = "M1045 HMMWV TOW", side = 2, cratesRequired = 2 }, + { weight = 1000.03, desc = ctld.i18n_translate("Light Tank - MRAP"), unit="MaxxPro_MRAP", side = 2, cratesRequired = 2 }, + { weight = 1000.04, desc = ctld.i18n_translate("Med Tank - LAV-25"), unit="LAV-25", side = 2, cratesRequired = 3 }, + { weight = 1000.05, desc = ctld.i18n_translate("Heavy Tank - Abrams"), unit="M1A2C_SEP_V3", side = 2, cratesRequired = 4 }, --- RED - { weight = 1000.11, desc = "BTR-D", unit = "BTR_D", side = 1 }, - { weight = 1000.12, desc = "BRDM-2", unit = "BRDM-2", side = 1 }, + { weight = 1000.11, desc = ctld.i18n_translate("BTR-D"), unit = "BTR_D", side = 1 }, + { weight = 1000.12, desc = ctld.i18n_translate("BRDM-2"), unit = "BRDM-2", side = 1 }, -- need more redfor! }, ["Support"] = { --- BLUE - { weight = 1001.01, desc = "Hummer - JTAC", unit = "Hummer", side = 2, cratesRequired = 2 }, -- used as jtac and unarmed, not on the crate list if JTAC is disabled - { weight = 1001.02, desc = "M-818 Ammo Truck", unit = "M 818", side = 2, cratesRequired = 2 }, - { weight = 1001.03, desc = "M-978 Tanker", unit = "M978 HEMTT Tanker", side = 2, cratesRequired = 2 }, + { weight = 1001.01, desc = ctld.i18n_translate("Hummer - JTAC"), unit = "Hummer", side = 2, cratesRequired = 2 }, -- used as jtac and unarmed, not on the crate list if JTAC is disabled + { weight = 1001.02, desc = ctld.i18n_translate("M-818 Ammo Truck"), unit = "M 818", side = 2, cratesRequired = 2 }, + { weight = 1001.03, desc = ctld.i18n_translate("M-978 Tanker"), unit = "M978 HEMTT Tanker", side = 2, cratesRequired = 2 }, --- RED - { weight = 1001.11, desc = "SKP-11 - JTAC", unit = "SKP-11", side = 1 }, -- used as jtac and unarmed, not on the crate list if JTAC is disabled - { weight = 1001.12, desc = "Ural-375 Ammo Truck", unit = "Ural-375", side = 1, cratesRequired = 2 }, - { weight = 1001.13, desc = "KAMAZ Ammo Truck", unit = "KAMAZ Truck", side = 1, cratesRequired = 2 }, + { weight = 1001.11, desc = ctld.i18n_translate("SKP-11 - JTAC"), unit = "SKP-11", side = 1 }, -- used as jtac and unarmed, not on the crate list if JTAC is disabled + { weight = 1001.12, desc = ctld.i18n_translate("Ural-375 Ammo Truck"), unit = "Ural-375", side = 1, cratesRequired = 2 }, + { weight = 1001.13, desc = ctld.i18n_translate("KAMAZ Ammo Truck"), unit = "KAMAZ Truck", side = 1, cratesRequired = 2 }, --- Both - { weight = 1001.21, desc = "EWR Radar", unit="FPS-117", cratesRequired = 3 }, - { weight = 1001.22, desc = "FOB Crate - Small", unit = "FOB-SMALL" }, -- Builds a FOB! - requires 3 * ctld.cratesRequiredForFOB + { weight = 1001.21, desc = ctld.i18n_translate("EWR Radar"), unit="FPS-117", cratesRequired = 3 }, + { weight = 1001.22, desc = ctld.i18n_translate("FOB Crate - Small"), unit = "FOB-SMALL" }, -- Builds a FOB! - requires 3 * ctld.cratesRequiredForFOB }, ["Artillery"] = { --- BLUE - { weight = 1002.01, desc = "MLRS", unit = "MLRS", side=2, cratesRequired = 3 }, - { weight = 1002.02, desc = "SpGH DANA", unit = "SpGH_Dana", side=2, cratesRequired = 3 }, - { weight = 1002.03, desc = "T155 Firtina", unit = "T155_Firtina", side=2, cratesRequired = 3 }, - { weight = 1002.04, desc = "Howitzer", unit = "M-109", side=2, cratesRequired = 3 }, + { weight = 1002.01, desc = ctld.i18n_translate("MLRS"), unit = "MLRS", side=2, cratesRequired = 3 }, + { weight = 1002.02, desc = ctld.i18n_translate("SpGH DANA"), unit = "SpGH_Dana", side=2, cratesRequired = 3 }, + { weight = 1002.03, desc = ctld.i18n_translate("T155 Firtina"), unit = "T155_Firtina", side=2, cratesRequired = 3 }, + { weight = 1002.04, desc = ctld.i18n_translate("Howitzer"), unit = "M-109", side=2, cratesRequired = 3 }, --- RED - { weight = 1002.11, desc = "SPH 2S19 Msta", unit = "SAU Msta", side = 1, cratesRequired = 3 }, + { weight = 1002.11, desc = ctld.i18n_translate("SPH 2S19 Msta"), unit = "SAU Msta", side = 1, cratesRequired = 3 }, }, ["SAM short range"] = { --- BLUE - { weight = 1003.01, desc = "M1097 Avenger", unit = "M1097 Avenger", side = 2, cratesRequired = 3 }, - { weight = 1003.02, desc = "M48 Chaparral", unit = "M48 Chaparral", side = 2, cratesRequired = 2 }, - { weight = 1003.03, desc = "Roland ADS", unit = "Roland ADS", side = 2, cratesRequired = 3 }, - { weight = 1003.04, desc = "Gepard AAA", unit = "Gepard", side = 2, cratesRequired = 3 }, - { weight = 1003.05, desc = "LPWS C-RAM", unit = "HEMTT_C-RAM_Phalanx", side = 2, cratesRequired = 3 }, + { weight = 1003.01, desc = ctld.i18n_translate("M1097 Avenger"), unit = "M1097 Avenger", side = 2, cratesRequired = 3 }, + { weight = 1003.02, desc = ctld.i18n_translate("M48 Chaparral"), unit = "M48 Chaparral", side = 2, cratesRequired = 2 }, + { weight = 1003.03, desc = ctld.i18n_translate("Roland ADS"), unit = "Roland ADS", side = 2, cratesRequired = 3 }, + { weight = 1003.04, desc = ctld.i18n_translate("Gepard AAA"), unit = "Gepard", side = 2, cratesRequired = 3 }, + { weight = 1003.05, desc = ctld.i18n_translate("LPWS C-RAM"), unit = "HEMTT_C-RAM_Phalanx", side = 2, cratesRequired = 3 }, --- RED - { weight = 1003.11, desc = "9K33 Osa", unit = "Osa 9A33 ln", side = 1, cratesRequired = 3 }, - { weight = 1003.12, desc = "9P31 Strela-1", unit = "Strela-1 9P31", side = 1, cratesRequired = 3 }, - { weight = 1003.13, desc = "9K35M Strela-10", unit = "Strela-10M3", side = 1, cratesRequired = 3 }, - { weight = 1003.14, desc = "9K331 Tor", unit = "Tor 9A331", side = 1, cratesRequired = 3 }, - { weight = 1003.15, desc = "2K22 Tunguska", unit = "2S6 Tunguska", side = 1, cratesRequired = 3 }, + { weight = 1003.11, desc = ctld.i18n_translate("9K33 Osa"), unit = "Osa 9A33 ln", side = 1, cratesRequired = 3 }, + { weight = 1003.12, desc = ctld.i18n_translate("9P31 Strela-1"), unit = "Strela-1 9P31", side = 1, cratesRequired = 3 }, + { weight = 1003.13, desc = ctld.i18n_translate("9K35M Strela-10"), unit = "Strela-10M3", side = 1, cratesRequired = 3 }, + { weight = 1003.14, desc = ctld.i18n_translate("9K331 Tor"), unit = "Tor 9A331", side = 1, cratesRequired = 3 }, + { weight = 1003.15, desc = ctld.i18n_translate("2K22 Tunguska"), unit = "2S6 Tunguska", side = 1, cratesRequired = 3 }, }, ["SAM mid range"] = { --- BLUE -- HAWK System - { weight = 1004.01, desc = "HAWK Launcher", unit = "Hawk ln", side = 2}, - { weight = 1004.02, desc = "HAWK Search Radar", unit = "Hawk sr", side = 2 }, - { weight = 1004.03, desc = "HAWK Track Radar", unit = "Hawk tr", side = 2 }, - { weight = 1004.04, desc = "HAWK PCP", unit = "Hawk pcp" , side = 2 }, - { weight = 1004.05, desc = "HAWK CWAR", unit = "Hawk cwar" , side = 2 }, - { weight = 1004.06, desc = "HAWK Repair", unit = "HAWK Repair" , side = 2 }, + { weight = 1004.01, desc = ctld.i18n_translate("HAWK Launcher"), unit = "Hawk ln", side = 2}, + { weight = 1004.02, desc = ctld.i18n_translate("HAWK Search Radar"), unit = "Hawk sr", side = 2 }, + { weight = 1004.03, desc = ctld.i18n_translate("HAWK Track Radar"), unit = "Hawk tr", side = 2 }, + { weight = 1004.04, desc = ctld.i18n_translate("HAWK PCP"), unit = "Hawk pcp" , side = 2 }, + { weight = 1004.05, desc = ctld.i18n_translate("HAWK CWAR"), unit = "Hawk cwar" , side = 2 }, + { weight = 1004.06, desc = ctld.i18n_translate("HAWK Repair"), unit = "HAWK Repair" , side = 2 }, -- End of HAWK - + -- NASAMS Sysyem - { weight = 1004.11, desc = "NASAMS Launcher 120C", unit = "NASAMS_LN_C", side = 2}, - { weight = 1004.12, desc = "NASAMS Search/Track Radar", unit = "NASAMS_Radar_MPQ64F1", side = 2 }, - { weight = 1004.13, desc = "NASAMS Command Post", unit = "NASAMS_Command_Post", side = 2 }, - { weight = 1004.14, desc = "NASAMS Repair", unit = "NASAMS Repair", side = 2 }, + { weight = 1004.11, desc = ctld.i18n_translate("NASAMS Launcher 120C"), unit = "NASAMS_LN_C", side = 2}, + { weight = 1004.12, desc = ctld.i18n_translate("NASAMS Search/Track Radar"), unit = "NASAMS_Radar_MPQ64F1", side = 2 }, + { weight = 1004.13, desc = ctld.i18n_translate("NASAMS Command Post"), unit = "NASAMS_Command_Post", side = 2 }, + { weight = 1004.14, desc = ctld.i18n_translate("NASAMS Repair"), unit = "NASAMS Repair", side = 2 }, -- End of NASAMS --- RED -- KUB SYSTEM - { weight = 1004.21, desc = "KUB Launcher", unit = "Kub 2P25 ln", side = 1}, - { weight = 1004.22, desc = "KUB Radar", unit = "Kub 1S91 str", side = 1 }, - { weight = 1004.23, desc = "KUB Repair", unit = "KUB Repair", side = 1}, + { weight = 1004.21, desc = ctld.i18n_translate("KUB Launcher"), unit = "Kub 2P25 ln", side = 1}, + { weight = 1004.22, desc = ctld.i18n_translate("KUB Radar"), unit = "Kub 1S91 str", side = 1 }, + { weight = 1004.23, desc = ctld.i18n_translate("KUB Repair"), unit = "KUB Repair", side = 1}, -- End of KUB -- BUK System - { weight = 1004.31, desc = "BUK Launcher", unit = "SA-11 Buk LN 9A310M1", side = 1}, - { weight = 1004.32, desc = "BUK Search Radar", unit = "SA-11 Buk SR 9S18M1", side = 1}, - { weight = 1004.33, desc = "BUK CC Radar", unit = "SA-11 Buk CC 9S470M1", side = 1}, - { weight = 1004.34, desc = "BUK Repair", unit = "BUK Repair", side = 1}, + { weight = 1004.31, desc = ctld.i18n_translate("BUK Launcher"), unit = "SA-11 Buk LN 9A310M1", side = 1}, + { weight = 1004.32, desc = ctld.i18n_translate("BUK Search Radar"), unit = "SA-11 Buk SR 9S18M1", side = 1}, + { weight = 1004.33, desc = ctld.i18n_translate("BUK CC Radar"), unit = "SA-11 Buk CC 9S470M1", side = 1}, + { weight = 1004.34, desc = ctld.i18n_translate("BUK Repair"), unit = "BUK Repair", side = 1}, -- END of BUK }, ["SAM long range"] = { --- BLUE -- Patriot System - { weight = 1005.01, desc = "Patriot Launcher", unit = "Patriot ln", side = 2 }, - { weight = 1005.02, desc = "Patriot Radar", unit = "Patriot str" , side = 2 }, - { weight = 1005.03, desc = "Patriot ECS", unit = "Patriot ECS", side = 2 }, - -- { weight = 1005.04, desc = "Patriot ICC", unit = "Patriot cp", side = 2 }, - -- { weight = 1005.05, desc = "Patriot EPP", unit = "Patriot EPP", side = 2 }, - { weight = 1005.06, desc = "Patriot AMG (optional)", unit = "Patriot AMG" , side = 2 }, - { weight = 1005.07, desc = "Patriot Repair", unit = "Patriot Repair" , side = 2 }, + { weight = 1005.01, desc = ctld.i18n_translate("Patriot Launcher"), unit = "Patriot ln", side = 2 }, + { weight = 1005.02, desc = ctld.i18n_translate("Patriot Radar"), unit = "Patriot str" , side = 2 }, + { weight = 1005.03, desc = ctld.i18n_translate("Patriot ECS"), unit = "Patriot ECS", side = 2 }, + -- { weight = 1005.04, desc = ctld.i18n_translate("Patriot ICC"), unit = "Patriot cp", side = 2 }, + -- { weight = 1005.05, desc = ctld.i18n_translate("Patriot EPP"), unit = "Patriot EPP", side = 2 }, + { weight = 1005.06, desc = ctld.i18n_translate("Patriot AMG (optional)"), unit = "Patriot AMG" , side = 2 }, + { weight = 1005.07, desc = ctld.i18n_translate("Patriot Repair"), unit = "Patriot Repair" , side = 2 }, -- End of Patriot -- S-300 SYSTEM - { weight = 1005.11, desc = "S-300 Grumble TEL C", unit = "S-300PS 5P85C ln", side = 1 }, - { weight = 1005.12, desc = "S-300 Grumble Flap Lid-A TR", unit = "S-300PS 40B6M tr", side = 1 }, - { weight = 1005.13, desc = "S-300 Grumble Clam Shell SR", unit = "S-300PS 40B6MD sr", side = 1 }, - { weight = 1005.14, desc = "S-300 Grumble Big Bird SR", unit = "S-300PS 64H6E sr", side = 1 }, - { weight = 1005.15, desc = "S-300 Grumble C2", unit = "S-300PS 54K6 cp", side = 1 }, - { weight = 1005.16, desc = "S-300 Repair", unit = "S-300 Repair", side = 1 }, + { weight = 1005.11, desc = ctld.i18n_translate("S-300 Grumble TEL C"), unit = "S-300PS 5P85C ln", side = 1 }, + { weight = 1005.12, desc = ctld.i18n_translate("S-300 Grumble Flap Lid-A TR"), unit = "S-300PS 40B6M tr", side = 1 }, + { weight = 1005.13, desc = ctld.i18n_translate("S-300 Grumble Clam Shell SR"), unit = "S-300PS 40B6MD sr", side = 1 }, + { weight = 1005.14, desc = ctld.i18n_translate("S-300 Grumble Big Bird SR"), unit = "S-300PS 64H6E sr", side = 1 }, + { weight = 1005.15, desc = ctld.i18n_translate("S-300 Grumble C2"), unit = "S-300PS 54K6 cp", side = 1 }, + { weight = 1005.16, desc = ctld.i18n_translate("S-300 Repair"), unit = "S-300 Repair", side = 1 }, -- End of S-300 }, } @@ -888,7 +1429,6 @@ ctld.jtacUnitTypes = { "SKP", "Hummer" -- there are some wierd encoding issues so if you write SKP-11 it wont match as the - sign is encoded differently... } - -- *************************************************************** -- **************** Mission Editor Functions ********************* -- *************************************************************** @@ -915,7 +1455,7 @@ function ctld.spawnGroupAtTrigger(_groupSide, _number, _triggerName, _searchRadi local _spawnTrigger = trigger.misc.getZone(_triggerName) -- trigger to use as reference position if _spawnTrigger == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find trigger called " .. _triggerName, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find trigger called %1",_triggerName), 10) return end @@ -1018,7 +1558,7 @@ function ctld.cratesInZone(_zone, _flagNumber) local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zone), 10) return end @@ -1080,7 +1620,7 @@ function ctld.createExtractZone(_zone, _flagNumber, _smoke) local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zone), 10) return end @@ -1152,7 +1692,7 @@ function ctld.countDroppedGroupsInZone(_zone, _blueFlag, _redFlag) local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zone), 10) return end @@ -1199,7 +1739,7 @@ function ctld.countDroppedUnitsInZone(_zone, _blueFlag, _redFlag) local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zone), 10) return end @@ -1253,7 +1793,7 @@ function ctld.createRadioBeaconAtZone(_zone, _coalition, _batteryLife, _name) local _triggerZone = trigger.misc.getZone(_zone) -- trigger to use as reference position if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zone), 10) return end @@ -1293,7 +1833,7 @@ function ctld.activatePickupZone(_zoneName) end if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone or ship called " .. _zoneName, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone or ship called %1", _zoneName), 10) end for _, _zoneDetails in pairs(ctld.pickupZones) do @@ -1303,7 +1843,6 @@ function ctld.activatePickupZone(_zoneName) --smoke could get messy if designer keeps calling this on an active zone, check its not active first if _zoneDetails[4] == 1 then -- they might have a continuous trigger so i've hidden the warning - --trigger.action.outText("CTLD.lua ERROR: Pickup Zone already active: " .. _zoneName, 10) return end @@ -1351,20 +1890,14 @@ function ctld.deactivatePickupZone(_zoneName) end if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zoneName, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zoneName), 10) return end for _, _zoneDetails in pairs(ctld.pickupZones) do if _zoneName == _zoneDetails[1] then - -- i'd just ignore it if its already been deactivated - -- if _zoneDetails[4] == 0 then --this really needed?? - -- trigger.action.outText("CTLD.lua ERROR: Pickup Zone already deactiveated: " .. _zoneName, 10) - -- return - -- end - _zoneDetails[4] = 0 --deactivate zone end end @@ -1388,7 +1921,7 @@ function ctld.changeRemainingGroupsForPickupZone(_zoneName, _amount) end if _triggerZone == nil then - trigger.action.outText("CTLD.lua ctld.changeRemainingGroupsForPickupZone ERROR: Cant find zone called " .. _zoneName, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zoneName), 10) return end @@ -1412,7 +1945,7 @@ function ctld.activateWaypointZone(_zoneName) if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zoneName, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zoneName), 10) return end @@ -1424,7 +1957,6 @@ function ctld.activateWaypointZone(_zoneName) --smoke could get messy if designer keeps calling this on an active zone, check its not active first if _zoneDetails[3] == 1 then -- they might have a continuous trigger so i've hidden the warning - --trigger.action.outText("CTLD.lua ERROR: Pickup Zone already active: " .. _zoneName, 10) return end @@ -1460,7 +1992,7 @@ function ctld.deactivateWaypointZone(_zoneName) local _triggerZone = trigger.misc.getZone(_zoneName) if _triggerZone == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zoneName, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zoneName), 10) return end @@ -1561,14 +2093,14 @@ function ctld.spawnCrateAtZone(_side, _weight,_zone) local _spawnTrigger = trigger.misc.getZone(_zone) -- trigger to use as reference position if _spawnTrigger == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find zone called " .. _zone, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find zone called %1", _zone), 10) return end local _crateType = ctld.crateLookupTable[tostring(_weight)] if _crateType == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find crate with weight " .. _weight, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find crate with weight %1", _weight), 10) return end @@ -1607,7 +2139,7 @@ function ctld.spawnCrateAtPoint(_side, _weight, _point,_hdg) local _crateType = ctld.crateLookupTable[tostring(_weight)] if _crateType == nil then - trigger.action.outText("CTLD.lua ERROR: Cant find crate with weight " .. _weight, 10) + trigger.action.outText(ctld.i18n_translate("CTLD.lua ERROR: Can't find crate with weight %1", _weight), 10) return end @@ -1985,7 +2517,7 @@ function ctld.spawnCrate(_arguments) if ctld.inLogisticsZone(_heli) == false then - ctld.displayMessageToGroup(_heli, "You are not close enough to friendly logistics to get a crate!", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You are not close enough to friendly logistics to get a crate!"), 10) return end @@ -2010,7 +2542,7 @@ function ctld.spawnCrate(_arguments) end if _limitHit then - ctld.displayMessageToGroup(_heli, "No more JTAC Crates Left!", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No more JTAC Crates Left!"), 10) return end end @@ -2018,14 +2550,13 @@ function ctld.spawnCrate(_arguments) -- check crate spam if _heli:getPlayerName() ~= nil and ctld.crateWait[_heli:getPlayerName()] and ctld.crateWait[_heli:getPlayerName()] > timer.getTime() then - ctld.displayMessageToGroup(_heli,"Sorry you must wait "..(ctld.crateWait[_heli:getPlayerName()] - timer.getTime()).. " seconds before you can get another crate", 20) + ctld.displayMessageToGroup(_heli,ctld.i18n_translate("Sorry you must wait %1 seconds before you can get another crate", (ctld.crateWait[_heli:getPlayerName()] - timer.getTime())), 20) return end if _heli:getPlayerName() ~= nil then ctld.crateWait[_heli:getPlayerName()] = timer.getTime() + ctld.crateWaitTime end - -- trigger.action.outText("Spawn Crate".._args[1].." ".._args[2],10) local _heli = ctld.getTransportUnit(_args[1]) @@ -2033,7 +2564,7 @@ function ctld.spawnCrate(_arguments) local _point = ctld.getPointAt12Oclock(_heli, 30) local _position = "12" - + if ctld.unitDynamicCargoCapable(_heli) then _model_type = "dynamic" _point = ctld.getPointAt6Oclock(_heli, 15) @@ -2051,7 +2582,7 @@ function ctld.spawnCrate(_arguments) -- add to move table ctld.crateMove[_name] = _name - ctld.displayMessageToGroup(_heli, string.format("A %s crate weighing %.0f kg has been brought out and is at your %s o'clock ", _crateType.desc, _crateType.weight, _position), 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock ", _crateType.desc, _crateType.weight, _position), 20) else env.info("Couldn't find crate item to spawn") @@ -2207,9 +2738,9 @@ function ctld.deployTroops(_heli, _troops) ctld.adaptWeightToCargo(_heli:getName()) if ctld.inAir(_heli) then - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " fast-ropped troops from " .. _heli:getTypeName() .. " into combat", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 fast-ropped troops from %2 into combat", ctld.getPlayerNameOrType(_heli), _heli:getTypeName()), 10) else - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " dropped troops from " .. _heli:getTypeName() .. " into combat", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 dropped troops from %2 into combat", ctld.getPlayerNameOrType(_heli), _heli:getTypeName()), 10) end ctld.processCallback({unit = _heli, unloaded = _droppedTroops, action = "dropped_troops"}) @@ -2227,13 +2758,13 @@ function ctld.deployTroops(_heli, _troops) ctld.adaptWeightToCargo(_heli:getName()) if ctld.inAir(_heli) then - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " troops fast-ropped from " .. _heli:getTypeName() .. " into " .. _extractZone.name, 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 fast-ropped troops from %2 into %3", ctld.getPlayerNameOrType(_heli), _heli:getTypeName(), _extractZone.name), 10) else - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " troops dropped from " .. _heli:getTypeName() .. " into " .. _extractZone.name, 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 dropped troops from %2 into %3", ctld.getPlayerNameOrType(_heli), _heli:getTypeName(), _extractZone.name), 10) end end else - ctld.displayMessageToGroup(_heli, "Too high or too fast to drop troops into combat! Hover below " .. ctld.metersToFeet(ctld.fastRopeMaximumHeight) .. " feet or land.", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Too high or too fast to drop troops into combat! Hover below %1 feet or land.", ctld.metersToFeet(ctld.fastRopeMaximumHeight)), 10) end end @@ -2256,7 +2787,7 @@ function ctld.deployTroops(_heli, _troops) ctld.processCallback({unit = _heli, unloaded = _droppedVehicles, action = "dropped_vehicles"}) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " dropped vehicles from " .. _heli:getTypeName() .. " into combat", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 dropped vehicles from %2 into combat", ctld.getPlayerNameOrType(_heli), _heli:getTypeName()), 10) end end end @@ -2444,7 +2975,7 @@ function ctld.loadTroops(_heli, _troops, _numberOrTemplate) if _troops then _onboard.troops = ctld.generateTroopTypes(_heli:getCoalition(), _numberOrTemplate, _heli:getCountry()) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " loaded troops into " .. _heli:getTypeName(), 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 loaded troops into %2", ctld.getPlayerNameOrType(_heli), _heli:getTypeName()), 10) ctld.processCallback({unit = _heli, onboard = _onboard.troops, action = "load_troops"}) else @@ -2455,7 +2986,7 @@ function ctld.loadTroops(_heli, _troops, _numberOrTemplate) ctld.processCallback({unit = _heli, onboard = _onboard.vehicles, action = "load_vehicles"}) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " loaded " .. _count .. " vehicles into " .. _heli:getTypeName(), 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 loaded %2 vehicles into %3", ctld.getPlayerNameOrType(_heli), _count, _heli:getTypeName()), 10) end ctld.inTransitTroops[_heli:getName()] = _onboard @@ -2533,22 +3064,22 @@ function ctld.loadUnloadFOBCrate(_args) ctld.droppedFOBCratesBLUE[_name] = _name end - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " delivered a FOB Crate", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 delivered a FOB Crate", ctld.getPlayerNameOrType(_heli)), 10) - ctld.displayMessageToGroup(_heli, "Delivered FOB Crate 60m at 6'oclock to you", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Delivered FOB Crate 60m at 6'oclock to you"), 10) elseif _inZone == true and _crateOnboard == true then - ctld.displayMessageToGroup(_heli, "FOB Crate dropped back to base", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("FOB Crate dropped back to base"), 10) ctld.inTransitFOBCrates[_heli:getName()] = nil elseif _inZone == true and _crateOnboard == false then - ctld.displayMessageToGroup(_heli, "FOB Crate Loaded", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("FOB Crate Loaded"), 10) ctld.inTransitFOBCrates[_heli:getName()] = true - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " loaded a FOB Crate ready for delivery!", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 loaded a FOB Crate ready for delivery!", ctld.getPlayerNameOrType(_heli)), 10) else @@ -2558,10 +3089,10 @@ function ctld.loadUnloadFOBCrate(_args) if _nearestCrate ~= nil and _nearestCrate.dist < 150 then - ctld.displayMessageToGroup(_heli, "FOB Crate Loaded", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("FOB Crate Loaded"), 10) ctld.inTransitFOBCrates[_heli:getName()] = true - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " loaded a FOB Crate ready for delivery!", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 loaded a FOB Crate ready for delivery!", ctld.getPlayerNameOrType(_heli)), 10) if _side == 1 then ctld.droppedFOBCratesRED[_nearestCrate.crateUnit:getName()] = nil @@ -2573,7 +3104,7 @@ function ctld.loadUnloadFOBCrate(_args) _nearestCrate.crateUnit:destroy() else - ctld.displayMessageToGroup(_heli, "There are no friendly logistic units nearby to load a FOB crate from!", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("There are no friendly logistic units nearby to load a FOB crate from!"), 10) end end end @@ -2594,9 +3125,9 @@ function ctld.loadTroopsFromZone(_args) if ctld.troopsOnboard(_heli, _troops) then if _troops then - ctld.displayMessageToGroup(_heli, "You already have troops onboard.", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You already have troops onboard."), 10) else - ctld.displayMessageToGroup(_heli, "You already have vehicles onboard.", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You already have vehicles onboard."), 10) end return false @@ -2635,16 +3166,16 @@ function ctld.loadTroopsFromZone(_args) return true else - ctld.displayMessageToGroup(_heli, "This area has no more reinforcements available!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("This area has no more reinforcements available!"), 20) return false end else if _allowExtract then - ctld.displayMessageToGroup(_heli, "You are not in a pickup zone and no one is nearby to extract", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You are not in a pickup zone and no one is nearby to extract"), 10) else - ctld.displayMessageToGroup(_heli, "You are not in a pickup zone", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You are not in a pickup zone"), 10) end return false @@ -2665,7 +3196,7 @@ function ctld.unloadTroops(_args) local _zone = ctld.inPickupZone(_heli) if not ctld.troopsOnboard(_heli, _troops) then - ctld.displayMessageToGroup(_heli, "No one to unload", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No one to unload"), 10) return false else @@ -2674,14 +3205,14 @@ function ctld.unloadTroops(_args) if _zone.inZone == true then if _troops then - ctld.displayMessageToGroup(_heli, "Dropped troops back to base", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Dropped troops back to base"), 20) ctld.processCallback({unit = _heli, unloaded = ctld.inTransitTroops[_heli:getName()].troops, action = "unload_troops_zone"}) ctld.inTransitTroops[_heli:getName()].troops = nil else - ctld.displayMessageToGroup(_heli, "Dropped vehicles back to base", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Dropped vehicles back to base"), 20) ctld.processCallback({unit = _heli, unloaded = ctld.inTransitTroops[_heli:getName()].vehicles, action = "unload_vehicles_zone"}) @@ -2718,9 +3249,9 @@ function ctld.extractTroops(_args) if ctld.troopsOnboard(_heli, _troops) then if _troops then - ctld.displayMessageToGroup(_heli, "You already have troops onboard.", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You already have troops onboard."), 10) else - ctld.displayMessageToGroup(_heli, "You already have vehicles onboard.", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You already have vehicles onboard."), 10) end return false @@ -2753,7 +3284,7 @@ function ctld.extractTroops(_args) if _limit < #_extractTroops.group:getUnits() then - ctld.displayMessageToGroup(_heli, "Sorry - The group of ".._size.." is too large to fit. \n\nLimit is ".._limit.." for ".._heli:getTypeName(), 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Sorry - The group of %1 is too large to fit. \n\nLimit is %2 for %3", _size, _limit, _heli:getTypeName()), 20) return end @@ -2765,7 +3296,7 @@ function ctld.extractTroops(_args) _onboard.troops.jtac = true end - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " extracted troops in " .. _heli:getTypeName() .. " from combat", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 extracted troops in %2 from combat", ctld.getPlayerNameOrType(_heli), _heli:getTypeName()), 10) if _heli:getCoalition() == 1 then ctld.droppedTroopsRED[_extractTroops.group:getName()] = nil @@ -2781,7 +3312,7 @@ function ctld.extractTroops(_args) _extracted = true else _onboard.troops = nil - ctld.displayMessageToGroup(_heli, "No extractable troops nearby!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No extractable troops nearby!"), 20) end else @@ -2808,7 +3339,7 @@ function ctld.extractTroops(_args) ctld.droppedVehiclesBLUE[_extractVehicles.group:getName()] = nil end - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " extracted vehicles in " .. _heli:getTypeName() .. " from combat", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 extracted vehicles in %2 from combat", ctld.getPlayerNameOrType(_heli), _heli:getTypeName()), 10) ctld.processCallback({unit = _heli, extracted = _extractVehicles, action = "extract_vehicles"}) --remove @@ -2817,7 +3348,7 @@ function ctld.extractTroops(_args) else _onboard.vehicles = nil - ctld.displayMessageToGroup(_heli, "No extractable vehicles nearby!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No extractable vehicles nearby!"), 20) end end @@ -2880,7 +3411,7 @@ function ctld.getWeightOfCargo(unitName) if _inTransit then local _troops = _inTransit.troops if _troops and _troops.units then - _description = _description .. string.format("%s troops onboard (%.0f kg)\n", #_troops.units, _troops.weight) + _description = _description .. ctld.i18n_translate("%1 troops onboard (%2 kg)\n", #_troops.units, _troops.weight) _weight = _weight + _troops.weight end local _vehicles = _inTransit.vehicles @@ -2888,7 +3419,7 @@ function ctld.getWeightOfCargo(unitName) for _, _unit in pairs(_vehicles.units) do _weight = _weight + _unit.weight end - _description = _description .. string.format("%s vehicles onboard (%.0f kg)\n", #_vehicles.units, _weight) + _description = _description .. ctld.i18n_translate("%1 vehicles onboard (%2)\n", #_vehicles.units, _weight) end end end @@ -2896,7 +3427,7 @@ function ctld.getWeightOfCargo(unitName) -- add FOB crates weight if ctld.inTransitFOBCrates[unitName] then _weight = _weight + FOB_CRATE_WEIGHT - _description = _description .. string.format("1 FOB Crate oboard (%.0f kg)\n", FOB_CRATE_WEIGHT) + _description = _description .. ctld.i18n_translate("1 FOB Crate oboard (%1 kg)\n", FOB_CRATE_WEIGHT) end -- add simulated slingload crates weight @@ -2904,13 +3435,13 @@ function ctld.getWeightOfCargo(unitName) local _crate = ctld.inTransitSlingLoadCrates[unitName][i] if _crate and _crate.simulatedSlingload then _weight = _weight + _crate.weight - _description = _description .. string.format("%s crate onboard (%.0f kg)\n", _crate.desc, _crate.weight) + _description = _description .. ctld.i18n_translate("%1 crate onboard (%2 kg)\n", _crate.desc, _crate.weight) end end if _description ~= "" then - _description = _description .. string.format("Total weight of cargo : %.0f kg\n", _weight) + _description = _description .. ctld.i18n_translate("Total weight of cargo : %1 kg\n", _weight) else - _description = "No cargo." + _description = ctld.i18n_translate("No cargo.") end return _weight, _description @@ -2954,10 +3485,10 @@ function ctld.checkHoverStatus() end if _time > 0 then - ctld.displayMessageToGroup(_transUnit, "Hovering above " .. _crate.details.desc .. " crate. \n\nHold hover for " .. _time .. " seconds! \n\nIf the countdown stops you're too far away!", 10,true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!", _crate.details.desc, _time), 10,true) else ctld.hoverStatus[_name] = nil - ctld.displayMessageToGroup(_transUnit, "Loaded " .. _crate.details.desc .. " crate!", 10,true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("Loaded %1 crate!", _crate.details.desc), 10,true) --crates been moved once! ctld.crateMove[_crateUnitName] = nil @@ -2980,10 +3511,10 @@ function ctld.checkHoverStatus() break elseif _height <= ctld.minimumHoverHeight then - ctld.displayMessageToGroup(_transUnit, "Too low to hook " .. _crate.details.desc .. " crate.\n\nHold hover for " .. ctld.hoverTime .. " seconds", 5,true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("Too low to hook %1 crate.\n\nHold hover for %2 seconds", _crate.details.desc, ctld.hoverTime), 5,true) break else - ctld.displayMessageToGroup(_transUnit, "Too high to hook " .. _crate.details.desc .. " crate.\n\nHold hover for " .. ctld.hoverTime .. " seconds", 5, true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("Too high to hook %1 crate.\n\nHold hover for %2 seconds", _crate.details.desc, ctld.hoverTime), 5,true) break end end @@ -3010,7 +3541,7 @@ function ctld.loadNearbyCrate(_name) ctld.inTransitSlingLoadCrates[_name] = ctld.inTransitSlingLoadCrates[_name] or {} if ctld.inAir(_transUnit) then - ctld.displayMessageToGroup(_transUnit, "You must land before you can load a crate!", 10,true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("You must land before you can load a crate!"), 10,true) return end @@ -3020,7 +3551,7 @@ function ctld.loadNearbyCrate(_name) for _, _crate in pairs(_crates) do if _crate.dist < 50.0 then - ctld.displayMessageToGroup(_transUnit, "Loaded " .. _crate.details.desc .. " crate!", 10,true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("Loaded %1 crate!", _crate.details.desc), 10,true) if _transUnit:getCoalition() == 1 then ctld.spawnedCratesRED[_crate.crateUnit:getName()] = nil @@ -3040,11 +3571,11 @@ function ctld.loadNearbyCrate(_name) end end - ctld.displayMessageToGroup(_transUnit, "No Crates within 50m to load!", 10,true) + ctld.displayMessageToGroup(_transUnit, ctld.i18n_translate("No Crates within 50m to load!"), 10,true) else -- Max crates onboard - local outputMsg = "Maximum number of crates are on board!" + local outputMsg = ctld.i18n_translate("Maximum number of crates are on board!") for i = 1, _cargoCapacity do outputMsg = outputMsg .. "\n" .. ctld.inTransitSlingLoadCrates[_name][i].desc end @@ -3064,7 +3595,6 @@ function ctld.refreshRadioBeacons() for _index, _beaconDetails in ipairs(ctld.deployedRadioBeacons) do - --trigger.action.outTextForCoalition(_beaconDetails.coalition,_beaconDetails.text,10) if ctld.updateRadioBeacon(_beaconDetails) == false then --search used frequencies + remove, add back to unused @@ -3165,7 +3695,7 @@ function ctld.listNearbyCrates(_args) for _, _crate in pairs(_crates) do if _crate.dist < 1000 and _crate.details.unit ~= "FOB" then - _message = string.format("%s\n%s crate - kg %i - %i m - %d o'clock", _message, _crate.details.desc, _crate.details.weight, _crate.dist, ctld.getClockDirection(_heli, _crate.crateUnit)) + _message = ctld.i18n_translate("%1\n%2 crate - kg %3 - %4 m - %5 o'clock", _message, _crate.details.desc, _crate.details.weight, _crate.dist, ctld.getClockDirection(_heli, _crate.crateUnit)) end end @@ -3174,42 +3704,35 @@ function ctld.listNearbyCrates(_args) for _, _fobCrate in pairs(_crates) do if _fobCrate.dist < 1000 and _fobCrate.details.unit == "FOB" then - _fobMsg = _fobMsg .. string.format("FOB Crate - %d m - %d o'clock\n", _fobCrate.dist, ctld.getClockDirection(_heli, _fobCrate.crateUnit)) + _fobMsg = _fobMsg .. ctld.i18n_translate("FOB Crate - %1 m - %2 o'clock\n", _fobCrate.dist, ctld.getClockDirection(_heli, _fobCrate.crateUnit)) end end + local _txt = ctld.i18n_translate("No Nearby Crates") if _message ~= "" or _fobMsg ~= "" then local _txt = "" if _message ~= "" then - _txt = "Nearby Crates:\n" .. _message + _txt = ctld.i18n_translate("Nearby Crates:\n%1", _message) end if _fobMsg ~= "" then - if _message ~= "" then + if _txt ~= "" then _txt = _txt .. "\n\n" end - _txt = _txt .. "Nearby FOB Crates (Not Slingloadable):\n" .. _fobMsg + _txt = _txt .. ctld.i18n_translate("Nearby FOB Crates (Not Slingloadable):\n%1", _fobMsg) end - - ctld.displayMessageToGroup(_heli, _txt, 20) - - else - --no crates nearby - - local _txt = "No Nearby Crates" - - ctld.displayMessageToGroup(_heli, _txt, 20) end + ctld.displayMessageToGroup(_heli, _txt, 20) end function ctld.listFOBS(_args) - local _msg = "FOB Positions:" + local _msg = ctld.i18n_translate("FOB Positions:") local _heli = ctld.getTransportUnit(_args[1]) @@ -3219,19 +3742,17 @@ function ctld.listFOBS(_args) end -- get fob positions - local _fobs = ctld.getSpawnedFobs(_heli) - -- now check spawned fobs - for _, _fob in ipairs(_fobs) do - _msg = string.format("%s\nFOB @ %s", _msg, ctld.getFOBPositionString(_fob)) - end - - if _msg == "FOB Positions:" then - ctld.displayMessageToGroup(_heli, "Sorry, there are no active FOBs!", 20) + if _fobs and #_fobs > 0 then + -- now check spawned fobs + for _, _fob in ipairs(_fobs) do + _msg = ctld.i18n_translate("%1\nFOB @ %2", _msg, ctld.getFOBPositionString(_fob)) + end else - ctld.displayMessageToGroup(_heli, _msg, 20) + _msg = ctld.i18n_translate("Sorry, there are no active FOBs!") end + ctld.displayMessageToGroup(_heli, _msg, 20) end function ctld.getFOBPositionString(_fob) @@ -3411,8 +3932,6 @@ function ctld.unpackCrates(_arguments) local _status, _err = pcall(function(_args) - -- trigger.action.outText("Unpack Crates".._args[1],10) - local _heli = ctld.getTransportUnit(_args[1]) if _heli ~= nil and ctld.inAir(_heli) == false then @@ -3423,7 +3942,7 @@ function ctld.unpackCrates(_arguments) if ctld.inLogisticsZone(_heli) == true or ctld.farEnoughFromLogisticZone(_heli) == false then - ctld.displayMessageToGroup(_heli, "You can't unpack that here! Take it to where it's needed!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You can't unpack that here! Take it to where it's needed!"), 20) return end @@ -3440,7 +3959,7 @@ function ctld.unpackCrates(_arguments) elseif _crate ~= nil and _crate.dist < 200 then if ctld.forceCrateToBeMoved and ctld.crateMove[_crate.crateUnit:getName()] and not ctld.unitDynamicCargoCapable(_heli) then - ctld.displayMessageToGroup(_heli,"Sorry you must move this crate before you unpack it!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Sorry you must move this crate before you unpack it!"), 20) return end @@ -3492,7 +4011,7 @@ function ctld.unpackCrates(_arguments) end - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " successfully deployed " .. _crate.details.desc .. " to the field", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 successfully deployed %2 to the field", ctld.getPlayerNameOrType(_heli), _crate.details.desc), 10) if ctld.isJTACUnitType(_crate.details.unit) and ctld.JTAC_dropEnabled then @@ -3506,7 +4025,7 @@ function ctld.unpackCrates(_arguments) else - ctld.displayMessageToGroup(_heli, "No friendly crates close enough to unpack, or crate too close to aircraft.", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No friendly crates close enough to unpack, or crate too close to aircraft."), 20) end end end, _arguments) @@ -3522,7 +4041,7 @@ function ctld.unpackFOBCrates(_crates, _heli) if ctld.inLogisticsZone(_heli) == true then - ctld.displayMessageToGroup(_heli, "You can't unpack that here! Take it to where it's needed!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You can't unpack that here! Take it to where it's needed!"), 20) return end @@ -3605,21 +4124,19 @@ function ctld.unpackFOBCrates(_crates, _heli) if ctld.troopPickupAtFOB == true then table.insert(ctld.builtFOBS, _fob:getName()) - trigger.action.outTextForCoalition(_args[3], "Finished building FOB! Crates and Troops can now be picked up.", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("Finished building FOB! Crates and Troops can now be picked up."), 10) else - trigger.action.outTextForCoalition(_args[3], "Finished building FOB! Crates can now be picked up.", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("Finished building FOB! Crates can now be picked up."), 10) end end, { _centroid, _heli:getCountry(), _heli:getCoalition() }, timer.getTime() + ctld.buildTimeFOB) - local _txt = string.format("%s started building FOB using %d FOB crates, it will be finished in %d seconds.\nPosition marked with smoke.", ctld.getPlayerNameOrType(_heli), _totalCrates, ctld.buildTimeFOB) - ctld.processCallback({unit = _heli, position = _centroid, action = "fob"}) trigger.action.smoke(_centroid, trigger.smokeColor.Green) - trigger.action.outTextForCoalition(_heli:getCoalition(), _txt, 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 started building FOB using %2 FOB crates, it will be finished in %3 seconds.\nPosition marked with smoke.", ctld.getPlayerNameOrType(_heli), _totalCrates, ctld.buildTimeFOB, 10)) else - local _txt = string.format("Cannot build FOB!\n\nIt requires %d Large FOB crates ( 3 small FOB crates equal 1 large FOB Crate) and there are the equivalent of %d large FOB crates nearby\n\nOr the crates are not within 750m of each other", ctld.cratesRequiredForFOB, _totalCrates) + local _txt = ctld.i18n_translate("Cannot build FOB!\n\nIt requires %1 Large FOB crates ( 3 small FOB crates equal 1 large FOB Crate) and there are the equivalent of %2 large FOB crates nearby\n\nOr the crates are not within 750m of each other", ctld.cratesRequiredForFOB, _totalCrates) ctld.displayMessageToGroup(_heli, _txt, 20) end end @@ -3638,11 +4155,11 @@ function ctld.dropSlingCrate(_args) if _currentCrate == nil then if ctld.hoverPickup and ctld.loadCrateFromMenu then - ctld.displayMessageToGroup(_heli, "You are not currently transporting any crates. \n\nTo Pickup a crate, hover for "..ctld.hoverTime.." seconds above the crate or land and use F10 Crate Commands", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate or land and use F10 Crate Commands.", ctld.hoverTime), 10) elseif ctld.hoverPickup then - ctld.displayMessageToGroup(_heli, "You are not currently transporting any crates. \n\nTo Pickup a crate, hover for "..ctld.hoverTime.." seconds above the crate", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate.", ctld.hoverTime), 10) else - ctld.displayMessageToGroup(_heli, "You are not currently transporting any crates. \n\nTo Pickup a crate - land and use F10 Crate Commands to load one.", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You are not currently transporting any crates. \n\nTo Pickup a crate, land and use F10 Crate Commands to load one."), 10) end else @@ -3656,14 +4173,14 @@ function ctld.dropSlingCrate(_args) local _heightDiff = ctld.heightDiff(_heli) if ctld.inAir(_heli) == false or _heightDiff <= 7.5 then - ctld.displayMessageToGroup(_heli, _currentCrate.desc .. " crate has been safely unhooked and is at your 12 o'clock", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("%1 crate has been safely unhooked and is at your %2 o'clock", _currentCrate.desc, ctld.getClockDirection(_heli, _currentCrate.crateUnit)), 10) _point = ctld.getPointAt12Oclock(_heli, 30) elseif _heightDiff > 7.5 and _heightDiff <= 40.0 then - ctld.displayMessageToGroup(_heli, _currentCrate.desc .. " crate has been safely dropped below you", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("%1 crate has been safely dropped below you", _currentCrate.desc), 10) else -- _heightDiff > 40.0, destroy crate - table.remove(ctld.inTransitSlingLoadCrates[_unitName],#ctld.inTransitSlingLoadCrates[_unitName]) + table.remove(ctld.inTransitSlingLoadCrates[_unitName],#ctld.inTransitSlingLoadCrates[_unitName]) ctld.adaptWeightToCargo(_unitName) - ctld.displayMessageToGroup(_heli, "You were too high! The crate has been destroyed", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You were too high! The crate has been destroyed"), 10) return end @@ -3723,7 +4240,7 @@ function ctld.createRadioBeacon(_point, _coalition, _country, _name, _batteryTim battery = _battery, coalition = _coalition, } - + ctld.updateRadioBeacon(_beaconDetails) table.insert(ctld.deployedRadioBeacons, _beaconDetails) @@ -3860,7 +4377,7 @@ function ctld.updateRadioBeacon(_beaconDetails) _groupController:setOption(AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD) - + -- stop the transmission at each call to the ctld.updateRadioBeacon method (default each minute) trigger.action.stopRadioTransmission(_radio.group:getName()) @@ -3887,9 +4404,9 @@ function ctld.listRadioBeacons(_args) end if _message ~= "" then - ctld.displayMessageToGroup(_heli, "Radio Beacons:\n" .. _message, 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Radio Beacons:\n%1", _message), 20) else - ctld.displayMessageToGroup(_heli, "No Active Radio Beacons", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No Active Radio Beacons"), 20) end end end @@ -3912,10 +4429,10 @@ function ctld.dropRadioBeacon(_args) -- mark with flare? - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " deployed a Radio Beacon.\n\n" .. _radioBeaconDetails.text, 20) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 deployed a Radio Beacon.\n\n%2", ctld.getPlayerNameOrType(_heli), _radioBeaconDetails.text, 20)) else - ctld.displayMessageToGroup(_heli, "You need to land before you can deploy a Radio Beacon!", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You need to land before you can deploy a Radio Beacon!"), 20) end end @@ -3929,7 +4446,7 @@ function ctld.removeRadioBeacon(_args) -- mark with flare? - local _closetBeacon = nil + local _closestBeacon = nil local _shortestDistance = -1 local _distance = 0 @@ -3944,18 +4461,18 @@ function ctld.removeRadioBeacon(_args) _distance = ctld.getDistance(_heli:getPoint(), _group:getUnit(1):getPoint()) if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then _shortestDistance = _distance - _closetBeacon = _details + _closestBeacon = _details end end end end - if _closetBeacon ~= nil and _shortestDistance then - local _vhfGroup = Group.getByName(_closetBeacon.vhfGroup) + if _closestBeacon ~= nil and _shortestDistance then + local _vhfGroup = Group.getByName(_closestBeacon.vhfGroup) - local _uhfGroup = Group.getByName(_closetBeacon.uhfGroup) + local _uhfGroup = Group.getByName(_closestBeacon.uhfGroup) - local _fmGroup = Group.getByName(_closetBeacon.fmGroup) + local _fmGroup = Group.getByName(_closestBeacon.fmGroup) if _vhfGroup ~= nil then trigger.action.stopRadioTransmission(_vhfGroup:getName()) @@ -3970,13 +4487,13 @@ function ctld.removeRadioBeacon(_args) _fmGroup:destroy() end - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " removed a Radio Beacon.\n\n" .. _closetBeacon.text, 20) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 removed a Radio Beacon.\n\n%2", ctld.getPlayerNameOrType(_heli), _closestBeacon.text, 20)) else - ctld.displayMessageToGroup(_heli, "No Radio Beacons within 500m.", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("No Radio Beacons within 500m."), 20) end else - ctld.displayMessageToGroup(_heli, "You need to land before remove a Radio Beacon", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("You need to land before remove a Radio Beacon"), 20) end end @@ -4077,7 +4594,7 @@ function ctld.rearmAASystem(_heli, _nearestCrate, _nearbyCrates, _aaSystemTempla ctld.processCallback({unit = _heli, crate = _nearestCrate , spawnedGroup = _spawnedGroup, action = "rearm"}) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " successfully rearmed a full ".._aaSystemTemplate.name.." in the field", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 successfully rearmed a full %2 in the field", ctld.getPlayerNameOrType(_heli), _aaSystemTemplate.name, 20)) if _heli:getCoalition() == 1 then ctld.spawnedCratesRED[_nearestCrate.crateUnit:getName()] = nil @@ -4227,7 +4744,7 @@ function ctld.unpackAASystem(_heli, _nearestCrate, _nearbyCrates,_aaSystemTempla -- check if enough crates were found to build the part if _systemPart.found < _systemPart.required then - _txt = _txt.."Missing ".._systemPart.desc.."\n" + _txt = _txt..ctld.i18n_translate("Missing %1\n",_systemPart.desc) else -- use the centroid of the crates for this part as a spawn location local _point = _crateCentroids[_name] @@ -4264,7 +4781,7 @@ function ctld.unpackAASystem(_heli, _nearestCrate, _nearbyCrates,_aaSystemTempla --handle multiple units per part by spawning them in a circle around the crate if partAmount > 1 then - + local angular_step = arcRad / partAmount for _i = 1, partAmount do @@ -4291,12 +4808,12 @@ function ctld.unpackAASystem(_heli, _nearestCrate, _nearbyCrates,_aaSystemTempla env.info("Active: ".._activeLaunchers.." Allowed: ".._allowed) if _activeLaunchers + 1 > _allowed then - trigger.action.outTextForCoalition(_heli:getCoalition(), "Out of parts for AA Systems. Current limit is ".._allowed.." \n", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("Out of parts for AA Systems. Current limit is %1\n", _allowed, 10)) return end if _txt ~= "" then - ctld.displayMessageToGroup(_heli, "Cannot build ".._aaSystemTemplate.name.."\n" .. _txt .. "\n\nOr the crates are not close enough together", 20) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Cannot build %1\n%2\n\nOr the crates are not close enough together", _aaSystemTemplate.name, _txt), 20) return else @@ -4337,8 +4854,7 @@ function ctld.unpackAASystem(_heli, _nearestCrate, _nearbyCrates,_aaSystemTempla ctld.processCallback({unit = _heli, crate = _nearestCrate , spawnedGroup = _spawnedGroup, action = "unpack"}) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " successfully deployed a full ".._aaSystemTemplate.name.." to the field. \n\nAA Active System limit is: ".._allowed.."\nActive: "..(_activeLaunchers+1), 10) - + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 successfully deployed a full %2 in the field. \n\nAA Active System limit is: %3\nActive: %4", ctld.getPlayerNameOrType(_heli), _aaSystemTemplate.name, _allowed, (_activeLaunchers+1)), 10) end end @@ -4435,7 +4951,7 @@ function ctld.repairAASystem(_heli, _nearestCrate,_aaSystem) ctld.processCallback({unit = _heli, crate = _nearestCrate , spawnedGroup = _spawnedGroup, action = "repair"}) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " successfully repaired a full ".._aaSystem.name.." in the field", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 successfully repaired a full %2 in the field.", ctld.getPlayerNameOrType(_heli), _aaSystem.name), 10) if _heli:getCoalition() == 1 then ctld.spawnedCratesRED[_nearestCrate.crateUnit:getName()] = nil @@ -4449,7 +4965,7 @@ function ctld.repairAASystem(_heli, _nearestCrate,_aaSystem) -- end else - ctld.displayMessageToGroup(_heli, "Cannot repair ".._aaSystem.name..". No damaged ".._aaSystem.name.." within 300m", 10) + ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Cannot repair %1. No damaged %2 within 300m", _aaSystem.name, _aaSystem.name), 10) end end @@ -4504,13 +5020,12 @@ function ctld.unpackMultiCrate(_heli, _nearestCrate, _nearbyCrates) ctld.logError("ctld.unpackMultiCrate group was not spawned - skipping setGrpROE") else ctld.setGrpROE(_spawnedGroup) - ctld.processCallback({unit = _heli, crate = _nearestCrate , spawnedGroup = _spawnedGroup, action = "unpack"}) - local _txt = string.format("%s successfully deployed %s to the field using %d crates", ctld.getPlayerNameOrType(_heli), _nearestCrate.details.desc, #_nearbyMultiCrates) - trigger.action.outTextForCoalition(_heli:getCoalition(), _txt, 10) + ctld.processCallback({unit = _heli, crate = _nearestCrate , spawnedGroup = _spawnedGroup, action = "unpack"}) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 successfully deployed %2 to the field using %3 crates.", ctld.getPlayerNameOrType(_heli), _nearestCrate.details.desc, #_nearbyMultiCrates), 10) end else - local _txt = string.format("Cannot build %s!\n\nIt requires %d crates and there are %d \n\nOr the crates are not within 300m of each other", _nearestCrate.details.desc, _nearestCrate.details.cratesRequired, #_nearbyMultiCrates) + local _txt = ctld.i18n_translate("Cannot build %1!\n\nIt requires %2 crates and there are %3 \n\nOr the crates are not within 300m of each other", _nearestCrate.details.desc, _nearestCrate.details.cratesRequired, #_nearbyMultiCrates) ctld.displayMessageToGroup(_heli, _txt, 20) end @@ -5106,7 +5621,7 @@ function ctld.dropSmoke(_args) trigger.action.smoke(_pos3, _args[2]) - trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.getPlayerNameOrType(_heli) .. " dropped " .. _colour .. " smoke ", 10) + trigger.action.outTextForCoalition(_heli:getCoalition(), ctld.i18n_translate("%1 dropped %2 smoke.", ctld.getPlayerNameOrType(_heli), _colour), 10) end end @@ -5452,10 +5967,10 @@ end function ctld.addOtherF10MenuOptions() ctld.logDebug("ctld.addOtherF10MenuOptions") - + -- reschedule every 10 seconds timer.scheduleFunction(ctld.addOtherF10MenuOptions, nil, timer.getTime() + 10) - + local status, error = pcall(function() -- now do any player controlled aircraft that ARENT transport units @@ -5511,17 +6026,17 @@ function ctld.addRadioListCommand(_side) end function ctld.addJTACRadioCommand(_side) - + local _players = coalition.getPlayers(_side) - + if _players ~= nil then - + for _, _playerUnit in pairs(_players) do - + local _groupId = ctld.getGroupId(_playerUnit) - + if _groupId then - + local newGroup = false if ctld.jtacRadioAdded[tostring(_groupId)] == nil then ctld.logDebug("ctld.addJTACRadioCommand - adding JTAC radio menu for unit [%s]", ctld.p(_playerUnit:getName())) @@ -5530,15 +6045,15 @@ function ctld.addJTACRadioCommand(_side) missionCommands.addCommandForGroup(_groupId, "JTAC Status", JTACpath, ctld.getJTACStatus, { _playerUnit:getName() }) ctld.jtacRadioAdded[tostring(_groupId)] = true end - + --fetch the time to check for a regular refresh local time = timer.getTime() - + --depending on the delay, this part of the radio menu will be refreshed less often or as often as the static JTAC status command, this is for better reliability for the user when navigating through the menus. New groups will get the lists regardless and if a new JTAC is added all lists will be refreshed regardless of the delay. if ctld.jtacLastRadioRefresh + ctld.jtacRadioRefreshDelay <= time or ctld.refreshJTACmenu[_side] or newGroup then - + ctld.jtacLastRadioRefresh = time - + --build the path to the CTLD JTAC menu local jtacCurrentPagePath = {[1]=ctld.jtacMenuName} --build the path for the NextPage submenu on the first page of the CTLD JTAC menu @@ -5546,13 +6061,13 @@ function ctld.addJTACRadioCommand(_side) local MainNextPagePath = {[1]=ctld.jtacMenuName, [2]=NextPageText} --remove it along with everything that's in it missionCommands.removeItemForGroup(_groupId, MainNextPagePath) - + --counter to know when to add the next page submenu to fit all of the JTAC group submenus local jtacCounter = 0 - + for _jtacGroupName,jtacUnit in pairs(ctld.jtacUnits) do --ctld.logTrace(string.format("JTAC - MENU - [%s] - processing menu", ctld.p(_jtacGroupName))) - + --if the JTAC is on the same team as the group being considered local jtacCoalition = ctld.jtacUnits[_jtacGroupName].side if jtacCoalition and jtacCoalition == _side then @@ -5562,7 +6077,7 @@ function ctld.addJTACRadioCommand(_side) end --ctld.logTrace(string.format("JTAC - MENU - [%s] - jtacTargetsList = %s", ctld.p(_jtacGroupName), ctld.p(ctld.jtacTargetsList[_jtacGroupName]))) --ctld.logTrace(string.format("JTAC - MENU - [%s] - jtacCurrentTargets = %s", ctld.p(_jtacGroupName), ctld.p(ctld.jtacCurrentTargets[_jtacGroupName]))) - + local jtacActionMenu = false for _,_specialOptionTable in pairs(ctld.jtacSpecialOptions) do if _specialOptionTable.globalToggle then @@ -5573,9 +6088,9 @@ function ctld.addJTACRadioCommand(_side) --if JTAC has at least one other target in sight or (if special options are available (NOTE : accessed through the JTAC's own menu also) and the JTAC has at least one target) if (ctld.jtacTargetsList[_jtacGroupName] and #ctld.jtacTargetsList[_jtacGroupName] >= 1) or (ctld.jtacCurrentTargets[_jtacGroupName] and jtacActionMenu) then - + local jtacGroupSubMenuName = string.format(_jtacGroupName .. " Selection") - + jtacCounter = jtacCounter + 1 --F2 through F10 makes 9 entries possible per page, with one being the NextMenu submenu. F1 is taken by JTAC status entry. if jtacCounter % 9 == 0 then @@ -5585,33 +6100,33 @@ function ctld.addJTACRadioCommand(_side) --add the JTAC group submenu to the current page ctld.jtacGroupSubMenuPath[_jtacGroupName] = missionCommands.addSubMenuForGroup(_groupId, jtacGroupSubMenuName, jtacCurrentPagePath) --ctld.logTrace(string.format("JTAC - MENU - [%s] - jtacGroupSubMenuPath = %s", ctld.p(_jtacGroupName), ctld.p(ctld.jtacGroupSubMenuPath[_jtacGroupName]))) - + --make a copy of the JTAC group submenu's path to insert the target's list on as many pages as required. The JTAC's group submenu path only leads to the first page local jtacTargetPagePath = mist.utils.deepCopy(ctld.jtacGroupSubMenuPath[_jtacGroupName]) - + --counter to know when to add the next page submenu to fit all of the targets in the JTAC's group submenu. SMay not actually start at 0 due to static items being present on the first page local itemCounter = 0 local jtacSpecialOptPagePath = nil - + if jtacActionMenu then --special options local SpecialOptionsCounter = 0 - + for _,_specialOption in pairs(ctld.jtacSpecialOptions) do - if _specialOption.globalToggle then - + if _specialOption.globalToggle then + if not jtacSpecialOptPagePath then itemCounter = itemCounter + 1 --one item is added to the first JTAC target page jtacSpecialOptPagePath = missionCommands.addSubMenuForGroup(_groupId, "Actions", jtacTargetPagePath) end - + SpecialOptionsCounter = SpecialOptionsCounter+1 - + if SpecialOptionsCounter%10 == 0 then jtacSpecialOptPagePath = missionCommands.addSubMenuForGroup(_groupId, NextPageText, jtacSpecialOptPagePath) SpecialOptionsCounter = SpecialOptionsCounter+1 --Added Next Page item end - + if _specialOption.jtacs then if _specialOption.jtacs[_jtacGroupName] then missionCommands.addCommandForGroup(_groupId, "DISABLE " .. _specialOption.message, jtacSpecialOptPagePath, _specialOption.setter, {jtacGroupName = _jtacGroupName, value = false}) @@ -5624,15 +6139,15 @@ function ctld.addJTACRadioCommand(_side) end end end - + if #ctld.jtacTargetsList[_jtacGroupName] >= 1 then --ctld.logTrace(string.format("JTAC - MENU - [%s] - adding targets menu", ctld.p(_jtacGroupName))) --add a reset targeting option to revert to automatic JTAC unit targeting missionCommands.addCommandForGroup(_groupId, "Reset TGT Selection", jtacTargetPagePath, ctld.setJTACTarget, {jtacGroupName = _jtacGroupName, targetName = nil}) - + itemCounter = itemCounter + 1 --one item is added to the first JTAC target page - + --indicator table to know which unitType was already added to the radio submenu local typeNameList = {} for _,target in pairs(ctld.jtacTargetsList[_jtacGroupName]) do @@ -5640,7 +6155,7 @@ function ctld.addJTACRadioCommand(_side) --check if the jtac has a current target before filtering it out if possible if (ctld.jtacCurrentTargets[_jtacGroupName] and targetName ~= ctld.jtacCurrentTargets[_jtacGroupName].name) then local targetType_name = target.unit:getTypeName() - + if targetType_name then if typeNameList[targetType_name] then typeNameList[targetType_name].amount = typeNameList[targetType_name].amount + 1 @@ -5652,18 +6167,18 @@ function ctld.addJTACRadioCommand(_side) end end end - + for typeName,info in pairs(typeNameList) do local amount = info.amount local targetName = info.targetName itemCounter = itemCounter + 1 - + --F1 through F10 makes 10 entries possible per page, with one being the NextMenu submenu. if itemCounter%10 == 0 then jtacTargetPagePath = missionCommands.addSubMenuForGroup(_groupId, NextPageText, jtacTargetPagePath) itemCounter = itemCounter + 1 --added the next page item end - + missionCommands.addCommandForGroup(_groupId, string.format(typeName .. "(" .. amount .. ")"), jtacTargetPagePath, ctld.setJTACTarget, {jtacGroupName = _jtacGroupName, targetName = targetName}) end end @@ -5673,7 +6188,7 @@ function ctld.addJTACRadioCommand(_side) end end end - + if ctld.refreshJTACmenu[_side] then ctld.refreshJTACmenu[_side] = false end @@ -5755,8 +6270,8 @@ ctld.jtacRadioData = {} --[[ Called when a new JTAC is spawned, it will wait one second for DCS to have time to fill the group with units, and then call ctld.JTACAutoLase. - - The goal here is to correct a bug: when a group is respawned (i.e. when any group with the name of a previously existing group is spawned), + + The goal here is to correct a bug: when a group is respawned (i.e. when any group with the name of a previously existing group is spawned), DCS spawns a group which exists (Group.getByName gets a valid table, and group:isExist returns true), but has no units (i.e. group:getUnits returns an empty table). This causes JTACAutoLase to call cleanupJTAC because it does not find the JTAC unit, and the JTAC to be put out of the JTACAutoLase loop, and never processed again. By waiting a bit, the group gets populated before JTACAutoLase is called, hence avoiding a trip to cleanupJTAC. @@ -5782,7 +6297,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ ctld.logTrace(string.format("_frequency=%s", ctld.p(_frequency))) _radio.freq = _frequency _radio.mod = "fm" - end + end end end @@ -5835,7 +6350,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ end if ctld.jtacUnits[_jtacGroupName] ~= nil then - ctld.notifyCoalition("JTAC Group " .. _jtacGroupName .. " KIA!", 10, ctld.jtacUnits[_jtacGroupName].side, _radio) + ctld.notifyCoalition(ctld.i18n_translate("JTAC Group %1 KIA!", _jtacGroupName), 10, ctld.jtacUnits[_jtacGroupName].side, _radio) end --remove from list @@ -5848,7 +6363,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ local _jtacCoalition = _jtacUnit:getCoalition() --add to list ctld.jtacUnits[_jtacGroupName] = { name = _jtacUnit:getName(), side = _jtacCoalition, radio = _radio } - + --Targets list, special options and Selected target initialization if not ctld.jtacTargetsList[_jtacGroupName] then --Target list @@ -5903,7 +6418,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ local _enemyUnit = ctld.getCurrentUnit(_jtacUnit, _jtacGroupName) --update targets list and store the next potential target if the selected one was lost - local _defaultEnemyUnit = ctld.findNearestVisibleEnemy(_jtacUnit, _lock) + local _defaultEnemyUnit = ctld.findNearestVisibleEnemy(_jtacUnit, _lock) -- if the JTAC sees a unit and a target was selected by users but is not the current unit, check if the selected target is in the targets list, if it is, then it's been reacquired if _enemyUnit and ctld.jtacSelectedTarget[_jtacGroupName] ~= 1 and ctld.jtacSelectedTarget[_jtacGroupName] ~= _enemyUnit:getName() then @@ -5917,8 +6432,8 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ ctld.jtacCurrentTargets[_jtacGroupName] = { name = targetName, unitType = targetUnit:getTypeName(), unitId = targetUnit:getID() } _enemyUnit = targetUnit - local message = _jtacGroupName .. ", selected target reacquired, " .. _enemyUnit:getTypeName() - local fullMessage = message .. '. CODE: ' .. _laserCode .. ". POSITION: " .. ctld.getPositionString(_enemyUnit) + local message = ctld.i18n_translate("%1, selected target reacquired, %2", _jtacGroupName, _enemyUnit:getTypeName()) + local fullMessage = message .. ctld.i18n_translate(". CODE: %1. POSITION: %2", _laserCode, ctld.getPositionString(_enemyUnit)) ctld.notifyCoalition(fullMessage, 10, _jtacUnit:getCoalition(), _radio, message) end end @@ -5965,44 +6480,44 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ -- store current target for easy lookup ctld.jtacCurrentTargets[_jtacGroupName] = { name = _defaultEnemyUnit:getName(), unitType = _defaultEnemyUnit:getTypeName(), unitId = _defaultEnemyUnit:getID() } - + --add check for lasing or not - local action = "new target, " + local action = ctld.i18n_translate("new target, ") if ctld.jtacSpecialOptions.standbyMode.jtacs[_jtacGroupName] then - action = "standing by on " .. action + action = ctld.i18n_translate("standing by on %1", action) else - action = "lasing " .. action + action = ctld.i18n_translate("lasing %1", action) end - + if wasSelected and targetLost then - action = ", temporarily " .. action + action = ctld.i18n_translate(", temporarily %1", action) else action = ", " .. action end - + if targetLost then - action = "target lost" .. action + action = ctld.i18n_translate("target lost") .. action elseif targetDestroyed then - action = "target destroyed" .. action + action = ctld.i18n_translate("target destroyed") .. action end if wasSelected then - action = ", selected " .. action + action = ctld.i18n_translate(", selected %1", action) elseif targetLost or targetDestroyed then action = ", " .. action end wasSelected = false targetDestroyed = false targetLost = false - + local message = _jtacGroupName .. action .. _defaultEnemyUnit:getTypeName() local fullMessage = message .. '. CODE: ' .. _laserCode .. ". POSITION: " .. ctld.getPositionString(_defaultEnemyUnit) ctld.notifyCoalition(fullMessage, 10, _jtacUnit:getCoalition(), _radio, message) -- JTAC Unit stop his route ----------------- trigger.action.groupStopMoving(Group.getByName(_jtacGroupName)) -- stop JTAC - + -- create smoke if _smoke == true then @@ -6026,7 +6541,7 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ if targetSpeed >= maxUpdateDist/refreshDelay then local updateTimeStep = maxUpdateDist/targetSpeed --calculate the time step so that the target is never more than maxUpdateDist from it's last lased position ctld.logTrace(string.format("JTAC - LASE - [%s] - target is moving at %s m/s, schedulting lasing steps every %ss", ctld.p(_jtacGroupName), ctld.p(targetSpeed), ctld.p(updateTimeStep))) - + local i = 1 while i*updateTimeStep <= refreshDelay - updateTimeStep do --while the scheduled time for the laseUnit call isn't greater than the time between two JTACAutoLase() calls minus one time step (because at the next time step JTACAutoLase() should have been called and this in term also calls laseUnit()) timer.scheduleFunction(ctld.timerLaseUnit,{_enemyUnit, _jtacUnit, _jtacGroupName, _laserCode}, timer.getTime()+i*updateTimeStep) @@ -6065,9 +6580,9 @@ function ctld.JTACAutoLase(_jtacGroupName, _laserCode, _smoke, _lock, _colour, _ end if targetLost then - ctld.notifyCoalition(_jtacGroupName .. action .. "target lost.", 10, _jtacUnit:getCoalition(), _radio) + ctld.notifyCoalition(ctld.i18n_translate("%1 %2 target lost.", _jtacGroupName , action), 10, _jtacUnit:getCoalition(), _radio) elseif targetDestroyed then - ctld.notifyCoalition(_jtacGroupName .. action .. "target destroyed.", 10, _jtacUnit:getCoalition(), _radio) + ctld.notifyCoalition(ctld.i18n_translate("%1 %2 target destroyed.", _jtacGroupName , action), 10, _jtacUnit:getCoalition(), _radio) end end @@ -6127,11 +6642,13 @@ end --- if _radio is set, the message will be read out loud via SRS function ctld.notifyCoalition(_message, _displayFor, _side, _radio, _shortMessage) + trigger.action.outTextForCoalition(_side, _message, _displayFor) + local _shortMessage = _shortMessage - if _shortMessage == nil then + if _shortMessage == nil then _shortMessage = _message end - + if STTS and STTS.TextToSpeech and _radio and _radio.freq then local _freq = _radio.freq local _modulation = _radio.mod or "FM" @@ -6142,10 +6659,9 @@ function ctld.notifyCoalition(_message, _displayFor, _side, _radio, _shortMessag local _voice = _radio.voice local _googleTTS = _radio.googleTTS or false STTS.TextToSpeech(_shortMessage, _freq, _modulation, _volume, _name, _side, nil, 1, _gender, _culture, _voice, _googleTTS) + else + trigger.action.outSoundForCoalition(_side, "radiobeep.ogg") end - - trigger.action.outTextForCoalition(_side, _message, _displayFor) - trigger.action.outSoundForCoalition(_side, "radiobeep.ogg") end function ctld.createSmokeMarker(_enemyUnit, _colour) @@ -6207,7 +6723,7 @@ function ctld.laseUnit(_enemyUnit, _jtacUnit, _jtacGroupName, _laserCode) local _WindSpeedVector = atmosphere.getWind(_enemyVectorUpdated) ctld.logTrace(string.format("_WindSpeedVector=%s", ctld.p(_WindSpeedVector))) - + --if target speed is greater than 0, calculated using absolute value norm if math.abs(_enemySpeedVector.x) + math.abs(_enemySpeedVector.y) + math.abs(_enemySpeedVector.z) > 0 then local CorrectionFactor = 1 --correction factor in seconds applied to the target speed components to determine the lasing spot for a direct hit on a moving vehicle @@ -6563,10 +7079,9 @@ function ctld.getJTACStatus(_args) _side = _playerUnit:getCoalition() end - local _jtacGroupName = nil local _jtacUnit = nil - - local _message = "JTAC STATUS: \n\n" + local hasJTAC = false + local _message = ctld.i18n_translate("JTAC STATUS: \n\n") for _jtacGroupName, _jtacDetails in pairs(ctld.jtacUnits) do @@ -6576,33 +7091,35 @@ function ctld.getJTACStatus(_args) if _jtacUnit ~= nil and _jtacUnit:getLife() > 0 and _jtacUnit:isActive() == true and _jtacUnit:getCoalition() == _side then + hasJTAC = true + local _enemyUnit = ctld.getCurrentUnit(_jtacUnit, _jtacGroupName) local _laserCode = ctld.jtacLaserPointCodes[_jtacGroupName] local _start = "->" .. _jtacGroupName if (_jtacDetails.radio) then - _start = _start .. ", available on ".._jtacDetails.radio.freq.." ".._jtacDetails.radio.mod .."," + _start = _start .. ctld.i18n_translate(", available on %1 %2,", _jtacDetails.radio.freq, _jtacDetails.radio.mod) end if _laserCode == nil then - _laserCode = "UNKNOWN" + _laserCode = ctld.i18n_translate("UNKNOWN") end if _enemyUnit ~= nil and _enemyUnit:getLife() > 0 and _enemyUnit:isActive() == true then - local action = " targeting " + local action = ctld.i18n_translate(" targeting ") - if ctld.jtacSelectedTarget[_jtacGroupName] == _enemyUnit:getName() then - action = " targeting selected unit " + if ctld.jtacSelectedTarget[_jtacGroupName] == _enemyUnit:getName() then + action = ctld.i18n_translate(" targeting selected unit ") else if ctld.jtacSelectedTarget[_jtacGroupName] ~= 1 then - action = " attempting to find selected unit, temporarily targeting " - end + action = ctld.i18n_translate(" attempting to find selected unit, temporarily targeting ") end + end - if ctld.jtacSpecialOptions.standbyMode.jtacs[_jtacGroupName] then - action = action .. "(Laser OFF) " + if ctld.jtacSpecialOptions.standbyMode.jtacs[_jtacGroupName] then + action = action .. ctld.i18n_translate("(Laser OFF) ") end _message = _message .. "" .. _start .. action .. _enemyUnit:getTypeName() .. " CODE: " .. _laserCode .. ctld.getPositionString(_enemyUnit) .. "\n" @@ -6610,7 +7127,7 @@ function ctld.getJTACStatus(_args) local _list = ctld.listNearbyEnemies(_jtacUnit) if _list then - _message = _message.."Visual On: " + _message = _message .. ctld.i18n_translate("Visual On: ") for _,_type in pairs(_list) do _message = _message.._type..", " @@ -6619,18 +7136,17 @@ function ctld.getJTACStatus(_args) end else - _message = _message .. "" .. _start .. " searching for targets" .. ctld.getPositionString(_jtacUnit) .. "\n" + _message = _message .. "" .. _start .. ctld.i18n_translate(" searching for targets %1\n", ctld.getPositionString(_jtacUnit)) end end end end - if _message == "JTAC STATUS: \n\n" then - _message = "No Active JTACs" + if not hasJTAC then + ctld.notifyCoalition(ctld.i18n_translate("No Active JTACs"), 10, _side) + else + ctld.notifyCoalition(_message, 10, _side) end - - - ctld.notifyCoalition(_message, 10, _side) end function ctld.setJTACTarget(_args) @@ -6639,22 +7155,22 @@ function ctld.setJTACTarget(_args) local targetName = _args.targetName if _jtacGroupName and targetName and ctld.jtacSelectedTarget[_jtacGroupName] and ctld.jtacTargetsList[_jtacGroupName] then - + --look for the unit's (target) name in the Targets List, create the required data structure for jtacCurrentTargets and then assign it to the JTAC called _jtacGroupName for _, target in pairs(ctld.jtacTargetsList[_jtacGroupName]) do if target then - local ListedTargetUnit = target.unit - local ListedTargetName = ListedTargetUnit:getName() + local listedTargetUnit = target.unit + local ListedTargetName = listedTargetUnit:getName() if ListedTargetName == targetName then ctld.jtacSelectedTarget[_jtacGroupName] = targetName - ctld.jtacCurrentTargets[_jtacGroupName] = { name = targetName, unitType = ListedTargetUnit:getTypeName(), unitId = ListedTargetUnit:getID() } - - local message = _jtacGroupName .. ", targeting selected unit, " .. ListedTargetUnit:getTypeName() - local fullMessage = message .. '. CODE: ' .. ctld.jtacLaserPointCodes[_jtacGroupName] .. ". POSITION: " .. ctld.getPositionString(ListedTargetUnit) + ctld.jtacCurrentTargets[_jtacGroupName] = { name = targetName, unitType = listedTargetUnit:getTypeName(), unitId = listedTargetUnit:getID() } + + local message = _jtacGroupName .. ctld.i18n_translate(", targeting selected unit, %1",listedTargetUnit:getTypeName()) + local fullMessage = message .. ctld.i18n_translate(". CODE: %1. POSITION: %2", ctld.jtacLaserPointCodes[_jtacGroupName], ctld.getPositionString(listedTargetUnit)) ctld.notifyCoalition(fullMessage, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName], message) end end @@ -6662,8 +7178,8 @@ function ctld.setJTACTarget(_args) elseif not targetName and ctld.jtacSelectedTarget[_jtacGroupName] ~= 1 then ctld.jtacSelectedTarget[_jtacGroupName] = 1 ctld.jtacCurrentTargets[_jtacGroupName] = nil - - local message = _jtacGroupName .. ", target selection reset." + + local message = _jtacGroupName .. ctld.i18n_translate(", target selection reset.") ctld.notifyCoalition(message, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) if ctld.jtacSpecialOptions.laseSpotCorrections.jtacs[_jtacGroupName] then @@ -6697,17 +7213,17 @@ end function ctld.setStdbMode(_args) local parsedArgs = ctld.setSpecialOptionArgsCheck(_args) if parsedArgs then - + local _jtacGroupName = parsedArgs.jtacGroupName local _value = parsedArgs.value local _noOutput = parsedArgs.noOutput - local message_end = " enabled" + local message = ctld.i18n_translate("%1, laser and smokes enabled", _jtacGroupName) if _value then - message_end = " disabled" + message = ctld.i18n_translate("%1, laser and smokes disabled", _jtacGroupName) end - if not _noOutput then - ctld.notifyCoalition(_jtacGroupName .. ", Laser and Smokes" .. message_end, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) + if not _noOutput then + ctld.notifyCoalition(message, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) end ctld.jtacSpecialOptions.standbyMode.jtacs[_jtacGroupName] = _value @@ -6719,17 +7235,17 @@ ctld.jtacSpecialOptions.standbyMode.setter = ctld.setStdbMode function ctld.setLaseCompensation(_args) local parsedArgs = ctld.setSpecialOptionArgsCheck(_args) if parsedArgs then - + local _jtacGroupName = parsedArgs.jtacGroupName local _value = parsedArgs.value local _noOutput = parsedArgs.noOutput - local message_end = " disabled." + local message = ctld.i18n_translate("%1, wind and target speed laser spot compensations enabled", _jtacGroupName) if _value then - message_end = " enabled." + message = ctld.i18n_translate("%1, wind and target speed laser spot compensations disabled", _jtacGroupName) end - if not _noOutput then - ctld.notifyCoalition(_jtacGroupName .. ", Wind and Target speed Laser Spot compensations" .. message_end, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) + if not _noOutput then + ctld.notifyCoalition(message, 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) end ctld.jtacSpecialOptions.laseSpotCorrections.jtacs[_jtacGroupName] = _value @@ -6741,14 +7257,14 @@ ctld.jtacSpecialOptions.laseSpotCorrections.setter = ctld.setLaseCompensation function ctld.setSmokeOnTarget(_args) local parsedArgs = ctld.setSpecialOptionArgsCheck(_args) if parsedArgs then - + local _jtacGroupName = parsedArgs.jtacGroupName local _noOutput = parsedArgs.noOutput local _enemyUnit = Unit.getByName(ctld.jtacCurrentTargets[_jtacGroupName].name) if _enemyUnit then if not _noOutput then - ctld.notifyCoalition(_jtacGroupName .. ", WHITE Smoke deployed near TGT", 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) + ctld.notifyCoalition(ctld.i18n_translate("%1, WHITE smoke deployed near target", _jtacGroupName), 10, ctld.jtacUnits[_jtacGroupName].side, ctld.jtacRadioData[_jtacGroupName]) end local _enemyPoint = _enemyUnit:getPoint() @@ -6762,9 +7278,9 @@ ctld.jtacSpecialOptions.smokeMarker.setter = ctld.setSmokeOnTarget function ctld.setJTAC9Line(_args) local parsedArgs = ctld.setSpecialOptionArgsCheck(_args) if parsedArgs then - + local _jtacGroupName = parsedArgs.jtacGroupName - + ctld.getJTACStatus({nil, _jtacGroupName}) end end @@ -7385,7 +7901,7 @@ function ctld.eventHandler:onEvent(event) unitName = event.initiator:getName() ctld.logDebug("caught event S_EVENT_PLAYER_ENTER_UNIT for unit [%s]", ctld.p(unitName)) end - if not unitName then + if not unitName then ctld.logWarning("no unitname found in event %s", ctld.p(event)) return end