Compare commits

..

4 Commits

Author SHA1 Message Date
C. Perreau
6524286f04 Merge pull request #403 from Khopa/develop_2_2_x
Release 2.2.1
2020-11-20 00:29:15 +01:00
Dan Albert
2891649531 Fix pyinstaller spec for release.
final and buildnumber are optional files. Move them into resources to
avoid naming them explicitly.

(cherry picked from commit fae9650f56)
2020-11-14 13:13:18 -08:00
Dan Albert
4b40739918 Fix versioning for release builds.
(cherry picked from commit 9019cbfd2b)
2020-11-14 13:13:18 -08:00
C. Perreau
e26e7f53c5 Merge pull request #367 from Khopa/develop_2_2_x
Release 2.2.0
2020-11-14 21:46:59 +01:00
12 changed files with 17 additions and 73 deletions

View File

@@ -154,7 +154,7 @@ class Game:
reward = PLAYER_BUDGET_BASE * len(self.theater.player_points()) reward = PLAYER_BUDGET_BASE * len(self.theater.player_points())
for cp in self.theater.player_points(): for cp in self.theater.player_points():
for g in cp.ground_objects: for g in cp.ground_objects:
if g.category in REWARDS.keys() and not g.is_dead: if g.category in REWARDS.keys():
reward = reward + REWARDS[g.category] reward = reward + REWARDS[g.category]
return reward return reward
else: else:
@@ -277,7 +277,7 @@ class Game:
production = 0.0 production = 0.0
for enemy_point in self.theater.enemy_points(): for enemy_point in self.theater.enemy_points():
for g in enemy_point.ground_objects: for g in enemy_point.ground_objects:
if g.category in REWARDS.keys() and not g.is_dead: if g.category in REWARDS.keys():
production = production + REWARDS[g.category] production = production + REWARDS[g.category]
production = production * 0.75 production = production * 0.75

View File

@@ -21,7 +21,7 @@ class Settings:
self.night_disabled = False self.night_disabled = False
self.external_views_allowed = True self.external_views_allowed = True
self.supercarrier = False self.supercarrier = False
self.multiplier = 1.0 self.multiplier = 1
self.generate_marks = True self.generate_marks = True
self.sams = True # Legacy parameter do not use self.sams = True # Legacy parameter do not use
self.cold_start = False # Legacy parameter do not use self.cold_start = False # Legacy parameter do not use

View File

@@ -144,16 +144,6 @@ class Conflict:
position = middle_point.point_from_heading(attack_heading, strength_delta * attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE) position = middle_point.point_from_heading(attack_heading, strength_delta * attack_distance / 2 - FRONTLINE_MIN_CP_DISTANCE)
return position, _opposite_heading(attack_heading) return position, _opposite_heading(attack_heading)
@classmethod
def flight_frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> Tuple[Point, int, int]:
"""Returns the frontline vector without regard for exclusion zones, used in CAS flight plan"""
frontline = cls.frontline_position(theater, from_cp, to_cp)
center_position, heading = frontline
left_position = center_position.point_from_heading(_heading_sum(heading, -90), int(FRONTLINE_LENGTH/2))
right_position = center_position.point_from_heading(_heading_sum(heading, 90), int(FRONTLINE_LENGTH/2))
return left_position, _heading_sum(heading, 90), int(right_position.distance_to_point(left_position))
@classmethod @classmethod
def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> Tuple[Point, int, int]: def frontline_vector(cls, from_cp: ControlPoint, to_cp: ControlPoint, theater: ConflictTheater) -> Tuple[Point, int, int]:

View File

@@ -803,7 +803,7 @@ class FlightPlanBuilder:
if not isinstance(location, FrontLine): if not isinstance(location, FrontLine):
raise InvalidObjectiveLocation(flight.flight_type, location) raise InvalidObjectiveLocation(flight.flight_type, location)
ingress, heading, distance = Conflict.flight_frontline_vector( ingress, heading, distance = Conflict.frontline_vector(
location.control_points[0], location.control_points[1], location.control_points[0], location.control_points[1],
self.game.theater self.game.theater
) )

View File

