fixed a number of issues: user directory on different drive, carrier ops, multiplayer debriefing parser, multiplayer mission generation; added su25

This commit is contained in:
Vasyl Horbachenko 2018-07-05 02:42:46 +03:00
parent fa55ae1fcc
commit 32fb5ad0e2
8 changed files with 130 additions and 28 deletions

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import os import os
import sys
import dcs import dcs
import theater.caucasus import theater.caucasus
@ -15,6 +16,47 @@ from game.game import Game
from theater import start_generator from theater import start_generator
from userdata import persistency from userdata import persistency
"""
from dcs.lua.parse import *
a = loads(open("build/mission", "r").read())
b = loads(open("build/mission_workin.lua", "r").read())
def get(a, k):
b = a
for x in k.strip().split(" "):
if isinstance(a, dict):
y = a
a = a.get(x, None)
if a is None:
try:
a = y.get(int(x), None)
except:
pass
else:
break
if a is None:
pass
return a
def cycle(kk, ref, v):
if isinstance(v, dict):
for k, v in v.items():
cycle(kk + " " + str(k), ref, v)
elif isinstance(v, list):
for i, v in enumerate(v):
cycle(kk + " " + str(i), ref, v)
else:
if get(ref, kk) != v:
print(kk, v)
print(get(ref, kk))
cycle("", a, b)
sys.exit(0)
"""
persistency.setup(sys.argv[1])
dcs.planes.FlyingType.payload_dirs.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads")) dcs.planes.FlyingType.payload_dirs.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources\\payloads"))

View File

