Ground war rework

This commit is contained in:
Khopa
2020-05-24 20:32:45 +02:00
parent 5884d9d120
commit f57e453d8d
74 changed files with 1255 additions and 1965 deletions

View File

@@ -1,70 +0,0 @@
from game.db import assigned_units_split
from gen.triggergen import *
from .operation import *
class BaseAttackOperation(Operation):
cas = None # type: db.AssignedUnitsDict
escort = None # type: db.AssignedUnitsDict
intercept = None # type: db.AssignedUnitsDict
attack = None # type: db.ArmorDict
defense = None # type: db.ArmorDict
aa = None # type: db.AirDefenseDict
trigger_radius = TRIGGER_RADIUS_SMALL
def setup(self,
cas: db.AssignedUnitsDict,
escort: db.AssignedUnitsDict,
attack: db.AssignedUnitsDict,
intercept: db.AssignedUnitsDict,
defense: db.ArmorDict,
aa: db.AirDefenseDict):
self.cas = cas
self.escort = escort
self.intercept = intercept
self.attack = attack
self.defense = defense
self.aa = aa
def prepare(self, terrain: dcs.terrain.Terrain, is_quick: bool):
super(BaseAttackOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
if self.game.player_name == self.defender_name:
self.attackers_starting_position = None
conflict = Conflict.capture_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
self.armorgen.generate(self.attack, self.defense)
self.airgen.generate_defense(*assigned_units_split(self.intercept), at=self.defenders_starting_position)
self.airgen.generate_cas_strikegroup(*assigned_units_split(self.cas), at=self.attackers_starting_position)
self.airgen.generate_attackers_escort(*assigned_units_split(self.escort), at=self.attackers_starting_position)
self.visualgen.generate_target_smokes(self.to_cp)
self.briefinggen.title = "Base attack"
self.briefinggen.description = "The goal of an attacker is to lower defender presence by destroying their armor and aircraft. Base will be considered captured if attackers on the ground overrun the defenders. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
if self.game.player_name == self.attacker_name:
self.briefinggen.append_waypoint("TARGET")
else:
pass
super(BaseAttackOperation, self).generate()

View File

@@ -1,51 +0,0 @@
from game.db import assigned_units_split
from .operation import *
class ConvoyStrikeOperation(Operation):
strikegroup = None # type: db.AssignedUnitsDict
target = None # type: db.ArmorDict
def setup(self,
target: db.ArmorDict,
strikegroup: db.AssignedUnitsDict):
self.strikegroup = strikegroup
self.target = target
def prepare(self, terrain: Terrain, is_quick: bool):
super(ConvoyStrikeOperation, self).prepare(terrain, is_quick)
conflict = Conflict.convoy_strike_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
if self.is_player_attack:
self.prepare_carriers(db.unitdict_from(self.strikegroup))
planes_flights = {k: v for k, v in self.strikegroup.items() if k in plane_map.values()}
self.airgen.generate_cas_strikegroup(*assigned_units_split(planes_flights), at=self.attackers_starting_position)
heli_flights = {k: v for k, v in self.strikegroup.items() if k in helicopters.helicopter_map.values()}
if heli_flights:
self.briefinggen.append_frequency("FARP + Heli flights", "127.5 MHz AM")
for farp, dict in zip(self.groundobjectgen.generate_farps(sum([x[0] for x in heli_flights.values()])),
db.assignedunits_split_to_count(heli_flights, self.groundobjectgen.FARP_CAPACITY)):
self.airgen.generate_cas_strikegroup(*assigned_units_split(dict),
at=farp,
escort=len(planes_flights) == 0)
self.armorgen.generate_convoy(self.target)
self.briefinggen.append_waypoint("TARGET")
super(ConvoyStrikeOperation, self).generate()

View File

@@ -1,61 +0,0 @@
from game.db import assigned_units_split
from .operation import *
MAX_DISTANCE_BETWEEN_GROUPS = 12000
class FrontlinePatrolOperation(Operation):
cas = None # type: db.AssignedUnitsDict
escort = None # type: db.AssignedUnitsDict
interceptors = None # type: db.AssignedUnitsDict
armor_attackers = None # type: db.ArmorDict
armor_defenders = None # type: db.ArmorDict
def setup(self,
cas: db.AssignedUnitsDict,
escort: db.AssignedUnitsDict,
interceptors: db.AssignedUnitsDict,
armor_attackers: db.ArmorDict,
armor_defenders: db.ArmorDict):
self.cas = cas
self.escort = escort
self.interceptors = interceptors
self.armor_attackers = armor_attackers
self.armor_defenders = armor_defenders
def prepare(self, terrain: Terrain, is_quick: bool):
super(FrontlinePatrolOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
conflict = Conflict.frontline_cap_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
if self.is_player_attack:
self.prepare_carriers(db.unitdict_from(self.interceptors))
self.airgen.generate_defenders_cas(*assigned_units_split(self.cas), at=self.defenders_starting_position)
self.airgen.generate_defenders_escort(*assigned_units_split(self.escort), at=self.defenders_starting_position)
self.airgen.generate_migcap(*assigned_units_split(self.interceptors), at=self.attackers_starting_position)
self.armorgen.generate_vec(self.armor_attackers, self.armor_defenders)
self.briefinggen.title = "Frontline CAP"
self.briefinggen.description = "Providing CAP support for ground units attacking enemy lines. Enemy will scramble its CAS and your task is to intercept it. Operation will be considered successful if total number of friendly units will be lower than enemy by at least a factor of 0.8 (i.e. with 12 units from both sides, there should be at least 8 friendly units alive), lowering targets strength as a result."
self.briefinggen.append_waypoint("CAP AREA IP")
self.briefinggen.append_waypoint("CAP AREA EGRESS")
super(FrontlinePatrolOperation, self).generate()

View File

@@ -1,47 +0,0 @@
from game.db import assigned_units_split
from .operation import *
class InfantryTransportOperation(Operation):
transport = None # type: db.AssignedUnitsDict
aa = None # type: db.AirDefenseDict
def setup(self, transport: db.AssignedUnitsDict, aa: db.AirDefenseDict):
self.transport = transport
self.aa = aa
def prepare(self, terrain: Terrain, is_quick: bool):
super(InfantryTransportOperation, self).prepare(terrain, is_quick)
conflict = Conflict.transport_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
self.airgen.generate_passenger_transport(*assigned_units_split(self.transport), at=self.attackers_starting_position)
self.armorgen.generate_passengers(count=6)
self.visualgen.generate_transportation_marker(self.conflict.ground_attackers_location)
self.visualgen.generate_transportation_destination(self.conflict.position)
self.briefinggen.title = "Infantry transport"
self.briefinggen.description = "Helicopter operation to transport infantry troops from the base to the front line. Lowers target strength"
self.briefinggen.append_waypoint("DROP POINT")
# TODO: horrible, horrible hack
# this will disable vehicle activation triggers,
# which aren't needed on this type of missions
self.is_quick = True
super(InfantryTransportOperation, self).generate()
self.is_quick = False

View File

@@ -1,40 +0,0 @@
from game.db import assigned_units_split
from .operation import *
class InsurgentAttackOperation(Operation):
strikegroup = None # type: db.AssignedUnitsDict
target = None # type: db.ArmorDict
def setup(self,
target: db.ArmorDict,
strikegroup: db.AssignedUnitsDict):
self.strikegroup = strikegroup
self.target = target
def prepare(self, terrain: Terrain, is_quick: bool):
super(InsurgentAttackOperation, self).prepare(terrain, is_quick)
conflict = Conflict.ground_attack_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
self.airgen.generate_defenders_cas(*assigned_units_split(self.strikegroup), at=self.defenders_starting_position)
self.armorgen.generate(self.target, {})
self.briefinggen.title = "Destroy insurgents"
self.briefinggen.description = "Destroy vehicles of insurgents in close proximity of the friendly base. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
self.briefinggen.append_waypoint("TARGET")
super(InsurgentAttackOperation, self).generate()

View File

@@ -1,67 +0,0 @@
from game.db import assigned_units_split
from .operation import *
class InterceptOperation(Operation):
location = None # type: Point
escort = None # type: db.AssignedUnitsDict
transport = None # type: db.PlaneDict
interceptors = None # type: db.AssignedUnitsDict
airdefense = None # type: db.AirDefenseDict
trigger_radius = TRIGGER_RADIUS_LARGE
def setup(self,
location: Point,
escort: db.AssignedUnitsDict,
transport: db.PlaneDict,
airdefense: db.AirDefenseDict,
interceptors: db.AssignedUnitsDict):
self.location = location
self.escort = escort
self.transport = transport
self.airdefense = airdefense
self.interceptors = interceptors
def prepare(self, terrain: Terrain, is_quick: bool):
super(InterceptOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
if self.defender_name == self.game.player_name:
self.attackers_starting_position = None
conflict = Conflict.intercept_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
position=self.location,
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
if self.is_player_attack:
self.prepare_carriers(db.unitdict_from(self.interceptors))
self.airgen.generate_transport(self.transport, self.to_cp.at)
self.airgen.generate_defenders_escort(*assigned_units_split(self.escort), at=self.defenders_starting_position)
self.airgen.generate_interception(*assigned_units_split(self.interceptors), at=self.attackers_starting_position)
self.briefinggen.title = "Air Intercept"
if self.game.player_name == self.attacker_name:
self.briefinggen.description = "Intercept enemy supply transport aircraft. Escort will also be present if there are available planes on the base. Operation will be considered successful if most of the targets are destroyed, lowering targets strength as a result"
self.briefinggen.append_waypoint("TARGET")
for unit_type, count in self.transport.items():
self.briefinggen.append_target("{} ({})".format(db.unit_type_name(unit_type), count))
else:
self.briefinggen.description = "Escort friendly supply transport aircraft. Operation will be considered failed if most of the targets are destroyed, lowering CP strength as a result"
super(InterceptOperation, self).generate()

View File

@@ -1,69 +0,0 @@
from game.db import assigned_units_split
from .operation import *
class NavalInterceptionOperation(Operation):
location = None # type: Point
strikegroup = None # type: db.AssignedUnitsDict
interceptors = None # type: db.AssignedUnitsDict
targets = None # type: db.ShipDict
trigger_radius = TRIGGER_RADIUS_LARGE
def setup(self,
location: Point,
strikegroup: db.AssignedUnitsDict,
interceptors: db.AssignedUnitsDict,
targets: db.ShipDict):
self.location = location
self.strikegroup = strikegroup
self.interceptors = interceptors
self.targets = targets
def prepare(self, terrain: Terrain, is_quick: bool):
super(NavalInterceptionOperation, self).prepare(terrain, is_quick)
if self.defender_name == self.game.player_name:
self.attackers_starting_position = None
conflict = Conflict.naval_intercept_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
position=self.location,
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(self.current_mission, conflict)
def generate(self):
if self.is_player_attack:
self.prepare_carriers(db.unitdict_from(self.strikegroup))
target_groups = self.shipgen.generate_cargo(units=self.targets)
self.airgen.generate_ship_strikegroup(
*assigned_units_split(self.strikegroup),
target_groups=target_groups,
at=self.attackers_starting_position
)
if self.interceptors:
self.airgen.generate_defense(
*assigned_units_split(self.interceptors),
at=self.defenders_starting_position
)
self.briefinggen.title = "Naval Intercept"
if self.game.player_name == self.attacker_name:
self.briefinggen.description = "Destroy supply transport ships. Lowers target strength. Be advised that your flight will not attack anything until you explicitly tell them so by comms menu."
for unit_type, count in self.targets.items():
self.briefinggen.append_target("{} ({})".format(db.unit_type_name(unit_type), count))
else:
self.briefinggen.description = "Protect supply transport ships."
self.briefinggen.append_waypoint("TARGET")
super(NavalInterceptionOperation, self).generate()

View File

@@ -65,7 +65,6 @@ class Operation:
def initialize(self, mission: Mission, conflict: Conflict):
self.current_mission = mission
self.conflict = conflict
self.armorgen = ArmorConflictGenerator(mission, conflict)
self.airgen = AircraftConflictGenerator(mission, conflict, self.game.settings)
self.shipgen = ShipGenerator(mission, conflict)
self.airsupportgen = AirSupportConflictGenerator(mission, conflict, self.game)
@@ -158,10 +157,13 @@ class Operation:
self.current_mission.country(self.attacker_country),
self.current_mission.country(self.defender_country),
player_cp, enemy_cp, self.game.theater)
armorgen = ArmorConflictGenerator(self.current_mission, conflict)
armorgen.generate_vec(player_cp.base.armor, enemy_cp.base.armor)
# 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]
groundConflictGen = GroundConflictGenerator(self.current_mission, conflict, self.game, player_gp, enemy_gp, player_cp.stances[enemy_cp.id])
groundConflictGen.generate()
#Setup combined arms parameters
# Setup combined arms parameters
self.current_mission.groundControl.pilot_can_control_vehicles = self.ca_slots > 0
if self.game.player_country in [country.name for country in self.current_mission.coalition["blue"].countries.values()]:
self.current_mission.groundControl.blue_tactical_commander = self.ca_slots

View File

@@ -1,96 +0,0 @@
from game.db import assigned_units_split
from .operation import *
class StrikeOperation(Operation):
strikegroup = None # type: db.AssignedUnitsDict
sead = None # type: db.AssignedUnitsDict
escort = None # type: db.AssignedUnitsDict
interceptors = None # type: db.AssignedUnitsDict
trigger_radius = TRIGGER_RADIUS_ALL_MAP
def setup(self,
strikegroup: db.AssignedUnitsDict,
sead: db.AssignedUnitsDict,
escort: db.AssignedUnitsDict,
interceptors: db.AssignedUnitsDict):
self.strikegroup = strikegroup
self.sead = sead
self.escort = escort
self.interceptors = interceptors
def prepare(self, terrain: Terrain, is_quick: bool):
super(StrikeOperation, self).prepare(terrain, is_quick)
self.defenders_starting_position = None
if self.game.player_name == self.defender_name:
self.attackers_starting_position = None
conflict = Conflict.strike_conflict(
attacker_name=self.attacker_name,
defender_name=self.defender_name,
attacker=self.current_mission.country(self.attacker_country),
defender=self.current_mission.country(self.defender_country),
from_cp=self.from_cp,
to_cp=self.to_cp,
theater=self.game.theater
)
self.initialize(mission=self.current_mission,
conflict=conflict)
def generate(self):
self.prepare_carriers(db.unitdict_merge(db.unitdict_from(self.strikegroup), db.unitdict_from(self.escort)))
targets = [] # type: typing.List[typing.Tuple[str, str, Point]]
sead_targets = [] # type: typing.List[typing.Tuple[str, str, Point]]
category_counters = {} # type: typing.Dict[str, int]
processed_groups = []
for object in self.to_cp.ground_objects:
if object.group_identifier in processed_groups:
continue
processed_groups.append(object.group_identifier)
category_counters[object.category] = category_counters.get(object.category, 0) + 1
markpoint_name = "{}{}".format(object.name_abbrev, category_counters[object.category])
if object.category == "aa":
sead_targets.append((str(object), markpoint_name, object.position))
targets.append((str(object), markpoint_name, object.position))
targets.sort(key=lambda x: self.from_cp.position.distance_to_point(x[2]))
for (name, markpoint_name, _) in targets:
self.briefinggen.append_waypoint("TARGET {} (TP {})".format(str(name), markpoint_name))
planes_flights = {k: v for k, v in self.strikegroup.items() if k in plane_map.values()}
self.airgen.generate_ground_attack_strikegroup(*assigned_units_split(planes_flights),
targets=[(mp, pos) for (n, mp, pos) in targets],
at=self.attackers_starting_position,
escort=len(self.sead) == 0)
self.airgen.generate_sead_strikegroup(*assigned_units_split(self.sead),
targets=[(mp, pos) for (n, mp, pos) in sead_targets],
at=self.attackers_starting_position,
escort=len(self.sead) > 0)
heli_flights = {k: v for k, v in self.strikegroup.items() if k in helicopters.helicopter_map.values()}
if heli_flights:
self.briefinggen.append_frequency("FARP", "127.5 MHz AM")
for farp, dict in zip(self.groundobjectgen.generate_farps(sum([x[0] for x in heli_flights.values()])),
db.assignedunits_split_to_count(heli_flights, self.groundobjectgen.FARP_CAPACITY)):
self.airgen.generate_ground_attack_strikegroup(*assigned_units_split(dict),
targets=[(mp, pos) for (n, mp, pos) in targets],
at=farp,
escort=len(planes_flights) == 0)
self.airgen.generate_attackers_escort(*assigned_units_split(self.escort), at=self.attackers_starting_position)
self.airgen.generate_barcap(*assigned_units_split(self.interceptors), at=self.defenders_starting_position)
self.briefinggen.title = "Strike"
self.briefinggen.description = "Destroy infrastructure assets and military supplies in the region. Each building destroyed will lower targets strength."
super(StrikeOperation, self).generate()