mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
parent
d26fc84316
commit
c37c56c879
@ -7,6 +7,7 @@ from typing import Any, List, Optional, TYPE_CHECKING
|
||||
from dcs import Point
|
||||
from dcs.planes import C_101CC, C_101EB, Su_33, FA_18C_hornet
|
||||
|
||||
from pydcs_extensions.hercules.hercules import Hercules
|
||||
from .flightroster import FlightRoster
|
||||
from .flightstate import FlightState, Navigating, Uninitialized
|
||||
from .flightstate.killed import Killed
|
||||
@ -18,9 +19,9 @@ from ..sidc import (
|
||||
Status,
|
||||
SymbolSet,
|
||||
)
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
from game.sim.gameupdateevents import GameUpdateEvents
|
||||
from game.sim.simulationresults import SimulationResults
|
||||
from game.squadrons import Squadron, Pilot
|
||||
@ -161,6 +162,10 @@ class Flight(SidcDescribable):
|
||||
def is_helo(self) -> bool:
|
||||
return self.unit_type.dcs_unit_type.helicopter
|
||||
|
||||
@property
|
||||
def is_hercules(self) -> bool:
|
||||
return self.unit_type == AircraftType.named("C-130J-30 Super Hercules")
|
||||
|
||||
@property
|
||||
def from_cp(self) -> ControlPoint:
|
||||
return self.departure
|
||||
@ -197,6 +202,8 @@ class Flight(SidcDescribable):
|
||||
return Su_33.fuel_max * 0.8
|
||||
elif unit_type in {C_101EB, C_101CC}:
|
||||
return unit_type.fuel_max * 0.5
|
||||
elif unit_type == Hercules:
|
||||
return unit_type.fuel_max * 0.75
|
||||
return None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
|
||||
@ -25,7 +25,7 @@ class AirAssaultLayout(StandardLayout):
|
||||
pickup: FlightWaypoint | None
|
||||
nav_to_ingress: list[FlightWaypoint]
|
||||
ingress: FlightWaypoint
|
||||
drop_off: FlightWaypoint
|
||||
drop_off: FlightWaypoint | None
|
||||
# This is an implementation detail used by CTLD. The aircraft will not go to this
|
||||
# waypoint. It is used by CTLD as the destination for unloaded troops.
|
||||
target: FlightWaypoint
|
||||
@ -37,7 +37,8 @@ class AirAssaultLayout(StandardLayout):
|
||||
yield self.pickup
|
||||
yield from self.nav_to_ingress
|
||||
yield self.ingress
|
||||
yield self.drop_off
|
||||
if self.drop_off is not None:
|
||||
yield self.drop_off
|
||||
yield self.target
|
||||
yield from self.nav_to_home
|
||||
yield self.arrival
|
||||
@ -53,7 +54,9 @@ class AirAssaultFlightPlan(StandardFlightPlan[AirAssaultLayout], UiZoneDisplay):
|
||||
|
||||
@property
|
||||
def tot_waypoint(self) -> FlightWaypoint:
|
||||
return self.layout.drop_off
|
||||
if self.flight.is_helo and self.layout.drop_off is not None:
|
||||
return self.layout.drop_off
|
||||
return self.layout.target
|
||||
|
||||
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> timedelta | None:
|
||||
if waypoint == self.tot_waypoint:
|
||||
@ -80,8 +83,10 @@ class AirAssaultFlightPlan(StandardFlightPlan[AirAssaultLayout], UiZoneDisplay):
|
||||
|
||||
class Builder(IBuilder[AirAssaultFlightPlan, AirAssaultLayout]):
|
||||
def layout(self) -> AirAssaultLayout:
|
||||
if not self.flight.is_helo:
|
||||
raise PlanningError("Air assault is only usable by helicopters")
|
||||
if not self.flight.is_helo and not self.flight.is_hercules:
|
||||
raise PlanningError(
|
||||
"Air assault is only usable by helicopters and Anubis' C-130 mod"
|
||||
)
|
||||
assert self.package.waypoints is not None
|
||||
|
||||
altitude = feet(1500) if self.flight.is_helo else self.doctrine.ingress_altitude
|
||||
@ -89,7 +94,7 @@ class Builder(IBuilder[AirAssaultFlightPlan, AirAssaultLayout]):
|
||||
|
||||
builder = WaypointBuilder(self.flight, self.coalition)
|
||||
|
||||
if self.flight.departure.cptype in [
|
||||
if self.flight.is_hercules or self.flight.departure.cptype in [
|
||||
ControlPointType.AIRCRAFT_CARRIER_GROUP,
|
||||
ControlPointType.LHA_GROUP,
|
||||
ControlPointType.OFF_MAP,
|
||||
@ -114,12 +119,15 @@ class Builder(IBuilder[AirAssaultFlightPlan, AirAssaultLayout]):
|
||||
pickup_position = pickup.position
|
||||
assault_area = builder.assault_area(self.package.target)
|
||||
heading = self.package.target.position.heading_between_point(pickup_position)
|
||||
if self.flight.is_hercules:
|
||||
assault_area.only_for_player = False
|
||||
|
||||
# TODO we can not gurantee a safe LZ for DropOff. See comment above.
|
||||
drop_off_zone = MissionTarget(
|
||||
"Dropoff zone",
|
||||
self.package.target.position.point_from_heading(heading, 1200),
|
||||
)
|
||||
dz = builder.dropoff_zone(drop_off_zone) if self.flight.is_helo else None
|
||||
|
||||
return AirAssaultLayout(
|
||||
departure=builder.takeoff(self.flight.departure),
|
||||
@ -135,7 +143,7 @@ class Builder(IBuilder[AirAssaultFlightPlan, AirAssaultLayout]):
|
||||
self.package.waypoints.ingress,
|
||||
self.package.target,
|
||||
),
|
||||
drop_off=builder.dropoff_zone(drop_off_zone),
|
||||
drop_off=dz,
|
||||
target=assault_area,
|
||||
nav_to_home=builder.nav_path(
|
||||
drop_off_zone.position,
|
||||
|
||||
@ -23,7 +23,7 @@ from game.theater import (
|
||||
TheaterGroundObject,
|
||||
TheaterUnit,
|
||||
)
|
||||
from game.utils import Distance, meters, nautical_miles
|
||||
from game.utils import Distance, meters, nautical_miles, feet
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.coalition import Coalition
|
||||
@ -225,15 +225,17 @@ class WaypointBuilder:
|
||||
position: Point,
|
||||
objective: MissionTarget,
|
||||
) -> FlightWaypoint:
|
||||
alt = self.doctrine.ingress_altitude
|
||||
alt_type: AltitudeReference = "BARO"
|
||||
if self.is_helo:
|
||||
if self.is_helo or self.flight.is_hercules:
|
||||
alt_type = "RADIO"
|
||||
alt = meters(60) if self.is_helo else feet(1000)
|
||||
|
||||
return FlightWaypoint(
|
||||
"INGRESS",
|
||||
ingress_type,
|
||||
position,
|
||||
meters(60) if self.is_helo else self.doctrine.ingress_altitude,
|
||||
alt,
|
||||
alt_type,
|
||||
description=f"INGRESS on {objective.name}",
|
||||
pretty_name=f"INGRESS on {objective.name}",
|
||||
|
||||
@ -29,6 +29,7 @@ from dcs.unitgroup import FlyingGroup
|
||||
from game.ato import Flight, FlightType
|
||||
from game.ato.flightplans.aewc import AewcFlightPlan
|
||||
from game.ato.flightplans.theaterrefueling import TheaterRefuelingFlightPlan
|
||||
from game.dcs.aircrafttype import AircraftType
|
||||
|
||||
|
||||
class AircraftBehavior:
|
||||
@ -298,11 +299,15 @@ class AircraftBehavior:
|
||||
|
||||
def configure_transport(self, group: FlyingGroup[Any], flight: Flight) -> None:
|
||||
group.task = Transport.name
|
||||
roe = OptROE.Values.WeaponHold
|
||||
if flight.is_hercules:
|
||||
group.task = GroundAttack.name
|
||||
roe = OptROE.Values.OpenFire
|
||||
self.configure_behavior(
|
||||
flight,
|
||||
group,
|
||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||
roe=OptROE.Values.WeaponHold,
|
||||
roe=roe,
|
||||
restrict_jettison=True,
|
||||
)
|
||||
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
from dcs.point import MovingPoint
|
||||
from dcs.task import Expend, WeaponType, CarpetBombing, OptROE
|
||||
|
||||
from game.ato.flightwaypointtype import FlightWaypointType
|
||||
from game.utils import feet, knots
|
||||
from pydcs_extensions.hercules.hercules import Hercules
|
||||
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
||||
|
||||
|
||||
class AirAssaultIngressBuilder(PydcsWaypointBuilder):
|
||||
def add_tasks(self, waypoint: MovingPoint) -> None:
|
||||
air_drop = self.group.units[0].unit_type in [Hercules]
|
||||
if air_drop:
|
||||
waypoint.speed = knots(230).meters_per_second
|
||||
waypoint.speed_locked = True
|
||||
waypoint.ETA_locked = False
|
||||
tgt = self.flight.flight_plan.package.target.position
|
||||
for wpt in self.flight.flight_plan.waypoints:
|
||||
if wpt.waypoint_type == FlightWaypointType.TARGET_GROUP_LOC:
|
||||
tgt = wpt.position
|
||||
break
|
||||
bombing = CarpetBombing(
|
||||
tgt,
|
||||
weapon_type=WeaponType.Bombs,
|
||||
expend=Expend.All,
|
||||
carpet_length=feet(9000).meters,
|
||||
)
|
||||
waypoint.add_task(bombing)
|
||||
@ -20,6 +20,7 @@ from game.missiongenerator.aircraft.waypoints.cargostop import CargoStopBuilder
|
||||
from game.missiongenerator.missiondata import MissionData
|
||||
from game.settings import Settings
|
||||
from game.utils import pairwise
|
||||
from .airassaultingress import AirAssaultIngressBuilder
|
||||
from .baiingress import BaiIngressBuilder
|
||||
from .landingzone import LandingZoneBuilder
|
||||
from .casingress import CasIngressBuilder
|
||||
@ -136,6 +137,7 @@ class WaypointGenerator:
|
||||
FlightWaypointType.DROPOFF_ZONE: LandingZoneBuilder,
|
||||
FlightWaypointType.REFUEL: RefuelPointBuilder,
|
||||
FlightWaypointType.CARGO_STOP: CargoStopBuilder,
|
||||
FlightWaypointType.INGRESS_AIR_ASSAULT: AirAssaultIngressBuilder,
|
||||
}
|
||||
builder = builders.get(waypoint.waypoint_type, DefaultWaypointBuilder)
|
||||
return builder(
|
||||
|
||||
@ -31,7 +31,7 @@ platformdirs==2.5.4
|
||||
pluggy==1.0.0
|
||||
pre-commit==2.20.0
|
||||
pydantic==1.10.2
|
||||
-e git+https://github.com/dcs-retribution/pydcs@f0bb4da4d458d714dedd1f3bba30deae5f25a80d#egg=pydcs
|
||||
-e git+https://github.com/dcs-retribution/pydcs@fb1fefcb32fbab82ac36b8519b87bae32326784e#egg=pydcs
|
||||
pyinstaller==5.6.2
|
||||
pyinstaller-hooks-contrib==2022.13
|
||||
pyparsing==3.0.9
|
||||
|
||||
@ -121,6 +121,52 @@ local unitPayloads = {
|
||||
[1] = 31,
|
||||
},
|
||||
},
|
||||
[9] = {
|
||||
["displayName"] = "Retribution CAS",
|
||||
["name"] = "Retribution CAS",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "Herc_JATO",
|
||||
["num"] = 1,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "{Herc_105mm_Howitzer}",
|
||||
["num"] = 8,
|
||||
},
|
||||
[3] = {
|
||||
["CLSID"] = "{Herc_M61_Vulcan_Rotary_Cannon}",
|
||||
["num"] = 6,
|
||||
},
|
||||
[4] = {
|
||||
["CLSID"] = "{Herc_GAU_23A_Chain_Gun}",
|
||||
["num"] = 7,
|
||||
},
|
||||
[5] = {
|
||||
["CLSID"] = "Herc_BattleStation_TGP",
|
||||
["num"] = 9,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 35,
|
||||
[2] = 31,
|
||||
},
|
||||
},
|
||||
[10] = {
|
||||
["name"] = "Retribution Air Assault",
|
||||
["pylons"] = {
|
||||
[1] = {
|
||||
["CLSID"] = "Herc_Soldier_Squad",
|
||||
["num"] = 12,
|
||||
},
|
||||
[2] = {
|
||||
["CLSID"] = "Herc_JATO",
|
||||
["num"] = 1,
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
[1] = 32,
|
||||
},
|
||||
},
|
||||
},
|
||||
["tasks"] = {
|
||||
},
|
||||
|
||||
@ -490,11 +490,11 @@ function Hercules_Cargo.Cargo_Initialize(initiator, Cargo_Contents, Cargo_Type_n
|
||||
Herc_Cargo[Herc_j].all_cargo_survive_to_the_ground = true
|
||||
else
|
||||
------------------------------------------------------------------------------
|
||||
if Hercules_Cargo.Calculate_Object_Height_AGL(Cargo_Drop_initiator) < 100.0 then--aircraft more than 10m but less than 100m above ground
|
||||
if Hercules_Cargo.Calculate_Object_Height_AGL(Cargo_Drop_initiator) < 152.4 then--aircraft more than 30ft but less than 500ft above ground
|
||||
Herc_Cargo[Herc_j].all_cargo_gets_destroyed = true
|
||||
else
|
||||
------------------------------------------------------------------------------
|
||||
Herc_Cargo[Herc_j].destroy_cargo_dropped_without_parachute = true--aircraft more than 100m above ground
|
||||
Herc_Cargo[Herc_j].destroy_cargo_dropped_without_parachute = true--aircraft more than 152.4m (500ft)above ground
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -568,7 +568,7 @@ function Hercules_Cargo.Hercules_Cargo_Drop_Events:onEvent(Cargo_Drop_Event)
|
||||
local Cargo_Container_Enclosed = Hercules_Cargo.types[GT_DisplayName]['container']
|
||||
Hercules_Cargo.Cargo_Initialize(Cargo_Drop_Event.initiator, Cargo_Drop_Event.weapon, GT_Name, Cargo_Container_Enclosed)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
world.addEventHandler(Hercules_Cargo.Hercules_Cargo_Drop_Events)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user