@ -54,6 +54,7 @@ PRICES = {
F_15C: 24, F_15C: 24,
# bomber # bomber
Su_25: 15,
Su_25T: 13, Su_25T: 13,
L_39ZA: 10, L_39ZA: 10,
Su_34: 18, Su_34: 18,
@ -150,6 +151,7 @@ UNIT_BY_TASK = {
AV8BNA, AV8BNA,
A_10A, A_10A,
A_10C, A_10C,
Su_25,
Su_25T, Su_25T,
Su_34, Su_34,
Ka_50, Ka_50,
@ -235,6 +237,7 @@ UNIT_BY_COUNTRY = {
C_101CC, C_101CC,
AJS37, AJS37,
F_5E_3, F_5E_3,
Su_25,
Su_27, Su_27,
Su_33, Su_33,
MiG_15bis, MiG_15bis,
@ -279,7 +282,6 @@ UNIT_BY_COUNTRY = {
F_15C, F_15C,
FA_18C_hornet, FA_18C_hornet,
AJS37, AJS37,
F_5E_3,
M_2000C, M_2000C,
MiG_21Bis, MiG_21Bis,
MiG_15bis, MiG_15bis,
@ -361,7 +363,7 @@ PLANE_PAYLOAD_OVERRIDES = {
Aircraft livery overrides. Syntax as follows: Aircraft livery overrides. Syntax as follows:
`Identifier`: "LiveryName", `Identifier`: "LiveryName",
`Identifier` is aircraft identifier (as used troughout the file) and "LiveryName" (with double quotes) `Identifier` is aircraft identifier (as used troughout the file) and "LiveryName" (with double quotes)
is livery name as found in mission editor. is livery name as found in mission editor.
""" """

View File

@ -26,7 +26,7 @@ class GroundInterceptEvent(Event):
return super(GroundInterceptEvent, self).threat_description return super(GroundInterceptEvent, self).threat_description
def __str__(self): def __str__(self):
return "Fontline CAS from {} at {}".format(self.from_cp, self.to_cp) return "Frontline CAS from {} at {}".format(self.from_cp, self.to_cp)
def is_successfull(self, debriefing: Debriefing): def is_successfull(self, debriefing: Debriefing):
total_targets = sum(self.targets.values()) total_targets = sum(self.targets.values())

View File

@ -1,4 +1,5 @@
from dcs.terrain import Terrain from dcs.terrain import Terrain
from dcs.lua.parse import loads
from userdata.debriefing import * from userdata.debriefing import *
@ -61,7 +62,11 @@ class Operation:
self.extra_aagen = ExtraAAConflictGenerator(mission, conflict, self.game, player_name, enemy_name) self.extra_aagen = ExtraAAConflictGenerator(mission, conflict, self.game, player_name, enemy_name)
def prepare(self, terrain: Terrain, is_quick: bool): def prepare(self, terrain: Terrain, is_quick: bool):
with open("resources/default_options.lua", "r") as f:
options_dict = loads(f.read())["options"]
self.mission = dcs.Mission(terrain) self.mission = dcs.Mission(terrain)
self.mission.options.load_from_dict(options_dict)
self.is_quick = is_quick self.is_quick = is_quick
if is_quick: if is_quick:

View File

@ -164,6 +164,16 @@ class AircraftConflictGenerator:
else: else:
assert False assert False
def _rtb_for(self, group: FlyingGroup, cp: ControlPoint, at: db.StartingPosition = None):
group.add_waypoint(cp.position, RTB_ALTITUDE)
if isinstance(cp.at, Point):
pass
elif isinstance(cp.at, ShipGroup):
pass
elif issubclass(cp.at, Airport):
group.land_at(cp.at)
def _at_position(self, at) -> Point: def _at_position(self, at) -> Point:
if isinstance(at, Point): if isinstance(at, Point):
return at return at
@ -226,9 +236,7 @@ class AircraftConflictGenerator:
group.task = CAS.name group.task = CAS.name
self._setup_group(group, CAS, client_count) self._setup_group(group, CAS, client_count)
self.escort_targets.append((group, group.points.index(waypoint))) self.escort_targets.append((group, group.points.index(waypoint)))
self._rtb_for(group, self.conflict.from_cp, at)
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.from_cp.at)
def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, target_groups: typing.Collection[ShipGroup], at: db.StartingPosition = None): def generate_ship_strikegroup(self, attackers: db.PlaneDict, clients: db.PlaneDict, target_groups: typing.Collection[ShipGroup], at: db.StartingPosition = None):
assert len(self.escort_targets) == 0 assert len(self.escort_targets) == 0
@ -249,9 +257,7 @@ class AircraftConflictGenerator:
group.task = AntishipStrike.name group.task = AntishipStrike.name
self._setup_group(group, AntishipStrike, client_count) self._setup_group(group, AntishipStrike, client_count)
self.escort_targets.append((group, group.points.index(wayp))) self.escort_targets.append((group, group.points.index(wayp)))
self._rtb_for(group, self.conflict.from_cp, at)
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.from_cp.at)
def generate_strikegroup_escort(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None): def generate_strikegroup_escort(self, attackers: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for g in self._generate_escort( for g in self._generate_escort(
@ -261,8 +267,7 @@ class AircraftConflictGenerator:
at=at and at or self._group_point(self.conflict.air_attackers_location), at=at and at or self._group_point(self.conflict.air_attackers_location),
is_quick=at is None, is_quick=at is None,
should_orbit=True): should_orbit=True):
g.add_waypoint(self.conflict.position, WARM_START_ALTITUDE) self._rtb_for(g, self.conflict.from_cp, at)
g.land_at(self.conflict.from_cp.at)
def generate_transport_escort(self, escort: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None): def generate_transport_escort(self, escort: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for g in self._generate_escort( for g in self._generate_escort(
@ -272,8 +277,7 @@ class AircraftConflictGenerator:
at=at and at or self._group_point(self.conflict.air_defenders_location), at=at and at or self._group_point(self.conflict.air_defenders_location),
is_quick=at is None, is_quick=at is None,
should_orbit=False): should_orbit=False):
g.add_waypoint(self.conflict.to_cp.position, RTB_ALTITUDE) self._rtb_for(g, self.conflict.to_cp, at)
g.land_at(self.conflict.to_cp.at)
def generate_defense(self, defenders: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None): def generate_defense(self, defenders: db.PlaneDict, clients: db.PlaneDict, at: db.StartingPosition = None):
for flying_type, count, client_count in self._split_to_groups(defenders, clients): for flying_type, count, client_count in self._split_to_groups(defenders, clients):
@ -290,9 +294,7 @@ class AircraftConflictGenerator:
wayp.tasks.append(dcs.task.EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE)) wayp.tasks.append(dcs.task.EngageTargets(max_distance=DEFENCE_ENGAGEMENT_MAX_DISTANCE))
wayp.tasks.append(dcs.task.OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle)) wayp.tasks.append(dcs.task.OrbitAction(ATTACK_CIRCLE_ALT, pattern=OrbitAction.OrbitPattern.Circle))
self._setup_group(group, CAP, client_count) self._setup_group(group, CAP, client_count)
self._rtb_for(group, self.conflict.to_cp, at)
group.add_waypoint(self.conflict.to_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.to_cp.at)
def generate_transport(self, transport: db.PlaneDict, destination: Airport): def generate_transport(self, transport: db.PlaneDict, destination: Airport):
assert len(self.escort_targets) == 0 assert len(self.escort_targets) == 0
@ -331,9 +333,7 @@ class AircraftConflictGenerator:
wayp = group.add_waypoint(self.conflict.position, WARM_START_ALTITUDE, INTERCEPTION_AIRSPEED) wayp = group.add_waypoint(self.conflict.position, WARM_START_ALTITUDE, INTERCEPTION_AIRSPEED)
wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE)) wayp.tasks.append(EngageTargets(max_distance=INTERCEPT_MAX_DISTANCE))
self._setup_group(group, CAP, client_count) self._setup_group(group, CAP, client_count)
self._rtb_for(group, self.conflict.from_cp, at)
group.add_waypoint(self.conflict.from_cp.position, RTB_ALTITUDE)
group.land_at(self.conflict.from_cp.at)
def generate_passenger_transport(self, helis: db.HeliDict, clients: db.HeliDict, at: db.StartingPosition): def generate_passenger_transport(self, helis: db.HeliDict, clients: db.HeliDict, at: db.StartingPosition):
for heli_type, count, client_count in self._split_to_groups(helis, clients): for heli_type, count, client_count in self._split_to_groups(helis, clients):

