-
Notifications
You must be signed in to change notification settings - Fork 86
WIP: Add A-10C presets support, with tests #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| import dcs.lua as lua | ||
|
|
||
|
|
||
| class A10CPresets: | ||
| def __init__(self): | ||
| self.presets: dict[int, int] = { | ||
| 1: 305000000, | ||
| 2: 264000000, | ||
| 3: 265000000, | ||
| 4: 256000000, | ||
| 5: 254000000, | ||
| 6: 250000000, | ||
| 7: 270000000, | ||
| 8: 257000000, | ||
| 9: 255000000, | ||
| 10: 262000000, | ||
| 11: 259000000, | ||
| 12: 268000000, | ||
| 13: 269000000, | ||
| 14: 260000000, | ||
| 15: 263000000, | ||
| 16: 261000000, | ||
| 17: 267000000, | ||
| 18: 251000000, | ||
| 19: 253000000, | ||
| 20: 266000000, | ||
| } | ||
|
|
||
| def load_dict(self, data): | ||
| presets = data.get("settings", {}).get("presets", {}) | ||
| for chan, freq in presets.items(): | ||
| self.presets[chan] = freq | ||
|
|
||
| def set_preset(self, channel: int, frequency: float): | ||
| freq_as_int = round(frequency * 10 ** 6) | ||
| self.presets[channel] = freq_as_int | ||
|
|
||
| def get_preset(self, channel: int) -> float: | ||
| frequency = self.presets[channel] | ||
| # TODO: Check if floating point precision is a problem | ||
| freq_as_float = frequency / (10 ** 6) | ||
| return freq_as_float | ||
|
|
||
| def __str__(self): | ||
| d = { | ||
| # TODO: dials if needed? | ||
| "presets": self.presets, | ||
| } | ||
| return lua.dumps(d, "settings", 1) | ||
|
|
||
|
|
||
| # Example data from UHF_RADIO/SETTINGS.lua in a miz file: | ||
|
|
||
| # -- These values overwrites the default settings for the A-10C, including hotstarts. | ||
| # -- To enable the server wide dials settings, remove the -- | ||
| # settings= | ||
| # { | ||
| # --["dials"]= | ||
| # { | ||
| # ["mode_dial"]=0, -- 0=OFF, 1=MAIN, 2=BOTH, 3=ADF | ||
| # ["manual_frequency"]=305000000, -- Overwrites the value set in the ME. Default=251000000 | ||
| # ["selection_dial"]=0, -- 1=MNL, 2=PRESET, 3=GRD | ||
| # ["channel_dial"]=0, -- See the presets below. 0=preset 1, 1=preset 2, etc | ||
| # }, | ||
| # ["presets"]= | ||
| # { | ||
| # [1]=305000000, | ||
| # [2]=264000000, | ||
| # [3]=265000000, | ||
| # [4]=256000000, | ||
| # [5]=254000000, | ||
| # [6]=250000000, | ||
| # [7]=270000000, | ||
| # [8]=257000000, | ||
| # [9]=255000000, | ||
| # [10]=262000000, | ||
| # [11]=259000000, | ||
| # [12]=268000000, | ||
| # [13]=269000000, | ||
| # [14]=260000000, | ||
| # [15]=263000000, | ||
| # [16]=261000000, | ||
| # [17]=267000000, | ||
| # [18]=251000000, | ||
| # [19]=253000000, | ||
| # [20]=266000000, | ||
| # }, | ||
| # } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ | |
| The mission module is the entry point to all pydcs functions. | ||
| """ | ||
| import copy | ||
|
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why the newline?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure, I ran flake8 and fixed until it stopped complaining. ;) |
||
| import os | ||
| import sys | ||
| import tempfile | ||
|
|
@@ -41,6 +42,7 @@ | |
| from dcs.helicopters import HelicopterType | ||
| from dcs.planes import PlaneType | ||
| from dcs.status_message import StatusMessage, MessageType, MessageSeverity | ||
| from dcs.a10c_presets import A10CPresets | ||
|
|
||
|
|
||
| class StartType(Enum): | ||
|
|
@@ -129,6 +131,7 @@ def __init__(self, terrain: Optional[Terrain] = None) -> None: | |
| self.init_script = None | ||
| self.options = Options() | ||
| self.warehouses = Warehouses(self.terrain) | ||
| self.a10c_presets = None | ||
| self.goals = Goals() | ||
| blue = Coalition("blue") | ||
| blue.add_country(countries.Australia()) | ||
|
|
@@ -254,6 +257,11 @@ def loaddict(fname: str, mizfile: zipfile.ZipFile, reserved_files: List[str]) -> | |
| mapresource_dict = loaddict('l10n/DEFAULT/mapResource', miz, reserved_files) | ||
| self.map_resource.load_from_dict(mapresource_dict, miz) | ||
|
|
||
| if 'UHF_RADIO/SETTINGS.lua' in miz.namelist(): | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so is this SETTINGS.lua file always bound to the a10c presets?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for reviewing! My understanding is it used to be A-10C and KA-50 only, until recently. See this comment I made on the PR:
Consider this PR paused for now. It will look different when it is done for individual airframes. It will still be these SETTINGS.lua files, but they will be in airframe-id subdirectories in the miz file. |
||
| a10c_presets_dict = loaddict('UHF_RADIO/SETTINGS.lua', miz, reserved_files) | ||
| self.a10c_presets = A10CPresets() | ||
| self.a10c_presets.load_dict(a10c_presets_dict) | ||
|
|
||
| self.map_resource.load_binary_files(miz, reserved_files) | ||
|
|
||
| imp_mission = mission_dict["mission"] | ||
|
|
@@ -461,6 +469,16 @@ def add_picture_blue(self, filepath: str) -> ResourceKey: | |
| self.pictureFileNameB.append(reskey) | ||
| return reskey | ||
|
|
||
| def set_10c_preset(self, channel: int, frequency: float): | ||
| if self.a10c_presets is None: | ||
| self.a10c_presets = A10CPresets() | ||
| self.a10c_presets.set_preset(channel, frequency) | ||
|
|
||
| def get_10c_preset(self, channel: int) -> float: | ||
| if self.a10c_presets: | ||
| return self.a10c_presets.get_preset(channel) | ||
| return None | ||
|
|
||
| def next_group_id(self): | ||
| """Get the next free group id | ||
|
|
||
|
|
@@ -1923,6 +1941,7 @@ def save(self, filename=None): | |
| options = str(self.options) | ||
| warehouses = str(self.warehouses) | ||
| mission = str(self) | ||
| a10c_presets = str(self.a10c_presets) if self.a10c_presets else None | ||
|
|
||
| with zipfile.ZipFile(filename, 'w', compression=zipfile.ZIP_DEFLATED) as zipf: | ||
| # options | ||
|
|
@@ -1931,6 +1950,10 @@ def save(self, filename=None): | |
| # warehouses | ||
| zipf.writestr('warehouses', warehouses) | ||
|
|
||
| # a10c presets | ||
| if a10c_presets: | ||
| zipf.writestr('UHF_RADIO/SETTINGS.lua', a10c_presets) | ||
|
|
||
| # translation files | ||
| dicttext = lua.dumps(self.translation.dict('DEFAULT'), "dictionary", 1) | ||
| zipf.writestr('l10n/DEFAULT/dictionary', dicttext) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import unittest | ||
|
|
||
| from dcs.a10c_presets import A10CPresets | ||
|
|
||
|
|
||
| class A10CPresetTests(unittest.TestCase): | ||
| def test_set_preset(self) -> None: | ||
| a10c_presets = A10CPresets() | ||
|
|
||
| self.assertEqual(a10c_presets.presets[1], 305000000) | ||
| self.assertEqual(a10c_presets.presets[20], 266000000) | ||
|
|
||
| a10c_presets.set_preset(1, 306.55) | ||
| self.assertEqual(a10c_presets.presets[1], 306550000) | ||
|
|
||
| a10c_presets.set_preset(20, 256.10) | ||
| self.assertEqual(a10c_presets.presets[20], 256100000) | ||
|
|
||
| def test_get_preset(self) -> None: | ||
| a10c_presets = A10CPresets() | ||
|
|
||
| self.assertEqual(a10c_presets.get_preset(1), 305.0) | ||
|
|
||
| a10c_presets.set_preset(1, 306.55) | ||
| self.assertEqual(a10c_presets.get_preset(1), 306.55) | ||
|
|
||
| a10c_presets.set_preset(20, 256.10) | ||
| self.assertEqual(a10c_presets.get_preset(20), 256.10) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -734,3 +734,25 @@ def test_mission_save_pictureFileName(self): | |
| self.assertEqual(m2.pictureFileNameB[0], reskey_b.key) | ||
| self.assertEqual(len(m2.pictureFileNameR), 1) | ||
| self.assertEqual(m2.pictureFileNameR[0], reskey_r.key) | ||
|
|
||
| def test_set_10c_presets(self): | ||
| m = dcs.mission.Mission() | ||
| m.load_file('tests/loadtest.miz') | ||
| self.assertIsNone(m.a10c_presets) | ||
|
|
||
| m.set_10c_preset(1, 251.0) | ||
| m.set_10c_preset(2, 252.0) | ||
| m.set_10c_preset(20, 253.0) | ||
|
|
||
| save_path = os.path.join('missions', 'a10c_presets_loadtest.miz') | ||
| m.save(save_path) | ||
| print('-' * 10, "Saved", save_path) | ||
| # reload mission | ||
| m = dcs.mission.Mission() | ||
| msgs = m.load_file(save_path) | ||
| self.assertEqual(0, len(msgs)) | ||
|
|
||
| self.assertIsNotNone(m.a10c_presets) | ||
| self.assertEqual(m.get_10c_preset(1), 251.0) | ||
| self.assertEqual(m.get_10c_preset(2), 252.0) | ||
| self.assertEqual(m.get_10c_preset(20), 253.0) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. newline missing here |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is a bit superflous? Could we just assign self.presets to the dict from the data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should work, until we need/want a deep copy