@@ -183,7 +183,6 @@ class WaypointBuilder:
waypoint.description = description waypoint.description = description
waypoint.pretty_name = description waypoint.pretty_name = description
waypoint.name = target.name waypoint.name = target.name
waypoint.alt_type = "RADIO"
# The target waypoints are only for the player's benefit. AI tasks for # The target waypoints are only for the player's benefit. AI tasks for
# the target are set on the ingress point so they begin their attack # the target are set on the ingress point so they begin their attack
# *before* reaching the target. # *before* reaching the target.
@@ -210,7 +209,6 @@ class WaypointBuilder:
waypoint.description = name waypoint.description = name
waypoint.pretty_name = name waypoint.pretty_name = name
waypoint.name = name waypoint.name = name
waypoint.alt_type = "RADIO"
# The target waypoints are only for the player's benefit. AI tasks for # The target waypoints are only for the player's benefit. AI tasks for
# the target are set on the ingress point so they begin their attack # the target are set on the ingress point so they begin their attack
# *before* reaching the target. # *before* reaching the target.

View File

@@ -134,7 +134,7 @@ RADIOS: List[Radio] = [
Radio("RSIU-4V", MHz(100), MHz(150), step=MHz(1)), Radio("RSIU-4V", MHz(100), MHz(150), step=MHz(1)),
# MiG-21bis # MiG-21bis
Radio("RSIU-5V", MHz(118), MHz(140), step=MHz(1)), Radio("RSIU-5V", MHz(100), MHz(150), step=MHz(1)),
# Ka-50 # Ka-50
# Note: Also capable of 100MHz-150MHz, but we can't model gaps. # Note: Also capable of 100MHz-150MHz, but we can't model gaps.

View File

@@ -1,5 +1,3 @@
from __future__ import annotations
from dcs.action import MarkToAll from dcs.action import MarkToAll
from dcs.condition import TimeAfter from dcs.condition import TimeAfter
from dcs.mission import Mission from dcs.mission import Mission
@@ -7,7 +5,7 @@ from dcs.task import Option
from dcs.translation import String from dcs.translation import String
from dcs.triggers import Event, TriggerOnce from dcs.triggers import Event, TriggerOnce
from dcs.unit import Skill from dcs.unit import Skill
from dcs.unitgroup import FlyingGroup
from .conflictgen import Conflict from .conflictgen import Conflict
PUSH_TRIGGER_SIZE = 3000 PUSH_TRIGGER_SIZE = 3000
@@ -75,9 +73,8 @@ class TriggersGenerator:
continue continue
for country in coalition.countries.values(): for country in coalition.countries.values():
flying_groups = country.plane_group + country.helicopter_group # type: FlyingGroup for plane_group in country.plane_group:
for flying_group in flying_groups: for plane_unit in plane_group.units:
for plane_unit in flying_group.units:
if plane_unit.skill != Skill.Client and plane_unit.skill != Skill.Player: if plane_unit.skill != Skill.Client and plane_unit.skill != Skill.Player:
plane_unit.skill = Skill(skill_level[0]) plane_unit.skill = Skill(skill_level[0])

View File

@@ -48,14 +48,12 @@ class QTopPanel(QFrame):
self.passTurnButton.setIcon(CONST.ICONS["PassTurn"]) self.passTurnButton.setIcon(CONST.ICONS["PassTurn"])
self.passTurnButton.setProperty("style", "btn-primary") self.passTurnButton.setProperty("style", "btn-primary")
self.passTurnButton.clicked.connect(self.passTurn) self.passTurnButton.clicked.connect(self.passTurn)
if not self.game:
self.passTurnButton.setEnabled(False)
self.proceedButton = QPushButton("Take off") self.proceedButton = QPushButton("Take off")
self.proceedButton.setIcon(CONST.ICONS["Proceed"]) self.proceedButton.setIcon(CONST.ICONS["Proceed"])
self.proceedButton.setProperty("style", "start-button") self.proceedButton.setProperty("style", "start-button")
self.proceedButton.clicked.connect(self.launch_mission) self.proceedButton.clicked.connect(self.launch_mission)
if not self.game or self.game.turn == 0: if self.game and self.game.turn == 0:
self.proceedButton.setEnabled(False) self.proceedButton.setEnabled(False)
self.factionsInfos = QFactionsInfos(self.game) self.factionsInfos = QFactionsInfos(self.game)
@@ -103,8 +101,6 @@ class QTopPanel(QFrame):
self.budgetBox.setGame(game) self.budgetBox.setGame(game)
self.factionsInfos.setGame(game) self.factionsInfos.setGame(game)
self.passTurnButton.setEnabled(True)
if game and game.turn == 0: if game and game.turn == 0:
self.proceedButton.setEnabled(False) self.proceedButton.setEnabled(False)
else: else:

View File

@@ -62,9 +62,7 @@ class NewGameWizard(QtWidgets.QWizard):
timePeriod = db.TIME_PERIODS[list(db.TIME_PERIODS.keys())[self.field("timePeriod")]] timePeriod = db.TIME_PERIODS[list(db.TIME_PERIODS.keys())[self.field("timePeriod")]]
midGame = self.field("midGame") midGame = self.field("midGame")
# QSlider forces integers, so we use 1 to 50 and divide by 10 to give multiplier = self.field("multiplier")
# 0.1 to 5.0.
multiplier = self.field("multiplier") / 10
no_carrier = self.field("no_carrier") no_carrier = self.field("no_carrier")
no_lha = self.field("no_lha") no_lha = self.field("no_lha")
supercarrier = self.field("supercarrier") supercarrier = self.field("supercarrier")
@@ -326,44 +324,6 @@ class BudgetInputs(QtWidgets.QGridLayout):
self.addWidget(self.starting_money, 1, 1) self.addWidget(self.starting_money, 1, 1)
class ForceMultiplierSpinner(QtWidgets.QSpinBox):
def __init__(self, minimum: Optional[int] = None,
maximum: Optional[int] = None,
initial: Optional[int] = None) -> None:
super().__init__()
if minimum is not None:
self.setMinimum(minimum)
if maximum is not None:
self.setMaximum(maximum)
if initial is not None:
self.setValue(initial)
def textFromValue(self, val: int) -> str:
return f"X {val / 10:.1f}"
class ForceMultiplierInputs(QtWidgets.QGridLayout):
def __init__(self) -> None:
super().__init__()
self.addWidget(QtWidgets.QLabel("Enemy forces multiplier"), 0, 0)
minimum = 1
maximum = 50
initial = 10
slider = QtWidgets.QSlider(Qt.Horizontal)
slider.setMinimum(minimum)
slider.setMaximum(maximum)
slider.setValue(initial)
self.multiplier = ForceMultiplierSpinner(minimum, maximum, initial)
slider.valueChanged.connect(lambda x: self.multiplier.setValue(x))
self.multiplier.valueChanged.connect(lambda x: slider.setValue(x))
self.addWidget(slider, 1, 0)
self.addWidget(self.multiplier, 1, 1)
class MiscOptions(QtWidgets.QWizardPage): class MiscOptions(QtWidgets.QWizardPage):
def __init__(self, parent=None): def __init__(self, parent=None):
super(MiscOptions, self).__init__(parent) super(MiscOptions, self).__init__(parent)
@@ -374,12 +334,14 @@ class MiscOptions(QtWidgets.QWizardPage):
QtGui.QPixmap('./resources/ui/wizard/logo1.png')) QtGui.QPixmap('./resources/ui/wizard/logo1.png'))
midGame = QtWidgets.QCheckBox() midGame = QtWidgets.QCheckBox()
multiplier_inputs = ForceMultiplierInputs() multiplier = QtWidgets.QSpinBox()
self.registerField('multiplier', multiplier_inputs.multiplier) multiplier.setEnabled(False)
multiplier.setMinimum(1)
multiplier.setMaximum(5)
miscSettingsGroup = QtWidgets.QGroupBox("Misc Settings") miscSettingsGroup = QtWidgets.QGroupBox("Misc Settings")
self.registerField('midGame', midGame) self.registerField('midGame', midGame)
self.registerField('multiplier', multiplier)
# Campaign settings # Campaign settings
generatorSettingsGroup = QtWidgets.QGroupBox("Generator Settings") generatorSettingsGroup = QtWidgets.QGroupBox("Generator Settings")
@@ -397,7 +359,8 @@ class MiscOptions(QtWidgets.QWizardPage):
layout = QtWidgets.QGridLayout() layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QLabel("Start at mid game"), 1, 0) layout.addWidget(QtWidgets.QLabel("Start at mid game"), 1, 0)
layout.addWidget(midGame, 1, 1) layout.addWidget(midGame, 1, 1)
layout.addLayout(multiplier_inputs, 2, 0) layout.addWidget(QtWidgets.QLabel("Ennemy forces multiplier [Disabled for Now]"), 2, 0)
layout.addWidget(multiplier, 2, 1)
miscSettingsGroup.setLayout(layout) miscSettingsGroup.setLayout(layout)
generatorLayout = QtWidgets.QGridLayout() generatorLayout = QtWidgets.QGridLayout()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B