Compare commits

...

213 Commits

Author SHA1 Message Date
David Pierron 9302203f09 add initial As-Is Analysis and Modernization Plan documents 2026-04-01 18:10:25 +02:00
David Pierron e59bc50e6c version pushed to 1.6.0-alpha (for testing) 2025-11-22 11:53:11 +01:00
FullGas1 c12c0b242d Work by Fullgas on multiple issues and new features
* Indicate obligation to use MIST delivered with CTLD

* update ctld.dynamicCargoUnits table

* Indicate obligation to use MIST delivered with CTLD

* MIST madatory in red

* MIST mandatory in red

* fix mist.utils.getHeadingPoints calls

* commit

* fix #164 Issue-wrong12oclock msg

* commit ctld.tools.getRelativeBearing()

* commit
2025-11-22 11:50:10 +01:00
David Pierron 659268d3f5 Merge branch 'master' into develop 2025-09-27 18:53:23 +02:00
David Pierron c9270a0fd2 changed the code that looks for nearby units (#163) 2025-09-10 14:39:58 +02:00
David Pierron def40f440c added coff.ee information to the readme 2025-07-31 08:47:54 +02:00
David Pierron 417c57f97c Bump version to 1.5.1 for release 2025-07-31 08:16:42 +02:00
David Pierron dec5bf02b4 Stop autosmoke being the default for JTAC and drones 2025-07-31 08:16:25 +02:00
David Pierron 68693300dc By default, recon is disabled 2025-07-31 08:15:57 +02:00
David Pierron f7f603c486 Added checks to avoind nil errors in ctld.adjustRoute 2025-07-31 08:15:31 +02:00
David Pierron 290950a16b updated README 2025-07-22 16:24:08 +02:00
David Pierron e335c981f3 v1.5.0: New features and issues corrections:
- Issue #137: Repack vehicles in crates
- Issue #139: MQ9 autolase follow a moving target
- Issue #151: Patriot Crate spawning into Chinook rear rotor
- Issue #131: Limit Number of Troops in the game
2025-07-22 15:49:59 +02:00
David Pierron 041a9ab6af small corrections to PR153 2025-07-22 15:24:20 +02:00
David Pierron 8d73c966db PR153 - multiple changes from FullGas1
Issue #137: Repack vehicles in crates
Issue #139: MQ9 autolase follow a moving target
Issue #151: Patriot Crate spawning into Chinook rear rotor
Issue #131: Limit Number of Troops in the game
2025-07-22 15:18:30 +02:00
FullGas1 af3e4fab17 commit 2025-05-20 17:46:02 +02:00
FullGas1 97e7c72144 fix "es" dictionary 2025-05-16 14:34:11 +02:00
FullGas1 65336fdab8 Final commit 2025-05-10 15:30:25 +02:00
FullGas1 61db3e9f93 Commit 2025-05-10 12:04:46 +02:00
FullGas1 a1da0ea1c4 Last fix commit !? 2025-05-10 12:04:18 +02:00
FullGas1 782940265d commit 2025-05-10 01:33:15 +02:00
FullGas1 b5cd8929f3 commit 2025-05-09 15:25:34 +02:00
FullGas1 1826d28a86 commit 2025-05-09 14:33:54 +02:00
FullGas1 359bf1418d commit 2025-05-09 11:54:54 +02:00
FullGas1 e3424c6af5 commit 2025-05-09 11:01:38 +02:00
FullGas1 1ac3b3f8a9 Merge branch 'Issues-#137-Repack-Vehicles-In-Crates' of https://github.com/FullGas1/DCS-CTLD_FG into Issues-#137-Repack-Vehicles-In-Crates 2025-05-09 10:15:41 +02:00
FullGas1 e13e630830 commit 2025-05-09 10:07:00 +02:00
FullGas1 7bfed7ef55 bommit fix 2025-05-08 19:30:19 +02:00
FullGas1 8bfaba399f bugs fix 2025-05-04 23:46:00 +02:00
FullGas1 4dada3d24d Merge branch 'Issues-#137-Repack-Vehicles-In-Crates' of https://github.com/FullGas1/DCS-CTLD_FG into Issues-#137-Repack-Vehicles-In-Crates 2025-05-03 16:10:34 +02:00
FullGas1 74b40fe3cb fix bug 2025-05-03 16:10:22 +02:00
FullGas1 aa8bc78b27 #131 test.miz 2025-04-26 13:50:01 +02:00
FullGas1 7286a6a010 Issue #131-Limit-Number-of-Troops 2025-04-26 13:45:31 +02:00
FullGas1 c8bb41648c Issue #131-Limit-Number-of-Troops 2025-04-26 13:44:25 +02:00
FullGas1 08635622b0 load temporary test .miz 2025-04-21 22:49:33 +02:00
FullGas1 42e8549649 commit 2025-04-21 22:48:32 +02:00
FullGas1 5c48a9d756 commit 2025-04-21 21:27:07 +02:00
FullGas1 f3983c6a90 Merge branch 'Issues-#137-Repack-Vehicles-In-Crates' of https://github.com/FullGas1/DCS-CTLD_FG into Issues-#137-Repack-Vehicles-In-Crates 2025-04-21 21:04:19 +02:00
FullGas1 1c66408127 Readme update 2025-04-21 21:04:17 +02:00
FullGas1 3ac2b3b22c commit 2025-04-21 16:49:55 +02:00
FullGas1 c576268d87 commit 2025-04-21 14:10:41 +02:00
FullGas1 35f52d543a commit 2025-04-21 14:09:18 +02:00
FullGas1 c608d00d15 commit #137 2025-04-21 13:29:31 +02:00
FullGas1 d2789f554a debug #137 2025-04-21 02:51:14 +02:00
FullGas1 fcef6a66d1 debug #137 2025-04-21 01:44:55 +02:00
FullGas1 dd71451194 debug #137 Repack 2025-04-20 22:55:49 +02:00
FullGas1 807e81e389 debug #137 2025-04-20 14:51:25 +02:00
FullGas1 33d8810ebb commit #149 drone follow target 2025-04-20 14:13:32 +02:00
FullGas1 87e8a31f31 debug 2025-04-20 14:06:58 +02:00
FullGas1 e4a0fff931 debug 2025-04-20 12:38:18 +02:00
FullGas1 ca5bf76c78 debug 2025-04-20 00:55:26 +02:00
FullGas1 f8659c5de6 debug 2025-04-19 01:49:10 +02:00
FullGas1 9a0cc8eeee debug 2025-04-17 23:48:58 +02:00
FullGas1 a706890cb6 debug 2025-04-17 23:48:37 +02:00
FullGas1 815684dd77 commit 2025-04-17 00:04:22 +02:00
FullGas1 0ccb2ba7bb debug 2025-04-13 23:14:21 +02:00
FullGas1 1e471df264 debug #159 jtac autoorbiting 2025-04-13 22:07:53 +02:00
FullGas1 cc8b916870 debug 2025-04-09 00:54:01 +02:00
FullGas1 cd62d0c60a Merge branch 'Issues-#137-Repack-Vehicles-In-Crates' of https://github.com/FullGas1/DCS-CTLD_FG into Issues-#137-Repack-Vehicles-In-Crates 2025-04-07 23:46:41 +02:00
FullGas1 a35e023752 #149 Flying JTAC orbit on target 2025-04-07 23:46:37 +02:00
FullGas1 f71e7f3213 commit 2025-04-06 22:31:37 +02:00
FullGas1 a468faefec commit 2025-04-06 21:53:15 +02:00
FullGas1 99f2c7aec0 commit 2025-04-06 19:26:06 +02:00
FullGas1 7db8e2d772 commit 2025-04-06 19:19:57 +02:00
FullGas1 026099bd12 commit 2025-04-06 19:19:45 +02:00
FullGas1 82a330e61a commit 2025-04-06 19:04:35 +02:00
FullGas1 b3470250e4 commit 2025-04-06 17:28:54 +02:00
FullGas1 bbde4ae62b comiit 2025-04-06 17:16:28 +02:00
FullGas1 540a316754 commit 2025-04-06 17:12:44 +02:00
FullGas1 574217d931 commit 2025-04-06 17:02:08 +02:00
FullGas1 1fce52088d commit 2025-04-06 11:15:16 +02:00
FullGas1 4d704a489e commit 2025-04-06 11:13:50 +02:00
FullGas1 da80f9ea06 commit 2025-04-06 11:09:38 +02:00
FullGas1 93260908c4 debug 2025-04-05 19:39:42 +02:00
FullGas1 3c261e8dc2 debug 2025-04-04 21:52:40 +02:00
FullGas1 7b7eb62bf0 debug 2025-04-03 23:48:00 +02:00
FullGas1 951ee37903 debbug 2025-04-03 21:45:46 +02:00
FullGas1 3a7ab50834 debug 2025-04-03 20:36:50 +02:00
FullGas1 9a69d4b52c debug 2025-04-03 16:32:55 +02:00
FullGas1 0345d16150 debug 2025-04-03 02:02:41 +02:00
FullGas1 d071fba20f debug 2025-04-03 01:10:03 +02:00
FullGas1 1a32ce6b57 debug 2025-04-03 00:50:30 +02:00
FullGas1 85275ad84b debug 2025-04-03 00:50:19 +02:00
FullGas1 819ba2de53 debug 2025-04-02 22:54:17 +02:00
FullGas1 8f34ad3902 debug 2025-04-02 22:19:34 +02:00
FullGas1 16f366d039 debug 2025-04-01 19:43:24 +02:00
FullGas1 2524320096 debug 2025-04-01 17:49:52 +02:00
FullGas1 e6b8c9ba14 ebug 2025-04-01 17:34:00 +02:00
FullGas1 a5b47503be Merge branch 'Issues-#137-Repack-Vehicles-In-Crates' of https://github.com/FullGas1/DCS-CTLD_FG into Issues-#137-Repack-Vehicles-In-Crates 2025-04-01 16:37:11 +02:00
FullGas1 aaa25dcd41 commit 2025-04-01 16:28:50 +02:00
FullGas1 e834dd1395 debug 2025-04-01 03:04:26 +02:00
FullGas1 774e499759 commit 2025-04-01 02:48:10 +02:00
FullGas1 0a1f4de471 commit 2025-04-01 02:22:35 +02:00
FullGas1 f9cd8b8b51 commit 2025-03-31 18:05:13 +02:00
FullGas1 3eef8d9a5d ctld.getNearbyUnits : sort by distance 2025-03-31 12:22:39 +02:00
FullGas1 e1b9e1d7d8 commit 2025-03-31 12:19:41 +02:00
FullGas1 ca976f4387 commit 2025-03-30 23:42:53 +02:00
FullGas1 91f74b73ed commit 2025-03-30 16:25:31 +02:00
FullGas1 f8df243043 commit 2025-03-30 15:42:07 +02:00
FullGas1 29b19d5262 commit 2025-03-30 15:24:20 +02:00
FullGas1 48aca9d488 commit 2025-03-30 15:07:49 +02:00
FullGas1 12741d0532 commit 2025-03-30 12:55:22 +02:00
FullGas1 6df583b9f1 commit 2025-03-30 12:23:40 +02:00
FullGas1 ca99c58f98 commit 2025-03-30 12:21:43 +02:00
FullGas1 879272a2e8 debug 2025-03-30 00:31:35 +01:00
FullGas1 267156e04e debug 2025-03-30 00:00:34 +01:00
FullGas1 6fa12ca46f debug 2025-03-29 23:49:50 +01:00
FullGas1 eb22f5dc67 debug 2025-03-29 23:20:10 +01:00
FullGas1 601805abb0 debug 2025-03-29 23:06:27 +01:00
FullGas1 e0e4279f20 debug 2025-03-29 23:00:17 +01:00
FullGas1 9023c571ba debug 2025-03-29 22:54:18 +01:00
FullGas1 72aab26e43 debug 2025-03-29 22:39:04 +01:00
FullGas1 aef146a6d8 debug 2025-03-29 22:16:48 +01:00
FullGas1 d8db662dc5 debug 2025-03-29 22:07:45 +01:00
FullGas1 e4f13f98b1 commit 2025-03-29 19:36:58 +01:00
FullGas1 c1aba95b6f for debug 2025-03-29 16:24:36 +01:00
FullGas1 d50bcfccd9 commit 2025-03-29 16:18:08 +01:00
FullGas1 f0f095e274 commit 2025-03-29 11:07:52 +01:00
FullGas1 69f04dfd57 commit 2025-03-29 10:53:37 +01:00
FullGas1 546f3feaae commit 2025-03-29 10:53:04 +01:00
FullGas1 23e83bf53a commit 2025-03-29 10:32:31 +01:00
FullGas1 ee07423588 Merge branch 'Issues-#137-Repack-Vehicles-In-Crates' of https://github.com/FullGas1/DCS-CTLD_FG into Issues-#137-Repack-Vehicles-In-Crates 2025-03-29 10:19:30 +01:00
FullGas1 96d801c342 commit 2025-03-29 10:19:27 +01:00
FullGas1 b1818d9fb3 update en dict version number 2025-03-29 09:57:57 +01:00
FullGas1 2bc6e76516 update fr & es dict version number 2025-03-29 09:57:33 +01:00
FullGas1 61a1fd42ee update dict versionnumber 2025-03-29 09:54:52 +01:00
FullGas1 954a6b0fad update dictionary 2025-03-29 09:48:35 +01:00
FullGas1 159915a6ac commit 2025-03-26 18:51:16 +01:00
FullGas1 d029e2479b commit 2025-03-26 18:43:54 +01:00
FullGas1 251467fee4 update dictionary 2025-03-26 18:39:35 +01:00
FullGas1 f3a9b44388 commit 2025-03-26 18:22:20 +01:00
FullGas1 f0adb72c49 comiit 2025-03-26 17:36:56 +01:00
FullGas1 ecc47bb247 fixes 2025-03-26 10:32:35 +01:00
FullGas1 0c74729837 fixes ctld.getSecureDistanceFromUnit 2025-03-26 10:32:10 +01:00
FullGas1 ef1d3d57e5 add ctld.getSecureDistanceFromUnit 2025-03-26 01:49:45 +01:00
FullGas1 b69f20eb6b add ctld.getSecureDistanceFromUnit fct 2025-03-26 01:31:53 +01:00
FullGas1 d80a70c0ee readme update 2025-03-26 01:18:09 +01:00
FullGas1 80fe5d59b0 readme update for repack 2025-03-26 01:00:37 +01:00
FullGas1 3eaa08b74e fixes 2025-03-26 00:01:15 +01:00
FullGas1 f83365ec63 fixes 2025-03-25 23:59:26 +01:00
FullGas1 0b3b1ea1f8 fixes 2025-03-25 23:59:06 +01:00
FullGas1 888d949234 fixes 2025-03-25 23:39:25 +01:00
FullGas1 75c9d0bf68 fixes 2025-03-25 18:10:39 +01:00
FullGas1 7517eaf188 fixes 2025-03-25 17:39:58 +01:00
FullGas1 1181fcfff7 fixes 2025-03-25 17:22:18 +01:00
FullGas1 9def2f1a3a fixes 2025-03-25 17:00:17 +01:00
FullGas1 9c25240c43 fixes 2025-03-25 16:33:09 +01:00
FullGas1 8a17ff52aa fixes 2025-03-25 15:24:12 +01:00
FullGas1 d125cdbe80 fixes 2025-03-25 15:14:03 +01:00
FullGas1 8dcaa3e0bb fixes 2025-03-25 15:05:28 +01:00
FullGas1 baf1231141 fixes 2025-03-25 14:57:32 +01:00
FullGas1 d1d9b55769 fixes 2025-03-25 14:55:10 +01:00
FullGas1 ff06dcecf7 fixes 2025-03-25 12:50:41 +01:00
FullGas1 dcdf6438a1 fixes 2025-03-25 12:29:25 +01:00
FullGas1 4d0062dee3 fixes 2025-03-25 11:37:16 +01:00
FullGas1 c618f4b282 fixes 2025-03-25 11:33:15 +01:00
FullGas1 b390d5dabf fixes 2025-03-25 11:22:57 +01:00
FullGas1 f4b81fd101 fixes 2025-03-25 11:20:40 +01:00
FullGas1 78aa8a010e fixes 2025-03-25 11:10:13 +01:00
FullGas1 6996769cec fixes 2025-03-25 11:04:00 +01:00
FullGas1 0d9c01283c fixes 2025-03-25 11:02:40 +01:00
FullGas1 fa1553a83e fixes 2025-03-24 16:09:58 +01:00
FullGas1 4db3c71728 fixes 2025-03-24 00:49:58 +01:00
FullGas1 0180cf33d2 fixes 2025-03-24 00:37:19 +01:00
FullGas1 c51a3d80ca fixes 2025-03-23 22:26:51 +01:00
FullGas1 9eb4fc66b5 fixes 2025-03-23 22:25:28 +01:00
FullGas1 8f2a335609 fixes 2025-03-23 22:12:19 +01:00
FullGas1 c5bae34ed1 fixes 2025-03-23 19:31:30 +01:00
FullGas1 6fc9f146ae fixes 2025-03-23 17:38:24 +01:00
FullGas1 b6232d3c15 fixes 2025-03-23 17:09:35 +01:00
FullGas1 111fd73b94 fixes 2025-03-23 17:03:37 +01:00
FullGas1 61d9e206b2 fixes 2025-03-23 16:58:32 +01:00
FullGas1 08ebd7e82d fixes 2025-03-23 16:54:27 +01:00
FullGas1 f152f58a97 fixes 2025-03-23 16:49:29 +01:00
FullGas1 38e86bead3 fixes 2025-03-23 16:37:30 +01:00
FullGas1 b0d8f8b5c7 fixes 2025-03-23 16:36:31 +01:00
FullGas1 a58efad985 fixes 2025-03-23 00:09:30 +01:00
FullGas1 0793d3bda5 fixes 2025-03-22 23:47:06 +01:00
FullGas1 c397bad107 fixes 2025-03-22 23:30:53 +01:00
FullGas1 791ee4e63e fixes 2025-03-22 23:02:57 +01:00
FullGas1 5aa37c52a4 fixes 2025-03-22 21:42:46 +01:00
FullGas1 fb26645996 add ctld.updateDynamicLogisticUnitsZones 2025-02-26 21:27:21 +01:00
FullGas1 3a3bcaf568 wip 2025-02-26 15:13:25 +01:00
FullGas1 fb804b4a22 1rst ok version 2025-02-26 15:05:22 +01:00
FullGas1 665bdddbdd wip 2025-02-26 03:34:05 +01:00
FullGas1 6beaedb79a ctld.getUnitsInRepackRadius(_PlayerTransportUnitName, _radius) added 2025-02-22 04:35:25 +01:00
FullGas1 9c2f982d03 ctld.getNearbyUnits 2025-02-21 23:48:02 +01:00
David Pierron 33c14cbead updated missions for 1.4.0 2025-02-04 17:09:54 +01:00
David Pierron 751f1453ec v1.4.0 2025-02-04 17:05:45 +01:00
David Pierron dddca7c59d Merge pull request #146 from ciribob/develop
Develop
2025-02-04 16:57:16 +01:00
David Pierron fa7ccc48e9 Merge pull request #145 from FullGas1/Release-v-1-4-0-Update-dictionaries
Update to 1.4.0 dictionaries + small modifications on ctld.i18n_check…
2025-02-04 16:56:58 +01:00
FullGas1 bbf2c6b7fd Update to 1.4.0 dictionaries + small modifications on ctld.i18n_check() for better readability of the result 2025-02-04 16:14:52 +01:00
David Pierron 75a62c32a9 correction to the multiple crates spawn 2025-02-02 15:28:13 +01:00
David Pierron b1b7163c54 corrected the ctld.unpackAASystem function (issue #140) 2025-02-01 11:34:49 +01:00
David Pierron f95b6dad27 corrections (again) 2025-01-31 22:19:35 +01:00
David Pierron e9724a433f correction 2025-01-31 22:01:00 +01:00
David Pierron c7748e6dfe - Load and drop multiple crates with one command
- Spawn and drop crates not in a pile (Issue #143)
2025-01-31 21:55:08 +01:00
David Pierron d77b15f099 re-release with EN as the default language #141
upward compatibility not working #142
2025-01-31 15:06:01 +01:00
David Pierron a5b68dbf90 Merge pull request #139 from FullGas1:features/FEAT-Recon-#136-MarksOfTargetsInLOS-Handler
Features/feat recon #136 marks of targets in los handler
2025-01-31 15:01:31 +01:00
David Pierron 7055c565ac review 2025-01-31 15:01:22 +01:00
David Pierron db50b9b1a9 Merge pull request #138 from FullGas1:Issues-#86-#101-JTAC-gives-altitude-+-spawn-Drone
Issues #86 #101 jtac gives altitude + spawn drone
2025-01-31 13:41:21 +01:00
David Pierron 57ca0fa02d review 2025-01-31 13:41:02 +01:00
FullGas1 24d1dcdc33 Readme update for recognition functions 2025-01-28 21:57:17 +01:00
FullGas1 bf3f4776fc Update F10 RECON menus in "fr" & "es" dictionaries 2025-01-28 18:05:06 +01:00
FullGas1 e92fbff633 Update "en" dictionary 2025-01-28 17:55:55 +01:00
FullGas1 9c2048cf92 fixes 2025-01-28 17:41:19 +01:00
FullGas1 907ec69265 fixes 2025-01-28 17:37:14 +01:00
FullGas1 4146408fe8 Add menu F10 cdes for F10 map Marks of targets in LOS 2025-01-28 17:34:11 +01:00
FullGas1 e4bc932d28 Show & refresh fct returns targetsInLOS table 2025-01-28 00:01:14 +01:00
FullGas1 7d217e6db1 Show/remove/refresh marks on targets in LOS for a unit 2025-01-27 23:32:16 +01:00
FullGas1 f4c7b58464 Update menu F10 Drones crates names in "fr" & "es" dictionaries 2025-01-25 12:15:08 +01:00
FullGas1 568724b8bf Update CTLD.lua
Update "en" dictionary for F10 sub-menus drones names
2025-01-24 22:49:25 +01:00
FullGas1 16891e9d5f Altitude added in JTAC msgs + Drone crate load/uload/unpack added. Unpack drone crate = spwan drone orbiting above the helicopter, and targets possible enemies 2025-01-24 18:24:02 +01:00
FullGas1 494efee777 #101-JTAC gives altitude info 2025-01-22 22:20:15 +01:00
14 changed files with 4000 additions and 2155 deletions
+265
View File
@@ -0,0 +1,265 @@
# DCS-CTLD — As-Is Analysis
> This document captures the current state of the CTLD codebase prior to
> the v2 modernization effort. It serves as a reference and justification
> for the changes outlined in `MODERNIZATION-PLAN.md`.
---
## 1. Overview
| Metric | Value |
| ------ | ----- |
| Primary script | `CTLD.lua` |
| Lines of code | ~8 700 |
| i18n script | `CTLD-i18n.lua` |
| Bundled dependency | `mist.lua` (MIST 4.5 build 128-DYNSLOTS-02) |
| Lua version | 5.1 (DCS sandbox) |
| Public functions (`ctld.*`) | 100+ |
| Local / private functions | 0 (everything is public on the `ctld` table) |
| OOP / metatables usage | None — fully procedural |
| Unit tests | None |
---
## 2. File structure
```text
.
├── CTLD.lua -- Main script (monolith)
├── CTLD-i18n.lua -- Translation tables (FR, ES, KO)
├── mist.lua -- MIST library (stock, not customized)
├── beacon.ogg -- Radio beacon sound
├── beaconsilent.ogg -- Silent beacon sound (FC3)
├── README.md -- User / mission-maker guide
├── demo-mission.miz
├── test-mission.miz
├── test-dev-dynamic.miz
├── test-dev-static.miz
├── test_witchcraft_#131.miz
└── test_witchcraft_#137 et #149.miz
```
No `src/`, no `test/`, no `docs/`, no CI configuration.
---
## 3. CTLD.lua section breakdown
| Section | Lines | Content |
| ------- | ----- | ------- |
| Header + contributors | 135 | Credits, links |
| i18n table setup | 36360 | English reference keys (all `= ""`), `i18n_translate()` |
| USER CONFIGURATION | 403600 | 50+ tunable parameters |
| Crate configuration | 6011 200 | `ctld.spawnableCrates`, AA system templates |
| Public API functions | 1 2001 950 | Functions usable from DO SCRIPT triggers |
| Core gameplay logic | 1 9504 600 | Troops, vehicles, crates, FOBs, beacons |
| JTAC subsystem | 4 6007 000 | Targeting, lasing, IR points, F10 menus |
| AI processing + menus | 7 0008 200 | AI auto-load/unload, F10 menu building |
| `ctld.initialize()` | 8 1908 400 | State tables init, zone parsing |
| Event handler + tools | 8 4008 705 | DCS event handler, `ctld.tools` utilities |
---
## 4. State management
34 global tables inside the `ctld` namespace track runtime state.
Most are duplicated per coalition.
### 4.1 — Coalition-duplicated tables (RED / BLUE pairs)
| Table pair | Content |
| ---------- | ------- |
| `ctld.spawnedCratesRED` / `BLUE` | Spawned crate statics |
| `ctld.droppedTroopsRED` / `BLUE` | Deployed infantry groups |
| `ctld.droppedVehiclesRED` / `BLUE` | Deployed vehicles |
| `ctld.droppedFOBCratesRED` / `BLUE` | FOB crates on ground |
This duplication creates **50+ `if coalition == 1 then … RED … else … BLUE`** branches.
### 4.2 — Shared tables
| Table | Content |
| ----- | ------- |
| `ctld.inTransitTroops` | Cargo currently onboard (keyed by unit name) |
| `ctld.inTransitSlingLoadCrates` | Simulated sling-load crates |
| `ctld.builtFOBS` | Completed FOB positions |
| `ctld.completeAASystems` | Assembled AA system groups |
| `ctld.deployedRadioBeacons` | Active beacons |
| `ctld.fobBeacons` | FOB beacon cache (refreshed every 60 s) |
| `ctld.extractZones` | Extract zone definitions |
| `ctld.hoverStatus` | Hover-over-crate tracking |
| `ctld.crateLookupTable` | Crate weight → type lookup |
| `ctld.callbacks` | Registered callback functions |
| `ctld.jtacUnits` | JTAC unit references |
| `ctld.jtacCurrentTargets` | JTAC active targets |
| `ctld.jtacSelectedTarget` | Player-selected JTAC targets |
| `ctld.jtacGeneratedLaserCodes` | Allocated laser codes |
| `ctld.usedUHFFrequencies` / `VHF` / `FM` | Radio frequency pools |
---
## 5. Code duplication patterns
### 5.1 — RED/BLUE branching (most pervasive)
```lua
-- This pattern appears 50+ times
if _heli:getCoalition() == 1 then
_list = ctld.droppedTroopsRED
else
_list = ctld.droppedTroopsBLUE
end
```
### 5.2 — Troop / Vehicle symmetry
Many functions have near-identical troop and vehicle variants differentiated
only by a boolean parameter (`true` = troops, `false` = vehicles).
### 5.3 — Sling load vs simulated load
Two code paths for crate pickup depending on `ctld.slingLoad`:
- Real sling load (DCS native, crashy)
- Simulated hover load (custom implementation)
### 5.4 — Zone handling
Pickup zones, dropoff zones, and waypoint zones share similar parsing
(smoke color, coalition check, active flag) but are implemented separately.
---
## 6. MIST dependency
91 calls to `mist.*` functions across the codebase.
| Category | Functions | Call count |
| -------- | --------- | ---------- |
| Utility | `deepCopy`, `round`, `makeVec2/3` | ~28 |
| Distance / vectors | `get2DDist`, `vec.mag`, `vec.dp`, `vec.sub` | ~15 |
| Heading / bearing | `getHeading` | ~8 |
| Coordinate format | `tostringLL`, `tostringMGRS` | ~4 |
| Spawning | `dynAdd`, `dynAddStatic` | ~8 |
| Route / waypoints | `buildWP`, `getGroupRoute` | ~4 |
| LOS / search | `getUnitsLOS`, `getAvgPos`, `makeUnitTable` | ~4 |
| Database | `mist.DBs.unitsByName` | iterated |
| Scheduling | `mist.scheduleFunction` | ~1 |
| Other | misc | ~19 |
No functions provide a fallback if MIST is absent — CTLD hard-crashes on
`assert(mist ~= nil)` during initialization.
---
## 7. Scheduling and timers
20+ `timer.scheduleFunction` calls drive recurring behavior.
All timers reschedule themselves recursively; there are no continuous
polling loops.
| Timer | Interval | Purpose |
| ----- | -------- | ------- |
| `checkTransportStatus` | 3 s | Monitor transport helicopters |
| `checkHoverStatus` | 1 s | Track hover-over-crate countdown |
| `refreshRadioBeacons` | 60 s | Update beacon battery status |
| `refreshSmoke` | 300 s | Refresh smoke markers |
| `checkAIStatus` | 2 s | AI troop behavior check |
| `timerJTACAutoLase` | variable | JTAC targeting loop |
| `timerLaseUnit` | variable | Single-unit lasing |
| `autoUpdateRepackMenu` | 1 s | Refresh vehicle repacking F10 menu |
| `reconRefreshTargetsInLosOnF10Map` | variable | RECON map markers |
---
## 8. Error handling
- **pcall usage**: 12 instances, mainly around crate spawning and hover math.
- **Nil checks**: Extensive `if X == nil then return end` before DCS API calls.
- **No structured error propagation**: errors are logged via `env.error()` /
`ctld.logError()` and silently swallowed.
- **No stack traces** or exception chaining.
---
## 9. Internationalization (i18n)
| Language | Code | `translation_version` | Completeness |
| -------- | ---- | --------------------- | ------------ |
| English | `en` | 1.6 | Reference (keys only, values = `""`) |
| French | `fr` | 1.6 | Partial — many crate/equipment names empty |
| Spanish | `es` | 1.6 | Similar to French |
| Korean | `ko` | **1.1** | Severely outdated, many missing keys |
Issues:
- No tooling to detect missing keys or version drift.
- Empty string (`""`) is a valid Lua value, so missing translations silently
fall back to the English key (which is also `""` for reference entries).
- All translations live in a single `CTLD-i18n.lua` file — no per-language
separation.
---
## 10. Documentation
| Audience | Coverage | Location |
| -------- | -------- | -------- |
| Mission maker | Partial | `README.md` (setup, config, API examples) |
| Player | Minimal | `README.md` (gameplay mechanics mentioned briefly) |
| Developer | None | No architecture doc, no contributing guide |
README strengths:
- Good coverage of pickup/dropoff zone configuration.
- Code examples for DO SCRIPT functions.
- Dynamic loading workflow documented.
README gaps:
- JTAC advanced features poorly explained.
- No API reference table (signatures, parameters, return values).
- No architecture or data flow diagrams.
- Some examples use different defaults than the current code.
---
## 11. Testing
- **No automated tests** of any kind.
- **Manual smoke testing** via `.miz` missions in the repository:
- `test-mission.miz` — full feature demonstration
- `test-dev-dynamic.miz` — dynamic script loading for fast iteration
- `test-dev-static.miz` — static loading variant
- `test_witchcraft_#131.miz`, `test_witchcraft_#137 et #149.miz` — bug repro missions
- No test framework, no mocks, no CI.
---
## 12. Dead code and technical debt
| Item | Location | Detail |
| ---- | -------- | ------ |
| Commented-out blocks | 18+ blocks across file | Old implementations, debug markers, disabled alternatives |
| Unused function | `ctld.tools.getRelativeBearing` | Defined but never called |
| Unused function | `ctld.tools.isValueInIpairTable` | Called once, could be inlined |
| Commented event handler | `ctld.initialize()` | Old `ctld.eventHandler` pattern, replaced but not removed |
| Disabled vehicle types | Crate config tables | Many entries commented out (`-- BUK`, `-- Strela`, etc.) |
| Debug markers | Various | `--ctld.logTrace("FG_ XXXX...")` left in code |
| Alternate coordinate | `ctld.listFOBS()` | MGRS conversion commented out |
---
## 13. Summary of pain points
1. **Monolithic file**: 8 700 lines, impossible to navigate or review efficiently.
2. **No encapsulation**: 100+ public functions, 0 local functions, all state is global.
3. **RED/BLUE duplication**: 50+ coalition branches + paired tables.
4. **MIST hard dependency**: 91 calls, no fallback, no abstraction layer.
5. **No tests**: zero automated tests, zero mocks, zero CI.
6. **No OOP**: purely procedural, no classes, no metatables.
7. **Dead code**: 18+ commented blocks, unused functions.
8. **i18n drift**: Korean 3 versions behind, many empty translations.
9. **No developer documentation**: new contributors must read 8 700 lines to understand the architecture.
10. **No build system**: the source file IS the deliverable.
+364
View File
@@ -0,0 +1,364 @@
# DCS-CTLD Modernization Plan
> Status: **Draft**
> Branch: `next` (git flow, `main` stays stable)
> Target: CTLD v2.0
---
## Vision
Rewrite CTLD as a modern, modular, and testable Lua project while
temporarily preserving backward compatibility with existing missions.
The deliverable remains a single `.lua` file produced by an automated build.
---
## Architectural decisions
Key decisions made during the planning phase, for reference.
| # | Topic | Decision |
| - | ----- | -------- |
| 1 | Module split | Separate source files in `src/`, concatenated into a single `dist/CTLD.lua` by a build script (CI) |
| 2 | OOP level | Full OOP Lua 5.1 with metatables and classes — ready to break backward compat when needed |
| 3 | MIST dependency | Middleware layer (`src/mist_compat/`): CTLD never calls `mist.*` directly. Long-term goal: eliminate MIST entirely |
| 4 | API breaking changes | Short/medium term: legacy wrappers with deprecation warnings. Long term (v3): legacy API removed |
| 5 | Lua environment | Lua 5.1 DCS sandbox, desanitized server assumed (`io`, `os`, `lfs` accessible) |
| 6 | Testing | Both: busted + DCS/MIST mocks in CI, and in-game test missions for integration |
| 7 | Documentation | 3 audiences (player, mission maker, developer). Markdown in `docs/`, auto-published to GitHub Pages via MkDocs |
| 8 | i18n | Included in plan: audit missing keys, CI lint for version drift, cleanup empty translations |
| 9 | Priorities | 1-Cleanup, 2-OOP, 3-MIST middleware, 4-Legacy compat, 5-Tests, 6-CI, 7-i18n, 8-Docs |
| 10 | Branching | `next` branch for v2, git flow. `main` stays stable. Feature branches: `feature/<phase>-<description>` |
---
## Guiding principles
- **OOP Lua 5.1**: metatables, classes, state encapsulation.
- **Separate modules** in development, single file in delivery.
- **Zero direct MIST dependency**: all MIST usage goes through a middleware layer.
- **Automated testing**: pure logic tested outside DCS, integration tested in-game.
- **Auto-generated documentation**: from the repo to GitHub Pages.
- **Transitional legacy compatibility**: deprecated wrappers with warnings, removed in v3.
---
## Phases
### Phase 1 — Dead code cleanup
**Goal**: Start from a clean, noise-free baseline.
| Task | Detail |
| ---- | ------ |
| 1.1 | Remove the 18+ identified commented-out code blocks |
| 1.2 | Remove unused functions (`ctld.tools.getRelativeBearing`, etc.) |
| 1.3 | Remove state variables that are never read |
| 1.4 | Clean up obsolete `--TODO`/`--FIXME` markers |
| 1.5 | Validate with existing test missions that nothing breaks |
**Deliverable**: A lighter CTLD.lua, functionally identical.
---
### Phase 2 — Module split + OOP
**Goal**: Transform the procedural monolith into a modular, object-oriented architecture.
#### 2.1 — Lua 5.1 class system
Define a micro class framework based on metatables:
```lua
-- src/lib/class.lua
local function class(base)
local cls = {}
cls.__index = cls
if base then setmetatable(cls, { __index = base }) end
function cls:new(...)
local instance = setmetatable({}, cls)
if instance.init then instance:init(...) end
return instance
end
return cls
end
```
#### 2.2 — Module layout
Target structure for the `src/` directory:
```text
src/
├── lib/
│ ├── class.lua -- OOP micro-framework
│ ├── utils.lua -- Utilities (deepCopy, formatText, logging)
│ └── vec.lua -- Vector math (2D/3D distance, bearing)
├── core/
│ ├── config.lua -- User configuration (USER CONFIGURATION)
│ ├── state.lua -- State manager (replaces 34 global tables)
│ ├── coalition.lua -- Coalition class (eliminates RED/BLUE duplication)
│ ├── i18n.lua -- i18n system
│ └── events.lua -- Event handler + callback system
├── transport/
│ ├── transport.lua -- Transport class (heli/plane)
│ ├── troops.lua -- Troop management (load/unload/extract)
│ └── vehicles.lua -- Vehicle management
├── logistics/
│ ├── crate.lua -- Crate class
│ ├── crate_manager.lua -- Spawning, hover, sling load, unpack
│ ├── fob.lua -- FOB construction and management
│ └── beacon.lua -- Radio beacons
├── jtac/
│ ├── jtac_controller.lua -- JTACController class
│ ├── targeting.lua -- Target acquisition, LOS, priorities
│ ├── lasing.lua -- Laser/IR point, spot corrections
│ └── menu.lua -- F10 JTAC menus
├── ui/
│ ├── f10_menu.lua -- F10 menu construction
│ ├── messages.lua -- Player messages (displayMessageToGroup)
│ └── smoke.lua -- Smoke markers
├── recon/
│ └── recon.lua -- Target recognition on F10 map
├── ai/
│ └── ai_transport.lua -- AI auto-load/unload logic
├── compat/
│ └── legacy_api.lua -- Deprecated ctld.* wrappers
├── mist_compat/
│ └── mist_middleware.lua -- MIST middleware (see Phase 3)
└── ctld.lua -- Entry point, initialization, orchestration
```
#### 2.3 — Core classes
| Class | Responsibility | Replaces |
| ----- | -------------- | -------- |
| `Coalition` | Encapsulates side (1/2) and per-coalition state | `ctld.spawnedCratesRED/BLUE`, `ctld.droppedTroopsRED/BLUE`, etc. (34 tables → 2 instances) |
| `Transport` | State of a transport helicopter/plane | `ctld.inTransitTroops[name]`, `ctld.hoverStatus[name]` |
| `Crate` | Represents a logistics crate | Entries from `ctld.spawnableCrates`, `ctld.crateLookupTable` |
| `CrateManager` | Spawn, pickup, drop, unpack crates | `ctld.spawnCrate`, `ctld.unpackCrates`, `ctld.checkHoverStatus` |
| `FOB` | A built Forward Operating Base | `ctld.builtFOBS[name]` |
| `JTACController` | An active JTAC with its lasing state | `ctld.jtacUnits`, `ctld.jtacCurrentTargets`, `ctld.jtacSelectedTarget` |
| `Beacon` | A deployed radio beacon | `ctld.deployedRadioBeacons[name]` |
| `StateManager` | Central registry of all active objects | Replaces 34 global tables |
| `Config` | Typed user configuration | Current USER CONFIGURATION section |
#### 2.4 — Eliminating RED/BLUE duplication
Before (50+ branches):
```lua
if _heli:getCoalition() == 1 then
_extract = ctld.findNearestGroup(_heli, ctld.droppedTroopsRED)
else
_extract = ctld.findNearestGroup(_heli, ctld.droppedTroopsBLUE)
end
```
After:
```lua
local side = stateManager:getCoalition(heli:getCoalition())
local extract = side:findNearestDroppedTroop(heli)
```
---
### Phase 3 — MIST middleware
**Goal**: Isolate MIST behind a facade. CTLD never references `mist.*` directly.
| Task | Detail |
| ---- | ------ |
| 3.1 | Inventory the 91 MIST calls and categorize them (trivial / medium / complex) |
| 3.2 | Create `src/mist_compat/mist_middleware.lua` exposing a clean API |
| 3.3 | Rewrite trivial functions: `deepCopy`, `get2DDist`, `round`, `makeVec2/3` |
| 3.4 | Wrap medium functions: `getHeading`, `vec.*`, `tostringLL/MGRS` |
| 3.5 | Delegate complex functions to MIST: `dynAdd`, `dynAddStatic`, `getUnitsLOS` |
| 3.6 | Replace all `mist.*` calls in modules with middleware calls |
| 3.7 | (Long term) Rewrite complex functions to eliminate MIST entirely |
**Deliverable**: CTLD works with or without MIST (graceful degradation when MIST is absent, eventually).
---
### Phase 4 — Legacy API compatibility layer
**Goal**: Existing missions continue to work without modification.
| Task | Detail |
| ---- | ------ |
| 4.1 | List all public `ctld.*` functions documented in the README |
| 4.2 | Create `src/compat/legacy_api.lua` with wrappers that call the new API |
| 4.3 | Each wrapper logs a deprecated warning with the new API name |
| 4.4 | Document old → new migration in `docs/migration-v2.md` |
| 4.5 | Announce the policy: legacy maintained in v2, removed in v3 |
Example:
```lua
-- legacy_api.lua
function ctld.spawnCrateAtZone(_side, _weight, _zone)
ctld.logWarning("DEPRECATED: ctld.spawnCrateAtZone() -> use CrateManager:spawnAtZone()")
local side = (_side == "red") and 1 or 2
return ctld.crateManager:spawnAtZone(side, _weight, _zone)
end
```
---
### Phase 5 — Unit tests
**Goal**: Coverage of pure logic outside DCS + in-game smoke tests.
#### 5.1 — Framework and mocks
| Task | Detail |
| ---- | ------ |
| 5.1.1 | Set up busted (Lua 5.1) + luarocks in the repo |
| 5.1.2 | Create `test/mocks/dcs_env.lua`: stubs for `trigger`, `Unit`, `Group`, `coalition`, `land`, `timer`, `missionCommands`, `coord`, `world`, `env` |
| 5.1.3 | Create `test/mocks/mist_env.lua`: stubs for MIST functions used |
| 5.1.4 | Configure busted to load mocks before tests |
#### 5.2 — Unit tests (outside DCS)
| Module | Priority tests |
| ------ | -------------- |
| `lib/class.lua` | Inheritance, instantiation, override |
| `lib/vec.lua` | 2D/3D distance, bearing, clock direction |
| `lib/utils.lua` | deepCopy, formatText |
| `core/coalition.lua` | Per-coalition state management, lookup |
| `core/i18n.lua` | Translation, fallback, parameters |
| `core/config.lua` | Default values, override |
| `logistics/crate.lua` | Weight uniqueness, lookup |
| `compat/legacy_api.lua` | Wrappers call the correct new API |
#### 5.3 — In-game tests
| Task | Detail |
| ---- | ------ |
| 5.3.1 | Create an automated test mission (DO SCRIPT running a test suite) |
| 5.3.2 | Write results to a file via `io.open` (desanitized server) |
| 5.3.3 | Validate: troop load/unload, crate spawn/unpack, JTAC lasing, FOB build, beacons |
---
### Phase 6 — CI infrastructure
**Goal**: Automate build, tests, and release.
| Task | Detail |
| ---- | ------ |
| 6.1 | **Build script**: Lua (or Python/Bash) script that concatenates `src/**/*.lua``dist/CTLD.lua` in the correct order |
| 6.2 | **GitHub Actions — Tests**: install Lua 5.1 + luarocks + busted, run `busted test/` |
| 6.3 | **GitHub Actions — Build**: generate `dist/CTLD.lua` and `dist/CTLD-i18n.lua` |
| 6.4 | **GitHub Actions — Release**: on tag, publish the `.lua` artifact as a GitHub release |
| 6.5 | **GitHub Actions — Docs**: MkDocs build + deploy to GitHub Pages |
| 6.6 | **i18n lint**: CI script comparing keys across languages and checking `translation_version` |
---
### Phase 7 — i18n cleanup + tooling
**Goal**: Reliable i18n with automatic drift detection.
| Task | Detail |
| ---- | ------ |
| 7.1 | Full audit: list EN vs FR vs ES vs KO keys, identify missing ones |
| 7.2 | Fill empty FR keys (crate/equipment names) |
| 7.3 | Update KO (1.1 → 1.6+) or mark it as `incomplete` |
| 7.4 | CI lint script for i18n (see 6.6) |
| 7.5 | Document the process of adding a language in `docs/contributing/i18n.md` |
| 7.6 | Consider extracting i18n into per-language files (`i18n/fr.lua`, `i18n/ko.lua`) |
---
### Phase 8 — Documentation
**Goal**: 3 guides for 3 audiences, auto-published.
#### 8.1 — `docs/` structure
```text
docs/
├── index.md -- Landing page
├── user-guide/
│ ├── getting-started.md -- For the player: F10 menus, in-game workflow
│ ├── troops.md -- Troop loading/unloading
│ ├── crates.md -- Crate system
│ ├── jtac.md -- Using JTACs
│ ├── fob.md -- FOB construction
│ └── beacons.md -- Radio beacons
├── mission-maker/
│ ├── setup.md -- Mission installation
│ ├── configuration.md -- All configurable options
│ ├── api-reference.md -- Public API (DO SCRIPT)
│ ├── zones.md -- Pickup/dropoff/waypoint zones
│ ├── jtac-setup.md -- Advanced JTAC configuration
│ └── examples.md -- Mission examples
├── developer/
│ ├── architecture.md -- Module, class, and flow diagrams
│ ├── contributing.md -- How to contribute
│ ├── building.md -- Build script, CI
│ ├── testing.md -- Running tests
│ ├── i18n.md -- Adding/maintaining a translation
│ └── migration-v2.md -- v1 → v2 migration guide
└── mkdocs.yml -- MkDocs configuration
```
#### 8.2 — Publishing
- MkDocs Material theme
- GitHub Actions: build + deploy to `gh-pages` on every push to `next`
- Slimmed-down README.md: links to the full documentation site
---
## Indicative timeline
| Phase | Dependencies | Complexity |
| ----- | ------------ | ---------- |
| 1 — Dead code cleanup | None | Low |
| 2 — Modules + OOP | Phase 1 | **High** |
| 3 — MIST middleware | Phase 2 | Medium |
| 4 — Legacy compat | Phase 2 | Medium |
| 5 — Tests | Phases 2-3 | Medium |
| 6 — CI | Phases 2, 5 | Medium |
| 7 — i18n | Phase 2 | Low |
| 8 — Documentation | Phases 2-4 | Medium |
> Phases 3 and 4 can be worked on in parallel.
> Phase 6 can start as early as Phase 2 (build script) and grow incrementally.
---
## Branching strategy
```text
main (stable, v1.x)
└── next (v2 development)
├── feature/phase1-cleanup
├── feature/phase2-oop-core
├── feature/phase2-oop-jtac
├── feature/phase3-mist-middleware
├── feature/phase4-legacy-compat
├── feature/phase5-tests
└── ...
```
- `main`: stable v1.x releases, urgent hotfixes only.
- `next`: v2 integration, git flow (feature → next → release).
- Tags: `v2.0-alpha.1`, `v2.0-beta.1`, `v2.0-rc.1`, `v2.0`.
---
## Risks and mitigations
| Risk | Impact | Mitigation |
| ---- | ------ | ---------- |
| Gameplay regressions after OOP refactoring | High | Unit tests + systematic test missions |
| DCS mock divergence from real API | Medium | In-game tests as complement, versioned mocks |
| Incomplete MIST middleware | Medium | Progressive approach, MIST remains as fallback |
| Mission maker resistance to API changes | Medium | Legacy layer + communication + migration guide |
| Build script complexity (module ordering) | Low | Explicit dependencies, build tested in CI |
+75
View File
@@ -0,0 +1,75 @@
# Copilot Instructions for DCS-CTLD
## Working mode / Mode de travail
- **Communication language**: French (français) for all conversations and commit messages.
- **Documentation language**: English for all technical documentation (code comments, docs/, README). French summaries in docs are acceptable but English is the primary language.
- **Development methodology**: TDD (Test-Driven Development) — write tests before implementation when possible.
- **Programming paradigm**: OOP Lua 5.1 with metatables and classes. No procedural spaghetti.
- **Branching strategy**: Git flow on the `next` branch. Feature branches named `feature/<phase>-<description>`. Never commit directly to `main` or `next`.
- **Commit style**: Conventional Commits (`feat:`, `fix:`, `refactor:`, `test:`, `docs:`, `chore:`).
- **Build target**: Individual source modules in `src/` are concatenated into a single `dist/CTLD.lua` deliverable by a build script. Never edit the built file directly.
- **MIST dependency**: CTLD code must never call `mist.*` directly. All MIST usage goes through the middleware layer (`src/mist_compat/`).
- **Legacy API**: When refactoring a public `ctld.*` function, always create a deprecated wrapper in `src/compat/legacy_api.lua` that logs a warning and delegates to the new API.
- **Refer to the modernization plan**: See `.github/MODERNIZATION-PLAN.md` for the full roadmap and architectural decisions.
## Project context
- This repository contains Lua mission scripts for DCS World.
- The primary script is CTLD.lua.
- Internationalization tables are split between CTLD.lua (English reference keys) and CTLD-i18n.lua (translated values).
- Runtime is DCS mission scripting environment (Lua 5.1, metatables available, no LuaJIT, no goto).
- Assumes desanitized server (io, os, lfs accessible).
- MIST is being progressively replaced by an internal middleware layer.
## Architecture (v2 target)
- Source modules live in `src/` organized by domain: `lib/`, `core/`, `transport/`, `logistics/`, `jtac/`, `ui/`, `recon/`, `ai/`, `compat/`, `mist_compat/`.
- OOP via a micro class system using metatables (`src/lib/class.lua`).
- State is managed by a `StateManager` singleton and per-coalition `Coalition` instances — no more `ctld.xxxRED`/`ctld.xxxBLUE` table pairs.
- Tests live in `test/` and use busted with DCS/MIST mocks.
## Compatibility (v1 legacy)
- Preserve existing public ctld.* APIs used by Mission Editor DO SCRIPT triggers.
- Do not rename exported ctld functions or change their parameter semantics unless explicitly requested.
- Keep behavior compatible with existing .miz missions in this repository.
- Keep script load order assumptions intact: MIST first, CTLD-i18n.lua before CTLD.lua.
## CTLD.lua editing rules
- Keep user-tunable options in the USER CONFIGURATION section with clear comments and safe defaults.
- Keep coalition conventions consistent:
- 1 = red
- 2 = blue
- 0 = both (where applicable)
- Keep pickup/dropoff/waypoint zone tuple formats compatible with current parser logic.
- Keep crate weight values unique in ctld.spawnableCrates.
- Preserve callback behavior and action names used by ctld.processCallback.
- Use defensive nil checks before calling methods on DCS objects (Unit/Group/zone lookups).
- Prefer existing logging patterns (ctld.logInfo, env.info, env.error) over ad-hoc prints.
- Avoid adding heavy polling loops; prefer bounded searches and scheduled checks.
## I18N rules
- For every new player-visible string, add an English reference key and use ctld.i18n_translate at call sites.
- Do not hardcode new menu or gameplay text without i18n_translate.
- When adding keys, keep translation_version alignment in mind and add placeholders in CTLD-i18n.lua tables.
- Do not remove or rename existing i18n keys unless all language tables are updated.
## Testing expectations
- Prefer the dynamic loading workflow documented in README for fast iteration.
- After gameplay logic changes, validate at least:
- troop load/unload flows
- crate spawn/load/unpack flows
- JTAC-related flows (if touched)
- Use repository missions for smoke tests when relevant:
- test-dev-dynamic.miz
- test-dev-static.miz
- test-mission.miz
- If user-facing behavior or configuration changes, update README examples in the same change.
## Code style conventions
- Follow existing file style and indentation.
- OOP Lua 5.1: use the project class system (`src/lib/class.lua`) for new classes.
- For internal helpers, follow existing naming patterns (local variables often prefixed with _).
- Keep mission-designer guidance comments concise and practical.
- No direct `mist.*` calls — use the middleware.
- Every new public function should have at least one unit test.
+5
View File
@@ -0,0 +1,5 @@
{
"Lua.diagnostics.globals": [
"ctld"
]
}
+274 -198
View File
@@ -18,7 +18,7 @@ ctld.i18n = {}
--======== FRENCH - FRANCAIS =====================================================================================
ctld.i18n["fr"] = {}
ctld.i18n["fr"].translation_version = "1.0" -- make sure that this translation is compatible with the current version of the english language texts (ctld.i18n["en"].translation_version)
ctld.i18n["fr"].translation_version = "1.6" -- make sure that this translation is compatible with the current version of the english language texts (ctld.i18n["en"].translation_version)
local lang="fr";env.info(string.format("I - CTLD.i18n_translate: Loading %s language version %s", lang, tostring(ctld.i18n[lang].translation_version)))
--- groups names
@@ -40,66 +40,98 @@ 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
ctld.i18n["fr"]["Humvee - MG"] = ""
ctld.i18n["fr"]["Humvee - TOW"] = ""
ctld.i18n["fr"]["Light Tank - MRAP"] = ""
ctld.i18n["fr"]["Med Tank - LAV-25"] = ""
ctld.i18n["fr"]["Heavy Tank - Abrams"] = ""
ctld.i18n["fr"]["BTR-D"] = ""
ctld.i18n["fr"]["BRDM-2"] = ""
ctld.i18n["fr"]["Hummer - JTAC"] = ""
ctld.i18n["fr"]["M-818 Ammo Truck"] = ""
ctld.i18n["fr"]["M-978 Tanker"] = ""
ctld.i18n["fr"]["SKP-11 - JTAC"] = ""
ctld.i18n["fr"]["Ural-375 Ammo Truck"] = ""
ctld.i18n["fr"]["KAMAZ Ammo Truck"] = ""
ctld.i18n["fr"]["EWR Radar"] = ""
ctld.i18n["fr"]["FOB Crate - Small"] = ""
ctld.i18n["fr"]["MQ-9 Repear - JTAC"] = ""
ctld.i18n["fr"]["RQ-1A Predator - JTAC"] = ""
ctld.i18n["fr"]["MLRS"] = ""
ctld.i18n["fr"]["SpGH DANA"] = ""
ctld.i18n["fr"]["T155 Firtina"] = ""
ctld.i18n["fr"]["Howitzer"] = ""
ctld.i18n["fr"]["SPH 2S19 Msta"] = ""
ctld.i18n["fr"]["M1097 Avenger"] = ""
ctld.i18n["fr"]["M48 Chaparral"] = ""
ctld.i18n["fr"]["Roland ADS"] = ""
ctld.i18n["fr"]["Gepard AAA"] = ""
ctld.i18n["fr"]["LPWS C-RAM"] = ""
ctld.i18n["fr"]["9K33 Osa"] = ""
ctld.i18n["fr"]["9P31 Strela-1"] = ""
ctld.i18n["fr"]["9K35M Strela-10"] = ""
ctld.i18n["fr"]["9K331 Tor"] = ""
ctld.i18n["fr"]["2K22 Tunguska"] = ""
ctld.i18n["fr"]["HAWK Launcher"] = ""
ctld.i18n["fr"]["HAWK Search Radar"] = ""
ctld.i18n["fr"]["HAWK Track Radar"] = ""
ctld.i18n["fr"]["HAWK PCP"] = ""
ctld.i18n["fr"]["HAWK CWAR"] = ""
ctld.i18n["fr"]["HAWK Repair"] = ""
ctld.i18n["fr"]["NASAMS Launcher 120C"] = ""
ctld.i18n["fr"]["NASAMS Search/Track Radar"] = ""
ctld.i18n["fr"]["NASAMS Command Post"] = ""
ctld.i18n["fr"]["NASAMS Repair"] = ""
ctld.i18n["fr"]["KUB Launcher"] = ""
ctld.i18n["fr"]["KUB Radar"] = ""
ctld.i18n["fr"]["KUB Repair"] = ""
ctld.i18n["fr"]["BUK Launcher"] = ""
ctld.i18n["fr"]["BUK Search Radar"] = ""
ctld.i18n["fr"]["BUK CC Radar"] = ""
ctld.i18n["fr"]["BUK Repair"] = ""
ctld.i18n["fr"]["Patriot Launcher"] = ""
ctld.i18n["fr"]["Patriot Radar"] = ""
ctld.i18n["fr"]["Patriot ECS"] = ""
ctld.i18n["fr"]["Patriot ICC"] = ""
ctld.i18n["fr"]["Patriot EPP"] = ""
ctld.i18n["fr"]["Patriot AMG (optional)"] = ""
ctld.i18n["fr"]["Patriot Repair"] = ""
ctld.i18n["fr"]["S-300 Grumble TEL C"] = ""
ctld.i18n["fr"]["S-300 Grumble Flap Lid-A TR"] = ""
ctld.i18n["fr"]["S-300 Grumble Clam Shell SR"] = ""
ctld.i18n["fr"]["S-300 Grumble Big Bird SR"] = ""
ctld.i18n["fr"]["S-300 Grumble C2"] = ""
ctld.i18n["fr"]["S-300 Repair"] = ""
ctld.i18n["fr"]["Humvee - TOW - All crates"] = "Humvee - TOW - Toutes les caisses"
ctld.i18n["fr"]["Light Tank - MRAP - All crates"] = "Light Tank - MRAP - Toutes les caisses"
ctld.i18n["fr"]["Med Tank - LAV-25 - All crates"] = "Med Tank - LAV-25 - Toutes les caisses"
ctld.i18n["fr"]["Heavy Tank - Abrams - All crates"] = "Heavy Tank - Abrams - Toutes les caisses"
ctld.i18n["fr"]["Hummer - JTAC - All crates"] = "Hummer - JTAC - Toutes les caisses"
ctld.i18n["fr"]["M-818 Ammo Truck - All crates"] = "M-818 Ammo Truck - Toutes les caisses"
ctld.i18n["fr"]["M-978 Tanker - All crates"] = "M-978 Tanker - Toutes les caisses"
ctld.i18n["fr"]["Ural-375 Ammo Truck - All crates"] = "Ural-375 Ammo Truck - Toutes les caisses"
ctld.i18n["fr"]["EWR Radar - All crates"] = "EWR Radar - Toutes les caisses"
ctld.i18n["fr"]["MLRS - All crates"] = "MLRS - Toutes les caisses"
ctld.i18n["fr"]["SpGH DANA - All crates"] = "SpGH DANA - Toutes les caisses"
ctld.i18n["fr"]["T155 Firtina - All crates"] = "T155 Firtina - Toutes les caisses"
ctld.i18n["fr"]["Howitzer - All crates"] = "Howitzer - Toutes les caisses"
ctld.i18n["fr"]["SPH 2S19 Msta - All crates"] = "SPH 2S19 Msta - Toutes les caisses"
ctld.i18n["fr"]["M1097 Avenger - All crates"] = "M1097 Avenger - Toutes les caisses"
ctld.i18n["fr"]["M48 Chaparral - All crates"] = "M48 Chaparral - Toutes les caisses"
ctld.i18n["fr"]["Roland ADS - All crates"] = "Roland ADS - Toutes les caisses"
ctld.i18n["fr"]["Gepard AAA - All crates"] = "Gepard AAA - Toutes les caisses"
ctld.i18n["fr"]["LPWS C-RAM - All crates"] = "LPWS C-RAM - Toutes les caisses"
ctld.i18n["fr"]["9K33 Osa - All crates"] = "9K33 Osa - Toutes les caisses"
ctld.i18n["fr"]["9P31 Strela-1 - All crates"] = "9P31 Strela-1 - Toutes les caisses"
ctld.i18n["fr"]["9K35M Strela-10 - All crates"] = "9K35M Strela-10 - Toutes les caisses"
ctld.i18n["fr"]["9K331 Tor - All crates"] = "9K331 Tor - Toutes les caisses"
ctld.i18n["fr"]["2K22 Tunguska - All crates"] = "2K22 Tunguska - Toutes les caisses"
ctld.i18n["fr"]["HAWK - All crates"] = "HAWK - Toutes les caisses"
ctld.i18n["fr"]["NASAMS - All crates"] = "NASAMS - Toutes les caisses"
ctld.i18n["fr"]["KUB - All crates"] = "KUB - Toutes les caisses"
ctld.i18n["fr"]["BUK - All crates"] = "BUK - Toutes les caisses"
ctld.i18n["fr"]["Patriot - All crates"] = "Patriot - Toutes les caisses"
ctld.i18n["fr"]["Patriot - All crates"] = "Patriot - Toutes les caisses"
--- mission design error messages
ctld.i18n["fr"]["CTLD.lua ERROR: Can't find trigger called %1"] = "CTLD.lua ERREUR : Impossible de trouver le déclencheur appelé %1"
@@ -126,8 +158,6 @@ ctld.i18n["fr"]["FOB Crate dropped back to base"] = "Caisse FOB ramenée à la b
ctld.i18n["fr"]["FOB Crate Loaded"] = "Caisse FOB chargée"
ctld.i18n["fr"]["%1 loaded a FOB Crate ready for delivery!"] = "%1 a chargé une caisse FOB prête à être livrée !"
ctld.i18n["fr"]["There are no friendly logistic units nearby to load a FOB crate from!"] = "Il n'y a pas d'unités logistiques alliée à proximité pour charger une caisse FOB !"
ctld.i18n["fr"]["You already have troops onboard."] = "Vous avez déjà des troupes à bord."
ctld.i18n["fr"]["You already have vehicles onboard."] = "Vous avez déjà des véhicules à bord."
ctld.i18n["fr"]["This area has no more reinforcements available!"] = "Cette zone n'a plus de renforts disponibles !"
ctld.i18n["fr"]["You are not in a pickup zone and no one is nearby to extract"] = "Vous n'êtes pas dans une zone d'embarquement et personne n'est à proximité pour être extrait."
ctld.i18n["fr"]["You are not in a pickup zone"] = "Vous n'êtes pas dans une zone d'embarquement"
@@ -135,6 +165,7 @@ ctld.i18n["fr"]["No one to unload"] = "Personne à débarquer"
ctld.i18n["fr"]["Dropped troops back to base"] = "Troupes larguées à la base"
ctld.i18n["fr"]["Dropped vehicles back to base"] = "Véhicules largués à la base"
ctld.i18n["fr"]["You already have troops onboard."] = "Vous avez déjà des troupes à bord."
ctld.i18n["fr"]["Count Infantries limit in the mission reached, you can't load more troops"] = "Nombre maximum de troupes sur mission atteint, vous ne pouvez pas charger plus de troupes"
ctld.i18n["fr"]["You already have vehicles onboard."] = "Vous avez déjà des véhicules à bord."
ctld.i18n["fr"]["Sorry - The group of %1 is too large to fit. \n\nLimit is %2 for %3"] = "Désolé - Le groupe de %1 est trop important. \n\nLa limite est de %2 pour %3"
ctld.i18n["fr"]["%1 extracted troops in %2 from combat"] = "%1 troupes extraites du combat en %2"
@@ -233,16 +264,17 @@ ctld.i18n["fr"]["Unload / Extract Troops"] = "Débarqt / Embarqt Troupes"
ctld.i18n["fr"]["Next page"] = "page suiv."
ctld.i18n["fr"]["Load "] = "Charger "
ctld.i18n["fr"]["Vehicle / FOB Transport"] = "Transport Vehicule / FOB"
ctld.i18n["fr"]["Vehicle / FOB Crates"] = "Caisses Vehicule / FOB"
ctld.i18n["fr"]["Crates: Vehicle / FOB / Drone"] = "Caisses Vehicule / FOB / Drone"
ctld.i18n["fr"]["Unload Vehicles"] = "Décharger Vehicles"
ctld.i18n["fr"]["Load / Extract Vehicles"] = "Chargt / Déchargt Vehicules"
ctld.i18n["fr"]["Load / Unload FOB Crate"] = "Chargt / Déchargt Caisse FOB"
ctld.i18n["fr"]["Repack Vehicles"] = "Ré-emballer véhicules"
ctld.i18n["fr"]["CTLD Commands"] = "Commandes CTLD"
ctld.i18n["fr"]["CTLD"] = "CTLD"
ctld.i18n["fr"]["Check Cargo"] = "Vérif° chargement"
ctld.i18n["fr"]["Load Nearby Crate"] = "Charger caisse proche"
ctld.i18n["fr"]["Load Nearby Crate(s)"] = "Charger caisse(s) proche"
ctld.i18n["fr"]["Unpack Any Crate"] = "Déballer caisses"
ctld.i18n["fr"]["Drop Crate"] = "Décharger Caisse"
ctld.i18n["fr"]["Drop Crate(s)"] = "Décharger caisse(s)"
ctld.i18n["fr"]["List Nearby Crates"] = "Liste caisses proches"
ctld.i18n["fr"]["List FOBs"] = "Liste FOBs"
ctld.i18n["fr"]["List Beacons"] = "Liste balises"
@@ -254,16 +286,22 @@ ctld.i18n["fr"]["Drop Orange Smoke"] = "Déposer Fumi Orange"
ctld.i18n["fr"]["Drop Green Smoke"] = "Déposer Fumi Vert"
ctld.i18n["fr"]["Drop Beacon"] = "Déposer Fumi Vert"
ctld.i18n["fr"]["Radio Beacons"] = "Déposer Balise"
ctld.i18n["fr"]["Remove Closet Beacon"] = "Supprimer Balise +proche"
ctld.i18n["fr"]["Remove Closest Beacon"] = "Supprimer Balise +proche"
ctld.i18n["fr"]["JTAC Status"] = "Statut JTAC"
ctld.i18n["fr"]["DISABLE "] = "DESACTIVE "
ctld.i18n["fr"]["ENABLE "] = "ACTIVE "
ctld.i18n["fr"]["REQUEST "] = "DEMANDE"
ctld.i18n["fr"]["Reset TGT Selection"] = "Réinitialiser sélection TGT"
-- F10 RECON menus
ctld.i18n["fr"]["RECON"] = "RECONNAISSANCE"
ctld.i18n["fr"]["Show targets in LOS (refresh)"] = "Marquer cibles visibles sur carte F10"
ctld.i18n["fr"]["Hide targets in LOS"] = "Effacer marques sur carte F10"
ctld.i18n["fr"]["START autoRefresh targets in LOS"] = "Lancer suivi automatique des cibles"
ctld.i18n["fr"]["STOP autoRefresh targets in LOS"] = "Stopper suivi automatique des cibles"
--====== SPANISH : ESPAÑOL====================================================================================
ctld.i18n["es"] = {}
ctld.i18n["es"].translation_version = "1.0" -- make sure that this translation is compatible with the current version of the english language texts (ctld.i18n["en"].translation_version)
ctld.i18n["es"].translation_version = "1.6" -- make sure that this translation is compatible with the current version of the english language texts (ctld.i18n["en"].translation_version)
local lang="es";env.info(string.format("I - CTLD.i18n_translate: Loading %s language version %s", lang, tostring(ctld.i18n[lang].translation_version)))
--- groups names
@@ -276,7 +314,7 @@ ctld.i18n["es"]["Single JTAC"] = "JTAC solo"
ctld.i18n["es"]["2x - Standard Groups"] = "2x - Grupos estándares"
ctld.i18n["es"]["2x - Anti Air"] = "2x - Defensas aéreas"
ctld.i18n["es"]["2x - Anti Tank"] = "2x - Antitanque"
ctld.i18n["es"]["2x - Standard Groups + 2x morteros"] = "2x - Grupos estándar + 2x Grupos morteros"
ctld.i18n["es"]["2x - Standard Groups + 2x Mortar"] = "2x - Grupos estándar + 2x Grupos morteros"
ctld.i18n["es"]["3x - Standard Groups"] = "3x - Defensas aéreas"
ctld.i18n["es"]["3x - Anti Air"] = "3x - Defensas aéreas"
ctld.i18n["es"]["3x - Anti Tank"] = "3x - Antitanque"
@@ -285,66 +323,98 @@ ctld.i18n["es"]["5x - Mortar Squad"] = "5x - Grupos de morteros"
ctld.i18n["es"]["Mortar Squad Red"] = "Grupo mortero rojo"
--- crates names
ctld.i18n["es"]["Humvee - MG"] = nil
ctld.i18n["es"]["Humvee - TOW"] = nil
ctld.i18n["es"]["Light Tank - MRAP"] = nil
ctld.i18n["es"]["Med Tank - LAV-25"] = nil
ctld.i18n["es"]["Heavy Tank - Abrams"] = nil
ctld.i18n["es"]["BTR-D"] = nil
ctld.i18n["es"]["BRDM-2"] = nil
ctld.i18n["es"]["Hummer - JTAC"] = nil
ctld.i18n["es"]["M-818 Ammo Truck"] = nil
ctld.i18n["es"]["M-978 Tanker"] = nil
ctld.i18n["es"]["SKP-11 - JTAC"] = nil
ctld.i18n["es"]["Ural-375 Ammo Truck"] = nil
ctld.i18n["es"]["KAMAZ Ammo Truck"] = nil
ctld.i18n["es"]["EWR Radar"] = nil
ctld.i18n["es"]["FOB Crate - Small"] = nil
ctld.i18n["es"]["MLRS"] = nil
ctld.i18n["es"]["SpGH DANA"] = nil
ctld.i18n["es"]["T155 Firtina"] = nil
ctld.i18n["es"]["Howitzer"] = nil
ctld.i18n["es"]["SPH 2S19 Msta"] = nil
ctld.i18n["es"]["M1097 Avenger"] = nil
ctld.i18n["es"]["M48 Chaparral"] = nil
ctld.i18n["es"]["Roland ADS"] = nil
ctld.i18n["es"]["Gepard AAA"] = nil
ctld.i18n["es"]["LPWS C-RAM"] = nil
ctld.i18n["es"]["9K33 Osa"] = nil
ctld.i18n["es"]["9P31 Strela-1"] = nil
ctld.i18n["es"]["9K35M Strela-10"] = nil
ctld.i18n["es"]["9K331 Tor"] = nil
ctld.i18n["es"]["2K22 Tunguska"] = nil
ctld.i18n["es"]["HAWK Launcher"] = nil
ctld.i18n["es"]["HAWK Search Radar"] = nil
ctld.i18n["es"]["HAWK Track Radar"] = nil
ctld.i18n["es"]["HAWK PCP"] = nil
ctld.i18n["es"]["HAWK CWAR"] = nil
ctld.i18n["es"]["HAWK Repair"] = nil
ctld.i18n["es"]["NASAMS Launcher 120C"] = nil
ctld.i18n["es"]["NASAMS Search/Track Radar"] = nil
ctld.i18n["es"]["NASAMS Command Post"] = nil
ctld.i18n["es"]["NASAMS Repair"] = nil
ctld.i18n["es"]["KUB Launcher"] = nil
ctld.i18n["es"]["KUB Radar"] = nil
ctld.i18n["es"]["KUB Repair"] = nil
ctld.i18n["es"]["BUK Launcher"] = nil
ctld.i18n["es"]["BUK Search Radar"] = nil
ctld.i18n["es"]["BUK CC Radar"] = nil
ctld.i18n["es"]["BUK Repair"] = nil
ctld.i18n["es"]["Patriot Launcher"] = nil
ctld.i18n["es"]["Patriot Radar"] = nil
ctld.i18n["es"]["Patriot ECS"] = nil
ctld.i18n["es"]["Patriot ICC"] = nil
ctld.i18n["es"]["Patriot EPP"] = nil
ctld.i18n["es"]["Patriot AMG (optional)"] = nil
ctld.i18n["es"]["Patriot Repair"] = nil
ctld.i18n["es"]["S-300 Grumble TEL C"] = nil
ctld.i18n["es"]["S-300 Grumble Flap Lid-A TR"] = nil
ctld.i18n["es"]["S-300 Grumble Clam Shell SR"] = nil
ctld.i18n["es"]["S-300 Grumble Big Bird SR"] = nil
ctld.i18n["es"]["S-300 Grumble C2"] = nil
ctld.i18n["es"]["S-300 Repair"] = nil
ctld.i18n["es"]["Humvee - MG"] = "Humvee - Antipersonal .50 cal"
ctld.i18n["es"]["Humvee - TOW"] = "Humvee - Antitanque TOW"
ctld.i18n["es"]["Light Tank - MRAP"] = "Tanque ligero - MRAP"
ctld.i18n["es"]["Med Tank - LAV-25"] = "Tanque Med - LAV-25"
ctld.i18n["es"]["Heavy Tank - Abrams"] = "Tanque pesado - Abrams"
ctld.i18n["es"]["BTR-D"] = "BTR-D - Transporte de tropas"
ctld.i18n["es"]["BRDM-2"] = "BRDM-2 - Reconocimiento"
ctld.i18n["es"]["Hummer - JTAC"] = "JTAC Hummer"
ctld.i18n["es"]["M-818 Ammo Truck"] = "Camión M-818 de municiones"
ctld.i18n["es"]["M-978 Tanker"] = "Camión cisterna M-978"
ctld.i18n["es"]["SKP-11 - JTAC"] = "JTAC SKP-11"
ctld.i18n["es"]["Ural-375 Ammo Truck"] = "Camión Ural-375 de municiones"
ctld.i18n["es"]["KAMAZ Ammo Truck"] = "Camión KAMAZ de municiones"
ctld.i18n["es"]["EWR Radar"] = "Radar Alerta Temprana"
ctld.i18n["es"]["FOB Crate - Small"] = "Caja FOB - Pequeña"
ctld.i18n["es"]["MQ-9 Repear - JTAC"] = "JTAC MQ-9 Repear"
ctld.i18n["es"]["RQ-1A Predator - JTAC"] = "JTAC RQ-1A Predator"
ctld.i18n["es"]["MLRS"] = "MLRS - Artilleria de cohetes"
ctld.i18n["es"]["SpGH DANA"] = "Obus autopropulsado SpGH DANA"
ctld.i18n["es"]["T155 Firtina"] = "Obus autopropulsado T155 Firtina"
ctld.i18n["es"]["Howitzer"] = "Obus autopropulsado M109A6 Paladin"
ctld.i18n["es"]["SPH 2S19 Msta"] = "SPH 2S19 Msta - Obus Autopropulsado"
ctld.i18n["es"]["M1097 Avenger"] = "M1097 Avenger - SAM Corta Distancia"
ctld.i18n["es"]["M48 Chaparral"] = "M48 Chaparral - SAM Corta Distancia"
ctld.i18n["es"]["Roland ADS"] = "Roland ADS - Lanzador"
ctld.i18n["es"]["Gepard AAA"] = "Gepard AAA - AAA"
ctld.i18n["es"]["LPWS C-RAM"] = "LPWS C-RAM - AAA"
ctld.i18n["es"]["9K33 Osa"] = "9K33 Osa - SA-8 Gecko"
ctld.i18n["es"]["9P31 Strela-1"] = "9P31 Strela-1 - SA-9 Gaskin"
ctld.i18n["es"]["9K35M Strela-10"] = "9K35M Strela-10 - SA-13 Gopher"
ctld.i18n["es"]["9K331 Tor"] = "9K331 Tor - SA-15 Tor"
ctld.i18n["es"]["2K22 Tunguska"] = "2K22 Tunguska - SA-19 Tunguska"
ctld.i18n["es"]["HAWK Launcher"] = "HAWK - Lanzador"
ctld.i18n["es"]["HAWK Search Radar"] = "HAWK - Radar de Búsqueda"
ctld.i18n["es"]["HAWK Track Radar"] = "HAWK - Radar de Seguimiento"
ctld.i18n["es"]["HAWK PCP"] = "HAWK - Puesto de Comando"
ctld.i18n["es"]["HAWK CWAR"] = "HAWK - Sistema de Control de Guerra"
ctld.i18n["es"]["HAWK Repair"] = "Reparar HAWK"
ctld.i18n["es"]["NASAMS Launcher 120C"] = "NASAMS - Lanzador 120C"
ctld.i18n["es"]["NASAMS Search/Track Radar"] = "NASAMS - Radar de Búsqueda/Seguimiento"
ctld.i18n["es"]["NASAMS Command Post"] = "NASAMS - Puesto de Mando"
ctld.i18n["es"]["NASAMS Repair"] = "Reparar NASAMS"
ctld.i18n["es"]["KUB Launcher"] = "KUB - Lanzador"
ctld.i18n["es"]["KUB Radar"] = "KUB - Radar"
ctld.i18n["es"]["KUB Repair"] = "Reparar KUB"
ctld.i18n["es"]["BUK Launcher"] = "BUK - Lanzador"
ctld.i18n["es"]["BUK Search Radar"] = "BUK - Radar de Búsqueda"
ctld.i18n["es"]["BUK CC Radar"] = "BUK - Radar de Control de Combate"
ctld.i18n["es"]["BUK Repair"] = "Reparar BUK"
ctld.i18n["es"]["Patriot Launcher"] = "Patriot - Lanzador"
ctld.i18n["es"]["Patriot Radar"] = "Patriot - Radar de Búsqueda"
ctld.i18n["es"]["Patriot ECS"] = "Patriot - Puesto de Mando"
ctld.i18n["es"]["Patriot ICC"] = "Patriot - Sistema de Control de Fuego"
ctld.i18n["es"]["Patriot EPP"] = "Patriot - Generador"
ctld.i18n["es"]["Patriot AMG (optional)"] = ""
ctld.i18n["es"]["Patriot Repair"] = "Reparar Patriot"
ctld.i18n["es"]["S-300 Grumble TEL C"] = "S-300 Grumble TEL C - Lanzador"
ctld.i18n["es"]["S-300 Grumble Flap Lid-A TR"] = "S-300 Grumble Flap Lid-A TR - Radar de Seguimiento"
ctld.i18n["es"]["S-300 Grumble Clam Shell SR"] = "S-300 Grumble Clam Shell SR - Radar de Búsqueda"
ctld.i18n["es"]["S-300 Grumble Big Bird SR"] = "S-300 Grumble Big Bird SR - Radar de Búsqueda"
ctld.i18n["es"]["S-300 Grumble C2"] = "S-300 Grumble C2 - Puesto de Mando"
ctld.i18n["es"]["S-300 Repair"] = "Reparar S-300"
ctld.i18n["es"]["Humvee - TOW - All crates"] = "Humvee - TOW - Todas las cajas"
ctld.i18n["es"]["Light Tank - MRAP - All crates"] = "Light Tank - MRAP - Todas las cajas"
ctld.i18n["es"]["Med Tank - LAV-25 - All crates"] = "Med Tank - LAV-25 - Todas las cajas"
ctld.i18n["es"]["Heavy Tank - Abrams - All crates"] = "Heavy Tank - Abrams - Todas las cajas"
ctld.i18n["es"]["Hummer - JTAC - All crates"] = "Hummer - JTAC - Todas las cajas"
ctld.i18n["es"]["M-818 Ammo Truck - All crates"] = "M-818 Ammo Truck - Todas las cajas"
ctld.i18n["es"]["M-978 Tanker - All crates"] = "M-978 Tanker - Todas las cajas"
ctld.i18n["es"]["Ural-375 Ammo Truck - All crates"] = "Ural-375 Ammo Truck - Todas las cajas"
ctld.i18n["es"]["EWR Radar - All crates"] = "EWR Radar - Todas las cajas"
ctld.i18n["es"]["MLRS - All crates"] = "MLRS - Todas las cajas"
ctld.i18n["es"]["SpGH DANA - All crates"] = "SpGH DANA - Todas las cajas"
ctld.i18n["es"]["T155 Firtina - All crates"] = "T155 Firtina - Todas las cajas"
ctld.i18n["es"]["Howitzer - All crates"] = "Howitzer - Todas las cajas"
ctld.i18n["es"]["SPH 2S19 Msta - All crates"] = "SPH 2S19 Msta - Todas las cajas"
ctld.i18n["es"]["M1097 Avenger - All crates"] = "M1097 Avenger - Todas las cajas"
ctld.i18n["es"]["M48 Chaparral - All crates"] = "M48 Chaparral - Todas las cajas"
ctld.i18n["es"]["Roland ADS - All crates"] = "Roland ADS - Todas las cajas"
ctld.i18n["es"]["Gepard AAA - All crates"] = "Gepard AAA - Todas las cajas"
ctld.i18n["es"]["LPWS C-RAM - All crates"] = "LPWS C-RAM - Todas las cajas"
ctld.i18n["es"]["9K33 Osa - All crates"] = "9K33 Osa - Todas las cajas"
ctld.i18n["es"]["9P31 Strela-1 - All crates"] = "9P31 Strela-1 - Todas las cajas"
ctld.i18n["es"]["9K35M Strela-10 - All crates"] = "9K35M Strela-10 - Todas las cajas"
ctld.i18n["es"]["9K331 Tor - All crates"] = "9K331 Tor - Todas las cajas"
ctld.i18n["es"]["2K22 Tunguska - All crates"] = "2K22 Tunguska - Todas las cajas"
ctld.i18n["es"]["HAWK - All crates"] = "HAWK - Todas clas ajas"
ctld.i18n["es"]["NASAMS - All crates"] = "NASAMS - Todas las cajas"
ctld.i18n["es"]["KUB - All crates"] = "KUB - Todas las cajas"
ctld.i18n["es"]["BUK - All crates"] = "BUK - Todas las cajas"
ctld.i18n["es"]["Patriot - All crates"] = "Patriot - Todas las cajas"
ctld.i18n["es"]["Patriot - All crates"] = "Patriot - Todas las cajas"
--- mission design error messages
ctld.i18n["es"]["CTLD.lua ERROR: Can't find trigger called %1"] = "CTLD.lua ERROR : Imposible encontrar el activador llamado %1"
@@ -353,34 +423,33 @@ ctld.i18n["es"]["CTLD.lua ERROR: Can't find zone or ship called %1"] = "CTLD.lua
ctld.i18n["es"]["CTLD.lua ERROR: Can't find crate with weight %1"] = "CTLD.lua ERROR : Imposible encontrar una caja con un peso de %1"
--- runtime messages
ctld.i18n["es"]["You are not close enough to friendly logistics to get a crate!"] = "¡No estás lo suficientemente cerca de la logística amigable para conseguir una caja!"
ctld.i18n["es"]["You are not close enough to friendly logistics to get a crate!"] = "¡No estás lo suficientemente cerca de la logística aliada para solicitar una caja!"
ctld.i18n["es"]["No more JTAC Crates Left!"] = "¡No hay más cajas JTAC disponibles!"
ctld.i18n["es"]["Sorry you must wait %1 seconds before you can get another crate"] = "Lo sentimos, debes esperar %1 segundos antes de poder conseguir otra caja"
ctld.i18n["es"]["A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock "] = "Una caja %1 que pesa %2 kg ha sido sacada y está a tus %3 horas "
ctld.i18n["es"]["%1 fast-ropped troops from %2 into combat"] = "%1 lanzó rápidamente tropas de %2 al combate"
ctld.i18n["es"]["%1 dropped troops from %2 into combat"] = "%1 arrojó tropas de %2 al combate"
ctld.i18n["es"]["%1 fast-ropped troops from %2 into %3"] = "%1 lanzó tropas rápidamente de %2 a %3"
ctld.i18n["es"]["Sorry you must wait %1 seconds before you can get another crate"] = "Lo sentimos, debes esperar %1 segundos antes de poder solicitar otra caja"
ctld.i18n["es"]["A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock "] = "Una caja %1 pesando %2 kg ha sido preparada y está a tus %3 en punto "
ctld.i18n["es"]["%1 fast-ropped troops from %2 into combat"] = "%1 descolgo tropas con cuerdas de %2 al combate"
ctld.i18n["es"]["%1 dropped troops from %2 into combat"] = "%1 descargo tropas de %2 al combate"
ctld.i18n["es"]["%1 fast-ropped troops from %2 into %3"] = "%1 descolgo tropas con cuerdas de %2 a %3"
ctld.i18n["es"]["%1 dropped troops from %2 into %3"] = "%1 arrojó tropas de %2 a %3"
ctld.i18n["es"]["Too high or too fast to drop troops into combat! Hover below %1 feet or land."] = "¡Demasiado alto o demasiado rápido para lanzar tropas al combate! Coloca el cursor por debajo de % 1 pies o aterriza."
ctld.i18n["es"]["%1 dropped vehicles from %2 into combat"] = "%1 descargo vehículos de %2 en combate"
ctld.i18n["es"]["Too high or too fast to drop troops into combat! Hover below %1 feet or land."] = "¡Demasiado alto o rápido para lanzar tropas al combate! Manten estacionario por debajo de % 1 pies o aterriza."
ctld.i18n["es"]["%1 dropped vehicles from %2 into combat"] = "%1 descargo vehículos de %2 al combate"
ctld.i18n["es"]["%1 loaded troops into %2"] = "%1 cargó tropas en %2"
ctld.i18n["es"]["%1 loaded %2 vehicles into %3"] = "%1 cargó %2 vehículos en %3"
ctld.i18n["es"]["%1 delivered a FOB Crate"] = "%1 entregó una caja FOB"
ctld.i18n["es"]["Delivered FOB Crate 60m at 6'oclock to you"] = "Se le entregó la caja FOB de 60 m a sus 6 horas"
ctld.i18n["es"]["FOB Crate dropped back to base"] = "La caja FOB volvió a la base"
ctld.i18n["es"]["Delivered FOB Crate 60m at 6 o'clock to you"] = "Se le entregó la caja FOB de 60 m a sus 6 en punto"
ctld.i18n["es"]["FOB Crate dropped back to base"] = "Caja FOB devuelta a la base"
ctld.i18n["es"]["FOB Crate Loaded"] = "Caja FOB cargada"
ctld.i18n["es"]["%1 loaded a FOB Crate ready for delivery!"] = "%1 cargó una caja FOB lista para su entrega!"
ctld.i18n["es"]["There are no friendly logistic units nearby to load a FOB crate from!"] = "¡No hay unidades logísticas amigas cerca para cargar una caja FOB!"
ctld.i18n["es"]["You already have troops onboard."] = "Ya tienes tropas a bordo."
ctld.i18n["es"]["You already have vehicles onboard."] = "Ya tiene vehículos a bordo."
ctld.i18n["es"]["This area has no more reinforcements available!"] = "¡Esta área no tiene más refuerzos disponibles!"
ctld.i18n["es"]["You are not in a pickup zone and no one is nearby to extract"] = "No estás en una zona de recogida y no hay nadie cerca para extraerlo"
ctld.i18n["es"]["You are not in a pickup zone"] = "No estás en una zona de recogida"
ctld.i18n["es"]["No one to unload"] = "Nadie para descargar"
ctld.i18n["es"]["Dropped troops back to base"] = "Tropas arrojadas a la base"
ctld.i18n["es"]["Dropped vehicles back to base"] = "Vehículos arrojados a la base"
ctld.i18n["es"]["You are not in a pickup zone and no one is nearby to extract"] = "No estás en una zona de carga y/o no hay nadie cerca para extraccion"
ctld.i18n["es"]["You are not in a pickup zone"] = "No estás en una zona de carga"
ctld.i18n["es"]["No one to unload"] = "Nadie / Nada para descargar"
ctld.i18n["es"]["Dropped troops back to base"] = "Tropas descargados de vuelta a la base"
ctld.i18n["es"]["Dropped vehicles back to base"] = "Vehículos descargados de vuelta a la base"
ctld.i18n["es"]["You already have troops onboard."] = "Ya tienes tropas a bordo."
ctld.i18n["es"]["You already have vehicles onboard."] = "Ya tiene vehículos a bordo."
ctld.i18n["es"]["Count Infantries limit in the mission reached, you can't load more troops"] = "Se alcanzó el límite de infantería en la misión, no puedes cargar más tropas"
ctld.i18n["es"]["You already have vehicles onboard."] = "Ya tienes vehículos a bordo."
ctld.i18n["es"]["Sorry - The group of %1 is too large to fit. \n\nLimit is %2 for %3"] = "Lo sentimos, el grupo de %1 es demasiado grande. \n \nEl límite es %2 para %3"
ctld.i18n["es"]["%1 extracted troops in %2 from combat"] = "%1 tropas extraídas del combate en %2"
ctld.i18n["es"]["No extractable troops nearby!"] = "¡No hay tropas extraíbles cerca!"
@@ -391,69 +460,69 @@ ctld.i18n["es"]["%1 vehicles onboard (%2)\n"] = "%1 vehículos a bordo (%2)\n"
ctld.i18n["es"]["1 FOB Crate oboard (%1 kg)\n"] = "1 caja FOB a bordo (%1 kg)\n"
ctld.i18n["es"]["%1 crate onboard (%2 kg)\n"] = "%1 caja a bordo (%2 kg)\n"
ctld.i18n["es"]["Total weight of cargo : %1 kg\n"] = "Peso total de la carga: %1 kg\n"
ctld.i18n["es"]["No cargo."] = "Aucune cargaison."
ctld.i18n["es"]["Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!"] = "Flotando sobre %1 caja. \n\n¡Manténte flotando sobre ella durante %2 segundos! \n\n¡Si la cuenta regresiva se detiene, estás demasiado lejos!"
ctld.i18n["es"]["No cargo."] = "Sin carga."
ctld.i18n["es"]["Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!"] = "En estacionario sobre la caja %1 \n\n¡Mantenlo durante %2 segundos! \n\n¡Si la cuenta atras se detiene, estás demasiado lejos!"
ctld.i18n["es"]["Loaded %1 crate!"] = "Caja %1 cargada !"
ctld.i18n["es"]["Too low to hook %1 crate.\n\nHold hover for %2 seconds"] = "Demasiado bajo para enganchar la caja %1.\n\nManténte flotando sobre ella durante %2 segundos"
ctld.i18n["es"]["Too high to hook %1 crate.\n\nHold hover for %2 seconds"] = "Demasiado alto para enganchar la caja %1.\n\nManténte flotando sobre ella durante %2 segundos"
ctld.i18n["es"]["Too low to hook %1 crate.\n\nHold hover for %2 seconds"] = "Demasiado bajo para enganchar la caja %1.\n\nMantén el estacionario durante %2 segundos"
ctld.i18n["es"]["Too high to hook %1 crate.\n\nHold hover for %2 seconds"] = "Demasiado alto para enganchar la caja %1.\n\nMantén el estacionario durante %2 segundos"
ctld.i18n["es"]["You must land before you can load a crate!"] = "¡Debes aterrizar antes de poder cargar una caja!"
ctld.i18n["es"]["No Crates within 50m to load!"] = "¡No hay cajas para cargar a 50 m a la redonda!"
ctld.i18n["es"]["No Crates within 50m to load!"] = "¡No hay cajas para cargar en un radio de 50 m!"
ctld.i18n["es"]["Maximum number of crates are on board!"] = "¡El número máximo de cajas está a bordo!"
ctld.i18n["es"]["%1\n%2 crate - kg %3 - %4 m - %5 o'clock"] = "%1\n%2 caja - kg %3 - %4 m - %5 horas"
ctld.i18n["es"]["FOB Crate - %1 m - %2 o'clock\n"] = "Caja FOB - %1 m - %2 horas\n"
ctld.i18n["es"]["%1\n%2 crate - kg %3 - %4 m - %5 o'clock"] = "%1\n%2 caja - kg %3 - %4 m - a tus %5 en punto"
ctld.i18n["es"]["FOB Crate - %1 m - %2 o'clock\n"] = "Caja FOB - %1 m - a las %2 en punto\n"
ctld.i18n["es"]["No Nearby Crates"] = "Ninguna caja de proximidad"
ctld.i18n["es"]["Nearby Crates:\n%1"] = "Cajas cercanas:\n%1"
ctld.i18n["es"]["Nearby FOB Crates (Not Slingloadable):\n%1"] = "Cajas FOB cercanas (no transportable por cable):\n%1"
ctld.i18n["es"]["Nearby FOB Crates (Not Slingloadable):\n%1"] = "Cajas FOB cercanas (no se pueden cargar con eslinga):\n%1"
ctld.i18n["es"]["FOB Positions:"] = "Posiciones FOB:"
ctld.i18n["es"]["%1\nFOB @ %2"] = "%1\nFOB @ %2"
ctld.i18n["es"]["Sorry, there are no active FOBs!"] = "¡Lo sentimos, no hay FOB activos!"
ctld.i18n["es"]["No cargo."] = "Sin carga."
ctld.i18n["es"]["Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!"] = "Estacionario sobre la caja %1 \n\n¡Mantenlo flotando durante %2 segundos! \n\n¡Si la cuenta regresiva se detiene, estás demasiado lejos!"
ctld.i18n["es"]["Hovering above %1 crate. \n\nHold hover for %2 seconds! \n\nIf the countdown stops you're too far away!"] = "En estacionario sobre la caja %1 \n\n¡Mantenlo durante %2 segundos! \n\n¡Si la cuenta atras se detiene, estás demasiado lejos!"
ctld.i18n["es"]["Loaded %1 crate!"] = "¡Caja %1 cargada!"
ctld.i18n["es"]["Too low to hook %1 crate.\n\nHold hover for %2 seconds"] = "Demasiado bajo para enganchar la caja %1.\n\nMantén el estacionario durante %2 segundos"
ctld.i18n["es"]["Too high to hook %1 crate.\n\nHold hover for %2 seconds"] = "Demasiado alto para enganchar la caja %1.\n\nMantén el estacionario durante %2 segundos"
ctld.i18n["es"]["You must land before you can load a crate!"] = "¡Debes aterrizar antes de poder cargar una caja!"
ctld.i18n["es"]["No Crates within 50m to load!"] = "¡No hay cajas para cargar en un radio de 50 m!"
ctld.i18n["es"]["Maximum number of crates are on board!"] = "¡Número máximo de cajas a bordo!"
ctld.i18n["es"]["%1\n%2 crate - kg %3 - %4 m - %5 o'clock"] = "%1\n%2 caja - kg %3 - %4 m - %5 horas"
ctld.i18n["es"]["FOB Crate - %1 m - %2 o'clock\n"] = "Caja FOB - %1 m - %2 horas\n"
ctld.i18n["es"]["%1\n%2 crate - kg %3 - %4 m - %5 o'clock"] = "%1\n%2 caja - kg %3 - %4 m - a tus %5 en punto"
ctld.i18n["es"]["FOB Crate - %1 m - %2 o'clock\n"] = "Caja FOB - %1 m - a tus %2 en punto\n"
ctld.i18n["es"]["No Nearby Crates"] = "No hay cajas cerca"
ctld.i18n["es"]["Nearby Crates:\n%1"] = "Cajas cercanas:\n%1"
ctld.i18n["es"]["Nearby FOB Crates (Not Slingloadable):\n%1"] = "Cajas FOB cercanas (no se pueden cargar con eslinga):\n%1"
ctld.i18n["es"]["FOB Positions:"] = "Posiciones FOB:"
ctld.i18n["es"]["%1\nFOB @ %2"] = "%1\nFOB @ %2"
ctld.i18n["es"]["Sorry, there are no active FOBs!"] = "¡Lo sentimos, no hay FOB activos!"
ctld.i18n["es"]["You can't unpack that here! Take it to where it's needed!"] = "¡No puedes desembalar eso aquí! ¡Llévalo a donde lo necesites!"
ctld.i18n["es"]["Sorry you must move this crate before you unpack it!"] = "¡Lo siento, debes mover esta caja antes de desempacarla!"
ctld.i18n["es"]["%1 successfully deployed %2 to the field"] = "%1 implementó exitosamente %2 en el campo."
ctld.i18n["es"]["No friendly crates close enough to unpack, or crate too close to aircraft."] = "No hay cajas amigas lo suficientemente cerca para desempacar, o la caja está demasiado cerca de un avión"
ctld.i18n["es"]["You can't unpack that here! Take it to where it's needed!"] = "¡No puedes desembalar eso aquí! ¡Llévalo a donde lo necesiten!"
ctld.i18n["es"]["Sorry you must move this crate before you unpack it!"] = "¡Lo siento, debes mover esta caja antes de desembalar!"
ctld.i18n["es"]["%1 successfully deployed %2 to the field"] = "%1 Desplego %2 con exito en el campo."
ctld.i18n["es"]["No friendly crates close enough to unpack, or crate too close to aircraft."] = "No hay cajas amigas lo suficientemente cerca por desembalar, o la caja está demasiado cerca de un avión"
ctld.i18n["es"]["Finished building FOB! Crates and Troops can now be picked up."] = "¡Construcción FOB completada! Ahora se pueden recoger cajas y tropas"
ctld.i18n["es"]["Finished building FOB! Crates can now be picked up."] ="¡Construcción FOB completada! Las cajas ahora se pueden recoger."
ctld.i18n["es"]["%1 started building FOB using %2 FOB crates, it will be finished in %3 seconds.\nPosition marked with smoke."] = "%1 comenzó a construir FOB usando %2 cajas FOB , estará terminado en %3 segundos.\nPosición marcada por la bomba de humo."
ctld.i18n["es"]["Finished building FOB! Crates can now be picked up."] ="¡Construcción FOB completada! Ahora se pueden recoger cajas."
ctld.i18n["es"]["%1 started building FOB using %2 FOB crates, it will be finished in %3 seconds.\nPosition marked with smoke."] = "%1 comenzó a construir FOB usando %2 cajas FOB , estará terminado en %3 segundos.\nPosición marcada con bomba de humo."
ctld.i18n["es"]["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"] = "¡No se puede construir el FOB!\n\nSe requiere %1 cajas FOB grandes (3 cajas FOB pequeñas equivalente a 1 caja FOB grande) y hay el equivalente a %2 cajas FOB grandes cerca\n\nO las cajas no están a menos de 750 m una de otra"
ctld.i18n["es"]["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."] = "Actualmente no estás transportando ninguna caja.\n\nPara cargar una caja, flota sobre la caja durante %1 segundos o aterrice y use los comandos de caja F10."
ctld.i18n["es"]["You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate."] = "Actualmente no estás transportando ninguna caja. \n\nPour recoge una caja, flota sobre la caja durante %1 segundos."
ctld.i18n["es"]["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."] = "Actualmente no estás transportando ninguna caja.\n\nPara cargar una caja, realiza un estacionario sobre la caja durante %1 segundos o aterrice y use los comandos de caja F10."
ctld.i18n["es"]["You are not currently transporting any crates. \n\nTo Pickup a crate, hover for %1 seconds above the crate."] = "Actualmente no estás transportando ninguna caja. \n\nPara cargar una caja, realiza un estacionario sobre la caja durante %1 segundos."
ctld.i18n["es"]["You are not currently transporting any crates. \n\nTo Pickup a crate, land and use F10 Crate Commands to load one."] = "Actualmente no estás transportando ninguna caja. \n\nPara cargar una caja, aterriza y usa los controles de la caja F10."
ctld.i18n["es"]["%1 crate has been safely unhooked and is at your %2 o'clock"] = "%1 caja ha sido desenganchada de forma segura y está en tus %2 horas"
ctld.i18n["es"]["%1 crate has been safely dropped below you"] = "%1 caja se ha dejado caer de forma segura debajo de ti"
ctld.i18n["es"]["You were too high! The crate has been destroyed"] = "¡Estabas demasiado drogado! La caja ha sido destruida"
ctld.i18n["es"]["%1 crate has been safely unhooked and is at your %2 o'clock"] = "%1 caja desenganchada de forma segura y está en tus %2 en punto"
ctld.i18n["es"]["%1 crate has been safely dropped below you"] = "%1 caja ha soltado de forma segura debajo de ti"
ctld.i18n["es"]["You were too high! The crate has been destroyed"] = "¡Estabas demasiado alto! La caja ha sido destruida"
ctld.i18n["es"]["Radio Beacons:\n%1"] = "Balizas de radio:\n%1"
ctld.i18n["es"]["No Active Radio Beacons"] = "No hay radiobalizas activas"
ctld.i18n["es"]["%1 deployed a Radio Beacon.\n\n%2"] = "%1 implementó una radiobaliza.\n\n%2"
ctld.i18n["es"]["%1 deployed a Radio Beacon.\n\n%2"] = "%1 Despliega una radiobaliza.\n\n%2"
ctld.i18n["es"]["You need to land before you can deploy a Radio Beacon!"] = "¡Debes aterrizar antes de poder desplegar una radiobaliza!"
ctld.i18n["es"]["%1 removed a Radio Beacon.\n\n%2"] = "%1 eliminó una radiobaliza.\n\n%2"
ctld.i18n["es"]["No Radio Beacons within 500m."] = "No hay radiobalizas a menos de 500 m."
ctld.i18n["es"]["You need to land before remove a Radio Beacon"] = "Es necesario aterrizar antes de eliminar una radiobaliza"
ctld.i18n["es"]["%1 successfully rearmed a full %2 in the field"] = "%1 rearmó exitosamente un %2 completo en el campo"
ctld.i18n["es"]["Missing %1\n"] = "%1 falta\n"
ctld.i18n["es"]["%1 successfully rearmed a full %2 in the field"] = "%1 rearmó con exito un %2 completo en el campo"
ctld.i18n["es"]["Missing %1\n"] = "Faltan: %1\n"
ctld.i18n["es"]["Out of parts for AA Systems. Current limit is %1\n"] = "Sin piezas para sistemas AA. El límite actual es %1\n"
ctld.i18n["es"]["Cannot build %1\n%2\n\nOr the crates are not close enough together"] = "Imposible construir %1\n%2\n\nO las cajas no están lo suficientemente cerca el uno del otro."
ctld.i18n["es"]["%1 successfully deployed a full %2 in the field. \n\nAA Active System limit is: %3\nActive: %4"] = "%1 implementó exitosamente un % 2 completo en el campo \n\nEl límite AA del sistema activo es: %3\nActivo: %4"
ctld.i18n["es"]["%1 successfully repaired a full %2 in the field."] = "%1 reparó exitosamente un %2 completo en el campo."
ctld.i18n["es"]["Cannot repair %1. No damaged %2 within 300m"] = "Imposible de reparar %1. No hay daños en %2 dentro de 300 m"
ctld.i18n["es"]["%1 successfully deployed %2 to the field using %3 crates."] = "%1 implementó exitosamente %2 en el campo usando %3 cajas."
ctld.i18n["es"]["Cannot build %1!\n\nIt requires %2 crates and there are %3 \n\nOr the crates are not within 300m of each other"] = "Imposible construir %1 !\n\nNecesitamos %2 cajas y hay %3 \n\nO las cajas están a no menos de 300 m una de otra"
ctld.i18n["es"]["%1 dropped %2 smoke."] = "%1 arrojó un %2 humo."
ctld.i18n["es"]["Cannot build %1\n%2\n\nOr the crates are not close enough together"] = "Imposible construir %1\n%2\n\nO las cajas no están lo suficientemente cerca unas de otras."
ctld.i18n["es"]["%1 successfully deployed a full %2 in the field. \n\nAA Active System limit is: %3\nActive: %4"] = "%1 Despliegue con exito un % 2 completo en el campo \n\nEl límite AA del sistema activo es: %3\nActivo: %4"
ctld.i18n["es"]["%1 successfully repaired a full %2 in the field."] = "%1 reparó con exito un %2 completo en el campo."
ctld.i18n["es"]["Cannot repair %1. No damaged %2 within 300m"] = "Imposible reparar %1. No hay daños en %2 en 300 m al rededor"
ctld.i18n["es"]["%1 successfully deployed %2 to the field using %3 crates."] = "%1 Despliegue con exito de %2 en el campo usando %3 cajas."
ctld.i18n["es"]["Cannot build %1!\n\nIt requires %2 crates and there are %3 \n\nOr the crates are not within 300m of each other"] = "Imposible construir %1 !\n\nNecesita %2 cajas y hay %3 \n\nO las cajas están a no menos de 300 m una de otra"
ctld.i18n["es"]["%1 dropped %2 smoke."] = "%1 lanzo humo %2."
--- JTAC messages
ctld.i18n["es"]["JTAC Group %1 KIA!"] = "¡Grupo JTAC %1 KIA!"
@@ -471,14 +540,14 @@ ctld.i18n["es"]["%1 %2 target destroyed."] = "%1 %2 objetivo destruido."
ctld.i18n["es"]["JTAC STATUS: \n\n"] = "ESTADO JTAC: \n\n"
ctld.i18n["es"][", available on %1 %2,"] = ", disponible en %1 %2,"
ctld.i18n["es"]["UNKNOWN"] = "DESCONOCIDO"
ctld.i18n["es"][" targeting "] = " apuntación "
ctld.i18n["es"][" targeting selected unit "] = " apuntando a la unidad seleccionada"
ctld.i18n["es"][" attempting to find selected unit, temporarily targeting "] = " intento de encontrar la unidad seleccionada, objetivo temporal "
ctld.i18n["es"][" targeting "] = " apuntando "
ctld.i18n["es"][" targeting selected unit "] = " apuntando a la unidad indicada"
ctld.i18n["es"][" attempting to find selected unit, temporarily targeting "] = " intentando encontrar la unidad indicada, laser activo "
ctld.i18n["es"]["(Laser OFF) "] = "(Láser INACTIVO) "
ctld.i18n["es"]["Visual On: "] = "Visual activado: "
ctld.i18n["es"][" searching for targets %1\n"] = " buscando objetivos %1\n"
ctld.i18n["es"]["No Active JTACs"] = "No hay JTAC activos"
ctld.i18n["es"][", targeting selected unit, %1"] = ", apuntando a la unidad seleccionada, %1"
ctld.i18n["es"]["No Active JTACs"] = "Sin JTAC activos"
ctld.i18n["es"][", targeting selected unit, %1"] = ", apuntando a la unidad indicada, %1"
ctld.i18n["es"][". CODE: %1. POSITION: %2"] = ". CÓDIGO: %1. POSICIÓN: %2"
ctld.i18n["es"][", target selection reset."] = ", reinicio de selección de objetivo."
ctld.i18n["es"]["%1, laser and smokes enabled"] = "%1, láser y humo habilitados"
@@ -493,39 +562,46 @@ ctld.i18n["es"]["Troop Transport"] = "Transporte de tropas"
ctld.i18n["es"]["Unload / Extract Troops"] = "Descargar/Extraer tropas"
ctld.i18n["es"]["Next page"] = "Página siguiente"
ctld.i18n["es"]["Load "] = "Cargar "
ctld.i18n["es"]["Vehicle / FOB Transport"] = "Transporte Vehículo / FOB"
ctld.i18n["es"]["Vehicle / FOB Crates"] = "Cajas Vehículo / FOB"
ctld.i18n["es"]["Vehicle / FOB Transport"] = "Transporte de Vehículo / FOB"
ctld.i18n["es"]["Vehicle / FOB Crates / Drone"] = "Cajas de Vehículo / FOB / Dron"
ctld.i18n["es"]["Unload Vehicles"] = "Descargar vehículos"
ctld.i18n["es"]["Load / Extract Vehicles"] = "Cargar/Extraer vehículos"
ctld.i18n["es"]["Load / Unload FOB Crate"] = "Cargar/Descargar caja FOB"
ctld.i18n["es"]["Repack Vehicles"] = "Reenvolver vehículos"
ctld.i18n["es"]["CTLD Commands"] = "Comandos CTLD"
ctld.i18n["es"]["CTLD"] = "CTLD"
ctld.i18n["es"]["Check Cargo"] = "Verificar carga"
ctld.i18n["es"]["Load Nearby Crate"] = "Cargar caja cercana"
ctld.i18n["es"]["Unpack Any Crate"] = "Desempaquetar las cajas"
ctld.i18n["es"]["Drop Crate"] = "Descargar caja"
ctld.i18n["es"]["Load Nearby Crate(s)"] = "Cargar caja(s) cercana(s)"
ctld.i18n["es"]["Unpack Any Crate"] = "Desempaquetar cajas"
ctld.i18n["es"]["Drop Crate(s)"] = "Soltar caja(s)"
ctld.i18n["es"]["List Nearby Crates"] = "Enumerar cajas cercanas"
ctld.i18n["es"]["List FOBs"] = "Enumerar FOBs"
ctld.i18n["es"]["List Beacons"] = "Enumerar balizas"
ctld.i18n["es"]["List Radio Beacons"] = "Enumerar radiobalizas"
ctld.i18n["es"]["Smoke Markers"] = "Marcadores de humo"
ctld.i18n["es"]["Drop Red Smoke"] = "Soltar humo rojo"
ctld.i18n["es"]["Drop Blue Smoke"] = "Soltar humo azul"
ctld.i18n["es"]["Drop Orange Smoke"] = "Soltar humo naranja"
ctld.i18n["es"]["Drop Green Smoke"] = "Soltar humo verde"
ctld.i18n["es"]["Drop Beacon"] = "Soltar baliza"
ctld.i18n["es"]["Drop Red Smoke"] = "Lanzar humo rojo"
ctld.i18n["es"]["Drop Blue Smoke"] = "Lanzar humo azul"
ctld.i18n["es"]["Drop Orange Smoke"] = "Lanzar humo naranja"
ctld.i18n["es"]["Drop Green Smoke"] = "Lanzar humo verde"
ctld.i18n["es"]["Drop Beacon"] = "Desplegar baliza"
ctld.i18n["es"]["Radio Beacons"] = "Balizas de radio"
ctld.i18n["es"]["Remove Closet Beacon"] = "Quitar baliza cercana"
ctld.i18n["es"]["Remove Closest Beacon"] = "Quitar la baliza mas cercana"
ctld.i18n["es"]["JTAC Status"] = "Estado de JTAC"
ctld.i18n["es"]["DISABLE "] = "DESHABILITAR "
ctld.i18n["es"]["ENABLE "] = "HABILITAR "
ctld.i18n["es"]["REQUEST "] = "SOLICITUD "
ctld.i18n["es"]["Reset TGT Selection"] = "Restablecer selección TGT"
ctld.i18n["es"]["Reset TGT Selection"] = "Restablecer selección de objetivo"
-- F10 RECON menus
ctld.i18n["es"]["RECON"] = "RECONOCIMIENTO"
ctld.i18n["es"]["Show targets in LOS (refresh)"] = "Marcar objetivos visibles en el mapa F10"
ctld.i18n["es"]["Hide targets in LOS"] = "Borrar marcas del mapa F10"
ctld.i18n["es"]["START autoRefresh targets in LOS"] = "Iniciar el seguimiento automático de objetivos"
ctld.i18n["es"]["STOP autoRefresh targets in LOS"] = "Detener el seguimiento automático de objetivos"
--========================================================================================================================
--======== Korean - 한국어 =====================================================================================
ctld.i18n["ko"] = {}
ctld.i18n["ko"].translation_version = "1.0" -- make sure that this translation is compatible with the current version of the english language texts (ctld.i18n["en"].translation_version)
ctld.i18n["ko"].translation_version = "1.1" -- make sure that this translation is compatible with the current version of the english language texts (ctld.i18n["en"].translation_version)
local lang="ko";env.info(string.format("I - CTLD.i18n_translate: Loading %s language version %s", lang, tostring(ctld.i18n[lang].translation_version)))
--- groups names
@@ -759,7 +835,7 @@ ctld.i18n["ko"]["Drop Orange Smoke"] = "주황색 연막 투하"
ctld.i18n["ko"]["Drop Green Smoke"] = "녹색 연막 투하"
ctld.i18n["ko"]["Drop Beacon"] = "비콘 투하"
ctld.i18n["ko"]["Radio Beacons"] = "라디오 비콘"
ctld.i18n["ko"]["Remove Closet Beacon"] = "가까운 비콘 제거"
ctld.i18n["ko"]["Remove Closest Beacon"] = "가까운 비콘 제거"
ctld.i18n["ko"]["JTAC Status"] = "JTAC 상태"
ctld.i18n["ko"]["DISABLE "] = "비활성화 "
ctld.i18n["ko"]["ENABLE "] = "활성화 "
+2972 -1953
View File
File diff suppressed because it is too large Load Diff
+42 -1
View File
@@ -11,6 +11,8 @@ It's open-source and free as in free beer (you don't have to pay to use it), and
We're always looking for help, please reach out to [Zip on Discord](https://discordapp.com/users/421317390807203850) if you want to participate in maintenance or development.
And if you'd like to support our work, you can [buy me a coffee](https://coff.ee/veaf_zip)!
## Contents
This script is a rewrite of some of the functionality of the original Complete Combat Troop Transport Script (CTTS) by Geloxo (http://forums.eagle.ru/showthread.php?t=108523), as well as adding new features.
@@ -44,12 +46,15 @@ This script is a rewrite of some of the functionality of the original Complete C
* [Spawn Sling loadable crate at a Zone](#spawn-sling-loadable-crate-at-a-zone)
* [Spawn Sling loadable crate at a Point](#spawn-sling-loadable-crate-at-a-point)
* [JTAC Automatic Targeting and Laser](#jtac-automatic-targeting-and-laser)
* [JTAC Automatic Orbiting Over Lased Target](#jtac-automatic-orbiting-over-lased-target)
* [In Game](#in-game)
* [Troop Loading and Unloading](#troop-loading-and-unloading)
* [Limit troop Loading](#limit-troop-loading)
* [Cargo Spawning and Sling Loading](#cargo-spawning-and-sling-loading)
* [Simulated Sling Loading](#simulated-sling-loading)
* [Real Sling Loading](#real-sling-loading)
* [Crate Unpacking](#crate-unpacking)
* [Crate Repacking](#crate-repacking)
* [Forward Operating Base (FOB) Construction](#forward-operating-base-fob-construction)
* [Radio Beacon Deployment](#radio-beacon-deployment)
* [A10\-C UHF ADF Radio Setup](#a10-c-uhf-adf-radio-setup)
@@ -57,6 +62,7 @@ This script is a rewrite of some of the functionality of the original Complete C
* [Mi\-8 ARC\-9 VHF Radio Setup](#mi-8-arc-9-vhf-radio-setup)
* [UH\-1 ADF VHF Radio Setup](#uh-1-adf-vhf-radio-setup)
* [Advanced Scripting](#advanced-scripting)
* [recognition assistance](#recognition-assistance)
## Features
The script supports:
@@ -103,6 +109,7 @@ The script supports:
* Count soldiers extracted to a zone (the soldiers disappear)
* Waypoint triggers to force dropped groups to head to a location
* Advanced Scripting Callback system
* Target recognition assistance functions to mark targets on the F10 map
A complete test mission is included.
@@ -125,7 +132,7 @@ Optionaly, you can disable the STTS (text to speech over SRS) feature (4).
![dynamic_loading]
### Script Setup
**This script requires MIST version 4.0.57 or above: https://github.com/mrSkortch/MissionScriptingTools**
🔴IMPORTANT: This script requires MIST supplied in the CTLD zipped pack to correctly manage dynamic spwans.
First make sure MIST is loaded, either as an Initialization Script for the mission or the first DO SCRIPT with a "TIME MORE" of 1. "TIME MORE" means run the actions after X seconds into the mission.
@@ -859,6 +866,14 @@ For example, if the laser code is *1688*, the frequency will be *40.40Mhz*.
JTAC frequency is available through the "JTAC Status" radio menu
#### Jtac-automatic-orbiting-over-lased-target
By setting parameter ctld.enableAutoOrbitingFlyingJtacOnTarget = true, a script dedicated script puts in orbit each flying JTAC over his detected target.
Associated with CTLD/JTAC functions, you can assign a fly route to the JTAC drone, this one follow it, and start orbiting when he detects a target.
As soon as it don't detect a target, it restart following its initial route at the nearest waypoint
# In Game
## Troop Loading and Unloading
@@ -913,7 +928,16 @@ ctld.MG_WEIGHT = 10 -- kg
ctld.MORTAR_WEIGHT = 26 -- kg
ctld.JTAC_WEIGHT = 15 -- kg
```
## Limit troop Loading
The number of Infantries units in mission can be limited by setting the table below :
`ctld.nbLimitSpawnedTroops = {0, 0} -- {redLimitInfantryCount, blueLimitInfantryCount}`
When this cumulative number of troops is reached for a coalition, no more troops can be loaded onboard, and a message is sent to player.
If set to `ctld.nbLimitSpawnedTroops = {0, 0}` (both values at 0) the limit control is disabled. This is the default.
If either value is non-zero, limit control becomes active for both coalitions.
## Cargo Spawning and Sling Loading
@@ -1004,6 +1028,16 @@ Rearming:
You can also repair a partially destroyed HAWK / BUK or KUB system by dropping a repair crate next to it and unpacking. A repair crate will also re-arm the system.
## Crate Repacking
The F10 menu allows you to repack units having associated crate types in the "ctld.spawnableCrates" table.
Simply land near the unit you wish to repack and select it from the list presented by the "CTLD//Vehicle/FOB transport...//Repack Vehicles" menu.
The defined radius of vehicles detection is specified by the parameter `ctld.maximumDistanceRepackableUnitsSearch` (default 200 meters).
*WARNING*: Due to technical reasons related to the refresh time of the F10 menus, there may be inconsistencies between the type of vehicles requested and those provided. It is recommended to wait 5 to 10 seconds without moving after landing and opening the F10 menu for a packaging order.
## Forward Operating Base (FOB) Construction
FOBs can be built by loading special FOB crates from a **Logistics** unit into a C-130 or other large aircraft configured in the script. To load the crate use the F10 - Troop Commands Menu. The idea behind FOBs is to make player vs player missions even more dynamic as these can be deployed in most locations. Once destroyed the FOB can no longer be used.
@@ -1102,6 +1136,13 @@ White pointer pointing to beacon on the compass:
![alt text](http://i1056.photobucket.com/albums/t379/cfisher881/dcs.exe_DX9_20150608_075211_zpsdaus4wxt.png~original "Radio Compass")
# recognition-assistance
The recognition functions in the F10 menu allow you to mark/delete/refresh marks on targets within sight of the aircraft being piloted by the player.
Enabling/disabling automatic refreshing of marks on targets within view allows you to track them as they move.
Below is a complete list of all the "actions" plus the data that is sent through. For more information its best to check the CTLD Code to see more details of the arguments.
# Advanced Scripting
CTLD has an optional callback API that can be used to trigger actions in code
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -35,7 +35,7 @@ mist = {}
-- don't change these
mist.majorVersion = 4
mist.minorVersion = 5
mist.build = "128-DYNSLOTS-01"
mist.build = "128-DYNSLOTS-02"
-- forward declaration of log shorthand
local log
@@ -826,11 +826,11 @@ do -- the main scope
if zone.verticies then
local offset = {}
for i = 1, #zone.verticies do
table.insert(offset, {dist = mist.utils.get2DDist(uRef.point, zone.verticies[i]), heading = mist.getHeadingPoints(uRef.point, zone.verticies[i]) + uRef.heading})
table.insert(offset, {dist = mist.utils.get2DDist(uRef.point, zone.verticies[i]), heading = mist.utils.getHeadingPoints(uRef.point, zone.verticies[i]) + uRef.heading})
end
zone.offset = offset
else
zone.offset = {dist = mist.utils.get2DDist(uRef.point, zone.point), heading = mist.getHeadingPoints(uRef.point, zone.point) + uRef.heading}
zone.offset = {dist = mist.utils.get2DDist(uRef.point, zone.point), heading = mist.utils.getHeadingPoints(uRef.point, zone.point) + uRef.heading}
end
end
end
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.