mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
new ground objects format & parser; place dead objects instead of removing them completely
This commit is contained in:
parent
6fb342a42c
commit
03fc17fae6
@ -100,18 +100,13 @@ class Event:
|
|||||||
|
|
||||||
for object_identifier in debriefing.destroyed_objects:
|
for object_identifier in debriefing.destroyed_objects:
|
||||||
for cp in self.game.theater.controlpoints:
|
for cp in self.game.theater.controlpoints:
|
||||||
remove_ids = []
|
|
||||||
if not cp.ground_objects:
|
if not cp.ground_objects:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for i, ground_object in enumerate(cp.ground_objects):
|
for i, ground_object in enumerate(cp.ground_objects):
|
||||||
if ground_object.matches_string_identifier(object_identifier):
|
if ground_object.matches_string_identifier(object_identifier):
|
||||||
logging.info("cp {} removing ground object {}".format(cp, ground_object.string_identifier))
|
logging.info("cp {} killing ground object {}".format(cp, ground_object.string_identifier))
|
||||||
remove_ids.append(i)
|
ground_object.is_dead = True
|
||||||
|
|
||||||
remove_ids.reverse()
|
|
||||||
for i in remove_ids:
|
|
||||||
del cp.ground_objects[i]
|
|
||||||
|
|
||||||
def skip(self):
|
def skip(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -10,17 +10,6 @@ from dcs.statics import *
|
|||||||
FARP_FRONTLINE_DISTANCE = 10000
|
FARP_FRONTLINE_DISTANCE = 10000
|
||||||
|
|
||||||
|
|
||||||
CATEGORY_MAPPING = {
|
|
||||||
"power": [Fortification.Workshop_A],
|
|
||||||
"warehouse": [Warehouse.Warehouse],
|
|
||||||
"fuel": [Warehouse.Tank],
|
|
||||||
"ammo": [Warehouse.Ammunition_depot],
|
|
||||||
"farp": [Fortification.FARP_Tent],
|
|
||||||
"comms": [Fortification.TV_tower],
|
|
||||||
"oil": [Fortification.Oil_platform],
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class GroundObjectsGenerator:
|
class GroundObjectsGenerator:
|
||||||
FARP_CAPACITY = 4
|
FARP_CAPACITY = 4
|
||||||
|
|
||||||
@ -53,7 +42,10 @@ class GroundObjectsGenerator:
|
|||||||
cp = self.conflict.from_cp
|
cp = self.conflict.from_cp
|
||||||
|
|
||||||
for ground_object in cp.ground_objects:
|
for ground_object in cp.ground_objects:
|
||||||
if ground_object.category == "defense":
|
if ground_object.dcs_identifier == "AA":
|
||||||
|
if ground_object.is_dead:
|
||||||
|
continue
|
||||||
|
|
||||||
unit_type = random.choice(self.game.commision_unit_types(cp, AirDefence))
|
unit_type = random.choice(self.game.commision_unit_types(cp, AirDefence))
|
||||||
assert unit_type is not None, "Cannot find unit type for GroundObject defense ({})!".format(cp)
|
assert unit_type is not None, "Cannot find unit type for GroundObject defense ({})!".format(cp)
|
||||||
|
|
||||||
@ -62,17 +54,23 @@ class GroundObjectsGenerator:
|
|||||||
name=ground_object.string_identifier,
|
name=ground_object.string_identifier,
|
||||||
_type=unit_type,
|
_type=unit_type,
|
||||||
position=ground_object.position,
|
position=ground_object.position,
|
||||||
heading=ground_object.heading
|
heading=ground_object.heading,
|
||||||
)
|
)
|
||||||
|
|
||||||
logging.info("generated defense object identifier {} with mission id {}".format(group.name, group.id))
|
logging.info("generated defense object identifier {} with mission id {}".format(group.name, group.id))
|
||||||
else:
|
else:
|
||||||
|
if ground_object.dcs_identifier in warehouse_map:
|
||||||
|
static_type = warehouse_map[ground_object.dcs_identifier]
|
||||||
|
else:
|
||||||
|
static_type = fortification_map[ground_object.dcs_identifier]
|
||||||
|
|
||||||
group = self.m.static_group(
|
group = self.m.static_group(
|
||||||
country=side,
|
country=side,
|
||||||
name=ground_object.string_identifier,
|
name=ground_object.string_identifier,
|
||||||
_type=random.choice(CATEGORY_MAPPING[ground_object.category]),
|
_type=static_type,
|
||||||
position=ground_object.position,
|
position=ground_object.position,
|
||||||
heading=ground_object.heading
|
heading=ground_object.heading,
|
||||||
|
dead=ground_object.is_dead,
|
||||||
)
|
)
|
||||||
|
|
||||||
logging.info("generated object identifier {} with mission id {}".format(group.name, group.id))
|
logging.info("generated object identifier {} with mission id {}".format(group.name, group.id))
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -1,86 +1,87 @@
|
|||||||
import pickle
|
import pickle
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
from game import db
|
|
||||||
from gen.groundobjectsgen import TheaterGroundObject
|
|
||||||
from dcs.mission import Mission
|
from dcs.mission import Mission
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
|
from dcs.unitgroup import VehicleGroup, StaticGroup
|
||||||
|
from dcs.unit import *
|
||||||
|
from dcs.statics import warehouse_map, fortification_map
|
||||||
|
|
||||||
|
from game import db
|
||||||
|
from gen.groundobjectsgen import TheaterGroundObject
|
||||||
|
|
||||||
m = Mission()
|
m = Mission()
|
||||||
m.load_file("./cau_groundobjects.miz")
|
m.load_file("./cau_groundobjects.miz")
|
||||||
|
|
||||||
result = {}
|
|
||||||
result_by_groups = {} # type: typing.Dict[int, TheaterGroundObject]
|
def parse_name(name: str) -> int:
|
||||||
cp_counters = {}
|
first_part = name.split()[0].split("|")
|
||||||
ids_counters = {}
|
return int(first_part[0]) if len(first_part) == 1 else int(first_part[1])
|
||||||
group_id_counter = 0
|
|
||||||
previous_group_id = None
|
|
||||||
|
|
||||||
|
|
||||||
def append_group(cp_id, category, group_id, object_id, position, heading):
|
if __name__ == "__main__":
|
||||||
global result
|
theater_objects = []
|
||||||
global result_by_groups
|
|
||||||
|
|
||||||
ground_object = TheaterGroundObject(category, cp_id, group_id, object_id, position, heading)
|
for group in m.country("Russia").static_group + m.country("Russia").vehicle_group:
|
||||||
|
for unit in group.units:
|
||||||
|
theater_object = TheaterGroundObject()
|
||||||
|
theater_object.object_id = len(theater_objects) + 1
|
||||||
|
|
||||||
if cp_id not in result:
|
try:
|
||||||
result[cp_id] = []
|
theater_object.cp_id = parse_name(str(unit.name))
|
||||||
result[cp_id].append(ground_object)
|
except Exception as e:
|
||||||
|
theater_object.cp_id = parse_name(str(group.name))
|
||||||
|
|
||||||
result_by_groups_key = "{}_{}_{}".format(cp_id, category, group_id)
|
theater_object.position = unit.position
|
||||||
if result_by_groups_key not in result_by_groups:
|
theater_object.heading = unit.heading
|
||||||
result_by_groups[result_by_groups_key] = []
|
|
||||||
result_by_groups[result_by_groups_key].append(ground_object)
|
|
||||||
|
|
||||||
|
if isinstance(unit, Vehicle):
|
||||||
|
theater_object.dcs_identifier = "AA"
|
||||||
|
else:
|
||||||
|
theater_object.dcs_identifier = unit.type
|
||||||
|
|
||||||
def parse_name(name: str) -> typing.Tuple:
|
airport_distance = m.terrain.airport_by_id(theater_object.cp_id).position.distance_to_point(theater_object.position)
|
||||||
args = str(name.split()[0]).split("|")
|
if airport_distance > 150000:
|
||||||
|
print("Object {} {} is placed {}m from airport {}!".format(theater_object.dcs_identifier,
|
||||||
|
group.name,
|
||||||
|
airport_distance,
|
||||||
|
m.terrain.airport_by_id(theater_object.cp_id)))
|
||||||
|
|
||||||
if len(args) == 2:
|
assert theater_object.dcs_identifier
|
||||||
global group_id_counter
|
assert theater_object.cp_id
|
||||||
group_id_counter += 1
|
assert theater_object.object_id
|
||||||
args.append(str(group_id_counter))
|
|
||||||
else:
|
|
||||||
global previous_group_id
|
|
||||||
if previous_group_id != args[2]:
|
|
||||||
group_id_counter += 1
|
|
||||||
previous_group_id = args[2]
|
|
||||||
|
|
||||||
return args[0], int(args[1]), int(args[2])
|
theater_objects.append(theater_object)
|
||||||
|
|
||||||
|
group_ids = 1
|
||||||
|
for object_a in theater_objects:
|
||||||
|
for object_b in theater_objects:
|
||||||
|
if object_a.position.distance_to_point(object_b.position) < 2000:
|
||||||
|
if object_a.group_id and object_b.group_id:
|
||||||
|
continue
|
||||||
|
elif object_a.group_id:
|
||||||
|
object_b.group_id = object_a.group_id
|
||||||
|
elif object_b.group_id:
|
||||||
|
object_a.group_id = object_b.group_id
|
||||||
|
else:
|
||||||
|
object_a.group_id = group_ids
|
||||||
|
object_b.group_id = group_ids
|
||||||
|
group_ids += 1
|
||||||
|
|
||||||
for group in m.country("Russia").static_group + m.country("Russia").vehicle_group:
|
assert object_a.cp_id == object_b.cp_id, "Object {} and {} are placed in group with different airports!".format(object_a.string_identifier, object_b.string_identifier)
|
||||||
try:
|
|
||||||
category, cp_id, group_id = parse_name(str(group.name))
|
|
||||||
except:
|
|
||||||
print("Failed to parse {}".format(group.name))
|
|
||||||
continue
|
|
||||||
|
|
||||||
ids_counters_key = "{}_{}".format(cp_id, group_id)
|
for a in theater_objects:
|
||||||
ids_counters[ids_counters_key] = ids_counters.get(ids_counters_key, 0) + 1
|
if not a.group_id:
|
||||||
object_id = ids_counters[ids_counters_key]
|
a.group_id = group_ids
|
||||||
cp_counters[cp_id] = cp_counters.get(cp_id, 0) + 1
|
group_ids += 1
|
||||||
|
|
||||||
append_group(cp_id, category, group_id, object_id, group.position, group.units[0].heading)
|
print("Total {} objects".format(len(theater_objects)))
|
||||||
|
with open("../cau_groundobjects.p", "wb") as f:
|
||||||
|
result = {}
|
||||||
|
for theater_object in theater_objects:
|
||||||
|
if theater_object.cp_id not in result:
|
||||||
|
result[theater_object.cp_id] = []
|
||||||
|
result[theater_object.cp_id].append(theater_object)
|
||||||
|
|
||||||
GROUP_TRESHOLD = 2000
|
pickle.dump(result, f)
|
||||||
did_check_pairs = []
|
|
||||||
for group_id, objects_in_group in result_by_groups.items():
|
|
||||||
for a in objects_in_group:
|
|
||||||
for b in objects_in_group:
|
|
||||||
if (a, b) in did_check_pairs:
|
|
||||||
continue
|
|
||||||
|
|
||||||
did_check_pairs.append((a, b))
|
|
||||||
distance = a.position.distance_to_point(b.position)
|
|
||||||
if distance > GROUP_TRESHOLD:
|
|
||||||
print("Objects {} and {} in group {} are too far apart ({})!".format(a.string_identifier, b.string_identifier, group_id, distance))
|
|
||||||
|
|
||||||
print("Total {} objects".format(sum([len(x) for x in result.values()])))
|
|
||||||
for cp_id, count in cp_counters.items():
|
|
||||||
print("{} - {} objects".format(cp_id, count))
|
|
||||||
|
|
||||||
|
|
||||||
with open("../cau_groundobjects.p", "wb") as f:
|
|
||||||
pickle.dump(result, f)
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ NAME_BY_CATEGORY = {
|
|||||||
"power": "Power plant",
|
"power": "Power plant",
|
||||||
"ammo": "Ammo depot",
|
"ammo": "Ammo depot",
|
||||||
"fuel": "Fuel depot",
|
"fuel": "Fuel depot",
|
||||||
"defense": "AA Defense Site",
|
"aa": "AA Defense Site",
|
||||||
"warehouse": "Warehouse",
|
"warehouse": "Warehouse",
|
||||||
"farp": "FARP",
|
"farp": "FARP",
|
||||||
"comms": "Comms. tower",
|
"comms": "Comms. tower",
|
||||||
@ -17,7 +17,7 @@ ABBREV_NAME = {
|
|||||||
"power": "PLANT",
|
"power": "PLANT",
|
||||||
"ammo": "AMMO",
|
"ammo": "AMMO",
|
||||||
"fuel": "FUEL",
|
"fuel": "FUEL",
|
||||||
"defense": "AA",
|
"aa": "AA",
|
||||||
"warehouse": "WARE",
|
"warehouse": "WARE",
|
||||||
"farp": "FARP",
|
"farp": "FARP",
|
||||||
"comms": "COMMST",
|
"comms": "COMMST",
|
||||||
@ -25,21 +25,35 @@ ABBREV_NAME = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CATEGORY_MAP = {
|
||||||
|
"aa": ["AA"],
|
||||||
|
"power": ["Workshop A"],
|
||||||
|
"warehouse": ["Warehouse"],
|
||||||
|
"fuel": ["Tank"],
|
||||||
|
"ammo": [".Ammunition depot"],
|
||||||
|
"farp": ["FARP Tent"],
|
||||||
|
"comms": ["TV tower", "Comms tower"],
|
||||||
|
"oil": ["Oil platform"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TheaterGroundObject:
|
class TheaterGroundObject:
|
||||||
object_id = 0
|
|
||||||
cp_id = 0
|
cp_id = 0
|
||||||
group_id = 0
|
group_id = 0
|
||||||
|
object_id = 0
|
||||||
|
|
||||||
|
dcs_identifier = None # type: str
|
||||||
|
is_dead = False
|
||||||
|
|
||||||
heading = 0
|
heading = 0
|
||||||
position = None # type: Point
|
position = None # type: Point
|
||||||
category = None # type: str
|
|
||||||
|
|
||||||
def __init__(self, category, cp_id, group_id, object_id, position, heading):
|
@property
|
||||||
self.category = category
|
def category(self) -> str:
|
||||||
self.cp_id = cp_id
|
for k, v in CATEGORY_MAP.items():
|
||||||
self.group_id = group_id
|
if self.dcs_identifier in v:
|
||||||
self.object_id = object_id
|
return k
|
||||||
self.position = position
|
assert False, "Identifier not found in mapping: {}".format(self.dcs_identifier)
|
||||||
self.heading = heading
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def string_identifier(self):
|
def string_identifier(self):
|
||||||
|
|||||||
@ -17,6 +17,7 @@ from dcs.unit import UnitType
|
|||||||
from game import db
|
from game import db
|
||||||
|
|
||||||
from .persistency import base_path
|
from .persistency import base_path
|
||||||
|
from theater.theatergroundobject import CATEGORY_MAP
|
||||||
|
|
||||||
DEBRIEFING_LOG_EXTENSION = "log"
|
DEBRIEFING_LOG_EXTENSION = "log"
|
||||||
|
|
||||||
@ -123,10 +124,9 @@ class Debriefing:
|
|||||||
for event in events.values():
|
for event in events.values():
|
||||||
event_type = event.get("type", None)
|
event_type = event.get("type", None)
|
||||||
if event_type in ["crash", "dead"]:
|
if event_type in ["crash", "dead"]:
|
||||||
object_initiator = event["initiator"] in ["SKLAD_CRUSH", "SKLADCDESTR", "TEC_A_CRUSH", "BAK_CRUSH"]
|
initiator_components = event["initiator"].split("|")
|
||||||
defense_initiator = event["initiator"].startswith("defense|")
|
|
||||||
|
|
||||||
if object_initiator or defense_initiator:
|
if initiator_components[0] in CATEGORY_MAP:
|
||||||
parse_dead_object(event)
|
parse_dead_object(event)
|
||||||
else:
|
else:
|
||||||
parse_dead_unit(event)
|
parse_dead_unit(event)
|
||||||
@ -138,7 +138,6 @@ class Debriefing:
|
|||||||
result = {}
|
result = {}
|
||||||
for group in groups:
|
for group in groups:
|
||||||
for unit in group.units:
|
for unit in group.units:
|
||||||
unit_type = None
|
|
||||||
if isinstance(unit, Vehicle):
|
if isinstance(unit, Vehicle):
|
||||||
unit_type = vehicle_map[unit.type]
|
unit_type = vehicle_map[unit.type]
|
||||||
elif isinstance(unit, Ship):
|
elif isinstance(unit, Ship):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user