diff --git a/game/event/event.py b/game/event/event.py index c5bb75b8..db39a61a 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -50,11 +50,15 @@ class Event: def threat_description(self) -> str: return "" - def flight_name(self, for_task: typing.Type[Task]) -> str: + def flight_name(self, for_task: typing.Type[typing.Type[Task]]) -> str: return "Flight" @property - def tasks(self) -> typing.Collection[Task]: + def tasks(self) -> typing.Collection[typing.Type[Task]]: + return [] + + @property + def ai_banned_tasks(self) -> typing.Collection[typing.Type[Task]]: return [] def bonus(self) -> int: diff --git a/game/event/strike.py b/game/event/strike.py index 9c65353d..50a50152 100644 --- a/game/event/strike.py +++ b/game/event/strike.py @@ -29,6 +29,10 @@ class StrikeEvent(Event): else: return [CAP] + @property + def ai_banned_tasks(self): + return [CAS] + def flight_name(self, for_task: typing.Type[Task]) -> str: if for_task == CAP: if self.is_player_attacking: diff --git a/gen/briefinggen.py b/gen/briefinggen.py index 851fe3fd..468d0d8e 100644 --- a/gen/briefinggen.py +++ b/gen/briefinggen.py @@ -37,12 +37,12 @@ class BriefingGenerator: description += "\n\n" + self.description if self.freqs: - description += "\n\n RADIO:" + description += "\n\nCOMMS:" for name, freq in self.freqs: description += "\n{}: {}".format(name, freq) if self.targets: - description += "\n\n TARGETS:" + description += "\n\nTARGETS:" for name, tp in self.targets: description += "\n{} {}".format(name, "(TP {})".format(tp) if tp else "") diff --git a/gen/environmentgen.py b/gen/environmentgen.py index 6f1a3cdd..4c3db832 100644 --- a/gen/environmentgen.py +++ b/gen/environmentgen.py @@ -49,7 +49,7 @@ class EnviromentGenerator: self.game = game def _gen_random_time(self): - start_time = datetime.combine(datetime.today(), time()) + start_time = datetime.fromtimestamp(1527206400) time_range = None for k, v in RANDOM_TIME.items(): if self.game.settings.night_disabled and k == "night": diff --git a/gen/groundobjectsgen.py b/gen/groundobjectsgen.py index ccbd4220..558c4c31 100644 --- a/gen/groundobjectsgen.py +++ b/gen/groundobjectsgen.py @@ -14,6 +14,8 @@ CATEGORY_MAPPING = { "fuel": [Warehouse.Tank], "ammo": [Warehouse.Ammunition_depot], "farp": [Fortification.FARP_Tent], + "comms": [Fortification.TV_tower], + "oil": [Fortification.Oil_platform], } diff --git a/resources/cau_groundobjects.p b/resources/cau_groundobjects.p index 1cf0d8a6..54012b23 100644 Binary files a/resources/cau_groundobjects.p and b/resources/cau_groundobjects.p differ diff --git a/resources/tools/cau_groundobjects.miz b/resources/tools/cau_groundobjects.miz index 6f1976f4..87eef17a 100644 Binary files a/resources/tools/cau_groundobjects.miz and b/resources/tools/cau_groundobjects.miz differ diff --git a/resources/tools/generate_groundobjectsmap.py b/resources/tools/generate_groundobjectsmap.py index 256b6f1f..6dc50b8e 100644 --- a/resources/tools/generate_groundobjectsmap.py +++ b/resources/tools/generate_groundobjectsmap.py @@ -11,7 +11,10 @@ m.load_file("./cau_groundobjects.miz") result = {} result_by_groups = {} # type: typing.Dict[int, TheaterGroundObject] +cp_counters = {} ids_counters = {} +group_id_counter = 0 +previous_group_id = None def append_group(cp_id, category, group_id, object_id, position, heading): @@ -33,6 +36,16 @@ def append_group(cp_id, category, group_id, object_id, position, heading): def parse_name(name: str) -> typing.Tuple: args = str(name.split()[0]).split("|") + if len(args) == 2: + global group_id_counter + group_id_counter += 1 + 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]) @@ -46,9 +59,11 @@ for group in m.country("Russia").static_group + m.country("Russia").vehicle_grou ids_counters_key = "{}_{}".format(cp_id, group_id) ids_counters[ids_counters_key] = ids_counters.get(ids_counters_key, 0) + 1 object_id = ids_counters[ids_counters_key] + cp_counters[cp_id] = cp_counters.get(cp_id, 0) + 1 + append_group(cp_id, category, group_id, object_id, group.position, group.units[0].heading) -GROUP_TRESHOLD = 300 +GROUP_TRESHOLD = 2000 did_check_pairs = [] for group_id, objects_in_group in result_by_groups.items(): for a in objects_in_group: @@ -62,6 +77,8 @@ for group_id, objects_in_group in result_by_groups.items(): 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: diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py index 1dc30230..3e091fa2 100644 --- a/theater/theatergroundobject.py +++ b/theater/theatergroundobject.py @@ -9,6 +9,8 @@ NAME_BY_CATEGORY = { "defense": "AA Defense Site", "warehouse": "Warehouse", "farp": "FARP", + "comms": "Comms. tower", + "oil": "Oil platform" } ABBREV_NAME = { @@ -18,6 +20,8 @@ ABBREV_NAME = { "defense": "AA", "warehouse": "WARE", "farp": "FARP", + "comms": "COMMST", + "oil": "OILP" } diff --git a/ui/eventmenu.py b/ui/eventmenu.py index a7893cd9..d8d4b027 100644 --- a/ui/eventmenu.py +++ b/ui/eventmenu.py @@ -38,10 +38,10 @@ class EventMenu(Menu): Label(head, text=text, **STYLES[style]).grid() row += 1 - def label(text, _row=None, _column=None, sticky=None): + def label(text, _row=None, _column=None, columnspan=None, sticky=None): nonlocal row new_label = Label(self.frame, text=text, **STYLES["widget"]) - new_label.grid(row=_row and _row or row, column=_column and _column or 0, sticky=sticky) + new_label.grid(row=_row and _row or row, column=_column and _column or 0, columnspan=columnspan, sticky=sticky) if _row is None: row += 1 @@ -105,7 +105,7 @@ class EventMenu(Menu): row += 1 header("Ready?") - self.error_label = label("") + self.error_label = label("", columnspan=4) self.error_label["fg"] = RED Button(self.frame, text="Commit", command=self.start, **STYLES["btn-primary"]).grid(column=0, row=row, sticky=E, padx=5, pady=(10,10)) Button(self.frame, text="Back", command=self.dismiss, **STYLES["btn-warning"]).grid(column=3, row=row, sticky=E, padx=5, pady=(10,10)) @@ -141,15 +141,18 @@ class EventMenu(Menu): self.event.is_awacs_enabled = False flights = {k: {} for k in self.event.tasks} # type: ScrambledFlightsDict - total_counts_scrambled = {} # type: typing.Dict[typing.Type[UnitType], int] + units_scramble_counts = {} # type: typing.Dict[typing.Type[UnitType], int] + tasks_scramble_counts = {} # type: typing.Dict[typing.Type[Task], int] + tasks_clients_counts = {} # type: typing.Dict[typing.Type[Task], int] - def dampen_count(unit_type: typing.Type[UnitType], count: int) -> int: - nonlocal total_counts_scrambled + def dampen_count(for_task: typing.Type[Task], unit_type: typing.Type[UnitType], count: int) -> int: + nonlocal units_scramble_counts total_count = self.base.total_units_of_type(unit_type) - total_scrambled = total_counts_scrambled.get(unit_type, 0) + total_scrambled = units_scramble_counts.get(unit_type, 0) dampened_value = count if count + total_scrambled < total_count else total_count - total_scrambled - total_counts_scrambled[unit_type] = total_counts_scrambled.get(unit_type, 0) + dampened_value + units_scramble_counts[unit_type] = units_scramble_counts.get(unit_type, 0) + dampened_value + return dampened_value for task_type, dict in self.scramble_entries.items(): @@ -164,8 +167,16 @@ class EventMenu(Menu): except: clients_count = 0 - flights[task_type][unit_type] = dampen_count(unit_type, count), clients_count + dampened_count = dampen_count(task_type, unit_type, count) + tasks_clients_counts[task_type] = tasks_clients_counts.get(task_type, 0) + clients_count + tasks_scramble_counts[task_type] = tasks_scramble_counts.get(task_type, 0) + dampened_count + flights[task_type][unit_type] = dampened_count, clients_count + + for task in self.event.ai_banned_tasks: + if tasks_clients_counts.get(task, 0) == 0 and tasks_scramble_counts.get(task, 0) > 0: + self.error_label["text"] = "Need at least one player in flight {}".format(self.event.flight_name(task)) + return if self.game.is_player_attack(self.event): self.event.player_attacking(flights) diff --git a/ui/eventresultsmenu.py b/ui/eventresultsmenu.py index b611b594..5f4e3ec9 100644 --- a/ui/eventresultsmenu.py +++ b/ui/eventresultsmenu.py @@ -78,6 +78,7 @@ class EventResultsMenu(Menu): header("Operation failed", "title-red") header("Player losses") + for unit_type, count in self.player_losses.items(): Label(self.frame, text=db.unit_type_name(unit_type), **STYLES["widget"]).grid(row=row) Label(self.frame, text="{}".format(count), **STYLES["widget"]).grid(column=1, row=row) diff --git a/ui/newgamemenu.py b/ui/newgamemenu.py index 8f34db6d..e30d3df2 100644 --- a/ui/newgamemenu.py +++ b/ui/newgamemenu.py @@ -98,6 +98,9 @@ class NewGameMenu(Menu): Label(terrain, text="Persian Gulf", **STYLES["widget"]).grid(row=2, column=1, sticky=W) self.create_label_image(terrain, "terrain_pg.png").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) diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index 5a56f101..d1323b06 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -99,7 +99,7 @@ class OverviewCanvas: color = self._enemy_color() cp_id = self.canvas.create_arc((coords[0] - arc_size/2, coords[1] - arc_size/2), - (coords[0]+arc_size/2, coords[1]+arc_size/2), + (coords[0] + arc_size/2, coords[1] + arc_size/2), fill=color, style=PIESLICE, start=start, @@ -118,8 +118,8 @@ class OverviewCanvas: self.create_cp_title((coords[0] + arc_size/4, coords[1] + arc_size/4), cp) units_title = "{}/{}/{}".format(cp.base.total_planes, cp.base.total_armor, cp.base.total_aa) - self.canvas.create_text(coords[0]+1, coords[1] - arc_size / 1.5 +1, text=units_title, font=("Helvetica", 10), fill=color) - self.canvas.create_text(coords[0], coords[1] - arc_size / 1.5, text=units_title, font=("Helvetica", 10), fill="white") + self.canvas.create_text(coords[0]+1, coords[1] - arc_size / 1.5 +1, text=units_title, font=("Helvetica", 8), fill=color) + self.canvas.create_text(coords[0], coords[1] - arc_size / 1.5, text=units_title, font=("Helvetica", 8), fill="white") def display(self, cp: ControlPoint): def action(_):