mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Implemented new options in settings:
- Pretense: Extra friendly zone connections - Add connections from each zone to this many closest friendly zones, which don't have an existing supply route defined in the campaign. - Number of cargo planes per side - Number of AI SEAD flights per control point / zone - Number of AI CAS flights per control point / zone - Number of AI BAI flights per control point / zone - Number of AI Strike flights per control point / zone - Number of AI BARCAP flights per control point / zone - Number of AI aircraft per flight - Number of player flights per aircraft type at each base - Number of AI cargo planes per side Implemented CAS helo mission handling for Pretense. Implemented separate pretense_air_groups container for storing/referencing Flight objects. Tweaked the supply costs of SAM sites and Command centers. Will no longer generate player air starts at roadbases either. Restored the missing DEAD flights to Pretense. Removed spawning of frontline units and moved the JTAC spawning to pretensemissiongenerator.py
This commit is contained in:
parent
e15aca8c54
commit
f4e8e30cb1
@ -22,6 +22,7 @@ from game.models.game_stats import GameStats
|
||||
from game.plugins import LuaPluginManager
|
||||
from game.utils import Distance
|
||||
from . import naming, persistency
|
||||
from .ato import Flight
|
||||
from .ato.flighttype import FlightType
|
||||
from .campaignloader import CampaignAirWingConfig
|
||||
from .coalition import Coalition
|
||||
@ -155,6 +156,7 @@ class Game:
|
||||
1: {},
|
||||
2: {},
|
||||
}
|
||||
self.pretense_air_groups: dict[str, Flight] = {}
|
||||
|
||||
self.on_load(game_still_initializing=True)
|
||||
|
||||
|
||||
@ -290,11 +290,9 @@ class GroundObjectGenerator:
|
||||
# All alive Ships
|
||||
ship_units.append(unit)
|
||||
if vehicle_units:
|
||||
vg = self.create_vehicle_group(group.group_name, vehicle_units)
|
||||
vg.hidden_on_mfd = self.ground_object.hide_on_mfd
|
||||
self.create_vehicle_group(group.group_name, vehicle_units)
|
||||
if ship_units:
|
||||
sg = self.create_ship_group(group.group_name, ship_units)
|
||||
sg.hidden_on_mfd = self.ground_object.hide_on_mfd
|
||||
self.create_ship_group(group.group_name, ship_units)
|
||||
|
||||
def create_vehicle_group(
|
||||
self, group_name: str, units: list[TheaterUnit]
|
||||
@ -827,30 +825,45 @@ class HelipadGenerator:
|
||||
else:
|
||||
self.helipads.append(sg)
|
||||
|
||||
# Generate a FARP Ammo and Fuel stack for each pad
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=Fortification.FARP_Fuel_Depot,
|
||||
position=pad.position.point_from_heading(helipad.heading.degrees, 35),
|
||||
heading=pad.heading + 180,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=Fortification.FARP_Ammo_Dump_Coating,
|
||||
position=pad.position.point_from_heading(
|
||||
helipad.heading.degrees, 35
|
||||
).point_from_heading(helipad.heading.degrees + 90, 10),
|
||||
heading=pad.heading + 90,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ws"),
|
||||
_type=Fortification.Windsock,
|
||||
position=helipad.point_from_heading(helipad.heading.degrees + 45, 35),
|
||||
heading=pad.heading,
|
||||
)
|
||||
if self.game.position_culled(helipad):
|
||||
cull_farp_statics = True
|
||||
if self.cp.coalition.player:
|
||||
for package in self.cp.coalition.ato.packages:
|
||||
for flight in package.flights:
|
||||
if flight.squadron.location == self.cp:
|
||||
cull_farp_statics = False
|
||||
break
|
||||
elif flight.divert and flight.divert == self.cp:
|
||||
cull_farp_statics = False
|
||||
break
|
||||
else:
|
||||
cull_farp_statics = False
|
||||
|
||||
if not cull_farp_statics:
|
||||
# Generate a FARP Ammo and Fuel stack for each pad
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=Fortification.FARP_Fuel_Depot,
|
||||
position=pad.position.point_from_heading(helipad.heading.degrees, 35),
|
||||
heading=pad.heading + 180,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=Fortification.FARP_Ammo_Dump_Coating,
|
||||
position=pad.position.point_from_heading(
|
||||
helipad.heading.degrees, 35
|
||||
).point_from_heading(helipad.heading.degrees + 90, 10),
|
||||
heading=pad.heading + 90,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ws"),
|
||||
_type=Fortification.Windsock,
|
||||
position=helipad.point_from_heading(helipad.heading.degrees + 45, 35),
|
||||
heading=pad.heading,
|
||||
)
|
||||
|
||||
def append_helipad(
|
||||
self,
|
||||
@ -927,61 +940,76 @@ class GroundSpawnRoadbaseGenerator:
|
||||
country.id
|
||||
)
|
||||
|
||||
# Generate ammo truck/farp and fuel truck/stack for each pad
|
||||
if self.game.settings.ground_start_trucks_roadbase:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=tanker_type,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 315,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=ammo_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
).point_from_heading(ground_spawn[0].heading.degrees + 180, 10),
|
||||
group_size=1,
|
||||
heading=pad.heading + 315,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
if self.game.position_culled(ground_spawn[0]):
|
||||
cull_farp_statics = True
|
||||
if self.cp.coalition.player:
|
||||
for package in self.cp.coalition.ato.packages:
|
||||
for flight in package.flights:
|
||||
if flight.squadron.location == self.cp:
|
||||
cull_farp_statics = False
|
||||
break
|
||||
elif flight.divert and flight.divert == self.cp:
|
||||
cull_farp_statics = False
|
||||
break
|
||||
else:
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=Fortification.FARP_Fuel_Depot,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
),
|
||||
heading=pad.heading + 270,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=Fortification.FARP_Ammo_Dump_Coating,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
).point_from_heading(ground_spawn[0].heading.degrees + 180, 10),
|
||||
heading=pad.heading + 180,
|
||||
)
|
||||
if self.game.settings.ground_start_ground_power_trucks_roadbase:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_power"),
|
||||
_type=power_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
).point_from_heading(ground_spawn[0].heading.degrees + 180, 20),
|
||||
group_size=1,
|
||||
heading=pad.heading + 315,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
cull_farp_statics = False
|
||||
|
||||
if not cull_farp_statics:
|
||||
# Generate ammo truck/farp and fuel truck/stack for each pad
|
||||
if self.game.settings.ground_start_trucks_roadbase:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=tanker_type,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 315,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=ammo_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
).point_from_heading(ground_spawn[0].heading.degrees + 180, 10),
|
||||
group_size=1,
|
||||
heading=pad.heading + 315,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
else:
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=Fortification.FARP_Fuel_Depot,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
),
|
||||
heading=pad.heading + 270,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=Fortification.FARP_Ammo_Dump_Coating,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
).point_from_heading(ground_spawn[0].heading.degrees + 180, 10),
|
||||
heading=pad.heading + 180,
|
||||
)
|
||||
if self.game.settings.ground_start_ground_power_trucks_roadbase:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_power"),
|
||||
_type=power_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
ground_spawn[0].heading.degrees + 90, 35
|
||||
).point_from_heading(ground_spawn[0].heading.degrees + 180, 20),
|
||||
group_size=1,
|
||||
heading=pad.heading + 315,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
|
||||
def generate(self) -> None:
|
||||
try:
|
||||
@ -1044,61 +1072,76 @@ class GroundSpawnGenerator:
|
||||
country.id
|
||||
)
|
||||
|
||||
# Generate a FARP Ammo and Fuel stack for each pad
|
||||
if self.game.settings.ground_start_trucks:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=tanker_type,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 175, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 45,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=ammo_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 185, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 45,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
if self.game.position_culled(vtol_pad[0]):
|
||||
cull_farp_statics = True
|
||||
if self.cp.coalition.player:
|
||||
for package in self.cp.coalition.ato.packages:
|
||||
for flight in package.flights:
|
||||
if flight.squadron.location == self.cp:
|
||||
cull_farp_statics = False
|
||||
break
|
||||
elif flight.divert and flight.divert == self.cp:
|
||||
cull_farp_statics = False
|
||||
break
|
||||
else:
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=Fortification.FARP_Fuel_Depot,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 180, 45
|
||||
),
|
||||
heading=pad.heading,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=Fortification.FARP_Ammo_Dump_Coating,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 180, 35
|
||||
),
|
||||
heading=pad.heading + 270,
|
||||
)
|
||||
if self.game.settings.ground_start_ground_power_trucks:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_power"),
|
||||
_type=power_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 185, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 45,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
cull_farp_statics = False
|
||||
|
||||
if not cull_farp_statics:
|
||||
# Generate a FARP Ammo and Fuel stack for each pad
|
||||
if self.game.settings.ground_start_trucks:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=tanker_type,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 175, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 45,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=ammo_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 185, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 45,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
else:
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_fuel"),
|
||||
_type=Fortification.FARP_Fuel_Depot,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 180, 45
|
||||
),
|
||||
heading=pad.heading,
|
||||
)
|
||||
self.m.static_group(
|
||||
country=country,
|
||||
name=(name + "_ammo"),
|
||||
_type=Fortification.FARP_Ammo_Dump_Coating,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 180, 35
|
||||
),
|
||||
heading=pad.heading + 270,
|
||||
)
|
||||
if self.game.settings.ground_start_ground_power_trucks:
|
||||
self.m.vehicle_group(
|
||||
country=country,
|
||||
name=(name + "_power"),
|
||||
_type=power_truck_type,
|
||||
position=pad.position.point_from_heading(
|
||||
vtol_pad[0].heading.degrees - 185, 35
|
||||
),
|
||||
group_size=1,
|
||||
heading=pad.heading + 45,
|
||||
move_formation=PointAction.OffRoad,
|
||||
)
|
||||
|
||||
def generate(self) -> None:
|
||||
try:
|
||||
|
||||
@ -49,17 +49,9 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
PRETENSE_SQUADRON_DEF_RETRIES = 100
|
||||
PRETENSE_SEAD_FLIGHTS_PER_CP = 2
|
||||
PRETENSE_CAS_FLIGHTS_PER_CP = 2
|
||||
PRETENSE_BAI_FLIGHTS_PER_CP = 2
|
||||
PRETENSE_STRIKE_FLIGHTS_PER_CP = 2
|
||||
PRETENSE_BARCAP_FLIGHTS_PER_CP = 2
|
||||
PRETENSE_AI_AIRCRAFT_PER_FLIGHT = 2
|
||||
PRETENSE_AI_AWACS_PER_FLIGHT = 1
|
||||
PRETENSE_AI_TANKERS_PER_FLIGHT = 1
|
||||
PRETENSE_AI_CARGO_PLANES_PER_SIDE = 2
|
||||
PRETENSE_PLAYER_AIRCRAFT_PER_FLIGHT = 1
|
||||
PRETENSE_PLAYER_FLIGHTS_PER_TYPE = 2
|
||||
|
||||
|
||||
class PretenseAircraftGenerator:
|
||||
@ -300,8 +292,12 @@ class PretenseAircraftGenerator:
|
||||
if cp.coalition != squadron.coalition:
|
||||
continue
|
||||
|
||||
squadron.owned_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.untasked_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.owned_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.untasked_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.populate_for_turn_0(False)
|
||||
package = Package(cp, squadron.flight_db, auto_asap=False)
|
||||
mission_types = squadron.auto_assignable_mission_types
|
||||
@ -320,46 +316,46 @@ class PretenseAircraftGenerator:
|
||||
FlightType.SEAD in mission_types
|
||||
or FlightType.SEAD_SWEEP in mission_types
|
||||
or FlightType.SEAD_ESCORT in mission_types
|
||||
) and num_of_sead < PRETENSE_SEAD_FLIGHTS_PER_CP:
|
||||
) and num_of_sead < self.game.settings.pretense_sead_flights_per_cp:
|
||||
flight_type = FlightType.SEAD
|
||||
num_of_sead += 1
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
elif (
|
||||
FlightType.DEAD in mission_types
|
||||
and num_of_sead < PRETENSE_SEAD_FLIGHTS_PER_CP
|
||||
and num_of_sead < self.game.settings.pretense_sead_flights_per_cp
|
||||
):
|
||||
flight_type = FlightType.DEAD
|
||||
num_of_sead += 1
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
elif (
|
||||
FlightType.CAS in mission_types
|
||||
) and num_of_cas < PRETENSE_CAS_FLIGHTS_PER_CP:
|
||||
) and num_of_cas < self.game.settings.pretense_cas_flights_per_cp:
|
||||
flight_type = FlightType.CAS
|
||||
num_of_cas += 1
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
elif (
|
||||
FlightType.BAI in mission_types
|
||||
) and num_of_bai < PRETENSE_BAI_FLIGHTS_PER_CP:
|
||||
) and num_of_bai < self.game.settings.pretense_bai_flights_per_cp:
|
||||
flight_type = FlightType.BAI
|
||||
num_of_bai += 1
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
elif (
|
||||
FlightType.STRIKE in mission_types
|
||||
or FlightType.OCA_RUNWAY in mission_types
|
||||
or FlightType.OCA_AIRCRAFT in mission_types
|
||||
) and num_of_strike < PRETENSE_STRIKE_FLIGHTS_PER_CP:
|
||||
) and num_of_strike < self.game.settings.pretense_strike_flights_per_cp:
|
||||
flight_type = FlightType.STRIKE
|
||||
num_of_strike += 1
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
elif (
|
||||
FlightType.BARCAP in mission_types
|
||||
or FlightType.TARCAP in mission_types
|
||||
or FlightType.ESCORT in mission_types
|
||||
or FlightType.INTERCEPTION in mission_types
|
||||
) and num_of_cap < PRETENSE_BARCAP_FLIGHTS_PER_CP:
|
||||
) and num_of_cap < self.game.settings.pretense_barcap_flights_per_cp:
|
||||
flight_type = FlightType.BARCAP
|
||||
num_of_cap += 1
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
elif FlightType.AEWC in mission_types:
|
||||
flight_type = FlightType.AEWC
|
||||
aircraft_per_flight = PRETENSE_AI_AWACS_PER_FLIGHT
|
||||
@ -429,8 +425,12 @@ class PretenseAircraftGenerator:
|
||||
PRETENSE_SQUADRON_DEF_RETRIES,
|
||||
)
|
||||
if squadron is not None:
|
||||
squadron.owned_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.untasked_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.owned_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.untasked_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.populate_for_turn_0(False)
|
||||
package = Package(cp, squadron.flight_db, auto_asap=False)
|
||||
flight = Flight(
|
||||
@ -453,7 +453,7 @@ class PretenseAircraftGenerator:
|
||||
if isinstance(cp, Airfield):
|
||||
# Generate SEAD flight
|
||||
flight_type = FlightType.SEAD
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
squadron = self.generate_pretense_squadron(
|
||||
cp,
|
||||
coalition,
|
||||
@ -470,8 +470,12 @@ class PretenseAircraftGenerator:
|
||||
PRETENSE_SQUADRON_DEF_RETRIES,
|
||||
)
|
||||
if squadron is not None:
|
||||
squadron.owned_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.untasked_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.owned_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.untasked_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.populate_for_turn_0(False)
|
||||
package = Package(cp, squadron.flight_db, auto_asap=False)
|
||||
flight = Flight(
|
||||
@ -494,7 +498,7 @@ class PretenseAircraftGenerator:
|
||||
|
||||
# Generate CAS flight
|
||||
flight_type = FlightType.CAS
|
||||
aircraft_per_flight = PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
aircraft_per_flight = self.game.settings.pretense_ai_aircraft_per_flight
|
||||
squadron = self.generate_pretense_squadron(
|
||||
cp,
|
||||
coalition,
|
||||
@ -511,8 +515,12 @@ class PretenseAircraftGenerator:
|
||||
PRETENSE_SQUADRON_DEF_RETRIES,
|
||||
)
|
||||
if squadron is not None:
|
||||
squadron.owned_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.untasked_aircraft += PRETENSE_AI_AIRCRAFT_PER_FLIGHT
|
||||
squadron.owned_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.untasked_aircraft += (
|
||||
self.game.settings.pretense_ai_aircraft_per_flight
|
||||
)
|
||||
squadron.populate_for_turn_0(False)
|
||||
package = Package(cp, squadron.flight_db, auto_asap=False)
|
||||
flight = Flight(
|
||||
@ -561,7 +569,7 @@ class PretenseAircraftGenerator:
|
||||
if not cp.can_operate(aircraft_type):
|
||||
continue
|
||||
|
||||
for i in range(PRETENSE_PLAYER_FLIGHTS_PER_TYPE):
|
||||
for i in range(self.game.settings.pretense_player_flights_per_type):
|
||||
squadron = self.generate_pretense_squadron_for(
|
||||
aircraft_type,
|
||||
cp,
|
||||
@ -607,7 +615,7 @@ class PretenseAircraftGenerator:
|
||||
cp: Control point to generate aircraft for.
|
||||
flight: The current flight being generated.
|
||||
"""
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
|
||||
for side in range(1, 3):
|
||||
if cp_name_trimmed not in cp.coalition.game.pretense_air[side]:
|
||||
@ -627,7 +635,7 @@ class PretenseAircraftGenerator:
|
||||
flight: The current flight being generated.
|
||||
"""
|
||||
flight_type = flight.flight_type
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
|
||||
for side in range(1, 3):
|
||||
if cp_name_trimmed not in flight.coalition.game.pretense_air[side]:
|
||||
@ -675,7 +683,7 @@ class PretenseAircraftGenerator:
|
||||
PRETENSE_SQUADRON_DEF_RETRIES,
|
||||
)
|
||||
num_of_cargo_sq_to_generate = (
|
||||
PRETENSE_AI_CARGO_PLANES_PER_SIDE
|
||||
self.game.settings.pretense_ai_cargo_planes_per_side
|
||||
- self.number_of_pretense_cargo_plane_sq_for(cp.coalition.air_wing)
|
||||
)
|
||||
for i in range(num_of_cargo_sq_to_generate):
|
||||
@ -795,7 +803,8 @@ class PretenseAircraftGenerator:
|
||||
if flight.package.target != flight.departure:
|
||||
break
|
||||
for mission_target in cp.ground_objects:
|
||||
flight.package.target = mission_target
|
||||
if mission_target.alive_unit_count > 0:
|
||||
flight.package.target = mission_target
|
||||
break
|
||||
elif (
|
||||
flight.flight_type == FlightType.OCA_RUNWAY
|
||||
@ -837,23 +846,30 @@ class PretenseAircraftGenerator:
|
||||
break
|
||||
|
||||
now = self.game.conditions.start_time
|
||||
flight.package.set_tot_asap(now)
|
||||
try:
|
||||
flight.package.set_tot_asap(now)
|
||||
except:
|
||||
raise RuntimeError(
|
||||
f"Pretense flight group {group.name} {flight.squadron.aircraft} {flight.flight_type} for target {flight.package.target} configuration failed. Please check if your Retribution campaign is compatible with Pretense."
|
||||
)
|
||||
|
||||
logging.info(
|
||||
f"Configuring flight {group.name} {flight.squadron.aircraft} {flight.flight_type}, number of players: {flight.client_count}"
|
||||
)
|
||||
PretenseFlightGroupConfigurator(
|
||||
flight,
|
||||
group,
|
||||
self.game,
|
||||
self.mission,
|
||||
self.time,
|
||||
self.radio_registry,
|
||||
self.tacan_registy,
|
||||
self.mission_data,
|
||||
dynamic_runways,
|
||||
self.use_client,
|
||||
).configure()
|
||||
self.mission_data.flights.append(
|
||||
PretenseFlightGroupConfigurator(
|
||||
flight,
|
||||
group,
|
||||
self.game,
|
||||
self.mission,
|
||||
self.time,
|
||||
self.radio_registry,
|
||||
self.tacan_registy,
|
||||
self.mission_data,
|
||||
dynamic_runways,
|
||||
self.use_client,
|
||||
).configure()
|
||||
)
|
||||
|
||||
if self.ewrj:
|
||||
self._track_ewrj_flight(flight, group)
|
||||
|
||||
@ -30,7 +30,7 @@ class PretenseNameGenerator(NameGenerator):
|
||||
@classmethod
|
||||
def next_pretense_aircraft_name(cls, cp: ControlPoint, flight: Flight) -> str:
|
||||
cls.aircraft_number += 1
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
return "{}-{}-{}".format(
|
||||
cp_name_trimmed, str(flight.flight_type).lower(), cls.aircraft_number
|
||||
)
|
||||
@ -77,12 +77,17 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
||||
== self.flight.coalition.game.coalition_for(is_player)
|
||||
else 1
|
||||
)
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
|
||||
if self.flight.client_count == 0:
|
||||
self.flight.coalition.game.pretense_air[cp_side][cp_name_trimmed][
|
||||
self.flight.flight_type
|
||||
].append(name)
|
||||
try:
|
||||
self.flight.coalition.game.pretense_air_groups[name] = self.flight
|
||||
except AttributeError:
|
||||
self.flight.coalition.game.pretense_air_groups = {}
|
||||
self.flight.coalition.game.pretense_air_groups[name] = self.flight
|
||||
|
||||
def generate_flight_at_departure(self) -> FlyingGroup[Any]:
|
||||
cp = self.flight.departure
|
||||
@ -94,7 +99,7 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
||||
== self.flight.coalition.game.coalition_for(is_player)
|
||||
else 1
|
||||
)
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
|
||||
try:
|
||||
if self.start_type is StartType.IN_FLIGHT:
|
||||
@ -139,8 +144,7 @@ class PretenseFlightGroupSpawner(FlightGroupSpawner):
|
||||
pad_group = self._generate_at_cp_ground_spawn(name, cp)
|
||||
if pad_group is not None:
|
||||
return pad_group
|
||||
self.insert_into_pretense(name)
|
||||
return self._generate_over_departure(name, cp)
|
||||
raise NoParkingSlotError
|
||||
elif isinstance(cp, Airfield):
|
||||
is_heli = self.flight.squadron.aircraft.helicopter
|
||||
if cp.has_helipads and is_heli:
|
||||
|
||||
@ -259,7 +259,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
def generate_pretense_land_upgrade_supply(self, cp_name: str, cp_side: int) -> str:
|
||||
lua_string_zones = ""
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalpha()])
|
||||
cp_side_str = "blue" if cp_side == PRETENSE_BLUE_SIDE else "red"
|
||||
cp = self.game.theater.controlpoints[0]
|
||||
for loop_cp in self.game.theater.controlpoints:
|
||||
@ -398,7 +398,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
)
|
||||
lua_string_zones += " products = {\n"
|
||||
for mission_type in self.game.pretense_air[cp_side][cp_name_trimmed]:
|
||||
if mission_type == FlightType.SEAD:
|
||||
if mission_type in (FlightType.SEAD, FlightType.DEAD):
|
||||
mission_name = "attack.sead"
|
||||
for air_group in self.game.pretense_air[cp_side][cp_name_trimmed][
|
||||
mission_type
|
||||
@ -414,6 +414,9 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
for air_group in self.game.pretense_air[cp_side][cp_name_trimmed][
|
||||
mission_type
|
||||
]:
|
||||
flight = self.game.pretense_air_groups[air_group]
|
||||
if flight.is_helo:
|
||||
mission_name = "attack.helo"
|
||||
lua_string_zones += (
|
||||
f" presets.missions.{mission_name}:extend"
|
||||
+ "({name='"
|
||||
@ -503,7 +506,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
def generate_pretense_sea_upgrade_supply(self, cp_name: str, cp_side: int) -> str:
|
||||
lua_string_zones = ""
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalpha()])
|
||||
cp_side_str = "blue" if cp_side == PRETENSE_BLUE_SIDE else "red"
|
||||
|
||||
if cp_side == PRETENSE_BLUE_SIDE:
|
||||
@ -608,6 +611,9 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
for air_group in self.game.pretense_air[cp_side][cp_name_trimmed][
|
||||
mission_type
|
||||
]:
|
||||
flight = self.game.pretense_air_groups[air_group]
|
||||
if flight.is_helo:
|
||||
mission_name = "attack.helo"
|
||||
lua_string_zones += (
|
||||
f" presets.missions.{mission_name}:extend"
|
||||
+ "({name='"
|
||||
@ -697,7 +703,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
def generate_pretense_zone_land(self, cp_name: str) -> str:
|
||||
lua_string_zones = ""
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalpha()])
|
||||
|
||||
lua_string_zones += f"zones.{cp_name_trimmed}:defineUpgrades(" + "{\n"
|
||||
lua_string_zones += " [1] = { --red side\n"
|
||||
@ -771,7 +777,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
def generate_pretense_zone_sea(self, cp_name: str) -> str:
|
||||
lua_string_zones = ""
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp_name.lower() if i.isalpha()])
|
||||
|
||||
lua_string_zones += f"zones.{cp_name_trimmed}:defineUpgrades(" + "{\n"
|
||||
lua_string_zones += " [1] = { --red side\n"
|
||||
@ -823,29 +829,29 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
|
||||
def generate_pretense_plugin_data(self) -> None:
|
||||
self.inject_plugin_script("base", "mist_4_5_107.lua", "mist_4_5_107")
|
||||
self.inject_plugin_script(
|
||||
"pretense", "pretense_compiled.lua", "pretense_compiled"
|
||||
)
|
||||
|
||||
trigger = TriggerStart(comment="Pretense init")
|
||||
|
||||
lua_string_config = ""
|
||||
lua_string_config = "Config = Config or {}\n"
|
||||
|
||||
lua_string_config += (
|
||||
f"Config.maxDistFromFront = "
|
||||
+ str(self.game.settings.pretense_maxdistfromfront_distance * 1000)
|
||||
+ "\n"
|
||||
)
|
||||
lua_string_config += (
|
||||
f"Config.closeOverride = "
|
||||
+ str(self.game.settings.pretense_closeoverride_distance * 1000)
|
||||
+ "\n"
|
||||
)
|
||||
if self.game.settings.pretense_do_not_generate_sead_missions:
|
||||
lua_string_config += "Config.disablePlayerSead = true\n"
|
||||
else:
|
||||
lua_string_config += "Config.disablePlayerSead = false\n"
|
||||
|
||||
trigger = TriggerStart(comment="Pretense config")
|
||||
trigger.add_action(DoScript(String(lua_string_config)))
|
||||
self.mission.triggerrules.triggers.append(trigger)
|
||||
|
||||
self.inject_plugin_script(
|
||||
"pretense", "pretense_compiled.lua", "pretense_compiled"
|
||||
)
|
||||
|
||||
trigger = TriggerStart(comment="Pretense init")
|
||||
|
||||
init_header_file = open("./resources/plugins/pretense/init_header.lua", "r")
|
||||
init_header = init_header_file.read()
|
||||
|
||||
@ -855,7 +861,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
if isinstance(cp, OffMapSpawn):
|
||||
continue
|
||||
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
cp_side = 2 if cp.captured else 1
|
||||
for side in range(1, 3):
|
||||
if cp_name_trimmed not in self.game.pretense_air[cp_side]:
|
||||
@ -947,12 +953,17 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
else:
|
||||
# Finally, connect remaining non-connected points
|
||||
closest_cps = self.game.theater.closest_friendly_control_points_to(cp)
|
||||
lua_string_connman += self.generate_pretense_zone_connection(
|
||||
connected_points, cp.name, closest_cps[0].name
|
||||
)
|
||||
lua_string_connman += self.generate_pretense_zone_connection(
|
||||
connected_points, cp.name, closest_cps[1].name
|
||||
)
|
||||
for extra_connection in range(
|
||||
self.game.settings.pretense_extra_zone_connections
|
||||
):
|
||||
if len(closest_cps) > extra_connection:
|
||||
lua_string_connman += self.generate_pretense_zone_connection(
|
||||
connected_points,
|
||||
cp.name,
|
||||
closest_cps[extra_connection].name,
|
||||
)
|
||||
else:
|
||||
break
|
||||
|
||||
lua_string_supply = "local redSupply = {\n"
|
||||
# Generate supply
|
||||
@ -963,7 +974,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
cp_side_captured = cp_side == 2
|
||||
if cp_side_captured != cp.captured:
|
||||
continue
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
for mission_type in self.game.pretense_air[cp_side][cp_name_trimmed]:
|
||||
if mission_type == FlightType.PRETENSE_CARGO:
|
||||
for air_group in self.game.pretense_air[cp_side][
|
||||
@ -976,7 +987,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
lua_string_supply += "local offmapZones = {\n"
|
||||
for cp in self.game.theater.controlpoints:
|
||||
if isinstance(cp, Airfield):
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalnum()])
|
||||
cp_name_trimmed = "".join([i for i in cp.name.lower() if i.isalpha()])
|
||||
lua_string_supply += f" zones.{cp_name_trimmed},\n"
|
||||
lua_string_supply += "}\n"
|
||||
|
||||
@ -997,8 +1008,7 @@ class PretenseLuaGenerator(LuaGenerator):
|
||||
init_footer = init_footer_file.read()
|
||||
|
||||
lua_string = (
|
||||
lua_string_config
|
||||
+ init_header
|
||||
init_header
|
||||
+ lua_string_zones
|
||||
+ lua_string_connman
|
||||
+ init_body_1
|
||||
|
||||
@ -12,6 +12,7 @@ from dcs.countries import (
|
||||
CombinedJointTaskForcesBlue,
|
||||
CombinedJointTaskForcesRed,
|
||||
)
|
||||
from dcs.task import AFAC, FAC, SetInvisibleCommand, SetImmortalCommand, OrbitAction
|
||||
|
||||
from game.lasercodes.lasercoderegistry import LaserCodeRegistry
|
||||
from game.missiongenerator.convoygenerator import ConvoyGenerator
|
||||
@ -21,7 +22,7 @@ from game.missiongenerator.forcedoptionsgenerator import ForcedOptionsGenerator
|
||||
from game.missiongenerator.frontlineconflictdescription import (
|
||||
FrontLineConflictDescription,
|
||||
)
|
||||
from game.missiongenerator.missiondata import MissionData
|
||||
from game.missiongenerator.missiondata import MissionData, JtacInfo
|
||||
from game.missiongenerator.tgogenerator import TgoGenerator
|
||||
from game.missiongenerator.visualsgenerator import VisualsGenerator
|
||||
from game.naming import namegen
|
||||
@ -34,6 +35,8 @@ from .pretenseluagenerator import PretenseLuaGenerator
|
||||
from .pretensetgogenerator import PretenseTgoGenerator
|
||||
from .pretensetriggergenerator import PretenseTriggerGenerator
|
||||
from ..ato.airtaaskingorder import AirTaskingOrder
|
||||
from ..callsigns import callsign_for_support_unit
|
||||
from ..dcs.aircrafttype import AircraftType
|
||||
from ..missiongenerator import MissionGenerator
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -148,27 +151,61 @@ class PretenseMissionGenerator(MissionGenerator):
|
||||
for front_line in self.game.theater.conflicts():
|
||||
player_cp = front_line.blue_cp
|
||||
enemy_cp = front_line.red_cp
|
||||
conflict = FrontLineConflictDescription.frontline_cas_conflict(
|
||||
front_line, self.game.theater
|
||||
)
|
||||
# Generate frontline ops
|
||||
player_gp = self.game.ground_planners[player_cp.id].units_per_cp[
|
||||
enemy_cp.id
|
||||
]
|
||||
enemy_gp = self.game.ground_planners[enemy_cp.id].units_per_cp[player_cp.id]
|
||||
ground_conflict_gen = FlotGenerator(
|
||||
self.mission,
|
||||
conflict,
|
||||
self.game,
|
||||
player_gp,
|
||||
enemy_gp,
|
||||
player_cp.stances[enemy_cp.id],
|
||||
enemy_cp.stances[player_cp.id],
|
||||
self.unit_map,
|
||||
self.radio_registry,
|
||||
self.mission_data,
|
||||
)
|
||||
ground_conflict_gen.generate()
|
||||
|
||||
# Add JTAC
|
||||
if self.game.blue.faction.has_jtac:
|
||||
freq = self.radio_registry.alloc_uhf()
|
||||
# If the option fc3LaserCode is enabled, force all JTAC
|
||||
# laser codes to 1113 to allow lasing for Su-25 Frogfoots and A-10A Warthogs.
|
||||
# Otherwise use 1688 for the first JTAC, 1687 for the second etc.
|
||||
if self.game.settings.plugins.get("ctld.fc3LaserCode"):
|
||||
code = self.game.laser_code_registry.fc3_code
|
||||
else:
|
||||
code = front_line.laser_code
|
||||
|
||||
utype = self.game.blue.faction.jtac_unit
|
||||
if utype is None:
|
||||
utype = AircraftType.named("MQ-9 Reaper")
|
||||
|
||||
country = self.mission.country(self.game.blue.faction.country.name)
|
||||
position = FrontLineConflictDescription.frontline_position(
|
||||
front_line, self.game.theater, self.game.settings
|
||||
)
|
||||
jtac = self.mission.flight_group(
|
||||
country=country,
|
||||
name=namegen.next_jtac_name(),
|
||||
aircraft_type=utype.dcs_unit_type,
|
||||
position=position[0],
|
||||
airport=None,
|
||||
altitude=5000,
|
||||
maintask=AFAC,
|
||||
)
|
||||
jtac.points[0].tasks.append(
|
||||
FAC(
|
||||
callsign=len(self.mission_data.jtacs) + 1,
|
||||
frequency=int(freq.mhz),
|
||||
modulation=freq.modulation,
|
||||
)
|
||||
)
|
||||
jtac.points[0].tasks.append(SetInvisibleCommand(True))
|
||||
jtac.points[0].tasks.append(SetImmortalCommand(True))
|
||||
jtac.points[0].tasks.append(
|
||||
OrbitAction(5000, 300, OrbitAction.OrbitPattern.Circle)
|
||||
)
|
||||
frontline = f"Frontline {player_cp.name}/{enemy_cp.name}"
|
||||
# Note: Will need to change if we ever add ground based JTAC.
|
||||
callsign = callsign_for_support_unit(jtac)
|
||||
self.mission_data.jtacs.append(
|
||||
JtacInfo(
|
||||
group_name=jtac.name,
|
||||
unit_name=jtac.units[0].name,
|
||||
callsign=callsign,
|
||||
region=frontline,
|
||||
code=str(code),
|
||||
blue=True,
|
||||
freq=freq,
|
||||
)
|
||||
)
|
||||
|
||||
def generate_air_units(self, tgo_generator: TgoGenerator) -> None:
|
||||
"""Generate the air units for the Operation"""
|
||||
|
||||
@ -988,21 +988,102 @@ class Settings:
|
||||
default=130,
|
||||
min=10,
|
||||
max=10000,
|
||||
detail=(
|
||||
"Zones farther away than this from the front line are switched "
|
||||
"into low activity state, but will still be there as functional "
|
||||
"parts of the economy. Use this to adjust performance."
|
||||
),
|
||||
)
|
||||
pretense_closeoverride_distance: int = bounded_int_option(
|
||||
"Close override distance (km)",
|
||||
pretense_extra_zone_connections: int = bounded_int_option(
|
||||
"Extra friendly zone connections",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=28,
|
||||
min=5,
|
||||
max=10000,
|
||||
default=2,
|
||||
min=0,
|
||||
max=10,
|
||||
detail=(
|
||||
"Add connections from each zone to this many closest friendly zones,"
|
||||
"which don't have an existing supply route defined in the campaign."
|
||||
),
|
||||
)
|
||||
pretense_do_not_generate_sead_missions: bool = boolean_option(
|
||||
"Do not generate player SEAD missions",
|
||||
page=PRETENSE_PAGE,
|
||||
section=PERFORMANCE_SECTION,
|
||||
section=GENERAL_SECTION,
|
||||
default=False,
|
||||
)
|
||||
pretense_num_of_cargo_planes: int = bounded_int_option(
|
||||
"Number of cargo planes per side",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=100,
|
||||
)
|
||||
pretense_sead_flights_per_cp: int = bounded_int_option(
|
||||
"Number of AI SEAD flights per control point / zone",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=10,
|
||||
)
|
||||
pretense_cas_flights_per_cp: int = bounded_int_option(
|
||||
"Number of AI CAS flights per control point / zone",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=10,
|
||||
)
|
||||
pretense_bai_flights_per_cp: int = bounded_int_option(
|
||||
"Number of AI BAI flights per control point / zone",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=10,
|
||||
)
|
||||
pretense_strike_flights_per_cp: int = bounded_int_option(
|
||||
"Number of AI Strike flights per control point / zone",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=10,
|
||||
)
|
||||
pretense_barcap_flights_per_cp: int = bounded_int_option(
|
||||
"Number of AI BARCAP flights per control point / zone",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=10,
|
||||
)
|
||||
pretense_ai_aircraft_per_flight: int = bounded_int_option(
|
||||
"Number of AI aircraft per flight",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=4,
|
||||
)
|
||||
pretense_player_flights_per_type: int = bounded_int_option(
|
||||
"Number of player flights per aircraft type at each base",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=10,
|
||||
)
|
||||
pretense_ai_cargo_planes_per_side: int = bounded_int_option(
|
||||
"Number of AI cargo planes per side",
|
||||
page=PRETENSE_PAGE,
|
||||
section=GENERAL_SECTION,
|
||||
default=2,
|
||||
min=1,
|
||||
max=20,
|
||||
)
|
||||
|
||||
# Cheating. Not using auto settings because the same page also has buttons which do
|
||||
# not alter settings.
|
||||
|
||||
@ -494,7 +494,7 @@ presets = {
|
||||
}),
|
||||
comCenter = Preset:new({
|
||||
display = 'Command Center',
|
||||
cost = 2500,
|
||||
cost = 12500,
|
||||
type = 'upgrade',
|
||||
template = "command-center"
|
||||
})
|
||||
@ -522,43 +522,43 @@ presets = {
|
||||
}),
|
||||
sa10 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=30000,
|
||||
type='defense',
|
||||
template='sa10',
|
||||
}),
|
||||
sa5 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=20000,
|
||||
type='defense',
|
||||
template='sa5',
|
||||
}),
|
||||
sa3 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=4000,
|
||||
type='defense',
|
||||
template='sa3',
|
||||
}),
|
||||
sa6 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=6000,
|
||||
type='defense',
|
||||
template='sa6',
|
||||
}),
|
||||
sa11 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=10000,
|
||||
type='defense',
|
||||
template='sa11',
|
||||
}),
|
||||
hawk = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=6000,
|
||||
type='defense',
|
||||
template='hawk',
|
||||
}),
|
||||
patriot = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=30000,
|
||||
type='defense',
|
||||
template='patriot',
|
||||
}),
|
||||
@ -596,43 +596,43 @@ presets = {
|
||||
}),
|
||||
sa10 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=30000,
|
||||
type='defense',
|
||||
template='sa10',
|
||||
}),
|
||||
sa5 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=20000,
|
||||
type='defense',
|
||||
template='sa5',
|
||||
}),
|
||||
sa3 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=4000,
|
||||
type='defense',
|
||||
template='sa3',
|
||||
}),
|
||||
sa6 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=6000,
|
||||
type='defense',
|
||||
template='sa6',
|
||||
}),
|
||||
sa11 = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=10000,
|
||||
type='defense',
|
||||
template='sa11',
|
||||
}),
|
||||
hawk = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=6000,
|
||||
type='defense',
|
||||
template='hawk',
|
||||
}),
|
||||
patriot = Preset:new({
|
||||
display = 'SAM',
|
||||
cost=3000,
|
||||
cost=30000,
|
||||
type='defense',
|
||||
template='patriot',
|
||||
}),
|
||||
|
||||
@ -32,7 +32,6 @@ Config.buildSpeed = Config.buildSpeed or 10 -- structure and defense build speed
|
||||
Config.supplyBuildSpeed = Config.supplyBuildSpeed or 85 -- supply helicopters and convoys build speed
|
||||
Config.missionBuildSpeedReduction = Config.missionBuildSpeedReduction or 0.12 -- reduction of build speed in case of ai missions
|
||||
Config.maxDistFromFront = Config.maxDistFromFront or 129640 -- max distance in meters from front after which zone is forced into low activity state (export mode)
|
||||
Config.closeOverride = Config.closeOverride or 27780 -- close override distance in meters from front within which zone is never forced into low activity state
|
||||
Config.disablePlayerSead = Config.disablePlayerSead or false
|
||||
|
||||
Config.missions = Config.missions or {}
|
||||
@ -505,8 +504,6 @@ end
|
||||
GroupMonitor = {}
|
||||
do
|
||||
GroupMonitor.blockedDespawnTime = 10*60 --used to despawn aircraft that are stuck taxiing for some reason
|
||||
GroupMonitor.blockedDespawnTimeGround = 30*60 --used to despawn ground units that are stuck en route for some reason
|
||||
GroupMonitor.blockedDespawnTimeGroundAssault = 90*60 --used to despawn assault units that are stuck en route for some reason
|
||||
GroupMonitor.landedDespawnTime = 10
|
||||
GroupMonitor.atDestinationDespawnTime = 2*60
|
||||
GroupMonitor.recoveryReduction = 0.8 -- reduce recovered resource from landed missions by this amount to account for maintenance
|
||||
@ -642,13 +639,7 @@ do
|
||||
group.state = 'enroute'
|
||||
group.lastStateTime = timer.getAbsTime()
|
||||
MissionTargetRegistry.addBaiTarget(group)
|
||||
elseif group.product.missionType == 'assault' and timer.getAbsTime() - group.lastStateTime > GroupMonitor.blockedDespawnTimeGroundAssault then
|
||||
env.info('GroupMonitor: processSurface ['..group.name..'] despawned due to blockage')
|
||||
gr:destroy()
|
||||
local todeliver = math.floor(group.product.cost)
|
||||
z:addResource(todeliver)
|
||||
return true
|
||||
elseif timer.getAbsTime() - group.lastStateTime > GroupMonitor.blockedDespawnTimeGround then
|
||||
elseif timer.getAbsTime() - group.lastStateTime > GroupMonitor.blockedDespawnTime then
|
||||
env.info('GroupMonitor: processSurface ['..group.name..'] despawned due to blockage')
|
||||
gr:destroy()
|
||||
local todeliver = math.floor(group.product.cost)
|
||||
@ -744,7 +735,7 @@ do
|
||||
y = group.target.zone.point.z
|
||||
}
|
||||
|
||||
TaskExtensions.moveOffRoadToPointAndAssault(gr, tp, group.target.built)
|
||||
TaskExtensions.moveOnRoadToPointAndAssault(gr, tp, group.target.built)
|
||||
group.isstopped = false
|
||||
end
|
||||
end
|
||||
@ -1231,7 +1222,7 @@ do
|
||||
if v.type == 'defense' and v.side ~= group:getCoalition() then
|
||||
local gr = Group.getByName(v.name)
|
||||
for _,unit in ipairs(gr:getUnits()) do
|
||||
if unit:hasAttribute('SAM SR') or unit:hasAttribute('SAM TR') or unit:hasAttribute('AAA') or unit:hasAttribute('IR Guided SAM') or unit:hasAttribute('SAM LL') then
|
||||
if unit:hasAttribute('SAM SR') or unit:hasAttribute('SAM TR') then
|
||||
table.insert(viable, unit:getName())
|
||||
end
|
||||
end
|
||||
@ -1245,7 +1236,7 @@ do
|
||||
{
|
||||
id = 'EngageTargets',
|
||||
params = {
|
||||
targetTypes = {'SAM SR', 'SAM TR', 'AAA', 'IR Guided SAM', 'SAM LL'}
|
||||
targetTypes = {'SAM SR', 'SAM TR'}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2145,68 +2136,7 @@ do
|
||||
}
|
||||
group:getController():setTask(mis)
|
||||
end
|
||||
|
||||
function TaskExtensions.moveOffRoadToPointAndAssault(group, point, targets)
|
||||
if not group or not point then return end
|
||||
if not group:isExist() or group:getSize()==0 then return end
|
||||
local startPos = group:getUnit(1):getPoint()
|
||||
|
||||
local srx, sry = land.getClosestPointOnRoads('roads', startPos.x, startPos.z)
|
||||
local erx, ery = land.getClosestPointOnRoads('roads', point.x, point.y)
|
||||
|
||||
local mis = {
|
||||
id='Mission',
|
||||
params = {
|
||||
route = {
|
||||
points = {
|
||||
[1] = {
|
||||
type= AI.Task.WaypointType.TURNING_POINT,
|
||||
x = srx,
|
||||
y = sry,
|
||||
speed = 1000,
|
||||
action = AI.Task.VehicleFormation.DIAMOND
|
||||
},
|
||||
[2] = {
|
||||
type= AI.Task.WaypointType.TURNING_POINT,
|
||||
x = erx,
|
||||
y = ery,
|
||||
speed = 1000,
|
||||
action = AI.Task.VehicleFormation.DIAMOND
|
||||
},
|
||||
[3] = {
|
||||
type= AI.Task.WaypointType.TURNING_POINT,
|
||||
x = point.x,
|
||||
y = point.y,
|
||||
speed = 1000,
|
||||
action = AI.Task.VehicleFormation.DIAMOND
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i,v in pairs(targets) do
|
||||
if v.type == 'defense' then
|
||||
local group = Group.getByName(v.name)
|
||||
if group then
|
||||
for i,v in ipairs(group:getUnits()) do
|
||||
local unpos = v:getPoint()
|
||||
local pnt = {x=unpos.x, y = unpos.z}
|
||||
|
||||
table.insert(mis.params.route.points, {
|
||||
type= AI.Task.WaypointType.TURNING_POINT,
|
||||
x = pnt.x,
|
||||
y = pnt.y,
|
||||
speed = 10,
|
||||
action = AI.Task.VehicleFormation.DIAMOND
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
group:getController():setTask(mis)
|
||||
end
|
||||
|
||||
|
||||
function TaskExtensions.landAtPointFromAir(group, point, alt)
|
||||
if not group or not point then return end
|
||||
if not group:isExist() or group:getSize()==0 then return end
|
||||
@ -4882,7 +4812,7 @@ do
|
||||
product.lastMission = {zoneName = zone.name}
|
||||
timer.scheduleFunction(function(param)
|
||||
local gr = Group.getByName(param.name)
|
||||
TaskExtensions.moveOffRoadToPointAndAssault(gr, param.point, param.targets)
|
||||
TaskExtensions.moveOnRoadToPointAndAssault(gr, param.point, param.targets)
|
||||
end, {name=product.name, point={ x=tgtPoint.point.x, y = tgtPoint.point.z}, targets=zone.built}, timer.getTime()+1)
|
||||
end
|
||||
end
|
||||
@ -5413,7 +5343,7 @@ do
|
||||
product.lastMission = {zoneName = v.name}
|
||||
timer.scheduleFunction(function(param)
|
||||
local gr = Group.getByName(param.name)
|
||||
TaskExtensions.moveOffRoadToPointAndAssault(gr, param.point, param.targets)
|
||||
TaskExtensions.moveOnRoadToPointAndAssault(gr, param.point, param.targets)
|
||||
end, {name=product.name, point={ x=tgtPoint.point.x, y = tgtPoint.point.z}, targets=v.built}, timer.getTime()+1)
|
||||
|
||||
env.info("ZoneCommand - "..product.name.." targeting "..v.name)
|
||||
@ -5975,7 +5905,7 @@ end
|
||||
|
||||
BattlefieldManager = {}
|
||||
do
|
||||
BattlefieldManager.closeOverride = Config.closeOverride -- default 15nm
|
||||
BattlefieldManager.closeOverride = 27780 -- 15nm
|
||||
BattlefieldManager.farOverride = Config.maxDistFromFront -- default 100nm
|
||||
BattlefieldManager.boostScale = {[0] = 1.0, [1]=1.0, [2]=1.0}
|
||||
BattlefieldManager.noRedZones = false
|
||||
@ -10554,7 +10484,6 @@ do
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function SEAD:getMissionName()
|
||||
@ -12208,7 +12137,7 @@ do
|
||||
if toGen > 0 then
|
||||
local validMissions = {}
|
||||
for _,v in pairs(Mission.types) do
|
||||
if timer.getAbsTime() - timer.getTime0() > 120 and self:canCreateMission(v) then
|
||||
if self:canCreateMission(v) then
|
||||
table.insert(validMissions,v)
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user