diff --git a/game/event/convoystrike.py b/game/event/convoystrike.py index e7418769..d6ce9798 100644 --- a/game/event/convoystrike.py +++ b/game/event/convoystrike.py @@ -28,6 +28,10 @@ class ConvoyStrikeEvent(Event): def tasks(self): return [CAS] + @property + def global_cp_available(self) -> bool: + return True + def flight_name(self, for_task: typing.Type[Task]) -> str: if for_task == CAS: return "Strike flight" diff --git a/game/event/event.py b/game/event/event.py index 8a01c736..d5bc9be8 100644 --- a/game/event/event.py +++ b/game/event/event.py @@ -70,6 +70,10 @@ class Event: def ai_banned_tasks(self) -> typing.Collection[typing.Type[Task]]: return [] + @property + def global_cp_available(self) -> bool: + return False + def bonus(self) -> int: return int(math.log(self.to_cp.importance + 1, DIFFICULTY_LOG_BASE) * self.BONUS_BASE) diff --git a/game/event/frontlineattack.py b/game/event/frontlineattack.py index 032b03a1..91c35088 100644 --- a/game/event/frontlineattack.py +++ b/game/event/frontlineattack.py @@ -22,6 +22,10 @@ class FrontlineAttackEvent(Event): else: return [CAP] + @property + def global_cp_available(self) -> bool: + return True + def flight_name(self, for_task: typing.Type[Task]) -> str: if for_task == CAS: return "CAS flight" diff --git a/game/event/intercept.py b/game/event/intercept.py index d5a89b3e..0c424344 100644 --- a/game/event/intercept.py +++ b/game/event/intercept.py @@ -37,6 +37,10 @@ class InterceptEvent(Event): def threat_description(self): return "{} aircraft".format(self.enemy_cp.base.scramble_count(self._enemy_scramble_multiplier(), CAP)) + @property + def global_cp_available(self) -> bool: + return True + def is_successfull(self, debriefing: Debriefing): units_destroyed = debriefing.destroyed_units[self.defender_name].get(self.transport_unit, 0) if self.departure_cp.captured: diff --git a/game/event/navalintercept.py b/game/event/navalintercept.py index f4c75f20..f1d335ce 100644 --- a/game/event/navalintercept.py +++ b/game/event/navalintercept.py @@ -42,6 +42,10 @@ class NavalInterceptEvent(Event): s += ", {} aircraft".format(self.departure_cp.base.scramble_count(self.game.settings.multiplier)) return s + @property + def global_cp_available(self) -> bool: + return True + def is_successfull(self, debriefing: Debriefing): total_targets = sum(self.targets.values()) destroyed_targets = 0 diff --git a/game/event/strike.py b/game/event/strike.py index 6e69dbdf..cf6a0c53 100644 --- a/game/event/strike.py +++ b/game/event/strike.py @@ -28,6 +28,10 @@ class StrikeEvent(Event): def ai_banned_tasks(self): return [CAS] + @property + def global_cp_available(self) -> bool: + return True + def flight_name(self, for_task: typing.Type[Task]) -> str: if for_task == CAP: if self.is_player_attacking: diff --git a/game/operation/convoystrike.py b/game/operation/convoystrike.py index 5cb76f55..c38a2eed 100644 --- a/game/operation/convoystrike.py +++ b/game/operation/convoystrike.py @@ -28,6 +28,9 @@ class ConvoyStrikeOperation(Operation): conflict=conflict) def generate(self): + if self.is_player_attack: + self.prepare_carriers(db.unitdict_from(self.strikegroup)) + planes_flights = {k: v for k, v in self.strikegroup.items() if k in plane_map.values()} self.airgen.generate_cas_strikegroup(*assigned_units_split(planes_flights), at=self.attackers_starting_position) diff --git a/game/operation/frontlineattack.py b/game/operation/frontlineattack.py index bc131a22..eb9b41f9 100644 --- a/game/operation/frontlineattack.py +++ b/game/operation/frontlineattack.py @@ -37,6 +37,9 @@ class FrontlineAttackOperation(Operation): conflict=conflict) def generate(self): + if self.is_player_attack: + self.prepare_carriers(db.unitdict_from(self.strikegroup)) + self.armorgen.generate_vec(self.attackers, self.target) planes_flights = {k: v for k, v in self.strikegroup.items() if k in plane_map.values()} diff --git a/game/operation/frontlinepatrol.py b/game/operation/frontlinepatrol.py index 877b8299..631d89fe 100644 --- a/game/operation/frontlinepatrol.py +++ b/game/operation/frontlinepatrol.py @@ -43,6 +43,9 @@ class FrontlinePatrolOperation(Operation): conflict=conflict) def generate(self): + if self.is_player_attack: + self.prepare_carriers(db.unitdict_from(self.interceptors)) + self.airgen.generate_defenders_cas(*assigned_units_split(self.cas), at=self.defenders_starting_position) self.airgen.generate_defenders_escort(*assigned_units_split(self.escort), at=self.defenders_starting_position) self.airgen.generate_migcap(*assigned_units_split(self.interceptors), at=self.attackers_starting_position) diff --git a/game/operation/intercept.py b/game/operation/intercept.py index 9414b0a2..19ac6b72 100644 --- a/game/operation/intercept.py +++ b/game/operation/intercept.py @@ -43,7 +43,8 @@ class InterceptOperation(Operation): conflict=conflict) def generate(self): - self.prepare_carriers(db.unitdict_from(self.interceptors)) + if self.is_player_attack: + self.prepare_carriers(db.unitdict_from(self.interceptors)) 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) diff --git a/game/operation/navalintercept.py b/game/operation/navalintercept.py index 5f7d5ce5..5c30581d 100644 --- a/game/operation/navalintercept.py +++ b/game/operation/navalintercept.py @@ -37,7 +37,8 @@ class NavalInterceptionOperation(Operation): self.initialize(self.current_mission, conflict) def generate(self): - self.prepare_carriers(db.unitdict_from(self.strikegroup)) + if self.is_player_attack: + self.prepare_carriers(db.unitdict_from(self.strikegroup)) target_groups = self.shipgen.generate_cargo(units=self.targets) diff --git a/game/operation/operation.py b/game/operation/operation.py index 509b3462..be34e4e1 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -55,6 +55,10 @@ class Operation: def is_successfull(self, debriefing: Debriefing) -> bool: return True + @property + def is_player_attack(self) -> bool: + return self.from_cp.captured + def initialize(self, mission: Mission, conflict: Conflict): self.current_mission = mission self.conflict = conflict @@ -104,7 +108,10 @@ class Operation: at=global_cp.at) if global_cp == self.departure_cp and not self.is_quick: - self.attackers_starting_position = ship + if self.to_cp.captured: + self.attackers_starting_position = ship + else: + self.defenders_starting_position = ship def generate(self): # air support diff --git a/ui/overviewcanvas.py b/ui/overviewcanvas.py index a3b3e9db..07fb2fe7 100644 --- a/ui/overviewcanvas.py +++ b/ui/overviewcanvas.py @@ -365,8 +365,9 @@ class OverviewCanvas: self.surface.blit(labelHover, (coords[0] - label.get_width() / 2 + 1, coords[1] + 1)) self.draw_base_info(self.overlay, cp, (0, 0)) - if self.selected_event_info and cp.captured and self.selected_event_info[0].location.distance_to_point(cp.position) < EVENT_DEPARTURE_MAX_DISTANCE: - pygame.draw.line(self.surface, self.WHITE, point, self.selected_event_info[1]) + if self.selected_event_info: + if self._cp_available_for_selected_event(cp): + pygame.draw.line(self.surface, self.WHITE, point, self.selected_event_info[1]) else: self.surface.blit(label, (coords[0] - label.get_width() / 2 + 1, coords[1] + 1)) @@ -510,11 +511,14 @@ class OverviewCanvas: def _selected_cp(self, cp): if self.selected_event_info: - event = self.selected_event_info[0] - event.departure_cp = cp + if self._cp_available_for_selected_event(cp): + event = self.selected_event_info[0] + event.departure_cp = cp - self.selected_event_info = None - self.parent.start_event(event) + self.selected_event_info = None + self.parent.start_event(event) + else: + return else: self.parent.go_cp(cp) @@ -563,6 +567,20 @@ class OverviewCanvas: else: return None + def _cp_available_for_selected_event(self, cp: ControlPoint) -> bool: + event = self.selected_event_info[0] + + if not cp.captured: + return False + + if event.location.distance_to_point(cp.position) > EVENT_DEPARTURE_MAX_DISTANCE: + return False + + if cp.is_global and not event.global_cp_available: + return False + + return True + def _player_color(self): return self.game.player == "USA" and self.BLUE or self.RED