Skip to content

Commit

Permalink
Support for CarpetBombing task (pydcs#356)
Browse files Browse the repository at this point in the history
This change allows WWIIBigFormation to use Carpet Bombing task.
Removed duplicate tests for big formation which crept in with PR pydcs#351
  • Loading branch information
332fg-raven committed May 20, 2024
1 parent 4d3b0df commit 01f92c6
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
40 changes: 40 additions & 0 deletions dcs/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,13 @@ class Expend(Enum):
Half = "Half"
All = "All"

def __eq__(self, other: Any) -> bool:
if isinstance(other, str):
return self.value == other
if isinstance(other, Expend):
return self.value == other.value
return False


class AttackGroup(Task):
"""Attack group task action
Expand Down Expand Up @@ -1077,6 +1084,38 @@ def __eq__(self, other) -> bool:
return False


class CarpetBombing(Task):
"""Create Carpet Bombing Task object
:param alt_above: AGL altitude (in meters) from which bombing is to be performed. Defaults to 2000.
:param pattern_length: The pattern length (in meters) of the carpet bombing run. Defaults to 500.
:param release_qty: How many weapons to release. Defaults to Expend.Auto. See :py:class:`dcs.task.Expend`
:param weapon_type: The weapon to be used. Defaults to WeaponType.Auto. See :py:class:`dcs.task.WeaponType`
"""
Id = "CarpetBombing"
DEFAULT_ALT: int = 2000

def __init__(self, alt_above: int = DEFAULT_ALT,
pattern_length: int = 500,
release_qty: Expend = Expend.Auto,
weapon_type: WeaponType = WeaponType.Auto) -> None:
super().__init__(self.Id)
# hardcoded parameters are present in .miz file, but not visible in Mission Editor
self.params = {
"altitude": alt_above,
"altitudeEnabled": True if alt_above != CarpetBombing.DEFAULT_ALT else False,
"attackQty": 1,
"attackQtyLimit": False,
"attackType": "Carpet",
"carpetLength": pattern_length,
"expend": release_qty.value,
"groupAttack": False,
"weaponType": weapon_type.value,
"x": -52946.816024994,
"y": -52425.804462374,
}


tasks_map: Dict[str, Type[Task]] = {
ControlledTask.Id: ControlledTask,
EscortTaskAction.Id: EscortTaskAction,
Expand Down Expand Up @@ -1110,6 +1149,7 @@ def __eq__(self, other) -> bool:
AttackMapObject.Id: AttackMapObject,
EngageTargets.Id: EngageTargets,
WWIIFollowBigFormation.Id: WWIIFollowBigFormation,
CarpetBombing.Id: CarpetBombing,
}


Expand Down
Binary file added tests/missions/big-formation-carpet-bombing.miz
Binary file not shown.
57 changes: 57 additions & 0 deletions tests/test_mission.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
from dcs.task import WWIIFollowBigFormation
from dcs.action import PictureAction
from dcs.action import PictureToAll, PictureToCoalition, PictureToCountry, PictureToGroup, PictureToUnit
from dcs.task import Task, CarpetBombing, Expend, WeaponType
from dcs.action import Coalition
from dcs.mission import Mission
from enum import IntEnum


class BasicTests(unittest.TestCase):
Expand Down Expand Up @@ -1240,3 +1244,56 @@ def test_action_a_out_picture_u(self) -> None:
m2.load_file(m2_name)

self.assertEqual(m_action, m2.triggerrules.triggers[0].actions[5])

def test_smoke_action_carpet_bombing(self) -> None:

# this is fictional enum to simplify addressing as defined
# in big-formation-carpet-bombing.miz
class FormationPosition(IntEnum):
Leader = 0,
Right = 1,
Back = 2,
Left = 3,

def get_task(m: Mission, coalition: Coalition, country_name: str,
plane_group_idx: FormationPosition, point_idx: int, task_idx: int) -> Task:
return m.coalition[coalition.value].country(
country_name).plane_group[plane_group_idx].points[point_idx].tasks[task_idx]

def get_carpetbombing_task(m: Mission, coalition: Coalition, country_name: str,
plane_group_idx: FormationPosition, point_idx: int, task_idx: int) -> CarpetBombing:
task = get_task(m, coalition, country_name, plane_group_idx, point_idx, task_idx)
assert isinstance(task, CarpetBombing)
return task

m_name = "tests/missions/big-formation-carpet-bombing.miz"
m = dcs.mission.Mission()
m.load_file(m_name)

m2_name = "missions/saved.big-formation-carpet-bombing.miz"
m.save(m2_name)

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

coalition = Coalition.Blue
country = "USA"

def validate_formation(m: Mission, m2: Mission, position: FormationPosition, expend: Expend,
weapon_type: WeaponType, altitude_enabled: bool) -> None:
point_idx = 2
task_idx = 0

m_task = get_carpetbombing_task(m, coalition, country, position, point_idx, task_idx)

self.assertEqual(m_task.params["expend"], expend)
self.assertEqual(m_task.params["weaponType"], weapon_type)
self.assertEqual(m_task.params["altitudeEnabled"], altitude_enabled)

m2_task = get_carpetbombing_task(m2, coalition, country, position, point_idx, task_idx)
self.assertEqual(m_task, m2_task)

validate_formation(m, m2, FormationPosition.Leader, Expend.Auto, WeaponType.Auto, True)
validate_formation(m, m2, FormationPosition.Left, Expend.Four, WeaponType.IronBombs, False)
validate_formation(m, m2, FormationPosition.Back, Expend.Auto, WeaponType.IronBombs, False)
validate_formation(m, m2, FormationPosition.Right, Expend.Auto, WeaponType.Auto, False)

0 comments on commit 01f92c6

Please sign in to comment.