new weather, strike objectives placement fixes & tarawa for av8b

This commit is contained in:
Vasyl Horbachenko 2018-10-13 22:28:30 +03:00
parent 6d0f488672
commit e2306ba0f3
16 changed files with 119 additions and 63 deletions

View File

@ -43,7 +43,7 @@ def is_version_compatible(save_version):
if current_version_components == save_version_components:
return True
if save_version in ["1.4_rc1", "1.4_rc2", "1.4_rc3", "1.4_rc4", "1.4_rc5"]:
if save_version in ["1.4_rc1", "1.4_rc2", "1.4_rc3", "1.4_rc4", "1.4_rc5", "1.4_rc6"]:
return False
if current_version_components[:2] == save_version_components[:2]:

View File

@ -76,7 +76,6 @@ PRICES = {
S_3B_Tanker: 13,
IL_78M: 13,
KC_135: 13,
KC130: 13,
A_50: 8,
E_3A: 8,
@ -110,9 +109,10 @@ PRICES = {
# ship
CV_1143_5_Admiral_Kuznetsov: 100,
CVN_74_John_C__Stennis: 100,
LHA_1_Tarawa: 50,
LHA_1_Tarawa: 30,
Bulk_cargo_ship_Yakushev: 10,
Armed_speedboat: 10,
Dry_cargo_ship_Ivanov: 10,
Tanker_Elnya_160: 10,
}
@ -166,14 +166,13 @@ UNIT_BY_TASK = {
An_30M,
Yak_40,
S_3B_Tanker,
C_130,
],
Refueling: [
IL_78M,
KC_135,
KC130,
S_3B_Tanker,
],
AWACS: [E_3A, A_50, ],
@ -198,8 +197,8 @@ UNIT_BY_TASK = {
Nothing: [Infantry.Infantry_M4, Infantry.Soldier_AK, ],
Embarking: [UH_1H, Mi_8MT, ],
Carriage: [CVN_74_John_C__Stennis, CV_1143_5_Admiral_Kuznetsov, ],
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev, Tanker_Elnya_160, LHA_1_Tarawa],
Carriage: [CVN_74_John_C__Stennis, LHA_1_Tarawa, CV_1143_5_Admiral_Kuznetsov, ],
CargoTransportation: [Dry_cargo_ship_Ivanov, Bulk_cargo_ship_Yakushev, Tanker_Elnya_160, Armed_speedboat, ],
}
"""
@ -299,7 +298,6 @@ UNIT_BY_COUNTRY = {
AV8BNA,
KC_135,
KC130,
S_3B_Tanker,
C_130,
E_3A,
@ -319,9 +317,18 @@ UNIT_BY_COUNTRY = {
CVN_74_John_C__Stennis,
LHA_1_Tarawa,
Armed_speedboat,
],
}
CARRIER_TYPE_BY_PLANE = {
FA_18C_hornet: CVN_74_John_C__Stennis,
Ka_50: LHA_1_Tarawa,
UH_1H: LHA_1_Tarawa,
Mi_8MT: LHA_1_Tarawa,
AV8BNA: LHA_1_Tarawa,
}
"""
Aircraft payload overrides. Usually default loadout for the task is loaded during the mission generation.
Syntax goes as follows:
@ -341,6 +348,8 @@ Payload will be used for operation of following type, "*" category will be used
PLANE_PAYLOAD_OVERRIDES = {
FA_18C_hornet: {
CAP: "AIM-120*4,AIM-9*2,AIM-7*2,Fuel",
PinpointStrike: "MK-82*8,AIM-9*2,AIM-7,FLIR Pod,Fuel",
AntishipStrike: "MK-82*8,AIM-9*2,AIM-7,FLIR Pod,Fuel",
},
Su_25T: {
@ -460,6 +469,14 @@ def unitdict_append(unit_dict: UnitsDict, unit_type: UnitType, count: int):
unit_dict[unit_type] = unit_dict.get(unit_type, 0) + 1
def unitdict_merge(a: UnitsDict, b: UnitsDict) -> UnitsDict:
b = b.copy()
for k, v in a.items():
b[k] = b.get(k, 0) + v
return b
def unitdict_split(unit_dict: UnitsDict, count: int):
buffer_dict = {}
for unit_type, unit_count in unit_dict.items():

View File

@ -11,7 +11,7 @@ class NavalInterceptEvent(Event):
def _targets_count(self) -> int:
from gen.conflictgen import IMPORTANCE_LOW
factor = (self.to_cp.importance - IMPORTANCE_LOW) * 10
factor = (self.to_cp.importance - IMPORTANCE_LOW + 0.1) * 20
return max(int(factor), 1)
def __str__(self) -> str:

View File

@ -39,16 +39,7 @@ class InterceptOperation(Operation):
conflict=conflict)
def generate(self):
for global_cp in self.game.theater.controlpoints:
if not global_cp.is_global:
continue
ship = self.shipgen.generate_carrier(type=db.find_unittype(Carriage, self.game.player)[0],
country=self.game.player,
at=global_cp.at)
if global_cp == self.from_cp and not self.is_quick:
self.attackers_starting_position = ship
self.prepare_carriers(self.interceptors.keys())
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)

