mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Generate WW2 Ship groups, added B17 to allies. Implemented modifiable doctrine to setup flight generator.
This commit is contained in:
parent
601375d06f
commit
cd41bcf45c
@ -3,6 +3,7 @@
|
|||||||
##Features/Improvements :
|
##Features/Improvements :
|
||||||
|
|
||||||
* **[Units/Factions]** Added P-47D-30 for factions allies_1944
|
* **[Units/Factions]** Added P-47D-30 for factions allies_1944
|
||||||
|
* **[Units/Factions]** Added factions : Bluefor Coldwar, Germany 1944 Easy
|
||||||
|
|
||||||
* **[Campaign/Map]** Added a campaign in the Channel map
|
* **[Campaign/Map]** Added a campaign in the Channel map
|
||||||
* **[Campaign/Map]** Changed the Normandy campaign map
|
* **[Campaign/Map]** Changed the Normandy campaign map
|
||||||
@ -22,6 +23,7 @@
|
|||||||
* **[Flight Planner]** Added STRIKE mission generator
|
* **[Flight Planner]** Added STRIKE mission generator
|
||||||
* **[Flight Planner]** Added buttons to add autogenerated waypoints (ASCEND, DESCEND, RTB)
|
* **[Flight Planner]** Added buttons to add autogenerated waypoints (ASCEND, DESCEND, RTB)
|
||||||
* **[Flight Planner]** Improved waypoint list
|
* **[Flight Planner]** Improved waypoint list
|
||||||
|
* **[Flight Planner]** WW2 factions uses different parameters for flight planning.
|
||||||
|
|
||||||
* **[Settings]** Added settings to disallow external views
|
* **[Settings]** Added settings to disallow external views
|
||||||
* **[Settings]** Added settings to choose F10 Map mode (All, Allies only, Player only, Fog of War, Map Only)
|
* **[Settings]** Added settings to choose F10 Map mode (All, Allies only, Player only, Fog of War, Map Only)
|
||||||
@ -37,6 +39,9 @@
|
|||||||
* **[Map]** Added "ww2 bunker" building (WW2)
|
* **[Map]** Added "ww2 bunker" building (WW2)
|
||||||
* **[Map]** Added "ally camp" building (WW2)
|
* **[Map]** Added "ally camp" building (WW2)
|
||||||
|
|
||||||
|
* **[Map]** Added "V1 Launch Site" building (WW2)
|
||||||
|
* **[Map]** Added "A camp" building (WW2)
|
||||||
|
|
||||||
* **[Misc]** Made it possible to setup DCS Saved Games directory and DCS installation directory manually at first start
|
* **[Misc]** Made it possible to setup DCS Saved Games directory and DCS installation directory manually at first start
|
||||||
|
|
||||||
##Fixed issues :
|
##Fixed issues :
|
||||||
@ -52,7 +57,7 @@
|
|||||||
|
|
||||||
* **[Maps/Campaign]** Now using Vasiani airbase instead of Soganlung airport in North Caucasus campaign (More parking slots)
|
* **[Maps/Campaign]** Now using Vasiani airbase instead of Soganlung airport in North Caucasus campaign (More parking slots)
|
||||||
|
|
||||||
* **[Info Panel]** Message displayed on base capture event stated that the ennemy captured an airbase, while it was the player who captured it.
|
* **[Info Panel]** Message displayed on base capture event stated that the enemy captured an airbase, while it was the player who captured it.
|
||||||
|
|
||||||
* **[Map View]** Graphical glitch on map when one building of an objective was destroyed, but not the others
|
* **[Map View]** Graphical glitch on map when one building of an objective was destroyed, but not the others
|
||||||
|
|
||||||
|
|||||||
113
game/data/doctrine.py
Normal file
113
game/data/doctrine.py
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
from game.utils import nm_to_meter, feet_to_meter
|
||||||
|
|
||||||
|
MAX_NUMBER_OF_INTERCEPTION_GROUP = 3
|
||||||
|
MISSION_DURATION = 120 # in minutes
|
||||||
|
CAP_EVERY_X_MINUTES = 20
|
||||||
|
CAS_EVERY_X_MINUTES = 30
|
||||||
|
SEAD_EVERY_X_MINUTES = 40
|
||||||
|
STRIKE_EVERY_X_MINUTES = 40
|
||||||
|
|
||||||
|
INGRESS_EGRESS_DISTANCE = nm_to_meter(45)
|
||||||
|
INGRESS_ALT = feet_to_meter(20000)
|
||||||
|
EGRESS_ALT = feet_to_meter(20000)
|
||||||
|
PATROL_ALT_RANGE = (feet_to_meter(15000), feet_to_meter(33000))
|
||||||
|
NAV_ALT = 9144
|
||||||
|
PATTERN_ALTITUDE = feet_to_meter(5000)
|
||||||
|
|
||||||
|
CAP_DEFAULT_ENGAGE_DISTANCE = nm_to_meter(40)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MODERN_DOCTRINE = {
|
||||||
|
|
||||||
|
"GENERATORS":{
|
||||||
|
"CAS": True,
|
||||||
|
"CAP": True,
|
||||||
|
"SEAD": True,
|
||||||
|
"STRIKE": True,
|
||||||
|
"ANTISHIP": True,
|
||||||
|
},
|
||||||
|
|
||||||
|
"STRIKE_MAX_RANGE": 1500000,
|
||||||
|
"SEAD_MAX_RANGE": 1500000,
|
||||||
|
|
||||||
|
"CAP_EVERY_X_MINUTES": 20,
|
||||||
|
"CAS_EVERY_X_MINUTES": 30,
|
||||||
|
"SEAD_EVERY_X_MINUTES": 40,
|
||||||
|
"STRIKE_EVERY_X_MINUTES": 40,
|
||||||
|
|
||||||
|
"INGRESS_EGRESS_DISTANCE": nm_to_meter(45),
|
||||||
|
"INGRESS_ALT": feet_to_meter(20000),
|
||||||
|
"EGRESS_ALT": feet_to_meter(20000),
|
||||||
|
"PATROL_ALT_RANGE": (feet_to_meter(15000), feet_to_meter(33000)),
|
||||||
|
"PATTERN_ALTITUDE": feet_to_meter(5000),
|
||||||
|
|
||||||
|
"CAP_PATTERN_LENGTH": (nm_to_meter(15), nm_to_meter(40)),
|
||||||
|
"FRONTLINE_CAP_DISTANCE_FROM_FRONTLINE": (nm_to_meter(6), nm_to_meter(15)),
|
||||||
|
"CAP_DISTANCE_FROM_CP": (nm_to_meter(10), nm_to_meter(40)),
|
||||||
|
|
||||||
|
"MAX_NUMBER_OF_INTERCEPTION_GROUP": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
COLDWAR_DOCTRINE = {
|
||||||
|
|
||||||
|
"GENERATORS": {
|
||||||
|
"CAS": True,
|
||||||
|
"CAP": True,
|
||||||
|
"SEAD": True,
|
||||||
|
"STRIKE": True,
|
||||||
|
"ANTISHIP": True,
|
||||||
|
},
|
||||||
|
|
||||||
|
"STRIKE_MAX_RANGE": 1500000,
|
||||||
|
"SEAD_MAX_RANGE": 1500000,
|
||||||
|
|
||||||
|
"CAP_EVERY_X_MINUTES": 20,
|
||||||
|
"CAS_EVERY_X_MINUTES": 30,
|
||||||
|
"SEAD_EVERY_X_MINUTES": 40,
|
||||||
|
"STRIKE_EVERY_X_MINUTES": 40,
|
||||||
|
|
||||||
|
"INGRESS_EGRESS_DISTANCE": nm_to_meter(30),
|
||||||
|
"INGRESS_ALT": feet_to_meter(18000),
|
||||||
|
"EGRESS_ALT": feet_to_meter(18000),
|
||||||
|
"PATROL_ALT_RANGE": (feet_to_meter(10000), feet_to_meter(24000)),
|
||||||
|
"PATTERN_ALTITUDE": feet_to_meter(5000),
|
||||||
|
|
||||||
|
"CAP_PATTERN_LENGTH": (nm_to_meter(12), nm_to_meter(24)),
|
||||||
|
"FRONTLINE_CAP_DISTANCE_FROM_FRONTLINE": (nm_to_meter(2), nm_to_meter(8)),
|
||||||
|
"CAP_DISTANCE_FROM_CP": (nm_to_meter(8), nm_to_meter(25)),
|
||||||
|
|
||||||
|
"MAX_NUMBER_OF_INTERCEPTION_GROUP": 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
WWII_DOCTRINE = {
|
||||||
|
|
||||||
|
"GENERATORS": {
|
||||||
|
"CAS": True,
|
||||||
|
"CAP": True,
|
||||||
|
"SEAD": False,
|
||||||
|
"STRIKE": True,
|
||||||
|
"ANTISHIP": True,
|
||||||
|
},
|
||||||
|
|
||||||
|
"STRIKE_MAX_RANGE": 1500000,
|
||||||
|
"SEAD_MAX_RANGE": 1500000,
|
||||||
|
|
||||||
|
"CAP_EVERY_X_MINUTES": 20,
|
||||||
|
"CAS_EVERY_X_MINUTES": 30,
|
||||||
|
"SEAD_EVERY_X_MINUTES": 40,
|
||||||
|
"STRIKE_EVERY_X_MINUTES": 40,
|
||||||
|
|
||||||
|
"INGRESS_EGRESS_DISTANCE": nm_to_meter(7),
|
||||||
|
"INGRESS_ALT": feet_to_meter(8000),
|
||||||
|
"EGRESS_ALT": feet_to_meter(8000),
|
||||||
|
"PATROL_ALT_RANGE": (feet_to_meter(4000), feet_to_meter(15000)),
|
||||||
|
"PATTERN_ALTITUDE": feet_to_meter(5000),
|
||||||
|
|
||||||
|
"CAP_PATTERN_LENGTH": (nm_to_meter(8), nm_to_meter(18)),
|
||||||
|
"FRONTLINE_CAP_DISTANCE_FROM_FRONTLINE": (nm_to_meter(1), nm_to_meter(6)),
|
||||||
|
"CAP_DISTANCE_FROM_CP": (nm_to_meter(5), nm_to_meter(15)),
|
||||||
|
|
||||||
|
"MAX_NUMBER_OF_INTERCEPTION_GROUP": 3,
|
||||||
|
|
||||||
|
}
|
||||||
@ -162,6 +162,7 @@ PRICES = {
|
|||||||
P_51D_30_NA: 6,
|
P_51D_30_NA: 6,
|
||||||
P_51D: 6,
|
P_51D: 6,
|
||||||
P_47D_30: 6,
|
P_47D_30: 6,
|
||||||
|
B_17G: 18,
|
||||||
|
|
||||||
# armor
|
# armor
|
||||||
Armor.APC_MTLB: 4,
|
Armor.APC_MTLB: 4,
|
||||||
@ -260,7 +261,6 @@ PRICES = {
|
|||||||
Artillery.M12_GMC: 2,
|
Artillery.M12_GMC: 2,
|
||||||
Artillery.Sturmpanzer_IV_Brummbär: 2,
|
Artillery.Sturmpanzer_IV_Brummbär: 2,
|
||||||
|
|
||||||
|
|
||||||
# ship
|
# ship
|
||||||
CV_1143_5_Admiral_Kuznetsov: 100,
|
CV_1143_5_Admiral_Kuznetsov: 100,
|
||||||
CVN_74_John_C__Stennis: 100,
|
CVN_74_John_C__Stennis: 100,
|
||||||
@ -350,6 +350,7 @@ UNIT_BY_TASK = {
|
|||||||
A_20G,
|
A_20G,
|
||||||
P_47D_30,
|
P_47D_30,
|
||||||
Ju_88A4,
|
Ju_88A4,
|
||||||
|
B_17G
|
||||||
],
|
],
|
||||||
Transport: [
|
Transport: [
|
||||||
IL_76MD,
|
IL_76MD,
|
||||||
@ -739,6 +740,8 @@ PLANE_PAYLOAD_OVERRIDES = {
|
|||||||
L_39C:COMMON_OVERRIDE,
|
L_39C:COMMON_OVERRIDE,
|
||||||
Su_17M4: COMMON_OVERRIDE,
|
Su_17M4: COMMON_OVERRIDE,
|
||||||
F_4E: COMMON_OVERRIDE,
|
F_4E: COMMON_OVERRIDE,
|
||||||
|
P_47D_30:COMMON_OVERRIDE,
|
||||||
|
B_17G: COMMON_OVERRIDE,
|
||||||
|
|
||||||
AH_64D:{
|
AH_64D:{
|
||||||
CAS: "AGM-114K*16"
|
CAS: "AGM-114K*16"
|
||||||
@ -1054,3 +1057,4 @@ OH_58D.Liveries = DefaultLiveries
|
|||||||
F_16C_50.Liveries = DefaultLiveries
|
F_16C_50.Liveries = DefaultLiveries
|
||||||
P_51D_30_NA.Liveries = DefaultLiveries
|
P_51D_30_NA.Liveries = DefaultLiveries
|
||||||
Ju_88A4.Liveries = DefaultLiveries
|
Ju_88A4.Liveries = DefaultLiveries
|
||||||
|
B_17G.Liveries = DefaultLiveries
|
||||||
@ -1,7 +1,9 @@
|
|||||||
from dcs.planes import *
|
from dcs.planes import *
|
||||||
|
from dcs.ships import Uboat_VIIC_U_flak, Schnellboot_type_S130
|
||||||
from dcs.vehicles import *
|
from dcs.vehicles import *
|
||||||
|
|
||||||
from game.data.building_data import WW2_GERMANY_BUILDINGS
|
from game.data.building_data import WW2_GERMANY_BUILDINGS
|
||||||
|
from game.data.doctrine import WWII_DOCTRINE
|
||||||
|
|
||||||
Germany_1944 = {
|
Germany_1944 = {
|
||||||
"country": "Third Reich",
|
"country": "Third Reich",
|
||||||
@ -36,7 +38,6 @@ Germany_1944 = {
|
|||||||
AirDefence.AAA_8_8cm_Flak_36,
|
AirDefence.AAA_8_8cm_Flak_36,
|
||||||
],
|
],
|
||||||
"objects": WW2_GERMANY_BUILDINGS,
|
"objects": WW2_GERMANY_BUILDINGS,
|
||||||
"doctrine": {
|
"doctrine": WWII_DOCTRINE,
|
||||||
# TODO
|
"boat": [Uboat_VIIC_U_flak, Schnellboot_type_S130]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
from dcs.planes import *
|
from dcs.planes import *
|
||||||
from dcs.vehicles import *
|
from dcs.vehicles import *
|
||||||
|
from dcs.ships import *
|
||||||
|
|
||||||
from game.data.building_data import WW2_GERMANY_BUILDINGS
|
from game.data.building_data import WW2_GERMANY_BUILDINGS
|
||||||
|
from game.data.doctrine import WWII_DOCTRINE
|
||||||
|
|
||||||
Germany_1944_Easy = {
|
Germany_1944_Easy = {
|
||||||
"country": "Third Reich",
|
"country": "Third Reich",
|
||||||
@ -29,7 +31,6 @@ Germany_1944_Easy = {
|
|||||||
AirDefence.AAA_8_8cm_Flak_36,
|
AirDefence.AAA_8_8cm_Flak_36,
|
||||||
],
|
],
|
||||||
"objects": WW2_GERMANY_BUILDINGS,
|
"objects": WW2_GERMANY_BUILDINGS,
|
||||||
"doctrine": {
|
"doctrine": WWII_DOCTRINE,
|
||||||
# TODO
|
"boat": [Uboat_VIIC_U_flak, Schnellboot_type_S130]
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -3,6 +3,7 @@ from dcs.ships import *
|
|||||||
from dcs.vehicles import *
|
from dcs.vehicles import *
|
||||||
|
|
||||||
from game.data.building_data import WW2_ALLIES_BUILDINGS
|
from game.data.building_data import WW2_ALLIES_BUILDINGS
|
||||||
|
from game.data.doctrine import WWII_DOCTRINE
|
||||||
|
|
||||||
USA_1944 = {
|
USA_1944 = {
|
||||||
"country": "USA",
|
"country": "USA",
|
||||||
@ -14,6 +15,7 @@ USA_1944 = {
|
|||||||
SpitfireLFMkIX,
|
SpitfireLFMkIX,
|
||||||
SpitfireLFMkIXCW,
|
SpitfireLFMkIXCW,
|
||||||
A_20G,
|
A_20G,
|
||||||
|
B_17G,
|
||||||
|
|
||||||
Armor.MT_M4_Sherman,
|
Armor.MT_M4_Sherman,
|
||||||
Armor.MT_M4A4_Sherman_Firefly,
|
Armor.MT_M4A4_Sherman_Firefly,
|
||||||
@ -38,5 +40,8 @@ USA_1944 = {
|
|||||||
AirDefence.AAA_Bofors_40mm,
|
AirDefence.AAA_Bofors_40mm,
|
||||||
], "shorad":[
|
], "shorad":[
|
||||||
AirDefence.AAA_Bofors_40mm,
|
AirDefence.AAA_Bofors_40mm,
|
||||||
], "objects": WW2_ALLIES_BUILDINGS
|
],
|
||||||
|
"objects": WW2_ALLIES_BUILDINGS,
|
||||||
|
"doctrine": WWII_DOCTRINE,
|
||||||
|
"boat": [LS_Samuel_Chase]
|
||||||
}
|
}
|
||||||
@ -73,6 +73,15 @@ class Game:
|
|||||||
self.informations = []
|
self.informations = []
|
||||||
self.informations.append(Information("Game Start", "-" * 40, 0))
|
self.informations.append(Information("Game Start", "-" * 40, 0))
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def player_faction(self):
|
||||||
|
return db.FACTIONS[self.player_name]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enemy_faction(self):
|
||||||
|
return db.FACTIONS[self.enemy_name]
|
||||||
|
|
||||||
def _roll(self, prob, mult):
|
def _roll(self, prob, mult):
|
||||||
if self.settings.version == "dev":
|
if self.settings.version == "dev":
|
||||||
# always generate all events for dev
|
# always generate all events for dev
|
||||||
|
|||||||
14
game/utils.py
Normal file
14
game/utils.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
def meter_to_feet(value_in_meter):
|
||||||
|
return int(3.28084 * value_in_meter)
|
||||||
|
|
||||||
|
|
||||||
|
def feet_to_meter(value_in_feet):
|
||||||
|
return int(float(value_in_feet)/3.048)
|
||||||
|
|
||||||
|
|
||||||
|
def meter_to_nm(value_in_meter):
|
||||||
|
return int(float(value_in_meter)*0.000539957)
|
||||||
|
|
||||||
|
|
||||||
|
def nm_to_meter(value_in_nm):
|
||||||
|
return int(float(value_in_nm)*1852)
|
||||||
@ -5,38 +5,22 @@ from dcs.terrain.terrain import NoParkingSlotError
|
|||||||
from dcs.triggers import TriggerOnce, Event
|
from dcs.triggers import TriggerOnce, Event
|
||||||
|
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from gen.flights.ai_flight_planner import FlightPlanner, CAP_DEFAULT_ENGAGE_DISTANCE, nm_to_meter
|
from gen.flights.ai_flight_planner import FlightPlanner
|
||||||
from gen.flights.flight import Flight, FlightType, FlightWaypointType
|
from gen.flights.flight import Flight, FlightType, FlightWaypointType
|
||||||
from .conflictgen import *
|
from .conflictgen import *
|
||||||
from .naming import *
|
from .naming import *
|
||||||
from .triggergen import TRIGGER_WAYPOINT_OFFSET
|
|
||||||
|
|
||||||
SPREAD_DISTANCE_FACTOR = 1, 2
|
|
||||||
ESCORT_ENGAGEMENT_MAX_DIST = 100000
|
|
||||||
WORKAROUND_WAYP_DIST = 1000
|
|
||||||
|
|
||||||
WARM_START_HELI_AIRSPEED = 120
|
WARM_START_HELI_AIRSPEED = 120
|
||||||
WARM_START_HELI_ALT = 500
|
WARM_START_HELI_ALT = 500
|
||||||
|
|
||||||
WARM_START_ALTITUDE = 3000
|
WARM_START_ALTITUDE = 3000
|
||||||
WARM_START_AIRSPEED = 550
|
WARM_START_AIRSPEED = 550
|
||||||
|
|
||||||
INTERCEPTION_AIRSPEED = 1000
|
CAP_DURATION = 30 # minutes
|
||||||
BARCAP_RACETRACK_DISTANCE = 20000
|
|
||||||
|
|
||||||
ATTACK_CIRCLE_ALT = 1000
|
|
||||||
ATTACK_CIRCLE_DURATION = 15
|
|
||||||
|
|
||||||
CAS_ALTITUDE = 800
|
|
||||||
RTB_ALTITUDE = 800
|
RTB_ALTITUDE = 800
|
||||||
RTB_DISTANCE = 5000
|
RTB_DISTANCE = 5000
|
||||||
HELI_ALT = 500
|
HELI_ALT = 500
|
||||||
|
|
||||||
TRANSPORT_LANDING_ALT = 2000
|
|
||||||
|
|
||||||
DEFENCE_ENGAGEMENT_MAX_DISTANCE = 60000
|
|
||||||
INTERCEPT_MAX_DISTANCE = 200000
|
|
||||||
|
|
||||||
|
|
||||||
class AircraftConflictGenerator:
|
class AircraftConflictGenerator:
|
||||||
escort_targets = [] # type: typing.List[typing.Tuple[FlyingGroup, int]]
|
escort_targets = [] # type: typing.List[typing.Tuple[FlyingGroup, int]]
|
||||||
@ -393,8 +377,8 @@ class AircraftConflictGenerator:
|
|||||||
if not point.only_for_player or (point.only_for_player and flight.client_count > 0):
|
if not point.only_for_player or (point.only_for_player and flight.client_count > 0):
|
||||||
pt = group.add_waypoint(Point(point.x, point.y), point.alt)
|
pt = group.add_waypoint(Point(point.x, point.y), point.alt)
|
||||||
if point.waypoint_type == FlightWaypointType.PATROL_TRACK:
|
if point.waypoint_type == FlightWaypointType.PATROL_TRACK:
|
||||||
action = OrbitAction(altitude=pt.alt, pattern=OrbitAction.OrbitPattern.RaceTrack)
|
action = ControlledTask(OrbitAction(altitude=pt.alt, pattern=OrbitAction.OrbitPattern.RaceTrack))
|
||||||
pt.tasks.append(action)
|
action.stop_after_duration(CAP_DURATION * 60)
|
||||||
#for tgt in point.targets:
|
#for tgt in point.targets:
|
||||||
# if hasattr(tgt, "position"):
|
# if hasattr(tgt, "position"):
|
||||||
# engagetgt = EngageTargetsInZone(tgt.position, radius=CAP_DEFAULT_ENGAGE_DISTANCE, targets=[Targets.All.Air])
|
# engagetgt = EngageTargetsInZone(tgt.position, radius=CAP_DEFAULT_ENGAGE_DISTANCE, targets=[Targets.All.Air])
|
||||||
|
|||||||
19
gen/fleet/schnellboot.py
Normal file
19
gen/fleet/schnellboot.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
|
from dcs.ships import Schnellboot_type_S130
|
||||||
|
|
||||||
|
from gen.sam.group_generator import GroupGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class SchnellbootGroupGenerator(GroupGenerator):
|
||||||
|
|
||||||
|
def __init__(self, game, ground_object, faction):
|
||||||
|
super(SchnellbootGroupGenerator, self).__init__(game, ground_object)
|
||||||
|
self.faction = faction
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
|
||||||
|
for i in range(random.randint(2, 4)):
|
||||||
|
self.add_unit(Schnellboot_type_S130, "Schnellboot" + str(i), self.position.x + i * random.randint(100, 250), self.position.y + (random.randint(100, 200)-100), self.heading)
|
||||||
|
|
||||||
|
self.get_generated_group().points[0].speed = 20
|
||||||
@ -1,6 +1,35 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
from gen.fleet.carrier_group import CarrierGroupGenerator
|
from gen.fleet.carrier_group import CarrierGroupGenerator
|
||||||
from gen.fleet.lha_group import LHAGroupGenerator
|
from gen.fleet.lha_group import LHAGroupGenerator
|
||||||
|
from dcs.ships import *
|
||||||
|
|
||||||
|
from gen.fleet.schnellboot import SchnellbootGroupGenerator
|
||||||
|
from gen.fleet.uboat import UBoatGroupGenerator
|
||||||
|
from gen.fleet.ww2lst import WW2LSTGroupGenerator
|
||||||
|
|
||||||
|
SHIP_MAP = {
|
||||||
|
Schnellboot_type_S130: SchnellbootGroupGenerator,
|
||||||
|
LS_Samuel_Chase: WW2LSTGroupGenerator,
|
||||||
|
Uboat_VIIC_U_flak: UBoatGroupGenerator
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def generate_ship_group(game, ground_object, faction:str):
|
||||||
|
"""
|
||||||
|
This generate a ship group
|
||||||
|
:return: Nothing, but put the group reference inside the ground object
|
||||||
|
"""
|
||||||
|
faction = db.FACTIONS[faction]
|
||||||
|
if "boat" in faction.keys():
|
||||||
|
ships = faction["boat"]
|
||||||
|
if len(ships) > 0:
|
||||||
|
sam = random.choice(ships)
|
||||||
|
generator = SHIP_MAP[sam](game, ground_object, faction)
|
||||||
|
generator.generate()
|
||||||
|
return generator.get_generated_group()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def generate_carrier_group(faction:str, game, ground_object):
|
def generate_carrier_group(faction:str, game, ground_object):
|
||||||
|
|||||||
19
gen/fleet/uboat.py
Normal file
19
gen/fleet/uboat.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
|
from dcs.ships import Uboat_VIIC_U_flak
|
||||||
|
|
||||||
|
from gen.sam.group_generator import GroupGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class UBoatGroupGenerator(GroupGenerator):
|
||||||
|
|
||||||
|
def __init__(self, game, ground_object, faction):
|
||||||
|
super(UBoatGroupGenerator, self).__init__(game, ground_object)
|
||||||
|
self.faction = faction
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
|
||||||
|
for i in range(random.randint(2, 6)):
|
||||||
|
self.add_unit(Uboat_VIIC_U_flak, "Uboat" + str(i), self.position.x + i * random.randint(100, 250), self.position.y + (random.randint(100, 200)-100), self.heading)
|
||||||
|
|
||||||
|
self.get_generated_group().points[0].speed = 20
|
||||||
22
gen/fleet/ww2lst.py
Normal file
22
gen/fleet/ww2lst.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
|
from dcs.ships import LS_Samuel_Chase, LST_Mk_II
|
||||||
|
|
||||||
|
from gen.sam.group_generator import GroupGenerator
|
||||||
|
|
||||||
|
|
||||||
|
class WW2LSTGroupGenerator(GroupGenerator):
|
||||||
|
|
||||||
|
def __init__(self, game, ground_object, faction):
|
||||||
|
super(WW2LSTGroupGenerator, self).__init__(game, ground_object)
|
||||||
|
self.faction = faction
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
|
||||||
|
# Add LS Samuel Chase
|
||||||
|
self.add_unit(LS_Samuel_Chase, "SamuelChase", self.position.x, self.position.y, self.heading)
|
||||||
|
|
||||||
|
for i in range(random.randint(2, 4)):
|
||||||
|
self.add_unit(LST_Mk_II, "LST" + str(i), self.position.x + i * random.randint(400, 600), self.position.y, self.heading)
|
||||||
|
|
||||||
|
self.get_generated_group().points[0].speed = 20
|
||||||
@ -3,46 +3,15 @@ import operator
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
|
from game.data.doctrine import MODERN_DOCTRINE
|
||||||
|
from game.data.radar_db import UNITS_WITH_RADAR
|
||||||
|
from game.utils import meter_to_feet, nm_to_meter
|
||||||
from gen import Conflict
|
from gen import Conflict
|
||||||
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE, STRIKE_CAPABLE
|
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE, STRIKE_CAPABLE
|
||||||
from gen.flights.flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
|
from gen.flights.flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
|
||||||
|
|
||||||
|
|
||||||
def meter_to_feet(value_in_meter):
|
MISSION_DURATION = 120
|
||||||
return int(3.28084 * value_in_meter)
|
|
||||||
|
|
||||||
|
|
||||||
def feet_to_meter(value_in_feet):
|
|
||||||
return int(float(value_in_feet)/3.048)
|
|
||||||
|
|
||||||
|
|
||||||
def meter_to_nm(value_in_meter):
|
|
||||||
return int(float(value_in_meter)*0.000539957)
|
|
||||||
|
|
||||||
|
|
||||||
def nm_to_meter(value_in_nm):
|
|
||||||
return int(float(value_in_nm)*1852)
|
|
||||||
|
|
||||||
|
|
||||||
# TODO : Ideally should be based on the aircraft type instead / Availability of fuel
|
|
||||||
STRIKE_MAX_RANGE = 1500000
|
|
||||||
SEAD_MAX_RANGE = 1500000
|
|
||||||
|
|
||||||
MAX_NUMBER_OF_INTERCEPTION_GROUP = 3
|
|
||||||
MISSION_DURATION = 120 # in minutes
|
|
||||||
CAP_EVERY_X_MINUTES = 20
|
|
||||||
CAS_EVERY_X_MINUTES = 30
|
|
||||||
SEAD_EVERY_X_MINUTES = 40
|
|
||||||
STRIKE_EVERY_X_MINUTES = 40
|
|
||||||
|
|
||||||
INGRESS_EGRESS_DISTANCE = nm_to_meter(45)
|
|
||||||
INGRESS_ALT = feet_to_meter(20000)
|
|
||||||
EGRESS_ALT = feet_to_meter(20000)
|
|
||||||
PATROL_ALT_RANGE = (feet_to_meter(15000), feet_to_meter(33000))
|
|
||||||
NAV_ALT = 9144
|
|
||||||
PATTERN_ALTITUDE = feet_to_meter(5000)
|
|
||||||
|
|
||||||
CAP_DEFAULT_ENGAGE_DISTANCE = nm_to_meter(40)
|
|
||||||
|
|
||||||
|
|
||||||
class FlightPlanner:
|
class FlightPlanner:
|
||||||
@ -54,6 +23,17 @@ class FlightPlanner:
|
|||||||
self.game = game
|
self.game = game
|
||||||
self.aircraft_inventory = {} # local copy of the airbase inventory
|
self.aircraft_inventory = {} # local copy of the airbase inventory
|
||||||
|
|
||||||
|
if from_cp.captured:
|
||||||
|
self.faction = self.game.player_faction
|
||||||
|
else:
|
||||||
|
self.faction = self.game.enemy_faction
|
||||||
|
|
||||||
|
if "doctrine" in self.faction.keys():
|
||||||
|
self.doctrine = self.faction["doctrine"]
|
||||||
|
else:
|
||||||
|
self.doctrine = MODERN_DOCTRINE
|
||||||
|
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
Reset the planned flights and available units
|
Reset the planned flights and available units
|
||||||
@ -111,7 +91,7 @@ class FlightPlanner:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# At least try to generate one interceptor group
|
# At least try to generate one interceptor group
|
||||||
number_of_interceptor_groups = min(max(sum([v for k, v in self.aircraft_inventory.items()]) / 4, MAX_NUMBER_OF_INTERCEPTION_GROUP), 1)
|
number_of_interceptor_groups = min(max(sum([v for k, v in self.aircraft_inventory.items()]) / 4, self.doctrine["MAX_NUMBER_OF_INTERCEPTION_GROUP"]), 1)
|
||||||
possible_interceptors = [k for k in self.aircraft_inventory.keys() if k in INTERCEPT_CAPABLE]
|
possible_interceptors = [k for k in self.aircraft_inventory.keys() if k in INTERCEPT_CAPABLE]
|
||||||
|
|
||||||
if len(possible_interceptors) <= 0:
|
if len(possible_interceptors) <= 0:
|
||||||
@ -144,7 +124,7 @@ class FlightPlanner:
|
|||||||
inventory = dict({k: v for k, v in self.aircraft_inventory.items() if k in possible_aircraft})
|
inventory = dict({k: v for k, v in self.aircraft_inventory.items() if k in possible_aircraft})
|
||||||
|
|
||||||
offset = random.randint(0,5)
|
offset = random.randint(0,5)
|
||||||
for i in range(int(MISSION_DURATION/CAP_EVERY_X_MINUTES)):
|
for i in range(int(MISSION_DURATION/self.doctrine["CAP_EVERY_X_MINUTES"])):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
unit = random.choice([k for k, v in inventory.items() if v >= 2])
|
unit = random.choice([k for k, v in inventory.items() if v >= 2])
|
||||||
@ -155,7 +135,7 @@ class FlightPlanner:
|
|||||||
flight = Flight(unit, 2, self.from_cp, FlightType.CAP)
|
flight = Flight(unit, 2, self.from_cp, FlightType.CAP)
|
||||||
|
|
||||||
flight.points = []
|
flight.points = []
|
||||||
flight.scheduled_in = offset + i*random.randint(CAP_EVERY_X_MINUTES-5, CAP_EVERY_X_MINUTES+5)
|
flight.scheduled_in = offset + i*random.randint(self.doctrine["CAP_EVERY_X_MINUTES"] - 5, self.doctrine["CAP_EVERY_X_MINUTES"] + 5)
|
||||||
|
|
||||||
if len(self._get_cas_locations()) > 0:
|
if len(self._get_cas_locations()) > 0:
|
||||||
enemy_cp = random.choice(self._get_cas_locations())
|
enemy_cp = random.choice(self._get_cas_locations())
|
||||||
@ -182,7 +162,7 @@ class FlightPlanner:
|
|||||||
if len(cas_location) > 0:
|
if len(cas_location) > 0:
|
||||||
|
|
||||||
offset = random.randint(0,5)
|
offset = random.randint(0,5)
|
||||||
for i in range(int(MISSION_DURATION/CAS_EVERY_X_MINUTES)):
|
for i in range(int(MISSION_DURATION/self.doctrine["CAS_EVERY_X_MINUTES"])):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
unit = random.choice([k for k, v in inventory.items() if v >= 2])
|
unit = random.choice([k for k, v in inventory.items() if v >= 2])
|
||||||
@ -192,7 +172,7 @@ class FlightPlanner:
|
|||||||
inventory[unit] = inventory[unit] - 2
|
inventory[unit] = inventory[unit] - 2
|
||||||
flight = Flight(unit, 2, self.from_cp, FlightType.CAS)
|
flight = Flight(unit, 2, self.from_cp, FlightType.CAS)
|
||||||
flight.points = []
|
flight.points = []
|
||||||
flight.scheduled_in = offset + i * random.randint(CAS_EVERY_X_MINUTES - 5, CAS_EVERY_X_MINUTES + 5)
|
flight.scheduled_in = offset + i * random.randint(self.doctrine["CAS_EVERY_X_MINUTES"] - 5, self.doctrine["CAS_EVERY_X_MINUTES"] + 5)
|
||||||
location = random.choice(cas_location)
|
location = random.choice(cas_location)
|
||||||
|
|
||||||
self.generate_cas(flight, flight.from_cp, location)
|
self.generate_cas(flight, flight.from_cp, location)
|
||||||
@ -215,7 +195,7 @@ class FlightPlanner:
|
|||||||
if len(self.potential_sead_targets) > 0:
|
if len(self.potential_sead_targets) > 0:
|
||||||
|
|
||||||
offset = random.randint(0,5)
|
offset = random.randint(0,5)
|
||||||
for i in range(int(MISSION_DURATION/SEAD_EVERY_X_MINUTES)):
|
for i in range(int(MISSION_DURATION/self.doctrine["SEAD_EVERY_X_MINUTES"])):
|
||||||
|
|
||||||
if len(self.potential_sead_targets) <= 0:
|
if len(self.potential_sead_targets) <= 0:
|
||||||
break
|
break
|
||||||
@ -229,7 +209,7 @@ class FlightPlanner:
|
|||||||
flight = Flight(unit, 2, self.from_cp, random.choice([FlightType.SEAD, FlightType.DEAD]))
|
flight = Flight(unit, 2, self.from_cp, random.choice([FlightType.SEAD, FlightType.DEAD]))
|
||||||
|
|
||||||
flight.points = []
|
flight.points = []
|
||||||
flight.scheduled_in = offset + i*random.randint(SEAD_EVERY_X_MINUTES-5, SEAD_EVERY_X_MINUTES+5)
|
flight.scheduled_in = offset + i*random.randint(self.doctrine["SEAD_EVERY_X_MINUTES"] - 5, self.doctrine["SEAD_EVERY_X_MINUTES"] + 5)
|
||||||
|
|
||||||
location = self.potential_sead_targets[0][0]
|
location = self.potential_sead_targets[0][0]
|
||||||
self.potential_sead_targets.pop(0)
|
self.potential_sead_targets.pop(0)
|
||||||
@ -254,7 +234,7 @@ class FlightPlanner:
|
|||||||
if len(self.potential_strike_targets) > 0:
|
if len(self.potential_strike_targets) > 0:
|
||||||
|
|
||||||
offset = random.randint(0,5)
|
offset = random.randint(0,5)
|
||||||
for i in range(int(MISSION_DURATION/STRIKE_EVERY_X_MINUTES)):
|
for i in range(int(MISSION_DURATION/self.doctrine["STRIKE_EVERY_X_MINUTES"])):
|
||||||
|
|
||||||
if len(self.potential_strike_targets) <= 0:
|
if len(self.potential_strike_targets) <= 0:
|
||||||
break
|
break
|
||||||
@ -268,7 +248,7 @@ class FlightPlanner:
|
|||||||
flight = Flight(unit, 2, self.from_cp, FlightType.STRIKE)
|
flight = Flight(unit, 2, self.from_cp, FlightType.STRIKE)
|
||||||
|
|
||||||
flight.points = []
|
flight.points = []
|
||||||
flight.scheduled_in = offset + i*random.randint(SEAD_EVERY_X_MINUTES-5, SEAD_EVERY_X_MINUTES+5)
|
flight.scheduled_in = offset + i*random.randint(self.doctrine["STRIKE_EVERY_X_MINUTES"] - 5, self.doctrine["STRIKE_EVERY_X_MINUTES"] + 5)
|
||||||
|
|
||||||
location = self.potential_strike_targets[0][0]
|
location = self.potential_strike_targets[0][0]
|
||||||
self.potential_strike_targets.pop(0)
|
self.potential_strike_targets.pop(0)
|
||||||
@ -306,7 +286,7 @@ class FlightPlanner:
|
|||||||
distance = math.hypot(cp.position.x - self.from_cp.position.x,
|
distance = math.hypot(cp.position.x - self.from_cp.position.x,
|
||||||
cp.position.y - self.from_cp.position.y)
|
cp.position.y - self.from_cp.position.y)
|
||||||
|
|
||||||
if distance > 2*STRIKE_MAX_RANGE:
|
if distance > 2*self.doctrine["STRIKE_MAX_RANGE"]:
|
||||||
# Then it's unlikely any child ground object is in range
|
# Then it's unlikely any child ground object is in range
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -318,7 +298,7 @@ class FlightPlanner:
|
|||||||
distance = math.hypot(cp.position.x - self.from_cp.position.x,
|
distance = math.hypot(cp.position.x - self.from_cp.position.x,
|
||||||
cp.position.y - self.from_cp.position.y)
|
cp.position.y - self.from_cp.position.y)
|
||||||
|
|
||||||
if distance < SEAD_MAX_RANGE:
|
if distance < self.doctrine["SEAD_MAX_RANGE"]:
|
||||||
self.potential_strike_targets.append((g, distance))
|
self.potential_strike_targets.append((g, distance))
|
||||||
added_group.append(g)
|
added_group.append(g)
|
||||||
|
|
||||||
@ -339,7 +319,7 @@ class FlightPlanner:
|
|||||||
cp.position.y - self.from_cp.position.y)
|
cp.position.y - self.from_cp.position.y)
|
||||||
|
|
||||||
# Then it's unlikely any ground object is range
|
# Then it's unlikely any ground object is range
|
||||||
if distance > 2*SEAD_MAX_RANGE:
|
if distance > 2*self.doctrine["SEAD_MAX_RANGE"]:
|
||||||
return
|
return
|
||||||
|
|
||||||
for g in cp.ground_objects:
|
for g in cp.ground_objects:
|
||||||
@ -347,8 +327,7 @@ class FlightPlanner:
|
|||||||
if g.dcs_identifier == "AA":
|
if g.dcs_identifier == "AA":
|
||||||
|
|
||||||
# Check that there is at least one unit with a radar in the ground objects unit groups
|
# Check that there is at least one unit with a radar in the ground objects unit groups
|
||||||
number_of_units = sum([len([r for r in group.units if hasattr(db.unit_type_from_name(r.type), "detection_range")
|
number_of_units = sum([len([r for r in group.units if db.unit_type_from_name(r.type) in UNITS_WITH_RADAR]) for group in g.groups])
|
||||||
and db.unit_type_from_name(r.type).detection_range > 1000]) for group in g.groups])
|
|
||||||
if number_of_units <= 0:
|
if number_of_units <= 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -356,7 +335,7 @@ class FlightPlanner:
|
|||||||
distance = math.hypot(cp.position.x - self.from_cp.position.x,
|
distance = math.hypot(cp.position.x - self.from_cp.position.x,
|
||||||
cp.position.y - self.from_cp.position.y)
|
cp.position.y - self.from_cp.position.y)
|
||||||
|
|
||||||
if distance < SEAD_MAX_RANGE:
|
if distance < self.doctrine["SEAD_MAX_RANGE"]:
|
||||||
self.potential_sead_targets.append((g, distance))
|
self.potential_sead_targets.append((g, distance))
|
||||||
|
|
||||||
self.potential_sead_targets.sort(key=operator.itemgetter(1))
|
self.potential_sead_targets.sort(key=operator.itemgetter(1))
|
||||||
@ -385,8 +364,8 @@ class FlightPlanner:
|
|||||||
ingress_heading = heading - 180 + 25
|
ingress_heading = heading - 180 + 25
|
||||||
egress_heading = heading - 180 - 25
|
egress_heading = heading - 180 - 25
|
||||||
|
|
||||||
ingress_pos = location.position.point_from_heading(ingress_heading, INGRESS_EGRESS_DISTANCE)
|
ingress_pos = location.position.point_from_heading(ingress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
|
||||||
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, INGRESS_ALT)
|
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, self.doctrine["INGRESS_ALT"])
|
||||||
ingress_point.pretty_name = "INGRESS on " + location.obj_name
|
ingress_point.pretty_name = "INGRESS on " + location.obj_name
|
||||||
ingress_point.description = "INGRESS on " + location.obj_name
|
ingress_point.description = "INGRESS on " + location.obj_name
|
||||||
ingress_point.name = "INGRESS"
|
ingress_point.name = "INGRESS"
|
||||||
@ -428,8 +407,8 @@ class FlightPlanner:
|
|||||||
ingress_point.targets.append(location)
|
ingress_point.targets.append(location)
|
||||||
flight.points.append(point)
|
flight.points.append(point)
|
||||||
|
|
||||||
egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE)
|
egress_pos = location.position.point_from_heading(egress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
|
||||||
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT)
|
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, self.doctrine["EGRESS_ALT"])
|
||||||
egress_point.name = "EGRESS"
|
egress_point.name = "EGRESS"
|
||||||
egress_point.pretty_name = "EGRESS from " + location.obj_name
|
egress_point.pretty_name = "EGRESS from " + location.obj_name
|
||||||
egress_point.description = "EGRESS from " + location.obj_name
|
egress_point.description = "EGRESS from " + location.obj_name
|
||||||
@ -447,22 +426,20 @@ class FlightPlanner:
|
|||||||
Generate a barcap flight at a given location
|
Generate a barcap flight at a given location
|
||||||
:param flight: Flight to setup
|
:param flight: Flight to setup
|
||||||
:param for_cp: CP to protect
|
:param for_cp: CP to protect
|
||||||
:param location: Location to protect in priority
|
|
||||||
:param location: Is the location to protect a frontline
|
|
||||||
"""
|
"""
|
||||||
flight.flight_type = FlightType.BARCAP if for_cp.is_carrier else FlightType.CAP
|
flight.flight_type = FlightType.BARCAP if for_cp.is_carrier else FlightType.CAP
|
||||||
patrol_alt = random.randint(PATROL_ALT_RANGE[0], PATROL_ALT_RANGE[1])
|
patrol_alt = random.randint(self.doctrine["PATROL_ALT_RANGE"][0], self.doctrine["PATROL_ALT_RANGE"][1])
|
||||||
|
|
||||||
if len(for_cp.ground_objects) > 0:
|
if len(for_cp.ground_objects) > 0:
|
||||||
loc = random.choice(for_cp.ground_objects)
|
loc = random.choice(for_cp.ground_objects)
|
||||||
hdg = for_cp.position.heading_between_point(loc.position)
|
hdg = for_cp.position.heading_between_point(loc.position)
|
||||||
radius = nm_to_meter(random.randint(15, 40))
|
radius = random.randint(self.doctrine["CAP_PATTERN_LENGTH"][0], self.doctrine["CAP_PATTERN_LENGTH"][1])
|
||||||
orbit0p = loc.position.point_from_heading(hdg - 90, radius)
|
orbit0p = loc.position.point_from_heading(hdg - 90, radius)
|
||||||
orbit1p = loc.position.point_from_heading(hdg + 90, radius)
|
orbit1p = loc.position.point_from_heading(hdg + 90, radius)
|
||||||
else:
|
else:
|
||||||
loc = for_cp.position.point_from_heading(random.randint(0, 360), random.randint(nm_to_meter(10), nm_to_meter(40)))
|
loc = for_cp.position.point_from_heading(random.randint(0, 360), random.randint(self.doctrine["CAP_DISTANCE_FROM_CP"][0], self.doctrine["CAP_DISTANCE_FROM_CP"][1]))
|
||||||
hdg = for_cp.position.heading_between_point(loc)
|
hdg = for_cp.position.heading_between_point(loc)
|
||||||
radius = nm_to_meter(random.randint(15, 40))
|
radius = random.randint(self.doctrine["CAP_PATTERN_LENGTH"][0], self.doctrine["CAP_PATTERN_LENGTH"][1])
|
||||||
orbit0p = loc.point_from_heading(hdg - 90, radius)
|
orbit0p = loc.point_from_heading(hdg - 90, radius)
|
||||||
orbit1p = loc.point_from_heading(hdg + 90, radius)
|
orbit1p = loc.point_from_heading(hdg + 90, radius)
|
||||||
|
|
||||||
@ -507,7 +484,7 @@ class FlightPlanner:
|
|||||||
:param enemy_cp: Enemy connected cp
|
:param enemy_cp: Enemy connected cp
|
||||||
"""
|
"""
|
||||||
flight.flight_type = FlightType.CAP
|
flight.flight_type = FlightType.CAP
|
||||||
patrol_alt = random.randint(PATROL_ALT_RANGE[0], PATROL_ALT_RANGE[1])
|
patrol_alt = random.randint(self.doctrine["PATROL_ALT_RANGE"][0], self.doctrine["PATROL_ALT_RANGE"][1])
|
||||||
|
|
||||||
# Find targets waypoints
|
# Find targets waypoints
|
||||||
ingress, heading, distance = Conflict.frontline_vector(ally_cp, enemy_cp, self.game.theater)
|
ingress, heading, distance = Conflict.frontline_vector(ally_cp, enemy_cp, self.game.theater)
|
||||||
@ -563,8 +540,8 @@ class FlightPlanner:
|
|||||||
ingress_heading = heading - 180 + 25
|
ingress_heading = heading - 180 + 25
|
||||||
egress_heading = heading - 180 - 25
|
egress_heading = heading - 180 - 25
|
||||||
|
|
||||||
ingress_pos = location.position.point_from_heading(ingress_heading, INGRESS_EGRESS_DISTANCE)
|
ingress_pos = location.position.point_from_heading(ingress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
|
||||||
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, INGRESS_ALT)
|
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, self.doctrine["INGRESS_ALT"])
|
||||||
ingress_point.name = "INGRESS"
|
ingress_point.name = "INGRESS"
|
||||||
ingress_point.pretty_name = "INGRESS on " + location.obj_name
|
ingress_point.pretty_name = "INGRESS on " + location.obj_name
|
||||||
ingress_point.description = "INGRESS on " + location.obj_name
|
ingress_point.description = "INGRESS on " + location.obj_name
|
||||||
@ -599,8 +576,8 @@ class FlightPlanner:
|
|||||||
ingress_point.targets.append(location)
|
ingress_point.targets.append(location)
|
||||||
flight.points.append(point)
|
flight.points.append(point)
|
||||||
|
|
||||||
egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE)
|
egress_pos = location.position.point_from_heading(egress_heading, self.doctrine["INGRESS_EGRESS_DISTANCE"])
|
||||||
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT)
|
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, self.doctrine["EGRESS_ALT"])
|
||||||
egress_point.name = "INGRESS"
|
egress_point.name = "INGRESS"
|
||||||
egress_point.pretty_name = "EGRESS from " + location.obj_name
|
egress_point.pretty_name = "EGRESS from " + location.obj_name
|
||||||
egress_point.description = "EGRESS from " + location.obj_name
|
egress_point.description = "EGRESS from " + location.obj_name
|
||||||
@ -670,11 +647,11 @@ class FlightPlanner:
|
|||||||
"""
|
"""
|
||||||
ascend_heading = from_cp.heading
|
ascend_heading = from_cp.heading
|
||||||
pos_ascend = from_cp.position.point_from_heading(ascend_heading, 10000)
|
pos_ascend = from_cp.position.point_from_heading(ascend_heading, 10000)
|
||||||
ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, PATTERN_ALTITUDE)
|
ascend = FlightWaypoint(pos_ascend.x, pos_ascend.y, self.doctrine["PATTERN_ALTITUDE"])
|
||||||
ascend.name = "ASCEND"
|
ascend.name = "ASCEND"
|
||||||
ascend.alt_type = "RADIO"
|
ascend.alt_type = "RADIO"
|
||||||
ascend.description = "Ascend to alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL], then proceed to next waypoint"
|
ascend.description = "Ascend to alt [" + str(meter_to_feet(self.doctrine["PATTERN_ALTITUDE"])) + " ft AGL], then proceed to next waypoint"
|
||||||
ascend.pretty_name = "Ascend to alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL]"
|
ascend.pretty_name = "Ascend to alt [" + str(meter_to_feet(self.doctrine["PATTERN_ALTITUDE"])) + " ft AGL]"
|
||||||
ascend.waypoint_type = FlightWaypointType.ASCEND_POINT
|
ascend.waypoint_type = FlightWaypointType.ASCEND_POINT
|
||||||
return ascend
|
return ascend
|
||||||
|
|
||||||
@ -687,11 +664,11 @@ class FlightPlanner:
|
|||||||
"""
|
"""
|
||||||
ascend_heading = from_cp.heading
|
ascend_heading = from_cp.heading
|
||||||
descend = from_cp.position.point_from_heading(ascend_heading - 180, 10000)
|
descend = from_cp.position.point_from_heading(ascend_heading - 180, 10000)
|
||||||
descend = FlightWaypoint(descend.x, descend.y, PATTERN_ALTITUDE)
|
descend = FlightWaypoint(descend.x, descend.y, self.doctrine["PATTERN_ALTITUDE"])
|
||||||
descend.name = "DESCEND"
|
descend.name = "DESCEND"
|
||||||
descend.alt_type = "RADIO"
|
descend.alt_type = "RADIO"
|
||||||
descend.description = "Descend to pattern alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL], contact tower, and land"
|
descend.description = "Descend to pattern alt [" + str(meter_to_feet(self.doctrine["PATTERN_ALTITUDE"])) + " ft AGL], contact tower, and land"
|
||||||
descend.pretty_name = "Descend to pattern alt [" + str(meter_to_feet(PATTERN_ALTITUDE)) + " ft AGL]"
|
descend.pretty_name = "Descend to pattern alt [" + str(meter_to_feet(self.doctrine["PATTERN_ALTITUDE"])) + " ft AGL]"
|
||||||
descend.waypoint_type = FlightWaypointType.DESCENT_POINT
|
descend.waypoint_type = FlightWaypointType.DESCENT_POINT
|
||||||
return descend
|
return descend
|
||||||
|
|
||||||
|
|||||||
@ -171,6 +171,7 @@ STRIKE_CAPABLE = [
|
|||||||
P_51D,
|
P_51D,
|
||||||
P_47D_30,
|
P_47D_30,
|
||||||
A_20G,
|
A_20G,
|
||||||
|
B_17G,
|
||||||
|
|
||||||
SpitfireLFMkIXCW,
|
SpitfireLFMkIXCW,
|
||||||
SpitfireLFMkIX,
|
SpitfireLFMkIX,
|
||||||
|
|||||||
@ -66,6 +66,7 @@ class GroundObjectsGenerator:
|
|||||||
|
|
||||||
utype = unit_type_from_name(g.units[0].type)
|
utype = unit_type_from_name(g.units[0].type)
|
||||||
|
|
||||||
|
if not ground_object.sea_object:
|
||||||
vg = self.m.vehicle_group(side, g.name, utype, position=g.position, heading=g.units[0].heading)
|
vg = self.m.vehicle_group(side, g.name, utype, position=g.position, heading=g.units[0].heading)
|
||||||
vg.units[0].name = self.m.string(g.units[0].name)
|
vg.units[0].name = self.m.string(g.units[0].name)
|
||||||
for i, u in enumerate(g.units):
|
for i, u in enumerate(g.units):
|
||||||
@ -75,12 +76,25 @@ class GroundObjectsGenerator:
|
|||||||
vehicle.position.y = u.position.y
|
vehicle.position.y = u.position.y
|
||||||
vehicle.heading = u.heading
|
vehicle.heading = u.heading
|
||||||
vg.add_unit(vehicle)
|
vg.add_unit(vehicle)
|
||||||
|
else:
|
||||||
|
vg = self.m.ship_group(side, g.name, utype, position=g.position,
|
||||||
|
heading=g.units[0].heading)
|
||||||
|
vg.units[0].name = self.m.string(g.units[0].name)
|
||||||
|
for i, u in enumerate(g.units):
|
||||||
|
utype = unit_type_from_name(u.type)
|
||||||
|
if i > 0:
|
||||||
|
ship = Ship(self.m.next_unit_id(), self.m.string(u.name), utype)
|
||||||
|
ship.position.x = u.position.x
|
||||||
|
ship.position.y = u.position.y
|
||||||
|
ship.heading = u.heading
|
||||||
|
vg.add_unit(ship)
|
||||||
|
|
||||||
if self.game.settings.perf_red_alert_state:
|
if self.game.settings.perf_red_alert_state:
|
||||||
vg.points[0].tasks.append(OptAlarmState(2))
|
vg.points[0].tasks.append(OptAlarmState(2))
|
||||||
else:
|
else:
|
||||||
vg.points[0].tasks.append(OptAlarmState(1))
|
vg.points[0].tasks.append(OptAlarmState(1))
|
||||||
|
|
||||||
|
|
||||||
elif ground_object.dcs_identifier in ["CARRIER", "LHA"]:
|
elif ground_object.dcs_identifier in ["CARRIER", "LHA"]:
|
||||||
for g in ground_object.groups:
|
for g in ground_object.groups:
|
||||||
if len(g.units) > 0:
|
if len(g.units) > 0:
|
||||||
|
|||||||
@ -15,7 +15,7 @@ class FlakGenerator(GroupGenerator):
|
|||||||
grid_x = random.randint(2, 4)
|
grid_x = random.randint(2, 4)
|
||||||
grid_y = random.randint(2, 4)
|
grid_y = random.randint(2, 4)
|
||||||
|
|
||||||
spacing = random.randint(10,40)
|
spacing = random.randint(30,60)
|
||||||
|
|
||||||
index = 0
|
index = 0
|
||||||
mixed = random.choice([True, False])
|
mixed = random.choice([True, False])
|
||||||
@ -25,8 +25,8 @@ class FlakGenerator(GroupGenerator):
|
|||||||
for j in range(grid_y):
|
for j in range(grid_y):
|
||||||
index = index+1
|
index = index+1
|
||||||
self.add_unit(unit_type, "AAA#" + str(index),
|
self.add_unit(unit_type, "AAA#" + str(index),
|
||||||
self.position.x + spacing*i,
|
self.position.x + spacing*i + random.randint(1,5),
|
||||||
self.position.y + spacing*j, self.heading)
|
self.position.y + spacing*j + random.randint(1,5), self.heading)
|
||||||
|
|
||||||
if(mixed):
|
if(mixed):
|
||||||
unit_type = random.choice(GFLAK)
|
unit_type = random.choice(GFLAK)
|
||||||
@ -35,5 +35,5 @@ class FlakGenerator(GroupGenerator):
|
|||||||
for i in range(grid_x):
|
for i in range(grid_x):
|
||||||
for j in range(grid_y):
|
for j in range(grid_y):
|
||||||
self.add_unit(Unarmed.Blitz_3_6_6700A, "AAA#" + str(index),
|
self.add_unit(Unarmed.Blitz_3_6_6700A, "AAA#" + str(index),
|
||||||
self.position.x + 200 + 9*i,
|
self.position.x + 200 + 15*i + random.randint(1,5),
|
||||||
self.position.y + 9*j, 90)
|
self.position.y + 15*j + random.randint(1,5), 90)
|
||||||
@ -43,6 +43,7 @@ class NewGameWizard(QtWidgets.QWizard):
|
|||||||
isTerrainNormandy = self.field("isTerrainNormandy")
|
isTerrainNormandy = self.field("isTerrainNormandy")
|
||||||
isTerrainNormandySmall = self.field("isTerrainNormandySmall")
|
isTerrainNormandySmall = self.field("isTerrainNormandySmall")
|
||||||
isTerrainChannel = self.field("isTerrainChannel")
|
isTerrainChannel = self.field("isTerrainChannel")
|
||||||
|
isTerrainChannelComplete = self.field("isTerrainChannelComplete")
|
||||||
isTerrainEmirates = self.field("isTerrainEmirates")
|
isTerrainEmirates = self.field("isTerrainEmirates")
|
||||||
timePeriod = db.TIME_PERIODS[list(db.TIME_PERIODS.keys())[self.field("timePeriod")]]
|
timePeriod = db.TIME_PERIODS[list(db.TIME_PERIODS.keys())[self.field("timePeriod")]]
|
||||||
midGame = self.field("midGame")
|
midGame = self.field("midGame")
|
||||||
@ -71,6 +72,8 @@ class NewGameWizard(QtWidgets.QWizard):
|
|||||||
conflicttheater = normandy.NormandySmall()
|
conflicttheater = normandy.NormandySmall()
|
||||||
elif isTerrainChannel:
|
elif isTerrainChannel:
|
||||||
conflicttheater = thechannel.ChannelTheater()
|
conflicttheater = thechannel.ChannelTheater()
|
||||||
|
elif isTerrainChannelComplete:
|
||||||
|
conflicttheater = thechannel.ChannelTheaterComplete()
|
||||||
else:
|
else:
|
||||||
conflicttheater = caucasus.CaucasusTheater()
|
conflicttheater = caucasus.CaucasusTheater()
|
||||||
|
|
||||||
@ -248,8 +251,10 @@ class TheaterConfiguration(QtWidgets.QWizardPage):
|
|||||||
terrainNormandy.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Normandy"]))
|
terrainNormandy.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Normandy"]))
|
||||||
terrainNormandySmall = QtWidgets.QRadioButton("Normandy Small")
|
terrainNormandySmall = QtWidgets.QRadioButton("Normandy Small")
|
||||||
terrainNormandySmall.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Normandy"]))
|
terrainNormandySmall.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Normandy"]))
|
||||||
terrainChannel = QtWidgets.QRadioButton("Channel")
|
terrainChannel = QtWidgets.QRadioButton("The Channel : Start in Dunkirk")
|
||||||
terrainChannel.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Channel"]))
|
terrainChannel.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Channel"]))
|
||||||
|
terrainChannelComplete = QtWidgets.QRadioButton("The Channel : Battle of Britain")
|
||||||
|
terrainChannelComplete.setIcon(QtGui.QIcon(CONST.ICONS["Terrain_Channel"]))
|
||||||
terrainCaucasusSmall.setChecked(True)
|
terrainCaucasusSmall.setChecked(True)
|
||||||
|
|
||||||
# Time Period
|
# Time Period
|
||||||
@ -273,6 +278,7 @@ class TheaterConfiguration(QtWidgets.QWizardPage):
|
|||||||
self.registerField('isTerrainNormandy', terrainNormandy)
|
self.registerField('isTerrainNormandy', terrainNormandy)
|
||||||
self.registerField('isTerrainNormandySmall', terrainNormandySmall)
|
self.registerField('isTerrainNormandySmall', terrainNormandySmall)
|
||||||
self.registerField('isTerrainChannel', terrainChannel)
|
self.registerField('isTerrainChannel', terrainChannel)
|
||||||
|
self.registerField('isTerrainChannelComplete', terrainChannelComplete)
|
||||||
self.registerField('timePeriod', timePeriodSelect)
|
self.registerField('timePeriod', timePeriodSelect)
|
||||||
|
|
||||||
# Build layout
|
# Build layout
|
||||||
@ -287,6 +293,7 @@ class TheaterConfiguration(QtWidgets.QWizardPage):
|
|||||||
terrainGroupLayout.addWidget(terrainNttr)
|
terrainGroupLayout.addWidget(terrainNttr)
|
||||||
terrainGroupLayout.addWidget(terrainNormandy)
|
terrainGroupLayout.addWidget(terrainNormandy)
|
||||||
terrainGroupLayout.addWidget(terrainNormandySmall)
|
terrainGroupLayout.addWidget(terrainNormandySmall)
|
||||||
|
terrainGroupLayout.addWidget(terrainChannelComplete)
|
||||||
terrainGroupLayout.addWidget(terrainChannel)
|
terrainGroupLayout.addWidget(terrainChannel)
|
||||||
terrainGroup.setLayout(terrainGroupLayout)
|
terrainGroup.setLayout(terrainGroupLayout)
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox
|
|||||||
from dcs import Point
|
from dcs import Point
|
||||||
|
|
||||||
from game import Game
|
from game import Game
|
||||||
from gen.flights.ai_flight_planner import meter_to_nm
|
from game.utils import meter_to_nm
|
||||||
from gen.flights.flight import Flight
|
from gen.flights.flight import Flight
|
||||||
from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import QPredefinedWaypointSelectionComboBox
|
from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import QPredefinedWaypointSelectionComboBox
|
||||||
from qt_ui.windows.mission.flight.generator.QAbstractMissionGenerator import QAbstractMissionGenerator
|
from qt_ui.windows.mission.flight.generator.QAbstractMissionGenerator import QAbstractMissionGenerator
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from PySide2.QtGui import Qt
|
|||||||
from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox
|
from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox
|
||||||
|
|
||||||
from game import Game
|
from game import Game
|
||||||
from gen.flights.ai_flight_planner import meter_to_nm
|
from game.utils import meter_to_nm
|
||||||
from gen.flights.flight import Flight
|
from gen.flights.flight import Flight
|
||||||
from qt_ui.widgets.combos.QSEADTargetSelectionComboBox import QSEADTargetSelectionComboBox
|
from qt_ui.widgets.combos.QSEADTargetSelectionComboBox import QSEADTargetSelectionComboBox
|
||||||
from qt_ui.widgets.views.QSeadTargetInfoView import QSeadTargetInfoView
|
from qt_ui.widgets.views.QSeadTargetInfoView import QSeadTargetInfoView
|
||||||
|
|||||||
@ -2,7 +2,7 @@ from PySide2.QtGui import Qt
|
|||||||
from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox
|
from PySide2.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QGroupBox
|
||||||
|
|
||||||
from game import Game
|
from game import Game
|
||||||
from gen.flights.ai_flight_planner import meter_to_nm
|
from game.utils import meter_to_nm
|
||||||
from gen.flights.flight import Flight
|
from gen.flights.flight import Flight
|
||||||
from qt_ui.widgets.combos.QStrikeTargetSelectionComboBox import QStrikeTargetSelectionComboBox
|
from qt_ui.widgets.combos.QStrikeTargetSelectionComboBox import QStrikeTargetSelectionComboBox
|
||||||
from qt_ui.widgets.views.QStrikeTargetInfoView import QStrikeTargetInfoView
|
from qt_ui.widgets.views.QStrikeTargetInfoView import QStrikeTargetInfoView
|
||||||
|
|||||||
69
resources/customized_payloads/B-17G.lua
Normal file
69
resources/customized_payloads/B-17G.lua
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
local unitPayloads = {
|
||||||
|
["name"] = "B-17G",
|
||||||
|
["payloads"] = {
|
||||||
|
[1] = {
|
||||||
|
["name"] = "STRIKE",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{12xM64}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
[1] = 32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
["name"] = "CAP",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{12xM64}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
[1] = 32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[3] = {
|
||||||
|
["name"] = "SEAD",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{12xM64}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
[1] = 32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[4] = {
|
||||||
|
["name"] = "ANTISHIP",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{12xM64}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
[1] = 32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[5] = {
|
||||||
|
["name"] = "CAS",
|
||||||
|
["pylons"] = {
|
||||||
|
[1] = {
|
||||||
|
["CLSID"] = "{12xM64}",
|
||||||
|
["num"] = 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
[1] = 32,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
["tasks"] = {
|
||||||
|
},
|
||||||
|
["unitType"] = "B-17G",
|
||||||
|
}
|
||||||
|
return unitPayloads
|
||||||
Binary file not shown.
@ -7,7 +7,7 @@ import logging
|
|||||||
from game.data.building_data import DEFAULT_AVAILABLE_BUILDINGS
|
from game.data.building_data import DEFAULT_AVAILABLE_BUILDINGS
|
||||||
from gen import namegen
|
from gen import namegen
|
||||||
from gen.defenses.armor_group_generator import generate_armor_group
|
from gen.defenses.armor_group_generator import generate_armor_group
|
||||||
from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group
|
from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group, generate_ship_group
|
||||||
from gen.sam.sam_group_generator import generate_anti_air_group, generate_shorad_group
|
from gen.sam.sam_group_generator import generate_anti_air_group, generate_shorad_group
|
||||||
from theater import ControlPointType
|
from theater import ControlPointType
|
||||||
from theater.base import *
|
from theater.base import *
|
||||||
@ -81,6 +81,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
|
|||||||
g.cp_id = cp.id
|
g.cp_id = cp.id
|
||||||
g.airbase_group = True
|
g.airbase_group = True
|
||||||
g.dcs_identifier = "CARRIER"
|
g.dcs_identifier = "CARRIER"
|
||||||
|
g.sea_object = True
|
||||||
g.obj_name = namegen.random_objective_name()
|
g.obj_name = namegen.random_objective_name()
|
||||||
g.heading = 0
|
g.heading = 0
|
||||||
g.position = Point(cp.position.x, cp.position.y)
|
g.position = Point(cp.position.x, cp.position.y)
|
||||||
@ -101,6 +102,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
|
|||||||
g.cp_id = cp.id
|
g.cp_id = cp.id
|
||||||
g.airbase_group = True
|
g.airbase_group = True
|
||||||
g.dcs_identifier = "LHA"
|
g.dcs_identifier = "LHA"
|
||||||
|
g.sea_object = True
|
||||||
g.obj_name = namegen.random_objective_name()
|
g.obj_name = namegen.random_objective_name()
|
||||||
g.heading = 0
|
g.heading = 0
|
||||||
g.position = Point(cp.position.x, cp.position.y)
|
g.position = Point(cp.position.x, cp.position.y)
|
||||||
@ -114,7 +116,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
|
|||||||
cp.name = random.choice(db.FACTIONS[faction]["lhanames"])
|
cp.name = random.choice(db.FACTIONS[faction]["lhanames"])
|
||||||
else:
|
else:
|
||||||
|
|
||||||
for i in range(random.randint(2,6)):
|
for i in range(random.randint(3,6)):
|
||||||
|
|
||||||
print("GENERATE BASE DEFENSE")
|
print("GENERATE BASE DEFENSE")
|
||||||
point = find_location(True, cp.position, theater, 1000, 2800, [], True)
|
point = find_location(True, cp.position, theater, 1000, 2800, [], True)
|
||||||
@ -132,6 +134,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
|
|||||||
g.cp_id = cp.id
|
g.cp_id = cp.id
|
||||||
g.airbase_group = True
|
g.airbase_group = True
|
||||||
g.dcs_identifier = "AA"
|
g.dcs_identifier = "AA"
|
||||||
|
g.sea_object = False
|
||||||
g.obj_name = namegen.random_objective_name()
|
g.obj_name = namegen.random_objective_name()
|
||||||
g.heading = 0
|
g.heading = 0
|
||||||
g.position = Point(point.x, point.y)
|
g.position = Point(point.x, point.y)
|
||||||
@ -144,6 +147,35 @@ def generate_groundobjects(theater: ConflictTheater, game):
|
|||||||
for ground_object in cp.ground_objects:
|
for ground_object in cp.ground_objects:
|
||||||
print(ground_object.groups)
|
print(ground_object.groups)
|
||||||
|
|
||||||
|
for i in range(random.randint(2, 3)):
|
||||||
|
|
||||||
|
print("GENERATE SHIPS")
|
||||||
|
point = find_location(False, cp.position, theater, 5000, 40000, [], False)
|
||||||
|
print(point)
|
||||||
|
|
||||||
|
if point is None:
|
||||||
|
print("Couldn't find point for {} ships".format(cp))
|
||||||
|
continue
|
||||||
|
|
||||||
|
group_id = group_id + 1
|
||||||
|
|
||||||
|
g = TheaterGroundObject("aa")
|
||||||
|
g.group_id = group_id
|
||||||
|
g.object_id = 0
|
||||||
|
g.cp_id = cp.id
|
||||||
|
g.airbase_group = False
|
||||||
|
g.dcs_identifier = "AA"
|
||||||
|
g.sea_object = True
|
||||||
|
g.obj_name = namegen.random_objective_name()
|
||||||
|
g.heading = 0
|
||||||
|
g.position = Point(point.x, point.y)
|
||||||
|
|
||||||
|
group = generate_ship_group(game, g, faction)
|
||||||
|
g.groups = []
|
||||||
|
if group is not None:
|
||||||
|
g.groups.append(group)
|
||||||
|
cp.ground_objects.append(g)
|
||||||
|
|
||||||
|
|
||||||
def generate_airbase_defense_group(airbase_defense_group_id, ground_obj:TheaterGroundObject, faction, game, cp):
|
def generate_airbase_defense_group(airbase_defense_group_id, ground_obj:TheaterGroundObject, faction, game, cp):
|
||||||
|
|
||||||
@ -286,6 +318,7 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat
|
|||||||
|
|
||||||
g.dcs_identifier = object["type"]
|
g.dcs_identifier = object["type"]
|
||||||
g.heading = object["heading"]
|
g.heading = object["heading"]
|
||||||
|
g.sea_object = False
|
||||||
g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y)
|
g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y)
|
||||||
|
|
||||||
if g.dcs_identifier == "AA":
|
if g.dcs_identifier == "AA":
|
||||||
|
|||||||
@ -69,6 +69,7 @@ class TheaterGroundObject:
|
|||||||
position = None # type: Point
|
position = None # type: Point
|
||||||
groups = []
|
groups = []
|
||||||
obj_name = ""
|
obj_name = ""
|
||||||
|
sea_object = False
|
||||||
|
|
||||||
def __init__(self, category: str):
|
def __init__(self, category: str):
|
||||||
self.category = category
|
self.category = category
|
||||||
|
|||||||
@ -21,7 +21,54 @@ class ChannelTheater(ConflictTheater):
|
|||||||
super(ChannelTheater, self).__init__()
|
super(ChannelTheater, self).__init__()
|
||||||
|
|
||||||
self.abeville = ControlPoint.from_airport(thechannel.Abbeville_Drucat, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
self.abeville = ControlPoint.from_airport(thechannel.Abbeville_Drucat, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
self.detling = ControlPoint.from_airport(thechannel.Detling, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
#self.detling = ControlPoint.from_airport(thechannel.Detling, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
|
||||||
|
self.stomer = ControlPoint.from_airport(thechannel.Saint_Omer_Longuenesse, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
self.dunkirk = ControlPoint.from_airport(thechannel.Dunkirk_Mardyck, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
self.hawkinge = ControlPoint.from_airport(thechannel.Hawkinge, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
#self.highhalden = ControlPoint.from_airport(thechannel.High_Halden, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
self.lympne = ControlPoint.from_airport(thechannel.Lympne, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
self.manston = ControlPoint.from_airport(thechannel.Manston, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
self.merville = ControlPoint.from_airport(thechannel.Merville_Calonne, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
|
||||||
|
|
||||||
|
# England
|
||||||
|
self.add_controlpoint(self.hawkinge, connected_to=[self.lympne, self.manston])
|
||||||
|
self.add_controlpoint(self.lympne, connected_to=[self.hawkinge])
|
||||||
|
self.add_controlpoint(self.manston, connected_to=[self.hawkinge])
|
||||||
|
|
||||||
|
# France
|
||||||
|
self.add_controlpoint(self.dunkirk, connected_to=[self.stomer])
|
||||||
|
self.add_controlpoint(self.stomer, connected_to=[self.dunkirk, self.merville, self.abeville])
|
||||||
|
self.add_controlpoint(self.merville, connected_to=[self.stomer])
|
||||||
|
self.add_controlpoint(self.abeville, connected_to=[self.stomer])
|
||||||
|
|
||||||
|
#self.detling.captured = True
|
||||||
|
self.hawkinge.captured = True
|
||||||
|
self.dunkirk.captured = True
|
||||||
|
#self.highhalden.captured = True
|
||||||
|
self.lympne.captured = True
|
||||||
|
self.manston.captured = True
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelTheaterComplete(ConflictTheater):
|
||||||
|
terrain = dcs.terrain.TheChannel()
|
||||||
|
overview_image = "thechannel.gif"
|
||||||
|
reference_points = {(thechannel.Abbeville_Drucat.position.x, thechannel.Abbeville_Drucat.position.y): (2400, 4100),
|
||||||
|
(thechannel.Detling.position.x, thechannel.Detling.position.y): (1100, 2000)}
|
||||||
|
landmap = load_landmap("resources\\channellandmap.p")
|
||||||
|
daytime_map = {
|
||||||
|
"dawn": (6, 8),
|
||||||
|
"day": (10, 17),
|
||||||
|
"dusk": (17, 18),
|
||||||
|
"night": (0, 5),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(ChannelTheaterComplete, self).__init__()
|
||||||
|
|
||||||
|
self.abeville = ControlPoint.from_airport(thechannel.Abbeville_Drucat, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
#self.detling = ControlPoint.from_airport(thechannel.Detling, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
|
||||||
self.stomer = ControlPoint.from_airport(thechannel.Saint_Omer_Longuenesse, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
self.stomer = ControlPoint.from_airport(thechannel.Saint_Omer_Longuenesse, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
self.dunkirk = ControlPoint.from_airport(thechannel.Dunkirk_Mardyck, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
self.dunkirk = ControlPoint.from_airport(thechannel.Dunkirk_Mardyck, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
@ -31,13 +78,11 @@ class ChannelTheater(ConflictTheater):
|
|||||||
self.manston = ControlPoint.from_airport(thechannel.Manston, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
self.manston = ControlPoint.from_airport(thechannel.Manston, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
self.merville = ControlPoint.from_airport(thechannel.Merville_Calonne, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
self.merville = ControlPoint.from_airport(thechannel.Merville_Calonne, LAND, SIZE_SMALL, IMPORTANCE_LOW)
|
||||||
|
|
||||||
|
|
||||||
# England
|
# England
|
||||||
self.add_controlpoint(self.detling, connected_to=[self.highhalden])
|
|
||||||
self.add_controlpoint(self.hawkinge, connected_to=[self.lympne, self.manston])
|
self.add_controlpoint(self.hawkinge, connected_to=[self.lympne, self.manston])
|
||||||
self.add_controlpoint(self.highhalden, connected_to=[self.detling, self.lympne])
|
self.add_controlpoint(self.lympne, connected_to=[self.hawkinge, self.highhalden])
|
||||||
self.add_controlpoint(self.lympne, connected_to=[self.highhalden, self.hawkinge])
|
|
||||||
self.add_controlpoint(self.manston, connected_to=[self.hawkinge])
|
self.add_controlpoint(self.manston, connected_to=[self.hawkinge])
|
||||||
|
self.add_controlpoint(self.highhalden, connected_to=[self.lympne])
|
||||||
|
|
||||||
# France
|
# France
|
||||||
self.add_controlpoint(self.dunkirk, connected_to=[self.stomer])
|
self.add_controlpoint(self.dunkirk, connected_to=[self.stomer])
|
||||||
@ -45,8 +90,9 @@ class ChannelTheater(ConflictTheater):
|
|||||||
self.add_controlpoint(self.merville, connected_to=[self.stomer])
|
self.add_controlpoint(self.merville, connected_to=[self.stomer])
|
||||||
self.add_controlpoint(self.abeville, connected_to=[self.stomer])
|
self.add_controlpoint(self.abeville, connected_to=[self.stomer])
|
||||||
|
|
||||||
self.detling.captured = True
|
#self.detling.captured = True
|
||||||
self.hawkinge.captured = True
|
self.hawkinge.captured = True
|
||||||
|
#self.dunkirk.captured = True
|
||||||
self.highhalden.captured = True
|
self.highhalden.captured = True
|
||||||
self.lympne.captured = True
|
self.lympne.captured = True
|
||||||
self.manston.captured = True
|
self.manston.captured = True
|
||||||
Loading…
x
Reference in New Issue
Block a user