-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add generation-time allocation for STNs.
This is a stop-gap solution so we can get a release out that supports datalink as quickly as possible. It would be better to assign these early so the player can select which flights should be their team/donors, but for that we need to keep a registry in Game, plumb it through to each Flight creation (and there are many callsites for that), subscribe each flight to its datalink contacts (so disbanded flights do not remain part of a network), and of course the UI itself. That'll come later. Follow up work: * Filtering to only apply for the airframes that can use it * Selection of team/donors
- Loading branch information
Showing
9 changed files
with
148 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from dataclasses import dataclass | ||
|
||
from game.datalink.sourcetracknumberprefix import SourceTrackNumberPrefix | ||
|
||
|
||
@dataclass(frozen=True) | ||
class SourceTrackNumber: | ||
"""Source track number (STN) for a flight member.""" | ||
|
||
prefix: SourceTrackNumberPrefix | ||
index: int | ||
|
||
def __post_init__(self) -> None: | ||
if self.index < 0: | ||
raise ValueError("STN indexes cannot be negative") | ||
if self.index >= 8: | ||
raise ValueError("STN indexes must be < 8") | ||
|
||
def __str__(self) -> str: | ||
return f"{self.prefix}{self.index}" | ||
|
||
def __repr__(self) -> str: | ||
return f"{self.__class__.__name__}({self.prefix!r}, {self.index})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from dataclasses import dataclass | ||
|
||
|
||
@dataclass(frozen=True) | ||
class SourceTrackNumberPrefix: | ||
"""The prefix of a source track number (STN) for a flight. | ||
STNs are 5 octal digits. To make it easier for players to guess the codes for their | ||
flight members, these are segmented so that the least significant digit is always | ||
the flight member index. This wastes of the address space, but even at the lowest | ||
density (single-member flights, ~88% waste), there are still enough prefixes for | ||
4096 aircraft. | ||
There is no per-package segmenting, however. DCS imposes a flight-size limitation on | ||
us (usually four, sometimes fewer), but we do not restrict the number of flights | ||
that can be in a package. If we were to carve out a digit for the package, we'd be | ||
limiting the package to a max of eight flights. It's larger than a typical package, | ||
but it's not unreasonable for a large OCA strike. If we carved out two digits, the | ||
limit would be more than enough (64), but it would also limit the game to 64 | ||
packages. That's also quite high, but it's low enough that it could be hit. There's | ||
some wiggle room here, since for now the only aircraft that need STNs are the F-16C, | ||
F/A-18C, and A-10C II, but we shouldn't break in the unlikely case where the game is | ||
composed entirely of those airframes. | ||
Carving up the address space in different ways (such as two bits for the flight and | ||
six for the package) would defeat the purpose of doing so, since they wouldn't be | ||
recognizable prefixes for players, since these are expressed as octal in the jet. | ||
""" | ||
|
||
value: int | ||
|
||
def __post_init__(self) -> None: | ||
if self.value < 0: | ||
raise ValueError("STN prefixes cannot be negative") | ||
if self.value >= 0o10000: | ||
raise ValueError("STN prefixes must be < 0o10000") | ||
|
||
def __str__(self) -> str: | ||
return f"{oct(self.value)[2:]:0>4}" | ||
|
||
def __repr__(self) -> str: | ||
return f"{self.__class__.__name__}({oct(self.value)})" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import pytest | ||
|
||
from game.datalink.sourcetracknumber import SourceTrackNumber | ||
from game.datalink.sourcetracknumberprefix import SourceTrackNumberPrefix | ||
|
||
|
||
def test_limits() -> None: | ||
SourceTrackNumber(SourceTrackNumberPrefix(0), 0) | ||
SourceTrackNumber(SourceTrackNumberPrefix(0o7777), 7) | ||
with pytest.raises(ValueError): | ||
SourceTrackNumber(SourceTrackNumberPrefix(0), -1) | ||
with pytest.raises(ValueError): | ||
SourceTrackNumber(SourceTrackNumberPrefix(0o7777), 0o10) | ||
|
||
|
||
def test_str() -> None: | ||
assert str(SourceTrackNumber(SourceTrackNumberPrefix(0), 0)) == "00000" | ||
assert str(SourceTrackNumber(SourceTrackNumberPrefix(0o123), 4)) == "01234" | ||
assert str(SourceTrackNumber(SourceTrackNumberPrefix(0o7777), 7)) == "77777" | ||
|
||
|
||
def test_repr() -> None: | ||
assert ( | ||
repr(SourceTrackNumber(SourceTrackNumberPrefix(0), 0)) | ||
== "SourceTrackNumber(SourceTrackNumberPrefix(0o0), 0)" | ||
) | ||
assert ( | ||
repr(SourceTrackNumber(SourceTrackNumberPrefix(0o123), 4)) | ||
== "SourceTrackNumber(SourceTrackNumberPrefix(0o123), 4)" | ||
) | ||
assert ( | ||
repr(SourceTrackNumber(SourceTrackNumberPrefix(0o7777), 7)) | ||
== "SourceTrackNumber(SourceTrackNumberPrefix(0o7777), 7)" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import pytest | ||
|
||
from game.datalink.sourcetracknumberprefix import SourceTrackNumberPrefix | ||
|
||
|
||
def test_limits() -> None: | ||
SourceTrackNumberPrefix(0) | ||
SourceTrackNumberPrefix(0o7777) | ||
with pytest.raises(ValueError): | ||
SourceTrackNumberPrefix(0o10000) | ||
with pytest.raises(ValueError): | ||
SourceTrackNumberPrefix(-1) | ||
|
||
|
||
def test_str() -> None: | ||
assert str(SourceTrackNumberPrefix(0)) == "0000" | ||
assert str(SourceTrackNumberPrefix(0o123)) == "0123" | ||
assert str(SourceTrackNumberPrefix(0o7777)) == "7777" | ||
|
||
|
||
def test_repr() -> None: | ||
assert repr(SourceTrackNumberPrefix(0)) == "SourceTrackNumberPrefix(0o0)" | ||
assert repr(SourceTrackNumberPrefix(0o123)) == "SourceTrackNumberPrefix(0o123)" | ||
assert repr(SourceTrackNumberPrefix(0o7777)) == "SourceTrackNumberPrefix(0o7777)" |