View File

@ -33,6 +33,8 @@ class NavalInterceptionOperation(Operation):
self.initialize(self.mission, conflict)
def generate(self):
self.prepare_carriers(db.unitdict_from(self.strikegroup))
target_groups = self.shipgen.generate_cargo(units=self.targets)
self.airgen.generate_ship_strikegroup(

View File

@ -83,6 +83,18 @@ class Operation:
self.attackers_starting_position = self.from_cp.at
self.defenders_starting_position = self.to_cp.at
def prepare_carriers(self, for_units: db.UnitsDict):
for global_cp in self.game.theater.controlpoints:
if not global_cp.is_global:
continue
ship = self.shipgen.generate_carrier(for_units=for_units,
country=self.game.player,
at=global_cp.at)
if global_cp == self.from_cp and not self.is_quick:
self.attackers_starting_position = ship
def generate(self):
self.visualgen.generate()

View File

@ -35,16 +35,7 @@ class StrikeOperation(Operation):
conflict=conflict)
def generate(self):
for global_cp in self.game.theater.controlpoints:
if not global_cp.is_global:
continue
ship = self.shipgen.generate_carrier(type=db.find_unittype(Carriage, self.game.player)[0],
country=self.game.player,
at=global_cp.at)
if global_cp == self.from_cp and not self.is_quick:
self.attackers_starting_position = ship
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]]
category_counters = {} # type: typing.Dict[str, int]

View File

@ -5,6 +5,7 @@ class Settings:
enemy_vehicle_skill = "Average"
only_player_takeoff = True
night_disabled = False
multiplier = 1
sams = True
cold_start = False

View File

@ -9,11 +9,11 @@ from dcs.task import *
from dcs.terrain.terrain import NoParkingSlotError
TANKER_DISTANCE = 15000
TANKER_ALT = 6000
TANKER_ALT = 4572
TANKER_HEADING_OFFSET = 45
AWACS_DISTANCE = 150000
AWACS_ALT = 15000
AWACS_ALT = 13000
class AirSupportConflictGenerator:

View File