View File

@ -1 +1 @@
py.exe __init__.py > logs.txt 2>&1 py.exe __init__.py %UserProfile% > logs.txt 2>&1

View File

@ -1,4 +1,5 @@
import typing import typing
import re
import threading import threading
import time import time
import os import os
@ -14,7 +15,7 @@ from dcs.unit import UnitType
from game import db from game import db
from .persistency import _base_path from .persistency import base_path
DEBRIEFING_LOG_EXTENSION = "log" DEBRIEFING_LOG_EXTENSION = "log"
@ -24,11 +25,53 @@ class Debriefing:
self.destroyed_units = {} # type: typing.Dict[str, typing.Dict[UnitType, int]] self.destroyed_units = {} # type: typing.Dict[str, typing.Dict[UnitType, int]]
self.alive_units = alive_units # type: typing.Dict[str, typing.Dict[UnitType, int]] self.alive_units = alive_units # type: typing.Dict[str, typing.Dict[UnitType, int]]
@classmethod
def parse_mp_debrief(cls, string: str):
# TODO: actually write a parser
result = {}
append = False
country = None
unit_type = None
for line in string.split("\n"):
line = line.strip()
if not append:
if line == "world_state =":
append = True
continue
if append:
if line.startswith("country"):
country = re.findall(r"country\s*=\s*(\d+),", line)[0]
if line.startswith("type"):
unit_type = re.findall(r"type\s*=\s*\"(.*?)\",", line)[0]
if country and unit_type:
result[len(result)+1] = {
"country": int(country),
"type": unit_type,
}
country = unit_type = None
if line.strip() == "} -- end of world_state":
break
return {
"debriefing": {
"world_state": result,
},
}
@classmethod @classmethod
def parse(cls, path: str): def parse(cls, path: str):
with open(path, "r") as f: with open(path, "r") as f:
table_string = f.read() table_string = f.read()
table = parse.loads(table_string) try:
table = parse.loads(table_string)
except:
table = cls.parse_mp_debrief(table_string)
units = table.get("debriefing", {}).get("world_state", {}) units = table.get("debriefing", {}).get("world_state", {})
alive_units = {} alive_units = {}
@ -94,7 +137,7 @@ class Debriefing:
def debriefing_directory_location() -> str: def debriefing_directory_location() -> str:
return os.path.join(_base_path(), "liberation_debriefings") return os.path.join(base_path(), "liberation_debriefings")
def _logfiles_snapshot() -> typing.Dict[str, float]: def _logfiles_snapshot() -> typing.Dict[str, float]:

View File

@ -3,9 +3,19 @@ import pickle
import os import os
import shutil import shutil
_user_folder = None # type: str
def _base_path() -> str:
openbeta_path = os.path.expanduser("~\Saved Games\DCS.openbeta") def setup(user_folder: str):
global _user_folder
_user_folder = user_folder
def base_path() -> str:
global _user_folder
assert _user_folder
openbeta_path = os.path.join(_user_folder, "Saved Games\DCS.openbeta")
if os.path.exists(openbeta_path): if os.path.exists(openbeta_path):
return openbeta_path return openbeta_path
else: else:
@ -13,11 +23,11 @@ def _base_path() -> str:
def _save_file() -> str: def _save_file() -> str:
return os.path.join(_base_path(), "liberation_save") return os.path.join(base_path(), "liberation_save")
def _temporary_save_file() -> str: def _temporary_save_file() -> str:
return os.path.join(_base_path(), "liberation_save_tmp") return os.path.join(base_path(), "liberation_save_tmp")
def _save_file_exists() -> bool: def _save_file_exists() -> bool:
@ -25,7 +35,7 @@ def _save_file_exists() -> bool:
def mission_path_for(name: str) -> str: def mission_path_for(name: str) -> str:
return os.path.join(_base_path(), "Missions\{}".format(name)) return os.path.join(base_path(), "Missions\{}".format(name))
def restore_game(): def restore_game():