Culling optimizations + fixed some aircraft icons

This commit is contained in:
Khopa 2020-06-19 14:31:25 +02:00
parent e78120d9c6
commit 5f1f4f8d81
14 changed files with 105 additions and 50 deletions

View File

@ -72,6 +72,7 @@ class Game:
self.ground_planners = {} self.ground_planners = {}
self.informations = [] self.informations = []
self.informations.append(Information("Game Start", "-" * 40, 0)) self.informations.append(Information("Game Start", "-" * 40, 0))
self.__culling_points = self.compute_conflicts_position()
@property @property
@ -187,6 +188,7 @@ class Game:
return 1 return 1
def pass_turn(self, no_action=False, ignored_cps: typing.Collection[ControlPoint] = None): def pass_turn(self, no_action=False, ignored_cps: typing.Collection[ControlPoint] = None):
logging.info("Pass turn") logging.info("Pass turn")
self.informations.append(Information("End of turn #" + str(self.turn), "-" * 40, 0)) self.informations.append(Information("End of turn #" + str(self.turn), "-" * 40, 0))
self.turn = self.turn + 1 self.turn = self.turn + 1
@ -202,7 +204,7 @@ class Game:
self._enemy_reinforcement() self._enemy_reinforcement()
self._budget_player() self._budget_player()
if not no_action: if not no_action and self.turn > 1:
for cp in self.theater.player_points(): for cp in self.theater.player_points():
cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY) cp.base.affect_strength(+PLAYER_BASE_STRENGTH_RECOVERY)
else: else:
@ -221,6 +223,7 @@ class Game:
self.game_stats.update(self) self.game_stats.update(self)
# Plan flights & combat for next turn # Plan flights & combat for next turn
self.__culling_points = self.compute_conflicts_position()
self.planners = {} self.planners = {}
self.ground_planners = {} self.ground_planners = {}
for cp in self.theater.controlpoints: for cp in self.theater.controlpoints:
@ -326,3 +329,49 @@ class Game:
""" """
self.current_group_id += 1 self.current_group_id += 1
return self.current_group_id return self.current_group_id
def compute_conflicts_position(self):
"""
Compute the current conflict center position(s), mainly used for culling calculation
:return: List of points of interests
"""
points = []
# By default, use the existing frontline conflict position
for conflict in self.theater.conflicts():
points.append(Conflict.frontline_position(self.theater, conflict[0], conflict[1])[0])
# If there is no conflict take the center point between the two nearest opposing bases
if len(points) == 0:
cpoint = None
min_distance = sys.maxsize
for cp in self.theater.player_points():
for cp2 in self.theater.enemy_points():
d = cp.position.distance_to_point(cp2.position)
if d < min_distance:
min_distance = d
cpoint = Point((cp.position.x + cp2.position.x) / 2, (cp.position.y + cp2.position.y) / 2)
if cpoint is not None:
points.append(cpoint)
# Else 0,0, since we need a default value
# (in this case this means the whole map is owned by the same player, so it is not an issue)
if len(points) == 0:
points.append(Point(0, 0))
return points
def position_culled(self, pos):
"""
Check if unit can be generated at given position depending on culling performance settings
:param pos: Position you are tryng to spawn stuff at
:return: True if units can not be added at given position
"""
if self.settings.perf_culling == False:
return False
else:
for c in self.__culling_points:
if c.distance_to_point(pos) < self.settings.perf_culling_distance * 1000:
return False
return True

View File

@ -25,4 +25,8 @@ class Settings:
perf_infantry = True perf_infantry = True
perf_ai_parking_start = True perf_ai_parking_start = True
# Performance culling
perf_culling = False
perf_culling_distance = 0

View File

@ -230,6 +230,11 @@ class AircraftConflictGenerator:
def generate_flights(self, cp, country, flight_planner:FlightPlanner): def generate_flights(self, cp, country, flight_planner:FlightPlanner):
for flight in flight_planner.flights: for flight in flight_planner.flights:
if flight.client_count == 0 and self.game.position_culled(flight.from_cp.position):
logging.info("Flight not generated : culled")
continue
group = self.generate_planned_flight(cp, country, flight) group = self.generate_planned_flight(cp, country, flight)
if flight.flight_type == FlightType.INTERCEPTION: if flight.flight_type == FlightType.INTERCEPTION:
self.setup_group_as_intercept_flight(group, flight) self.setup_group_as_intercept_flight(group, flight)

View File

