diff --git a/game/game.py b/game/game.py index d22dca3f..270542cf 100644 --- a/game/game.py +++ b/game/game.py @@ -208,7 +208,7 @@ class Game: naming.namegen = self.name_generator LuaPluginManager.load_settings(self.settings) ObjectiveDistanceCache.set_theater(self.theater) - self.compute_conflicts_position() + self.compute_unculled_zones() if not game_still_initializing: self.compute_threat_zones() @@ -347,8 +347,6 @@ class Game: return self.process_win_loss(turn_state) # Plan flights & combat for next turn - with logged_duration("Computing conflict positions"): - self.compute_conflicts_position() with logged_duration("Threat zone computation"): self.compute_threat_zones() @@ -366,6 +364,10 @@ class Game: gplanner.plan_groundwar() self.ground_planners[cp.id] = gplanner + # Update cull zones + with logged_duration("Computing culling positions"): + self.compute_unculled_zones() + def message(self, title: str, text: str = "") -> None: self.informations.append(Information(title, text, turn=self.turn)) @@ -406,10 +408,9 @@ class Game: def navmesh_for(self, player: bool) -> NavMesh: return self.coalition_for(player).nav_mesh - def compute_conflicts_position(self) -> None: + def compute_unculled_zones(self) -> None: """ - Compute the current conflict center position(s), mainly used for culling calculation - :return: List of points of interests + Compute the current conflict position(s) used for culling calculation """ from game.missiongenerator.frontlineconflictdescription import ( FrontLineConflictDescription, diff --git a/game/settings/boundedintoption.py b/game/settings/boundedintoption.py index 0a5b556e..a716ac0b 100644 --- a/game/settings/boundedintoption.py +++ b/game/settings/boundedintoption.py @@ -19,6 +19,7 @@ def bounded_int_option( max: int, detail: Optional[str] = None, tooltip: Optional[str] = None, + causes_expensive_game_update: bool = False, **kwargs: Any, ) -> int: return field( @@ -29,7 +30,7 @@ def bounded_int_option( text, detail, tooltip, - causes_expensive_game_update=False, + causes_expensive_game_update, min=min, max=max, ) diff --git a/game/settings/settings.py b/game/settings/settings.py index 0764daa5..f33e665e 100644 --- a/game/settings/settings.py +++ b/game/settings/settings.py @@ -448,6 +448,7 @@ class Settings: default=100, min=10, max=10000, + causes_expensive_game_update=True, ) perf_do_not_cull_carrier: bool = boolean_option( "Do not cull carrier's surroundings", diff --git a/qt_ui/models.py b/qt_ui/models.py index 40c1d31c..ca9ae581 100644 --- a/qt_ui/models.py +++ b/qt_ui/models.py @@ -222,6 +222,7 @@ class AtoModel(QAbstractListModel): PackageRole = Qt.UserRole client_slots_changed = Signal() + packages_changed = Signal() def __init__(self, game_model: GameModel, ato: AirTaskingOrder) -> None: super().__init__() @@ -254,6 +255,7 @@ class AtoModel(QAbstractListModel): self.endInsertRows() # noinspection PyUnresolvedReferences self.client_slots_changed.emit() + self.on_packages_changed() def delete_package_at_index(self, index: QModelIndex) -> None: """Removes the package at the given index from the ATO.""" @@ -272,6 +274,12 @@ class AtoModel(QAbstractListModel): self.endRemoveRows() # noinspection PyUnresolvedReferences self.client_slots_changed.emit() + self.on_packages_changed() + + def on_packages_changed(self) -> None: + if self.game is not None: + self.game.compute_unculled_zones() + self.packages_changed.emit() def package_at_index(self, index: QModelIndex) -> Package: """Returns the package at the given index.""" diff --git a/qt_ui/widgets/map/model/mapmodel.py b/qt_ui/widgets/map/model/mapmodel.py index c046a204..7ff37fe4 100644 --- a/qt_ui/widgets/map/model/mapmodel.py +++ b/qt_ui/widgets/map/model/mapmodel.py @@ -106,6 +106,12 @@ class MapModel(QObject): GameUpdateSignal.get_instance().flight_selection_changed.connect( self.set_flight_selection ) + self.game_model.ato_model_for(True).packages_changed.connect( + self.on_package_change + ), + self.game_model.ato_model_for(False).packages_changed.connect( + self.on_package_change + ), sim_controller.sim_update.connect(self.on_sim_update) self.reset() @@ -374,6 +380,9 @@ class MapModel(QObject): def mapZones(self) -> NavMeshJs: return self._map_zones + def on_package_change(self) -> None: + self.reset_unculled_zones() + def reset_unculled_zones(self) -> None: self._unculled_zones = list(UnculledZone.each_from_game(self.game)) self.unculledZonesChanged.emit() diff --git a/qt_ui/windows/settings/QSettingsWindow.py b/qt_ui/windows/settings/QSettingsWindow.py index 4717280e..f013529d 100644 --- a/qt_ui/windows/settings/QSettingsWindow.py +++ b/qt_ui/windows/settings/QSettingsWindow.py @@ -169,6 +169,8 @@ class AutoSettingsLayout(QGridLayout): ) -> None: def on_changed(value: int) -> None: self.settings.__dict__[name] = value + if description.causes_expensive_game_update: + self.write_full_settings() spinner = QSpinBox() spinner.setMinimum(description.min) @@ -354,7 +356,7 @@ class QSettingsWindow(QDialog): self.cheat_options.show_base_capture_cheat ) - self.game.compute_conflicts_position() + self.game.compute_unculled_zones() GameUpdateSignal.get_instance().updateGame(self.game) def onSelectionChanged(self):