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 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 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]** 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
|
## Fixes
|
||||||
* **[UI]** Removed deprecated options
|
* **[UI]** Removed deprecated options
|
||||||
|
|||||||
@ -183,3 +183,12 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
|
|||||||
if iads_threat not in state.threatening_air_defenses:
|
if iads_threat not in state.threatening_air_defenses:
|
||||||
state.threatening_air_defenses.append(iads_threat)
|
state.threatening_air_defenses.append(iads_threat)
|
||||||
return not threatened
|
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)
|
state.eliminate_ship(self.target)
|
||||||
|
|
||||||
def propose_flights(self) -> None:
|
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)
|
self.propose_flight(FlightType.ESCORT, 2, EscortType.AirToAir)
|
||||||
|
|||||||
@ -22,5 +22,6 @@ class PlanAntiShipping(PackagePlanningTask[CargoShip]):
|
|||||||
state.enemy_shipping.remove(self.target)
|
state.enemy_shipping.remove(self.target)
|
||||||
|
|
||||||
def propose_flights(self) -> None:
|
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()
|
self.propose_common_escorts()
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import random
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from random import randint
|
from random import randint
|
||||||
|
|
||||||
@ -22,7 +23,8 @@ class PlanBarcap(PackagePlanningTask[ControlPoint]):
|
|||||||
state.barcaps_needed[self.target] -= 1
|
state.barcaps_needed[self.target] -= 1
|
||||||
|
|
||||||
def propose_flights(self) -> None:
|
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
|
@property
|
||||||
def purchase_multiplier(self) -> int:
|
def purchase_multiplier(self) -> int:
|
||||||
|
|||||||
@ -30,5 +30,6 @@ class PlanCas(PackagePlanningTask[FrontLine]):
|
|||||||
state.vulnerable_front_lines.remove(self.target)
|
state.vulnerable_front_lines.remove(self.target)
|
||||||
|
|
||||||
def propose_flights(self) -> None:
|
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)
|
self.propose_flight(FlightType.TARCAP, 2)
|
||||||
|
|||||||
@ -24,7 +24,8 @@ class PlanOcaStrike(PackagePlanningTask[ControlPoint]):
|
|||||||
state.oca_targets.remove(self.target)
|
state.oca_targets.remove(self.target)
|
||||||
|
|
||||||
def propose_flights(self) -> None:
|
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:
|
if self.aircraft_cold_start:
|
||||||
self.propose_flight(FlightType.OCA_AIRCRAFT, 2)
|
self.propose_flight(FlightType.OCA_AIRCRAFT, 2)
|
||||||
self.propose_common_escorts()
|
self.propose_common_escorts()
|
||||||
|
|||||||
@ -36,6 +36,7 @@ CAMPAIGN_MANAGEMENT_PAGE = "Campaign Management"
|
|||||||
GENERAL_SECTION = "General"
|
GENERAL_SECTION = "General"
|
||||||
PILOTS_AND_SQUADRONS_SECTION = "Pilots and Squadrons"
|
PILOTS_AND_SQUADRONS_SECTION = "Pilots and Squadrons"
|
||||||
HQ_AUTOMATION_SECTION = "HQ Automation"
|
HQ_AUTOMATION_SECTION = "HQ Automation"
|
||||||
|
FLIGHT_PLANNER_AUTOMATION = "Flight Planner Automation"
|
||||||
|
|
||||||
MISSION_GENERATOR_PAGE = "Mission Generator"
|
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
|
# Mission Generator
|
||||||
# Gameplay
|
# Gameplay
|
||||||
fast_forward_to_first_contact: bool = boolean_option(
|
fast_forward_to_first_contact: bool = boolean_option(
|
||||||
|
|||||||
@ -12,7 +12,7 @@ from ..utils import Heading, pairwise
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.ato import FlightType
|
from game.ato import FlightType
|
||||||
from .controlpoint import ControlPoint
|
from .controlpoint import ControlPoint, Coalition
|
||||||
|
|
||||||
|
|
||||||
FRONTLINE_MIN_CP_DISTANCE = 5000
|
FRONTLINE_MIN_CP_DISTANCE = 5000
|
||||||
@ -121,6 +121,10 @@ class FrontLine(MissionTarget):
|
|||||||
"""Returns a tuple of the two control points."""
|
"""Returns a tuple of the two control points."""
|
||||||
return self.blue_cp, self.red_cp
|
return self.blue_cp, self.red_cp
|
||||||
|
|
||||||
|
@property
|
||||||
|
def coalition(self) -> Coalition:
|
||||||
|
return self.blue_cp.coalition
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def route_length(self) -> float:
|
def route_length(self) -> float:
|
||||||
"""The total distance of all segments"""
|
"""The total distance of all segments"""
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from dcs.mapping import Point
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.ato.flighttype import FlightType
|
from game.ato.flighttype import FlightType
|
||||||
from game.theater import TheaterUnit
|
from game.theater import TheaterUnit, Coalition
|
||||||
|
|
||||||
|
|
||||||
class MissionTarget:
|
class MissionTarget:
|
||||||
@ -47,3 +47,7 @@ class MissionTarget:
|
|||||||
@property
|
@property
|
||||||
def strike_targets(self) -> list[TheaterUnit]:
|
def strike_targets(self) -> list[TheaterUnit]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def coalition(self) -> Coalition:
|
||||||
|
raise NotImplementedError
|
||||||
|
|||||||
@ -27,7 +27,7 @@ if TYPE_CHECKING:
|
|||||||
from game.ato.flighttype import FlightType
|
from game.ato.flighttype import FlightType
|
||||||
from game.threatzones import ThreatPoly
|
from game.threatzones import ThreatPoly
|
||||||
from .theatergroup import TheaterUnit, TheaterGroup
|
from .theatergroup import TheaterUnit, TheaterGroup
|
||||||
from .controlpoint import ControlPoint
|
from .controlpoint import ControlPoint, Coalition
|
||||||
|
|
||||||
|
|
||||||
NAME_BY_CATEGORY = {
|
NAME_BY_CATEGORY = {
|
||||||
@ -275,6 +275,10 @@ class TheaterGroundObject(MissionTarget, SidcDescribable, ABC):
|
|||||||
def is_iads(self) -> bool:
|
def is_iads(self) -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def coalition(self) -> Coalition:
|
||||||
|
return self.control_point.coalition
|
||||||
|
|
||||||
|
|
||||||
class BuildingGroundObject(TheaterGroundObject):
|
class BuildingGroundObject(TheaterGroundObject):
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|||||||
@ -59,6 +59,7 @@ from game.utils import meters, nautical_miles
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game import Game
|
from game import Game
|
||||||
from game.squadrons import Squadron
|
from game.squadrons import Squadron
|
||||||
|
from game.theater import Coalition
|
||||||
|
|
||||||
|
|
||||||
class Transport:
|
class Transport:
|
||||||
@ -432,6 +433,10 @@ class MultiGroupTransport(MissionTarget, Transport):
|
|||||||
def description(self) -> str:
|
def description(self) -> str:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def coalition(self) -> Coalition:
|
||||||
|
return self.origin.coalition
|
||||||
|
|
||||||
|
|
||||||
class Convoy(MultiGroupTransport):
|
class Convoy(MultiGroupTransport):
|
||||||
def __init__(self, origin: ControlPoint, destination: ControlPoint) -> None:
|
def __init__(self, origin: ControlPoint, destination: ControlPoint) -> None:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user