@ -61,9 +61,12 @@ class GroundObjectsGenerator:
for ground_object in cp.ground_objects: for ground_object in cp.ground_objects:
if ground_object.dcs_identifier == "AA": if ground_object.dcs_identifier == "AA":
if self.game.position_culled(ground_object.position):
continue
for g in ground_object.groups: for g in ground_object.groups:
if len(g.units) > 0: if len(g.units) > 0:
utype = unit_type_from_name(g.units[0].type) utype = unit_type_from_name(g.units[0].type)
if not ground_object.sea_object: if not ground_object.sea_object:
@ -125,6 +128,10 @@ class GroundObjectsGenerator:
sg.points[0].tasks.append(ActivateICLSCommand(cp.icls, unit_id=sg.units[0].id)) sg.points[0].tasks.append(ActivateICLSCommand(cp.icls, unit_id=sg.units[0].id))
else: else:
if self.game.position_culled(ground_object.position):
continue
static_type = None static_type = None
if ground_object.dcs_identifier in warehouse_map: if ground_object.dcs_identifier in warehouse_map:
static_type = warehouse_map[ground_object.dcs_identifier] static_type = warehouse_map[ground_object.dcs_identifier]
@ -161,33 +168,3 @@ class GroundObjectsGenerator:
) )
logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id)) logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id))
def farp_aa(mission_obj, country, name, position: mapping.Point):
"""
Add AAA to a FARP :)
:param mission_obj:
:param country:
:param name:
:param position:
:return:
"""
vg = unitgroup.VehicleGroup(mission_obj.next_group_id(), mission_obj.string(name))
units = [
AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.AAA_ZU_23_Closed,
]
v = mission_obj.vehicle(name + "_AAA", random.choice(units))
v.position.x = position.x - random.randint(5, 30)
v.position.y = position.y - random.randint(5, 30)
v.heading = random.randint(0, 359)
vg.add_unit(v)
wp = vg.add_waypoint(vg.units[0].position, PointAction.OffRoad, 0)
wp.ETA_locked = True
country.add_vehicle_group(vg)
return vg

View File

