diff --git a/game/game.py b/game/game.py
index a4087ec1..f5040dd0 100644
--- a/game/game.py
+++ b/game/game.py
@@ -150,17 +150,13 @@ class Game:
front_line.control_point_b)
@property
- def budget_reward_amount(self):
- reward = 0
- if len(self.theater.player_points()) > 0:
- reward = PLAYER_BUDGET_BASE * len(self.theater.player_points())
- for cp in self.theater.player_points():
- for g in cp.ground_objects:
- if g.category in REWARDS.keys() and not g.is_dead:
- reward = reward + REWARDS[g.category]
- return reward
- else:
- return reward
+ def budget_reward_amount(self) -> int:
+ reward = PLAYER_BUDGET_BASE * len(self.theater.player_points())
+ for cp in self.theater.player_points():
+ for g in cp.ground_objects:
+ if g.category in REWARDS.keys() and not g.is_dead:
+ reward += REWARDS[g.category]
+ return int(reward * self.settings.player_income_multiplier)
def _budget_player(self):
self.budget += self.budget_reward_amount
@@ -182,7 +178,8 @@ class Game:
def finish_event(self, event: Event, debriefing: Debriefing):
logging.info("Finishing event {}".format(event))
event.commit(debriefing)
- self.budget += event.bonus()
+ self.budget += int(event.bonus() *
+ self.settings.player_income_multiplier)
if event in self.events:
self.events.remove(event)
@@ -272,8 +269,7 @@ class Game:
if g.category in REWARDS.keys() and not g.is_dead:
production = production + REWARDS[g.category]
- # TODO: Why doesn't the enemy get the full budget?
- budget = production * 0.75
+ budget = production * self.settings.enemy_income_multiplier
for control_point in self.theater.enemy_points():
if budget < db.RUNWAY_REPAIR_COST:
diff --git a/game/settings.py b/game/settings.py
index c85f5c28..8dae3061 100644
--- a/game/settings.py
+++ b/game/settings.py
@@ -22,6 +22,8 @@ class Settings:
manpads: bool = True
cold_start: bool = False # Legacy parameter do not use
version: Optional[str] = None
+ player_income_multiplier: float = 1.0
+ enemy_income_multiplier: float = 1.0
# Performance oriented
perf_red_alert_state: bool = True
diff --git a/qt_ui/widgets/floatspinners.py b/qt_ui/widgets/floatspinners.py
new file mode 100644
index 00000000..058b3516
--- /dev/null
+++ b/qt_ui/widgets/floatspinners.py
@@ -0,0 +1,20 @@
+from typing import Optional
+
+from PySide2.QtWidgets import QSpinBox
+
+
+class TenthsSpinner(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}"
diff --git a/qt_ui/widgets/spinsliders.py b/qt_ui/widgets/spinsliders.py
new file mode 100644
index 00000000..1b63862b
--- /dev/null
+++ b/qt_ui/widgets/spinsliders.py
@@ -0,0 +1,26 @@
+from PySide2.QtCore import Qt
+from PySide2.QtWidgets import QGridLayout, QLabel, QSlider
+
+from qt_ui.widgets.floatspinners import TenthsSpinner
+
+
+class TenthsSpinSlider(QGridLayout):
+ def __init__(self, label: str, minimum: int, maximum: int,
+ initial: int) -> None:
+ super().__init__()
+ self.addWidget(QLabel(label), 0, 0)
+
+ slider = QSlider(Qt.Horizontal)
+ slider.setMinimum(minimum)
+ slider.setMaximum(maximum)
+ slider.setValue(initial)
+ self.spinner = TenthsSpinner(minimum, maximum, initial)
+ slider.valueChanged.connect(lambda x: self.spinner.setValue(x))
+ self.spinner.valueChanged.connect(lambda x: slider.setValue(x))
+
+ self.addWidget(slider, 1, 0)
+ self.addWidget(self.spinner, 1, 1)
+
+ @property
+ def value(self) -> float:
+ return self.spinner.value() / 10
diff --git a/qt_ui/windows/finances/QFinancesMenu.py b/qt_ui/windows/finances/QFinancesMenu.py
index 362f642c..67cd27c9 100644
--- a/qt_ui/windows/finances/QFinancesMenu.py
+++ b/qt_ui/windows/finances/QFinancesMenu.py
@@ -64,7 +64,11 @@ class QFinancesMenu(QDialog):
self.setLayout(layout)
- layout.addWidget(QHorizontalSeparationLine(), i+1, 0, 1, 3)
-
- layout.addWidget(QLabel("" + str(self.game.budget_reward_amount) + "M "), i+2, 2)
-
+ layout.addWidget(QHorizontalSeparationLine(), i + 1, 0, 1, 3)
+ layout.addWidget(QLabel(
+ f"Income multiplier: {game.settings.player_income_multiplier:.1f}"),
+ i + 2, 1
+ )
+ layout.addWidget(
+ QLabel("" + str(self.game.budget_reward_amount) + "M "),
+ i + 2, 2)
diff --git a/qt_ui/windows/newgame/QNewGameWizard.py b/qt_ui/windows/newgame/QNewGameWizard.py
index 65b7becc..704f9a9c 100644
--- a/qt_ui/windows/newgame/QNewGameWizard.py
+++ b/qt_ui/windows/newgame/QNewGameWizard.py
@@ -10,6 +10,7 @@ from jinja2 import Environment, FileSystemLoader, select_autoescape
from game import db
from game.settings import Settings
+from qt_ui.widgets.spinsliders import TenthsSpinSlider
from qt_ui.windows.newgame.QCampaignList import (
Campaign,
QCampaignList,
@@ -56,7 +57,10 @@ class NewGameWizard(QtWidgets.QWizard):
campaign = self.campaigns[0]
settings = Settings(
- supercarrier=self.field("supercarrier"),
+ player_income_multiplier=self.field(
+ "player_income_multiplier") / 10,
+ enemy_income_multiplier=self.field("enemy_income_multiplier") / 10,
+ supercarrier=self.field("supercarrier")
)
generator_settings = GeneratorSettings(
start_date=db.TIME_PERIODS[
@@ -321,44 +325,6 @@ class BudgetInputs(QtWidgets.QGridLayout):
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):
def __init__(self, parent=None):
super(MiscOptions, self).__init__(parent)
@@ -369,9 +335,14 @@ class MiscOptions(QtWidgets.QWizardPage):
QtGui.QPixmap('./resources/ui/wizard/logo1.png'))
midGame = QtWidgets.QCheckBox()
- multiplier_inputs = ForceMultiplierInputs()
- self.registerField('multiplier', multiplier_inputs.multiplier)
+ multiplier = TenthsSpinSlider("Enemy forces multiplier", 1, 50, 10)
+ self.registerField('multiplier', multiplier.spinner)
+ player_income = TenthsSpinSlider("Player income multiplier", 1, 50, 10)
+ self.registerField("player_income_multiplier", player_income.spinner)
+
+ enemy_income = TenthsSpinSlider("Enemy income multiplier", 1, 50, 10)
+ self.registerField("enemy_income_multiplier", enemy_income.spinner)
miscSettingsGroup = QtWidgets.QGroupBox("Misc Settings")
self.registerField('midGame', midGame)
@@ -392,7 +363,9 @@ class MiscOptions(QtWidgets.QWizardPage):
layout = QtWidgets.QGridLayout()
layout.addWidget(QtWidgets.QLabel("Start at mid game"), 1, 0)
layout.addWidget(midGame, 1, 1)
- layout.addLayout(multiplier_inputs, 2, 0)
+ layout.addLayout(multiplier, 2, 0)
+ layout.addLayout(player_income, 3, 0)
+ layout.addLayout(enemy_income, 4, 0)
miscSettingsGroup.setLayout(layout)
generatorLayout = QtWidgets.QGridLayout()
diff --git a/qt_ui/windows/settings/QSettingsWindow.py b/qt_ui/windows/settings/QSettingsWindow.py
index 0bf0de82..fae49153 100644
--- a/qt_ui/windows/settings/QSettingsWindow.py
+++ b/qt_ui/windows/settings/QSettingsWindow.py
@@ -24,6 +24,7 @@ import qt_ui.uiconstants as CONST
from game.game import Game
from game.infos.information import Information
from qt_ui.widgets.QLabeledWidget import QLabeledWidget
+from qt_ui.widgets.spinsliders import TenthsSpinSlider
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.finances.QFinancesMenu import QHorizontalSeparationLine
from qt_ui.windows.settings.plugins import PluginOptionsPage, PluginsPage
@@ -150,6 +151,15 @@ class QSettingsWindow(QDialog):
self.enemyCoalitionSkill.setCurrentIndex(CONST.SKILL_OPTIONS.index(self.game.settings.enemy_skill))
self.enemyAASkill.setCurrentIndex(CONST.SKILL_OPTIONS.index(self.game.settings.enemy_vehicle_skill))
+ self.player_income = TenthsSpinSlider(
+ "Player income multiplier", 1, 50,
+ int(self.game.settings.player_income_multiplier * 10))
+ self.player_income.spinner.valueChanged.connect(self.applySettings)
+ self.enemy_income = TenthsSpinSlider(
+ "Enemy income multiplier", 1, 50,
+ int(self.game.settings.enemy_income_multiplier * 10))
+ self.enemy_income.spinner.valueChanged.connect(self.applySettings)
+
self.playerCoalitionSkill.currentIndexChanged.connect(self.applySettings)
self.enemyCoalitionSkill.currentIndexChanged.connect(self.applySettings)
self.enemyAASkill.currentIndexChanged.connect(self.applySettings)
@@ -203,6 +213,8 @@ class QSettingsWindow(QDialog):
self.aiDifficultyLayout.addWidget(self.enemyCoalitionSkill, 1, 1, Qt.AlignRight)
self.aiDifficultyLayout.addWidget(QLabel("Enemy AA and vehicles skill"), 2, 0)
self.aiDifficultyLayout.addWidget(self.enemyAASkill, 2, 1, Qt.AlignRight)
+ self.aiDifficultyLayout.addLayout(self.player_income, 3, 0)
+ self.aiDifficultyLayout.addLayout(self.enemy_income, 4, 0)
self.aiDifficultySettings.setLayout(self.aiDifficultyLayout)
self.difficultyLayout.addWidget(self.aiDifficultySettings)
@@ -377,6 +389,8 @@ class QSettingsWindow(QDialog):
self.game.settings.player_skill = CONST.SKILL_OPTIONS[self.playerCoalitionSkill.currentIndex()]
self.game.settings.enemy_skill = CONST.SKILL_OPTIONS[self.enemyCoalitionSkill.currentIndex()]
self.game.settings.enemy_vehicle_skill = CONST.SKILL_OPTIONS[self.enemyAASkill.currentIndex()]
+ self.game.settings.player_income_multiplier = self.player_income.value
+ self.game.settings.enemy_income_multiplier = self.enemy_income.value
self.game.settings.manpads = self.manpads.isChecked()
self.game.settings.labels = CONST.LABELS_OPTIONS[self.difficultyLabel.currentIndex()]
self.game.settings.night_disabled = self.noNightMission.isChecked()