예제 #1
0
def main():
    logging_config.init_logging(VERSION)

    logging.debug("Python version %s", sys.version)

    game: Optional[Game] = None

    args = parse_args()

    # TODO: Flesh out data and then make unconditional.
    if args.warn_missing_weapon_data:
        lint_weapon_data()

    if args.subcommand == "new-game":
        with logged_duration("New game creation"):
            game = create_game(
                args.campaign,
                args.blue,
                args.red,
                args.supercarrier,
                args.auto_procurement,
                args.inverted,
                args.cheats,
            )

    run_ui(game)
예제 #2
0
    def process_debriefing(self):
        with logged_duration("Turn processing"):
            self.sim_controller.process_results(self.debriefing)
            self.game.pass_turn()

            GameUpdateSignal.get_instance().sendDebriefing(self.debriefing)
            GameUpdateSignal.get_instance().updateGame(self.game)
        self.close()
예제 #3
0
    def process_debriefing(self):
        with logged_duration("Turn processing"):
            self.game.finish_event(event=self.gameEvent, debriefing=self.debriefing)
            self.game.pass_turn()

            GameUpdateSignal.get_instance().sendDebriefing(self.debriefing)
            GameUpdateSignal.get_instance().updateGame(self.game)
        self.close()
예제 #4
0
def save_game(game: Game) -> bool:
    with logged_duration("Saving game"):
        try:
            with open(_temporary_save_file(), "wb") as f:
                pickle.dump(game, f)
            shutil.copy(_temporary_save_file(), game.savepath)
            return True
        except Exception:
            logging.exception("Could not save game")
            return False
예제 #5
0
    def plan_missions(self) -> None:
        """Identifies and plans mission for the turn."""
        player = "Blue" if self.is_player else "Red"
        with logged_duration(f"{player} mission identification and fulfillment"):
            with MultiEventTracer() as tracer:
                for proposed_mission in self.propose_missions():
                    self.plan_mission(proposed_mission, tracer)

        with logged_duration(f"{player} reserve mission planning"):
            with MultiEventTracer() as tracer:
                for critical_mission in self.critical_missions():
                    self.plan_mission(critical_mission, tracer, reserves=True)

        with logged_duration(f"{player} mission scheduling"):
            self.stagger_missions()

        for cp in self.objective_finder.friendly_control_points():
            inventory = self.game.aircraft_inventory.for_control_point(cp)
            for aircraft, available in inventory.all_aircraft:
                self.message("Unused aircraft", f"{available} {aircraft} from {cp}")
예제 #6
0
    def initialize_turn(self) -> None:
        """Processes coalition-specific turn initialization.

        For more information on turn initialization in general, see the documentation
        for `Game.initialize_turn`.
        """
        # Needs to happen *before* planning transfers so we don't cancel them.
        self.ato.clear()
        self.air_wing.reset()
        self.refund_outstanding_orders()
        self.procurement_requests.clear()

        with logged_duration("Transit network identification"):
            self.update_transit_network()
        with logged_duration("Procurement of airlift assets"):
            self.transfers.order_airlift_assets()
        with logged_duration("Transport planning"):
            self.transfers.plan_transports()

        self.plan_missions()
        self.plan_procurement()
    def __init__(self, miz: Path, theater: ConflictTheater) -> None:
        self.theater = theater
        self.mission = Mission()
        with logged_duration("Loading miz"):
            self.mission.load_file(str(miz))

        # If there are no red carriers there usually aren't red units. Make sure
        # both countries are initialized so we don't have to deal with None.
        if self.mission.country(self.BLUE_COUNTRY.name) is None:
            self.mission.coalition["blue"].add_country(self.BLUE_COUNTRY)
        if self.mission.country(self.RED_COUNTRY.name) is None:
            self.mission.coalition["red"].add_country(self.RED_COUNTRY)
예제 #8
0
    def import_templates(self) -> None:
        """This will import all layouts from the template folder
        and dumps them to a pickle"""
        self._layouts = {}
        mappings: dict[str, list[LayoutMapping]] = defaultdict(list)
        with logged_duration("Parsing mapping yamls"):
            for file in Path(TEMPLATE_DIR).rglob("*.yaml"):
                if not file.is_file():
                    raise RuntimeError(f"{file.name} is not a file")
                with file.open("r", encoding="utf-8") as f:
                    mapping_dict = yaml.safe_load(f)

                template_map = LayoutMapping.from_dict(mapping_dict, f.name)
                mappings[template_map.layout_file].append(template_map)

        with logged_duration(f"Parsing all layout miz multithreaded"):
            with ThreadPoolExecutor() as exe:
                exe.map(self._load_from_miz, mappings.keys(),
                        mappings.values())

        logging.info(f"Imported {len(self._layouts)} layouts")
        self._dump_templates()
예제 #9
0
 def reset(self) -> None:
     if self.game_model.game is None:
         self.clear()
         return
     with logged_duration("Map reset"):
         self.reset_control_points()
         self.reset_ground_objects()
         self.reset_routes()
         self.reset_atos()
         self.reset_front_lines()
         self.reset_threat_zones()
         self.reset_navmeshes()
         self.reset_map_zones()
         self.reset_unculled_zones()