@ -1,13 +1,14 @@
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
from PySide2.QtGui import QStandardItemModel, QStandardItem from PySide2.QtGui import QStandardItemModel, QStandardItem
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \ from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
from dcs.forcedoptions import ForcedOptions from dcs.forcedoptions import ForcedOptions
import qt_ui.uiconstants as CONST import qt_ui.uiconstants as CONST
from game.game import Game from game.game import Game
from game.infos.information import Information from game.infos.information import Information
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.finances.QFinancesMenu import QHorizontalSeparationLine
class QSettingsWindow(QDialog): class QSettingsWindow(QDialog):
@ -199,6 +200,16 @@ class QSettingsWindow(QDialog):
self.ai_parking_start.setChecked(self.game.settings.perf_ai_parking_start) self.ai_parking_start.setChecked(self.game.settings.perf_ai_parking_start)
self.ai_parking_start.toggled.connect(self.applySettings) self.ai_parking_start.toggled.connect(self.applySettings)
self.culling = QCheckBox()
self.culling.setChecked(self.game.settings.perf_culling)
self.culling.toggled.connect(self.applySettings)
self.culling_distance = QSpinBox()
self.culling_distance.setMinimum(50)
self.culling_distance.setMaximum(10000)
self.culling_distance.setValue(self.game.settings.perf_culling_distance)
self.culling_distance.valueChanged.connect(self.applySettings())
self.performanceLayout.addWidget(QLabel("Smoke visual effect on frontline"), 0, 0) self.performanceLayout.addWidget(QLabel("Smoke visual effect on frontline"), 0, 0)
self.performanceLayout.addWidget(self.smoke, 0, 1, alignment=Qt.AlignRight) self.performanceLayout.addWidget(self.smoke, 0, 1, alignment=Qt.AlignRight)
self.performanceLayout.addWidget(QLabel("SAM starts in RED alert mode"), 1, 0) self.performanceLayout.addWidget(QLabel("SAM starts in RED alert mode"), 1, 0)
@ -212,6 +223,12 @@ class QSettingsWindow(QDialog):
self.performanceLayout.addWidget(QLabel("AI planes parking start (AI starts in flight if disabled)"), 5, 0) self.performanceLayout.addWidget(QLabel("AI planes parking start (AI starts in flight if disabled)"), 5, 0)
self.performanceLayout.addWidget(self.ai_parking_start, 5, 1, alignment=Qt.AlignRight) self.performanceLayout.addWidget(self.ai_parking_start, 5, 1, alignment=Qt.AlignRight)
self.performanceLayout.addWidget(QHorizontalSeparationLine(), 6, 0, 1, 2)
self.performanceLayout.addWidget(QLabel("Culling of distant units enabled"), 7, 0)
self.performanceLayout.addWidget(self.culling, 7, 1, alignment=Qt.AlignRight)
self.performanceLayout.addWidget(QLabel("Culling distance (km)"), 8, 0)
self.performanceLayout.addWidget(self.culling_distance, 8, 1, alignment=Qt.AlignRight)
self.generatorLayout.addWidget(self.gameplay) self.generatorLayout.addWidget(self.gameplay)
self.generatorLayout.addWidget(QLabel("Disabling settings below may improve performance, but will impact the overall quality of the experience.")) self.generatorLayout.addWidget(QLabel("Disabling settings below may improve performance, but will impact the overall quality of the experience."))
self.generatorLayout.addWidget(self.performance) self.generatorLayout.addWidget(self.performance)
@ -277,6 +294,9 @@ class QSettingsWindow(QDialog):
self.game.settings.perf_infantry = self.infantry.isChecked() self.game.settings.perf_infantry = self.infantry.isChecked()
self.game.settings.perf_ai_parking_start = self.ai_parking_start.isChecked() self.game.settings.perf_ai_parking_start = self.ai_parking_start.isChecked()
self.game.settings.perf_culling = self.culling.isChecked()
self.game.settings.perf_culling_distance = int(self.culling_distance.value())
GameUpdateSignal.get_instance().updateGame(self.game) GameUpdateSignal.get_instance().updateGame(self.game)
def onSelectionChanged(self): def onSelectionChanged(self):

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,12 +1,10 @@
import typing import typing
import itertools
import dcs import dcs
from dcs.mapping import Point from dcs.mapping import Point
from .landmap import Landmap, poly_contains
from .controlpoint import ControlPoint from .controlpoint import ControlPoint
from .theatergroundobject import TheaterGroundObject from .landmap import poly_contains
SIZE_TINY = 150 SIZE_TINY = 150
SIZE_SMALL = 600 SIZE_SMALL = 600
@ -66,7 +64,7 @@ class ConflictTheater:
self.land_poly = self.land_poly.difference(geometry.Polygon(x)) self.land_poly = self.land_poly.difference(geometry.Polygon(x))
""" """
def add_controlpoint(self, point: ControlPoint, connected_to: typing.Collection[ControlPoint] = []): def add_controlpoint(self, point: ControlPoint, connected_to: [ControlPoint] = []):
for connected_point in connected_to: for connected_point in connected_to:
point.connect(to=connected_point) point.connect(to=connected_point)
@ -118,3 +116,5 @@ class ConflictTheater:
def enemy_points(self) -> typing.Collection[ControlPoint]: def enemy_points(self) -> typing.Collection[ControlPoint]:
return [point for point in self.controlpoints if not point.captured] return [point for point in self.controlpoints if not point.captured]

View File