@ -21,6 +21,10 @@ WEATHER_CLOUD_DENSITY = 1, 8
WEATHER_CLOUD_THICKNESS = 100, 400
WEATHER_CLOUD_BASE_MIN = 1600
WEATHER_FOG_CHANCE = 20
WEATHER_FOG_VISIBILITY = 2500, 5000
WEATHER_FOG_THICKNESS = 100, 500
RANDOM_TIME = {
"night": 5,
"dusk": 30,
@ -29,11 +33,10 @@ RANDOM_TIME = {
}
RANDOM_WEATHER = {
1: 0, # heavy rain
2: 5, # rain
3: 15, # dynamic
4: 40, # clear
5: 100, # random
1: 0, # thunderstorm
2: 20, # rain
3: 80, # clouds
4: 100, # clear
}
@ -68,6 +71,29 @@ class EnviromentGenerator:
self.mission.start_time = start_time
def _generate_wind(self, wind_speed, wind_direction=None):
# wind
if not wind_direction:
wind_direction = random.randint(0, 360)
self.mission.weather.wind_at_ground = Wind(wind_direction, wind_speed)
self.mission.weather.wind_at_2000 = Wind(wind_direction, wind_speed * 2)
self.mission.weather.wind_at_8000 = Wind(wind_direction, wind_speed * 3)
def _generate_base_weather(self):
# clouds
self.mission.weather.clouds_base = random.randint(*WEATHER_CLOUD_BASE)
self.mission.weather.clouds_density = random.randint(*WEATHER_CLOUD_DENSITY)
self.mission.weather.clouds_thickness = random.randint(*WEATHER_CLOUD_THICKNESS)
# wind
self._generate_wind(random.randint(0, 4))
# fog
if random.randint(0, 100) < WEATHER_FOG_CHANCE:
self.mission.weather.fog_visibility = random.randint(*WEATHER_FOG_VISIBILITY)
self.mission.weather.fog_thickness = random.randint(*WEATHER_FOG_THICKNESS)
def _gen_random_weather(self):
weather_type = None
for k, v in RANDOM_WEATHER.items():
@ -77,24 +103,25 @@ class EnviromentGenerator:
logging.info("generated weather {}".format(weather_type))
if weather_type == 1:
self.mission.weather.heavy_rain()
elif weather_type == 2:
self.mission.weather.heavy_rain()
self.mission.weather.enable_fog = False
elif weather_type == 3:
self.mission.weather.random(self.mission.start_time, self.conflict.theater.terrain)
elif weather_type == 4:
pass
elif weather_type == 5:
self.mission.weather.clouds_base = random.randint(*WEATHER_CLOUD_BASE)
self.mission.weather.clouds_density = random.randint(*WEATHER_CLOUD_DENSITY)
self.mission.weather.clouds_thickness = random.randint(*WEATHER_CLOUD_THICKNESS)
# thunderstorm
self._generate_base_weather()
self._generate_wind(random.randint(8, 12))
wind_direction = random.randint(0, 360)
wind_speed = random.randint(0, 4)
self.mission.weather.wind_at_ground = Wind(wind_direction, wind_speed)
self.mission.weather.wind_at_2000 = Wind(wind_direction, wind_speed * 2)
self.mission.weather.wind_at_8000 = Wind(wind_direction, wind_speed * 3)
self.mission.weather.clouds_density = random.randint(9, 10)
self.mission.weather.clouds_iprecptns = Weather.Preceptions.Thunderstorm
elif weather_type == 2:
# rain
self._generate_base_weather()
self.mission.weather.clouds_density = random.randint(5, 8)
self.mission.weather.clouds_iprecptns = Weather.Preceptions.Rain
self._generate_wind(random.randint(4, 8))
elif weather_type == 3:
# clouds
self._generate_base_weather()
elif weather_type == 4:
# clear
pass
if self.mission.weather.clouds_density > 0:
# sometimes clouds are randomized way too low and need to be fixed

View File

@ -16,7 +16,17 @@ class ShipGenerator:
self.m = mission
self.conflict = conflict
def generate_carrier(self, type: ShipType, country: str, at: Point) -> ShipGroup:
def generate_carrier(self, for_units: db.UnitsDict, country: str, at: Point) -> ShipGroup:
type = db.find_unittype(Carriage, country)[0]
print(for_units)
for unit_type, unit_count in for_units.items():
if unit_count == 0:
continue
if unit_type in db.CARRIER_TYPE_BY_PLANE:
type = db.CARRIER_TYPE_BY_PLANE[unit_type]
break
group = self.m.ship_group(
country=self.m.country(country),
name=namegen.next_carrier_name(self.m.country(country)),

View File

@ -10,9 +10,9 @@ from dcs.task import *
from game import db
STRENGTH_AA_ASSEMBLE_MIN = 0.2
PLANES_SCRAMBLE_MIN_BASE = 4
PLANES_SCRAMBLE_MIN_BASE = 2
PLANES_SCRAMBLE_MAX_BASE = 8
PLANES_SCRAMBLE_FACTOR = 0.6
PLANES_SCRAMBLE_FACTOR = 0.3
BASE_MAX_STRENGTH = 1
BASE_MIN_STRENGTH = 0

View File

@ -72,8 +72,8 @@ class PersianGulfTheater(ConflictTheater):
self.add_controlpoint(self.havadarya, connected_to=[self.lar, self.qeshm, self.bandar_abbas])
self.add_controlpoint(self.bandar_abbas, connected_to=[self.havadarya])
self.add_controlpoint(self.east_carrier)
self.add_controlpoint(self.west_carrier)
self.add_controlpoint(self.east_carrier)
self.west_carrier.captured = True
self.east_carrier.captured = True

View File

@ -2,6 +2,7 @@ import math
import pickle
import random
import typing
import logging
from theater.base import *
from theater.conflicttheater import *
@ -72,8 +73,8 @@ def generate_groundobjects(theater: ConflictTheater):
group_id = 0
for cp in theater.enemy_points():
for _ in range(0, random.randrange(3, 6)):
available_categories = list(tpls) + ["aa", "aa", "aa"]
for _ in range(0, random.randrange(2, 4)):
available_categories = list(tpls) + ["aa", "aa"]
tpl_category = random.choice(available_categories)
tpl = random.choice(list(tpls[tpl_category].values()))
@ -84,14 +85,17 @@ def generate_groundobjects(theater: ConflictTheater):
print("Couldn't find point for {}".format(cp))
continue
dist = point.distance_to_point(cp.position)
"""
dist = point.distance_to_point(cp.position) - 15000
for another_cp in theater.enemy_points():
if another_cp.position.distance_to_point(point) < dist:
cp = another_cp
"""
group_id += 1
object_id = 0
logging.info("generated {} for {}".format(tpl_category, cp))
for object in tpl:
object_id += 1

View File

@ -79,10 +79,14 @@ class ConfigurationMenu(Menu):
Label(body, text="Takeoff only for player group", **STYLES["widget"]).grid(row=row, column=0, sticky=W)
Checkbutton(body, variable=self.takeoff_var, **STYLES["radiobutton"]).grid(row=row, column=1, sticky=E)
row += 1
Label(body, text="Only player group will start on the ground. AI units will be circling in the air until player takes off.", **STYLES["widget"]).grid(row=row, column=0, columnspan=2)
row += 1
Label(body, text="Disable night missions", **STYLES["widget"]).grid(row=row, column=0, sticky=W)
Checkbutton(body, variable=self.night_var, **STYLES["radiobutton"]).grid(row=row, column=1, sticky=E)
row += 1
Label(body, text="No night missions. Dawns and dusks will still be present.", **STYLES["widget"]).grid(row=row, column=0, columnspan=2)
row += 1
Button(body, text="Display logs", command=self.display_logs, **STYLES["btn-primary"]).grid(row=row, column=1, sticky=E, pady=30)
row += 1

View File

@ -98,9 +98,6 @@ class NewGameMenu(Menu):
Label(terrain, text="Persian Gulf", **STYLES["widget"]).grid(row=2, column=1, sticky=W)
self.create_label_image(terrain, "terrain_pg.gif").grid(row=2, column=2, padx=5)
Label(terrain, text="Currently strike missions are only\navailable for a number of airports only in Caucasus", **STYLES["widget"]) \
.grid(row=3, column=0, columnspan=3, sticky=W)
# Misc Options
options = LabelFrame(body, text="Misc Options", **STYLES["label-frame"])
options.grid(row=0, column=2, sticky=NE, padx=5)