Skip to content

Commit

Permalink
Added support for FollowBigFormations task (pydcs#353)
Browse files Browse the repository at this point in the history
  • Loading branch information
332fg-raven authored and Raffson committed Feb 18, 2024
1 parent 349743d commit 24a90b7
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 3 deletions.
7 changes: 7 additions & 0 deletions dcs/mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ class Vector2:
y: float


@dataclass(frozen=True)
class Vector3:
x: int
y: int
z: int


class Point(Vector2):
def __init__(self, x: float, y: float, terrain: Terrain) -> None:
super().__init__(x, y)
Expand Down
52 changes: 49 additions & 3 deletions dcs/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""
from typing import List, Dict, Optional, Type, Any, Union
from enum import Enum, IntEnum
from dcs.mapping import Vector2
from dcs.mapping import Vector2, Vector3
from dcs.unit import Unit


Expand Down Expand Up @@ -536,7 +536,7 @@ def __init__(self,
"targetTypes": {i: targets[i - 1] for i in range(1, len(targets) + 1)},
"pos": position
}
if group_id:
if group_id is not None:
self.params["groupId"] = group_id
if lastwpt:
self.params["lastWptIndexFlagChangedManually"] = True
Expand Down Expand Up @@ -1048,6 +1048,51 @@ def __init__(self, from_index=None, to_index=None):
self.params["nWaypointIndx"] = to_index


class WWIIFollowBigFormation(Task):
Id = "FollowBigFormation"

class FormationType(IntEnum):
COMBAT_BOX_FOR_OPEN_FORMATION = 18
JAVELIN_DOWN = 16
COMBAT_BOX = 15

def __init__(self,
group_id: Optional[int] = None,
position: Vector3 = Vector3(0, 0, 0),
last_wpt_index_flag: bool = False,
last_wpt_index_flag_changed_manually: bool = False,
formation_type: FormationType = FormationType.COMBAT_BOX_FOR_OPEN_FORMATION,
pos_in_box: int = 0,
pos_in_group: int = 0,
pos_in_wing: int = 0,
last_wpt_index: Optional[int] = None) -> None:
super().__init__(self.Id)

self.params = {
"pos": {
"x": position.x,
"y": position.y,
"z": position.z
},
"lastWptIndexFlag": last_wpt_index_flag,
"lastWptIndexFlagChangedManually": last_wpt_index_flag_changed_manually,
"lastWptIndex": last_wpt_index,
"formationType": formation_type,
"posInBox": pos_in_box,
"posInGroup": pos_in_group,
"posInWing": pos_in_wing
}
if group_id is not None:
self.params["groupId"] = group_id
if last_wpt_index:
self.params["lastWptIndex"] = last_wpt_index

def __eq__(self, other) -> bool:
if isinstance(other, self.__class__):
return self.__dict__ == other.__dict__
return False


tasks_map: Dict[str, Type[Task]] = {
ControlledTask.Id: ControlledTask,
EscortTaskAction.Id: EscortTaskAction,
Expand Down Expand Up @@ -1079,7 +1124,8 @@ def __init__(self, from_index=None, to_index=None):
FireAtPoint.Id: FireAtPoint,
AttackUnit.Id: AttackUnit,
AttackMapObject.Id: AttackMapObject,
EngageTargets.Id: EngageTargets
EngageTargets.Id: EngageTargets,
WWIIFollowBigFormation.Id: WWIIFollowBigFormation,
}


Expand Down
Binary file added tests/missions/big-formation.miz
Binary file not shown.
117 changes: 117 additions & 0 deletions tests/test_mission.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from dcs.status_message import MessageSeverity, MessageType
from dcs.flyingunit import FlyingUnit
from dcs.unit import Ship
from dcs.task import WWIIFollowBigFormation


class BasicTests(unittest.TestCase):
Expand Down Expand Up @@ -884,3 +885,119 @@ def test_smoke_required_modules(self) -> None:
m2 = dcs.mission.Mission()
m2.load_file(saved_miz)
self.assertEqual(m.required_modules, m2.required_modules)

def test_big_formation_action_leader(self) -> None:
m_name = "tests/missions/big-formation.miz"
m = dcs.mission.Mission()
m.load_file(m_name)

assert isinstance(m.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[0].points[0].tasks[5], WWIIFollowBigFormation)

task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[0].points[0].tasks[5]

self.assertNotIn("groupId", task.params)
self.assertNotIn("lastWptIndex", task.params)
self.assertEqual(task.params["formationType"], WWIIFollowBigFormation.FormationType.COMBAT_BOX_FOR_OPEN_FORMATION)
self.assertEqual(task.params["pos"], {"x": 0, "y": 0, "z": 0})
self.assertTrue(task.params["lastWptIndexFlagChangedManually"])
self.assertEqual(len(task.params), 7)

m2_name = "missions/saved_big-formation.miz"
m.save(m2_name)

m2 = dcs.mission.Mission()
m2.load_file(m2_name)

assert isinstance(m2.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[0].points[0].tasks[5], WWIIFollowBigFormation)
m2_task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[0].points[0].tasks[5]

self.assertEqual(task, m2_task)

def test_big_formation_action_left(self) -> None:
m_name = "tests/missions/big-formation.miz"
m = dcs.mission.Mission()
m.load_file(m_name)

assert isinstance(m.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[1].points[0].tasks[5], WWIIFollowBigFormation)
task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[1].points[0].tasks[5]

self.assertEqual(task.params["formationType"], WWIIFollowBigFormation.FormationType.JAVELIN_DOWN)
self.assertEqual(task.params["pos"], {"x": -480, "y": -70, "z": -240})
self.assertEqual(task.params["groupId"], 2)
self.assertEqual(task.params["posInGroup"], 2)
self.assertEqual(task.params["lastWptIndex"], 3)
self.assertTrue(task.params["lastWptIndexFlag"])
self.assertEqual(len(task.params), 9)

m2_name = "missions/saved_big-formation.miz"
m.save(m2_name)

m2 = dcs.mission.Mission()
m2.load_file(m2_name)

assert isinstance(m2.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[1].points[0].tasks[5], WWIIFollowBigFormation)
m2_task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[1].points[0].tasks[5]

self.assertEqual(task, m2_task)

def test_big_formation_action_back(self) -> None:
m_name = "tests/missions/big-formation.miz"
m = dcs.mission.Mission()
m.load_file(m_name)

assert isinstance(m.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[2].points[0].tasks[5], WWIIFollowBigFormation)
task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[2].points[0].tasks[5]

self.assertEqual(task.params["formationType"], WWIIFollowBigFormation.FormationType.COMBAT_BOX)
self.assertEqual(task.params["pos"], {"x": -320, "y": -50, "z": -0})
self.assertEqual(task.params["groupId"], 2)
self.assertEqual(task.params["posInBox"], 3)
self.assertEqual(task.params["lastWptIndex"], 3)
self.assertFalse(task.params["lastWptIndexFlag"])
self.assertEqual(len(task.params), 9)

m2_name = "missions/saved_big-formation.miz"
m.save(m2_name)

m2 = dcs.mission.Mission()
m2.load_file(m2_name)

assert isinstance(m2.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[2].points[0].tasks[5], WWIIFollowBigFormation)
m2_task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[2].points[0].tasks[5]

self.assertEqual(task, m2_task)

def test_big_formation_action_right(self) -> None:
m_name = "tests/missions/big-formation.miz"
m = dcs.mission.Mission()
m.load_file(m_name)

assert isinstance(m.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[3].points[0].tasks[5], WWIIFollowBigFormation)
task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[3].points[0].tasks[5]

self.assertEqual(task.params["formationType"], WWIIFollowBigFormation.FormationType.COMBAT_BOX_FOR_OPEN_FORMATION)
self.assertEqual(task.params["pos"], {"x": -160, "y": 50, "z": 240})
self.assertEqual(task.params["groupId"], 2)
self.assertEqual(task.params["posInBox"], 1)
self.assertEqual(task.params["lastWptIndex"], 3)
self.assertTrue(task.params["lastWptIndexFlag"])
self.assertEqual(len(task.params), 9)

m2_name = "missions/saved_big-formation.miz"
m.save(m2_name)

m2 = dcs.mission.Mission()
m2.load_file(m2_name)

assert isinstance(m2.coalition['blue'].country("Combined Joint Task Forces Blue")
.plane_group[3].points[0].tasks[5], WWIIFollowBigFormation)
m2_task = m.coalition['blue'].country("Combined Joint Task Forces Blue").plane_group[3].points[0].tasks[5]

self.assertEqual(task, m2_task)

0 comments on commit 24a90b7

Please sign in to comment.