@ -52,30 +52,30 @@ class PersianGulfTheater(ConflictTheater):
self.east_carrier = ControlPoint.carrier("East carrier", Point(59514.324335475, 28165.517980635)) self.east_carrier = ControlPoint.carrier("East carrier", Point(59514.324335475, 28165.517980635))
self.add_controlpoint(self.liwa, connected_to=[self.al_dhafra]) self.add_controlpoint(self.liwa, connected_to=[self.al_dhafra])
self.add_controlpoint(self.al_dhafra, connected_to=[self.liwa, self.sir_abu_nuayr, self.al_maktoum, self.al_ain]) self.add_controlpoint(self.al_dhafra, connected_to=[self.liwa, self.al_maktoum, self.al_ain])
self.add_controlpoint(self.al_ain, connected_to=[self.al_dhafra, self.al_maktoum]) self.add_controlpoint(self.al_ain, connected_to=[self.al_dhafra, self.al_maktoum])
self.add_controlpoint(self.al_maktoum, connected_to=[self.al_dhafra, self.al_minhad, self.sir_abu_nuayr, self.al_ain]) self.add_controlpoint(self.al_maktoum, connected_to=[self.al_dhafra, self.al_minhad, self.al_ain])
self.add_controlpoint(self.al_minhad, connected_to=[self.al_maktoum, self.dubai]) self.add_controlpoint(self.al_minhad, connected_to=[self.al_maktoum, self.dubai])
self.add_controlpoint(self.dubai, connected_to=[self.al_minhad, self.sharjah, self.fujairah]) self.add_controlpoint(self.dubai, connected_to=[self.al_minhad, self.sharjah, self.fujairah])
self.add_controlpoint(self.sharjah, connected_to=[self.dubai, self.ras_al_khaimah]) self.add_controlpoint(self.sharjah, connected_to=[self.dubai, self.ras_al_khaimah])
self.add_controlpoint(self.ras_al_khaimah, connected_to=[self.sharjah, self.khasab]) self.add_controlpoint(self.ras_al_khaimah, connected_to=[self.sharjah, self.khasab])
self.add_controlpoint(self.fujairah, connected_to=[self.dubai, self.khasab]) self.add_controlpoint(self.fujairah, connected_to=[self.dubai, self.khasab])
self.add_controlpoint(self.khasab, connected_to=[self.ras_al_khaimah, self.fujairah, self.tunb_island]) self.add_controlpoint(self.khasab, connected_to=[self.ras_al_khaimah, self.fujairah])
self.add_controlpoint(self.sir_abu_nuayr, connected_to=[self.al_dhafra, self.al_maktoum, self.sirri]) self.add_controlpoint(self.sir_abu_nuayr, connected_to=[])
self.add_controlpoint(self.sirri, connected_to=[self.sir_abu_nuayr, self.abu_musa]) self.add_controlpoint(self.sirri, connected_to=[])
self.add_controlpoint(self.abu_musa, connected_to=[self.sirri, self.sir_abu_nuayr]) self.add_controlpoint(self.abu_musa, connected_to=[])
self.add_controlpoint(self.tunb_kochak, connected_to=[self.sirri, self.abu_musa, self.tunb_island]) self.add_controlpoint(self.tunb_kochak, connected_to=[])
self.add_controlpoint(self.tunb_island, connected_to=[self.khasab, self.qeshm, self.tunb_kochak]) self.add_controlpoint(self.tunb_island, connected_to=[])
self.add_controlpoint(self.bandar_lengeh, connected_to=[self.tunb_island, self.lar, self.qeshm]) self.add_controlpoint(self.bandar_lengeh, connected_to=[self.lar, self.qeshm])
self.add_controlpoint(self.qeshm, connected_to=[self.bandar_lengeh, self.havadarya, self.tunb_island]) self.add_controlpoint(self.qeshm, connected_to=[self.bandar_lengeh, self.havadarya])
self.add_controlpoint(self.havadarya, connected_to=[self.lar, self.qeshm, self.bandar_abbas]) self.add_controlpoint(self.havadarya, connected_to=[self.lar, self.qeshm, self.bandar_abbas])
self.add_controlpoint(self.bandar_abbas, connected_to=[self.havadarya, self.kerman]) self.add_controlpoint(self.bandar_abbas, connected_to=[self.havadarya, self.kerman])
self.add_controlpoint(self.shiraz, connected_to=[self.lar, self.kerman]) self.add_controlpoint(self.shiraz, connected_to=[self.lar, self.kerman])
self.add_controlpoint(self.kerman, connected_to=[self.lar, self.shiraz, self.bandar_abbas]) self.add_controlpoint(self.kerman, connected_to=[self.lar, self.shiraz, self.bandar_abbas])
self.add_controlpoint(self.lar, connected_to=[self.bandar_lengeh, self.havadarya, self.shiraz, self.kerman]) self.add_controlpoint(self.lar, connected_to=[self.havadarya, self.shiraz, self.kerman])
self.add_controlpoint(self.west_carrier) self.add_controlpoint(self.west_carrier)
self.add_controlpoint(self.east_carrier) self.add_controlpoint(self.east_carrier)

View File

@ -5,7 +5,7 @@ import typing
import logging import logging
from game.data.building_data import DEFAULT_AVAILABLE_BUILDINGS from game.data.building_data import DEFAULT_AVAILABLE_BUILDINGS
from gen import namegen from gen import namegen, TheaterGroundObject
from gen.defenses.armor_group_generator import generate_armor_group from gen.defenses.armor_group_generator import generate_armor_group
from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group, generate_ship_group from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group, generate_ship_group
from gen.missiles.missiles_group_generator import generate_missile_group from gen.missiles.missiles_group_generator import generate_missile_group