mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Introduce weighted distribution for random 2/3/4-ships
This commit is contained in:
parent
f2cebc82cc
commit
ae379bd8f5
@ -27,6 +27,7 @@
|
||||
* **[Campaign Design]** Ability to define designated CTLD zones for Control Points (Airbases & FOBs/FARPs)
|
||||
* **[Campaign Design]** Ability to define preset groups for specific TGOs, given the preset group is accessible for the faction and the task matches.
|
||||
* **[Campaign Management]** Additional options for automated budget management.
|
||||
* **[Campaign Management]** New options to allow more control of randomized flight sizes (applicable for BARCAP/CAS/OCA/ANTI-SHIP).
|
||||
|
||||
## Fixes
|
||||
* **[UI]** Removed deprecated options
|
||||
|
||||
@ -183,3 +183,12 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
|
||||
if iads_threat not in state.threatening_air_defenses:
|
||||
state.threatening_air_defenses.append(iads_threat)
|
||||
return not threatened
|
||||
|
||||
def get_flight_size(self) -> int:
|
||||
settings = self.target.coalition.game.settings
|
||||
weights = [
|
||||
settings.fpa_2ship_weight,
|
||||
settings.fpa_3ship_weight,
|
||||
settings.fpa_4ship_weight,
|
||||
]
|
||||
return random.choices([2, 3, 4], weights, k=1)[0]
|
||||
|
||||
@ -23,5 +23,6 @@ class PlanAntiShip(PackagePlanningTask[NavalGroundObject]):
|
||||
state.eliminate_ship(self.target)
|
||||
|
||||
def propose_flights(self) -> None:
|
||||
self.propose_flight(FlightType.ANTISHIP, randint(2, 4))
|
||||
size = self.get_flight_size()
|
||||
self.propose_flight(FlightType.ANTISHIP, size)
|
||||
self.propose_flight(FlightType.ESCORT, 2, EscortType.AirToAir)
|
||||
|
||||
@ -22,5 +22,6 @@ class PlanAntiShipping(PackagePlanningTask[CargoShip]):
|
||||
state.enemy_shipping.remove(self.target)
|
||||
|
||||
def propose_flights(self) -> None:
|
||||
self.propose_flight(FlightType.ANTISHIP, randint(2, 4))
|
||||
size = self.get_flight_size()
|
||||
self.propose_flight(FlightType.ANTISHIP, size)
|
||||
self.propose_common_escorts()
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from random import randint
|
||||
|
||||
@ -22,7 +23,8 @@ class PlanBarcap(PackagePlanningTask[ControlPoint]):
|
||||
state.barcaps_needed[self.target] -= 1
|
||||
|
||||
def propose_flights(self) -> None:
|
||||
self.propose_flight(FlightType.BARCAP, randint(2, 4))
|
||||
size = self.get_flight_size()
|
||||
self.propose_flight(FlightType.BARCAP, size)
|
||||
|
||||
@property
|
||||
def purchase_multiplier(self) -> int:
|
||||
|
||||
@ -30,5 +30,6 @@ class PlanCas(PackagePlanningTask[FrontLine]):
|
||||
state.vulnerable_front_lines.remove(self.target)
|
||||
|
||||
def propose_flights(self) -> None:
|
||||
self.propose_flight(FlightType.CAS, randint(2, 4))
|
||||
size = self.get_flight_size()
|
||||
self.propose_flight(FlightType.CAS, size)
|
||||
self.propose_flight(FlightType.TARCAP, 2)
|
||||
|
||||
@ -24,7 +24,8 @@ class PlanOcaStrike(PackagePlanningTask[ControlPoint]):
|
||||
state.oca_targets.remove(self.target)
|
||||
|
||||
def propose_flights(self) -> None:
|
||||
self.propose_flight(FlightType.OCA_RUNWAY, randint(2, 4))
|
||||
size = self.get_flight_size()
|
||||
self.propose_flight(FlightType.OCA_RUNWAY, size)
|
||||
if self.aircraft_cold_start:
|
||||
self.propose_flight(FlightType.OCA_AIRCRAFT, 2)
|
||||
self.propose_common_escorts()
|
||||
|
||||
@ -36,6 +36,7 @@ CAMPAIGN_MANAGEMENT_PAGE = "Campaign Management"
|
||||
GENERAL_SECTION = "General"
|
||||
PILOTS_AND_SQUADRONS_SECTION = "Pilots and Squadrons"
|
||||
HQ_AUTOMATION_SECTION = "HQ Automation"
|
||||
FLIGHT_PLANNER_AUTOMATION = "Flight Planner Automation"
|
||||
|
||||
MISSION_GENERATOR_PAGE = "Mission Generator"
|
||||
|
||||
@ -310,6 +311,41 @@ class Settings:
|
||||
),
|
||||
)
|
||||
|
||||
# Flight Planner Automation
|
||||
#: The weight used for 2-ships.
|
||||
fpa_2ship_weight: int = bounded_int_option(
|
||||
"2-ship weight factor (WF2)",
|
||||
CAMPAIGN_MANAGEMENT_PAGE,
|
||||
FLIGHT_PLANNER_AUTOMATION,
|
||||
default=50,
|
||||
min=0,
|
||||
max=100,
|
||||
detail=(
|
||||
"Used as a distribution to randomize 2/3/4-ships for BARCAP, CAS, OCA & ANTI-SHIP flights. "
|
||||
"The weight W_i is calculated according to the following formula: "
|
||||
"W_i = WF_i / (WF2 + WF3 + WF4)"
|
||||
),
|
||||
)
|
||||
#: The weight used for 3-ships.
|
||||
fpa_3ship_weight: int = bounded_int_option(
|
||||
"3-ship weight factor (WF3)",
|
||||
CAMPAIGN_MANAGEMENT_PAGE,
|
||||
FLIGHT_PLANNER_AUTOMATION,
|
||||
default=35,
|
||||
min=0,
|
||||
max=100,
|
||||
detail="See 2-ship weight factor (WF2)",
|
||||
)
|
||||
fpa_4ship_weight: int = bounded_int_option(
|
||||
"4-ship weight factor (WF4)",
|
||||
CAMPAIGN_MANAGEMENT_PAGE,
|
||||
FLIGHT_PLANNER_AUTOMATION,
|
||||
default=15,
|
||||
min=0,
|
||||
max=100,
|
||||
detail="See 2-ship weight factor (WF2)",
|
||||
)
|
||||
|
||||
# Mission Generator
|
||||
# Gameplay
|
||||
fast_forward_to_first_contact: bool = boolean_option(
|
||||
|
||||
@ -12,7 +12,7 @@ from ..utils import Heading, pairwise
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.ato import FlightType
|
||||
from .controlpoint import ControlPoint
|
||||
from .controlpoint import ControlPoint, Coalition
|
||||
|
||||
|
||||
FRONTLINE_MIN_CP_DISTANCE = 5000
|
||||
@ -121,6 +121,10 @@ class FrontLine(MissionTarget):
|
||||
"""Returns a tuple of the two control points."""
|
||||
return self.blue_cp, self.red_cp
|
||||
|
||||
@property
|
||||
def coalition(self) -> Coalition:
|
||||
return self.blue_cp.coalition
|
||||
|
||||
@property
|
||||
def route_length(self) -> float:
|
||||
"""The total distance of all segments"""
|
||||
|
||||
@ -6,7 +6,7 @@ from dcs.mapping import Point
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from game.ato.flighttype import FlightType
|
||||
from game.theater import TheaterUnit
|
||||
from game.theater import TheaterUnit, Coalition
|
||||
|
||||
|
||||
class MissionTarget:
|
||||
@ -47,3 +47,7 @@ class MissionTarget:
|
||||
@property
|
||||
def strike_targets(self) -> list[TheaterUnit]:
|
||||
return []
|
||||
|
||||
@property
|
||||
def coalition(self) -> Coalition:
|
||||
raise NotImplementedError
|
||||
|
||||
@ -27,7 +27,7 @@ if TYPE_CHECKING:
|
||||
from game.ato.flighttype import FlightType
|
||||
from game.threatzones import ThreatPoly
|
||||
from .theatergroup import TheaterUnit, TheaterGroup
|
||||
from .controlpoint import ControlPoint
|
||||
from .controlpoint import ControlPoint, Coalition
|
||||
|
||||
|
||||
NAME_BY_CATEGORY = {
|
||||
@ -275,6 +275,10 @@ class TheaterGroundObject(MissionTarget, SidcDescribable, ABC):
|
||||
def is_iads(self) -> bool:
|
||||
return False
|
||||
|
||||
@property
|
||||
def coalition(self) -> Coalition:
|
||||
return self.control_point.coalition
|
||||
|
||||
|
||||
class BuildingGroundObject(TheaterGroundObject):
|
||||
def __init__(
|
||||
|
||||
@ -59,6 +59,7 @@ from game.utils import meters, nautical_miles
|
||||
if TYPE_CHECKING:
|
||||
from game import Game
|
||||
from game.squadrons import Squadron
|
||||
from game.theater import Coalition
|
||||
|
||||
|
||||
class Transport:
|
||||
@ -432,6 +433,10 @@ class MultiGroupTransport(MissionTarget, Transport):
|
||||
def description(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def coalition(self) -> Coalition:
|
||||
return self.origin.coalition
|
||||
|
||||
|
||||
class Convoy(MultiGroupTransport):
|
||||
def __init__(self, origin: ControlPoint, destination: ControlPoint) -> None:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user