예제 #10
0
def main():
    logging_config.init_logging(VERSION)

    logging.debug("Python version %s", sys.version)

    if not str(Path(__file__)).isascii():
        logging.warning(
            "Installation path contains non-ASCII characters. This is known to cause problems."
        )

    game: Optional[Game] = None

    args = parse_args()

    # TODO: Flesh out data and then make unconditional.
    if args.warn_missing_weapon_data:
        lint_all_weapon_data()

    load_mods()

    if args.subcommand == "new-game":
        with logged_duration("New game creation"):
            game = create_game(
                args.campaign,
                args.blue,
                args.red,
                args.supercarrier,
                args.auto_procurement,
                args.inverted,
                args.cheats,
                args.date,
                args.restrict_weapons_by_date,
            )
    if args.subcommand == "lint-weapons":
        lint_weapon_data_for_aircraft(AircraftType.named(args.aircraft))
        return

    with Server().run_in_thread():
        run_ui(game, args.dev)
예제 #11
0
    def launch_mission(self):
        """Finishes planning and waits for mission completion."""
        if not self.ato_has_clients() and not self.confirm_no_client_launch():
            return

        if self.check_no_missing_pilots():
            return

        negative_starts = self.negative_start_packages()
        if negative_starts:
            if not self.confirm_negative_start_time(negative_starts):
                return

        if self.game.settings.fast_forward_to_first_contact:
            with logged_duration("Simulating to first contact"):
                self.sim_controller.run_to_first_contact()
        self.sim_controller.generate_miz(
            persistency.mission_path_for("liberation_nextturn.miz"))

        waiting = QWaitingForMissionResultWindow(self.game,
                                                 self.sim_controller, self)
        waiting.exec_()
예제 #12
0
    def load_theater(self) -> ConflictTheater:
        theaters = {
            "Caucasus": CaucasusTheater,
            "Nevada": NevadaTheater,
            "Persian Gulf": PersianGulfTheater,
            "Normandy": NormandyTheater,
            "The Channel": TheChannelTheater,
            "Syria": SyriaTheater,
            "MarianaIslands": MarianaIslandsTheater,
        }
        theater = theaters[self.data["theater"]]
        t = theater()

        try:
            miz = self.data["miz"]
        except KeyError as ex:
            raise RuntimeError(
                "Old format (non-miz) campaigns are no longer supported."
            ) from ex

        with logged_duration("Importing miz data"):
            MizCampaignLoader(self.path.parent / miz, t).populate_theater()
        return t
예제 #13
0
 def passTurn(self):
     with logged_duration("Skipping turn"):
         self.game.pass_turn(no_action=True)
         GameUpdateSignal.get_instance().updateGame(self.game)
         self.proceedButton.setEnabled(True)
예제 #14
0
 def initialize(self) -> None:
     if not self._layouts:
         with logged_duration("Loading layouts"):
             self.load_templates()
예제 #15
0
    def _load_from_miz(self, miz: str, mappings: list[LayoutMapping]) -> None:
        template_position: dict[str, Point] = {}
        temp_mis = dcs.Mission()
        with logged_duration(f"Parsing {miz}"):
            # The load_file takes a lot of time to compute. That's why the layouts
            # are written to a pickle and can be reloaded from the ui
            # Example the whole routine: 0:00:00.934417,
            # the .load_file() method: 0:00:00.920409
            temp_mis.load_file(miz)

        for mapping in mappings:
            # Find the group from the mapping in any coalition
            for country in itertools.chain(
                    temp_mis.coalition["red"].countries.values(),
                    temp_mis.coalition["blue"].countries.values(),
            ):
                for dcs_group in itertools.chain(
                        temp_mis.country(country.name).vehicle_group,
                        temp_mis.country(country.name).ship_group,
                        temp_mis.country(country.name).static_group,
                ):

                    try:
                        g_id, group_name, group_mapping = mapping.group_for_name(
                            dcs_group.name)
                    except KeyError:
                        continue

                    if not isinstance(dcs_group, StaticGroup) and max(
                            group_mapping.unit_count) > len(dcs_group.units):
                        logging.error(
                            f"Incorrect unit_count found in Layout {mapping.name}-{group_mapping.name}"
                        )

                    layout = self._layouts.get(mapping.name, None)
                    if layout is None:
                        # Create a new template
                        layout = TEMPLATE_TYPES[mapping.primary_role](
                            mapping.name, mapping.description)
                        layout.generic = mapping.generic
                        layout.tasks = mapping.tasks
                        self._layouts[layout.name] = layout

                    for i, unit in enumerate(dcs_group.units):
                        group_layout = None
                        for group in layout.all_groups:
                            if group.name == group_mapping.name:
                                # We already have a layoutgroup for this dcs_group
                                group_layout = group
                        if not group_layout:
                            group_layout = TgoLayoutGroup(
                                group_mapping.name,
                                [],
                                group_mapping.unit_count,
                                group_mapping.unit_types,
                                group_mapping.unit_classes,
                                group_mapping.fallback_classes,
                            )
                            group_layout.optional = group_mapping.optional
                            group_layout.fill = group_mapping.fill
                            # Add the group at the correct index
                            layout.add_layout_group(group_name, group_layout,
                                                    g_id)
                        layout_unit = LayoutUnit.from_unit(unit)
                        if i == 0 and layout.name not in template_position:
                            template_position[layout.name] = unit.position
                        layout_unit.position = (layout_unit.position -
                                                template_position[layout.name])
                        group_layout.layout_units.append(layout_unit)