mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Move generator only settings out of Settings.
This commit is contained in:
parent
b8e64d4369
commit
f1a2602cfd
@ -6,12 +6,6 @@ from dcs.forcedoptions import ForcedOptions
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Settings:
|
class Settings:
|
||||||
# Generator settings
|
|
||||||
inverted: bool = False
|
|
||||||
do_not_generate_carrier: bool = False
|
|
||||||
do_not_generate_lha: bool = False
|
|
||||||
do_not_generate_player_navy: bool = False
|
|
||||||
do_not_generate_enemy_navy: bool = False
|
|
||||||
|
|
||||||
# Difficulty settings
|
# Difficulty settings
|
||||||
player_skill: str = "Good"
|
player_skill: str = "Good"
|
||||||
@ -25,7 +19,6 @@ class Settings:
|
|||||||
supercarrier: bool = False
|
supercarrier: bool = False
|
||||||
multiplier: float = 1.0
|
multiplier: float = 1.0
|
||||||
generate_marks: bool = True
|
generate_marks: bool = True
|
||||||
sams: bool = True # Legacy parameter do not use
|
|
||||||
manpads: bool = True
|
manpads: bool = True
|
||||||
cold_start: bool = False # Legacy parameter do not use
|
cold_start: bool = False # Legacy parameter do not use
|
||||||
version: Optional[str] = None
|
version: Optional[str] = None
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import logging
|
|||||||
import math
|
import math
|
||||||
import pickle
|
import pickle
|
||||||
import random
|
import random
|
||||||
from typing import Any, Dict, Iterable, Optional, Set
|
from dataclasses import dataclass
|
||||||
|
from datetime import datetime
|
||||||
|
from typing import Any, Dict, Iterable, List, Optional, Set
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.task import CAP, CAS, PinpointStrike
|
from dcs.task import CAP, CAS, PinpointStrike
|
||||||
@ -12,8 +14,7 @@ from dcs.vehicles import AirDefence
|
|||||||
|
|
||||||
from game import Game, db
|
from game import Game, db
|
||||||
from game.factions.faction import Faction
|
from game.factions.faction import Faction
|
||||||
from game.settings import Settings
|
from game.theater import Carrier, Lha, LocationType
|
||||||
from game.theater import LocationType
|
|
||||||
from game.theater.conflicttheater import IMPORTANCE_HIGH, IMPORTANCE_LOW
|
from game.theater.conflicttheater import IMPORTANCE_HIGH, IMPORTANCE_LOW
|
||||||
from game.theater.theatergroundobject import (
|
from game.theater.theatergroundobject import (
|
||||||
BuildingGroundObject,
|
BuildingGroundObject,
|
||||||
@ -44,9 +45,10 @@ from . import (
|
|||||||
ConflictTheater,
|
ConflictTheater,
|
||||||
ControlPoint,
|
ControlPoint,
|
||||||
ControlPointType,
|
ControlPointType,
|
||||||
OffMapSpawn,
|
|
||||||
Fob,
|
Fob,
|
||||||
|
OffMapSpawn,
|
||||||
)
|
)
|
||||||
|
from ..settings import Settings
|
||||||
|
|
||||||
GroundObjectTemplates = Dict[str, Dict[str, Any]]
|
GroundObjectTemplates = Dict[str, Dict[str, Any]]
|
||||||
|
|
||||||
@ -62,18 +64,28 @@ COUNT_BY_TASK = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class GeneratorSettings:
|
||||||
|
start_date: datetime
|
||||||
|
starting_budget: int
|
||||||
|
multiplier: float
|
||||||
|
midgame: bool
|
||||||
|
inverted: bool
|
||||||
|
no_carrier: bool
|
||||||
|
no_lha: bool
|
||||||
|
no_player_navy: bool
|
||||||
|
no_enemy_navy: bool
|
||||||
|
|
||||||
|
|
||||||
class GameGenerator:
|
class GameGenerator:
|
||||||
def __init__(self, player: str, enemy: str, theater: ConflictTheater,
|
def __init__(self, player: str, enemy: str, theater: ConflictTheater,
|
||||||
settings: Settings, start_date, starting_budget: int,
|
settings: Settings,
|
||||||
multiplier: float, midgame: bool) -> None:
|
generator_settings: GeneratorSettings) -> None:
|
||||||
self.player = player
|
self.player = player
|
||||||
self.enemy = enemy
|
self.enemy = enemy
|
||||||
self.theater = theater
|
self.theater = theater
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
self.start_date = start_date
|
self.generator_settings = generator_settings
|
||||||
self.starting_budget = starting_budget
|
|
||||||
self.multiplier = multiplier
|
|
||||||
self.midgame = midgame
|
|
||||||
|
|
||||||
def generate(self) -> Game:
|
def generate(self) -> Game:
|
||||||
# Reset name generator
|
# Reset name generator
|
||||||
@ -83,35 +95,30 @@ class GameGenerator:
|
|||||||
game = Game(player_name=self.player,
|
game = Game(player_name=self.player,
|
||||||
enemy_name=self.enemy,
|
enemy_name=self.enemy,
|
||||||
theater=self.theater,
|
theater=self.theater,
|
||||||
start_date=self.start_date,
|
start_date=self.generator_settings.start_date,
|
||||||
settings=self.settings)
|
settings=self.settings)
|
||||||
|
|
||||||
GroundObjectGenerator(game).generate()
|
GroundObjectGenerator(game, self.generator_settings).generate()
|
||||||
game.budget = self.starting_budget
|
game.budget = self.generator_settings.starting_budget
|
||||||
game.settings.multiplier = self.multiplier
|
|
||||||
game.settings.sams = True
|
|
||||||
game.settings.version = VERSION
|
game.settings.version = VERSION
|
||||||
return game
|
return game
|
||||||
|
|
||||||
def prepare_theater(self) -> None:
|
def prepare_theater(self) -> None:
|
||||||
to_remove = []
|
to_remove: List[ControlPoint] = []
|
||||||
# Auto-capture half the bases if midgame.
|
# Auto-capture half the bases if midgame.
|
||||||
if self.midgame:
|
if self.generator_settings.midgame:
|
||||||
control_points = self.theater.controlpoints
|
control_points = self.theater.controlpoints
|
||||||
for control_point in control_points[:len(control_points) // 2]:
|
for control_point in control_points[:len(control_points) // 2]:
|
||||||
control_point.captured = True
|
control_point.captured = True
|
||||||
|
|
||||||
# Remove carrier and lha, invert situation if needed
|
# Remove carrier and lha, invert situation if needed
|
||||||
for cp in self.theater.controlpoints:
|
for cp in self.theater.controlpoints:
|
||||||
no_carrier = self.settings.do_not_generate_carrier
|
if isinstance(cp, Carrier) and self.generator_settings.no_carrier:
|
||||||
no_lha = self.settings.do_not_generate_lha
|
|
||||||
if cp.cptype is ControlPointType.AIRCRAFT_CARRIER_GROUP and \
|
|
||||||
no_carrier:
|
|
||||||
to_remove.append(cp)
|
to_remove.append(cp)
|
||||||
elif cp.cptype is ControlPointType.LHA_GROUP and no_lha:
|
elif isinstance(cp, Lha) and self.generator_settings.no_lha:
|
||||||
to_remove.append(cp)
|
to_remove.append(cp)
|
||||||
|
|
||||||
if self.settings.inverted:
|
if self.generator_settings.inverted:
|
||||||
cp.captured = cp.captured_invert
|
cp.captured = cp.captured_invert
|
||||||
|
|
||||||
# do remove
|
# do remove
|
||||||
@ -120,7 +127,7 @@ class GameGenerator:
|
|||||||
|
|
||||||
# TODO: Fix this. This captures all bases for blue.
|
# TODO: Fix this. This captures all bases for blue.
|
||||||
# reapply midgame inverted if needed
|
# reapply midgame inverted if needed
|
||||||
if self.midgame and self.settings.inverted:
|
if self.generator_settings.midgame and self.generator_settings.inverted:
|
||||||
for i, cp in enumerate(reversed(self.theater.controlpoints)):
|
for i, cp in enumerate(reversed(self.theater.controlpoints)):
|
||||||
if i > len(self.theater.controlpoints):
|
if i > len(self.theater.controlpoints):
|
||||||
break
|
break
|
||||||
@ -163,9 +170,10 @@ class GameGenerator:
|
|||||||
|
|
||||||
count_log = math.log(control_point.importance + 0.01,
|
count_log = math.log(control_point.importance + 0.01,
|
||||||
UNIT_COUNT_IMPORTANCE_LOG)
|
UNIT_COUNT_IMPORTANCE_LOG)
|
||||||
count = max(
|
count = max((COUNT_BY_TASK[task] *
|
||||||
COUNT_BY_TASK[task] * self.multiplier * (1 + count_log), 1
|
self.generator_settings.multiplier *
|
||||||
)
|
(count_log + 1)),
|
||||||
|
1)
|
||||||
|
|
||||||
count_per_type = max(int(float(count) / len(unit_types)), 1)
|
count_per_type = max(int(float(count) / len(unit_types)), 1)
|
||||||
for unit_type in unit_types:
|
for unit_type in unit_types:
|
||||||
@ -316,8 +324,10 @@ class LocationFinder:
|
|||||||
|
|
||||||
|
|
||||||
class ControlPointGroundObjectGenerator:
|
class ControlPointGroundObjectGenerator:
|
||||||
def __init__(self, game: Game, control_point: ControlPoint) -> None:
|
def __init__(self, game: Game, generator_settings: GeneratorSettings,
|
||||||
|
control_point: ControlPoint) -> None:
|
||||||
self.game = game
|
self.game = game
|
||||||
|
self.generator_settings = generator_settings
|
||||||
self.control_point = control_point
|
self.control_point = control_point
|
||||||
self.location_finder = LocationFinder(game, control_point)
|
self.location_finder = LocationFinder(game, control_point)
|
||||||
|
|
||||||
@ -344,11 +354,11 @@ class ControlPointGroundObjectGenerator:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def generate_navy(self) -> None:
|
def generate_navy(self) -> None:
|
||||||
skip_player_navy = self.game.settings.do_not_generate_player_navy
|
skip_player_navy = self.generator_settings.no_player_navy
|
||||||
if self.control_point.captured and skip_player_navy:
|
if self.control_point.captured and skip_player_navy:
|
||||||
return
|
return
|
||||||
|
|
||||||
skip_enemy_navy = self.game.settings.do_not_generate_enemy_navy
|
skip_enemy_navy = self.generator_settings.no_enemy_navy
|
||||||
if not self.control_point.captured and skip_enemy_navy:
|
if not self.control_point.captured and skip_enemy_navy:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -538,6 +548,8 @@ class BaseDefenseGenerator:
|
|||||||
return
|
return
|
||||||
g.groups.append(group)
|
g.groups.append(group)
|
||||||
self.control_point.base_defenses.append(g)
|
self.control_point.base_defenses.append(g)
|
||||||
|
|
||||||
|
|
||||||
class FobDefenseGenerator(BaseDefenseGenerator):
|
class FobDefenseGenerator(BaseDefenseGenerator):
|
||||||
def generate(self) -> None:
|
def generate(self) -> None:
|
||||||
self.generate_garrison()
|
self.generate_garrison()
|
||||||
@ -559,10 +571,12 @@ class FobDefenseGenerator(BaseDefenseGenerator):
|
|||||||
else:
|
else:
|
||||||
self.generate_garrison()
|
self.generate_garrison()
|
||||||
|
|
||||||
|
|
||||||
class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
||||||
def __init__(self, game: Game, control_point: ControlPoint,
|
def __init__(self, game: Game, generator_settings: GeneratorSettings,
|
||||||
|
control_point: ControlPoint,
|
||||||
templates: GroundObjectTemplates) -> None:
|
templates: GroundObjectTemplates) -> None:
|
||||||
super().__init__(game, control_point)
|
super().__init__(game, generator_settings, control_point)
|
||||||
self.templates = templates
|
self.templates = templates
|
||||||
|
|
||||||
def generate(self) -> bool:
|
def generate(self) -> bool:
|
||||||
@ -699,6 +713,7 @@ class AirbaseGroundObjectGenerator(ControlPointGroundObjectGenerator):
|
|||||||
self.control_point.connected_objectives.append(g)
|
self.control_point.connected_objectives.append(g)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
class FobGroundObjectGenerator(AirbaseGroundObjectGenerator):
|
class FobGroundObjectGenerator(AirbaseGroundObjectGenerator):
|
||||||
def generate(self) -> bool:
|
def generate(self) -> bool:
|
||||||
self.generate_fob()
|
self.generate_fob()
|
||||||
@ -729,9 +744,12 @@ class FobGroundObjectGenerator(AirbaseGroundObjectGenerator):
|
|||||||
unit["heading"], self.control_point, unit["type"], airbase_group=True)
|
unit["heading"], self.control_point, unit["type"], airbase_group=True)
|
||||||
self.control_point.connected_objectives.append(g)
|
self.control_point.connected_objectives.append(g)
|
||||||
|
|
||||||
|
|
||||||
class GroundObjectGenerator:
|
class GroundObjectGenerator:
|
||||||
def __init__(self, game: Game) -> None:
|
def __init__(self, game: Game,
|
||||||
|
generator_settings: GeneratorSettings) -> None:
|
||||||
self.game = game
|
self.game = game
|
||||||
|
self.generator_settings = generator_settings
|
||||||
with open("resources/groundobject_templates.p", "rb") as f:
|
with open("resources/groundobject_templates.p", "rb") as f:
|
||||||
self.templates: GroundObjectTemplates = pickle.load(f)
|
self.templates: GroundObjectTemplates = pickle.load(f)
|
||||||
|
|
||||||
@ -746,15 +764,20 @@ class GroundObjectGenerator:
|
|||||||
def generate_for_control_point(self, control_point: ControlPoint) -> bool:
|
def generate_for_control_point(self, control_point: ControlPoint) -> bool:
|
||||||
generator: ControlPointGroundObjectGenerator
|
generator: ControlPointGroundObjectGenerator
|
||||||
if control_point.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP:
|
if control_point.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP:
|
||||||
generator = CarrierGroundObjectGenerator(self.game, control_point)
|
generator = CarrierGroundObjectGenerator(
|
||||||
|
self.game, self.generator_settings, control_point)
|
||||||
elif control_point.cptype == ControlPointType.LHA_GROUP:
|
elif control_point.cptype == ControlPointType.LHA_GROUP:
|
||||||
generator = LhaGroundObjectGenerator(self.game, control_point)
|
generator = LhaGroundObjectGenerator(
|
||||||
|
self.game, self.generator_settings, control_point)
|
||||||
elif isinstance(control_point, OffMapSpawn):
|
elif isinstance(control_point, OffMapSpawn):
|
||||||
generator = NoOpGroundObjectGenerator(self.game, control_point)
|
generator = NoOpGroundObjectGenerator(
|
||||||
|
self.game, self.generator_settings, control_point)
|
||||||
elif isinstance(control_point, Fob):
|
elif isinstance(control_point, Fob):
|
||||||
generator = FobGroundObjectGenerator(self.game, control_point,
|
generator = FobGroundObjectGenerator(
|
||||||
self.templates)
|
self.game, self.generator_settings, control_point,
|
||||||
|
self.templates)
|
||||||
else:
|
else:
|
||||||
generator = AirbaseGroundObjectGenerator(self.game, control_point,
|
generator = AirbaseGroundObjectGenerator(
|
||||||
self.templates)
|
self.game, self.generator_settings, control_point,
|
||||||
|
self.templates)
|
||||||
return generator.generate()
|
return generator.generate()
|
||||||
|
|||||||
@ -13,7 +13,7 @@ from PySide2.QtWidgets import QApplication, QSplashScreen
|
|||||||
|
|
||||||
from game import Game, db, persistency, VERSION
|
from game import Game, db, persistency, VERSION
|
||||||
from game.settings import Settings
|
from game.settings import Settings
|
||||||
from game.theater.start_generator import GameGenerator
|
from game.theater.start_generator import GameGenerator, GeneratorSettings
|
||||||
from qt_ui import (
|
from qt_ui import (
|
||||||
liberation_install,
|
liberation_install,
|
||||||
liberation_theme,
|
liberation_theme,
|
||||||
@ -128,11 +128,21 @@ def parse_args() -> argparse.Namespace:
|
|||||||
def create_game(campaign_path: Path, blue: str, red: str,
|
def create_game(campaign_path: Path, blue: str, red: str,
|
||||||
supercarrier: bool) -> Game:
|
supercarrier: bool) -> Game:
|
||||||
campaign = Campaign.from_json(campaign_path)
|
campaign = Campaign.from_json(campaign_path)
|
||||||
generator = GameGenerator(blue, red, campaign.load_theater(),
|
generator = GameGenerator(
|
||||||
Settings(supercarrier=supercarrier),
|
blue, red, campaign.load_theater(),
|
||||||
start_date=datetime.today(),
|
Settings(supercarrier=supercarrier),
|
||||||
starting_budget=650,
|
GeneratorSettings(
|
||||||
multiplier=1, midgame=False)
|
start_date=datetime.today(),
|
||||||
|
starting_budget=650,
|
||||||
|
multiplier=1.0,
|
||||||
|
midgame=False,
|
||||||
|
inverted=False,
|
||||||
|
no_carrier=False,
|
||||||
|
no_lha=False,
|
||||||
|
no_player_navy=False,
|
||||||
|
no_enemy_navy=False
|
||||||
|
)
|
||||||
|
)
|
||||||
return generator.generate()
|
return generator.generate()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ from qt_ui.windows.newgame.QCampaignList import (
|
|||||||
QCampaignList,
|
QCampaignList,
|
||||||
load_campaigns,
|
load_campaigns,
|
||||||
)
|
)
|
||||||
from game.theater.start_generator import GameGenerator
|
from game.theater.start_generator import GameGenerator, GeneratorSettings
|
||||||
|
|
||||||
jinja_env = Environment(
|
jinja_env = Environment(
|
||||||
loader=FileSystemLoader("resources/ui/templates"),
|
loader=FileSystemLoader("resources/ui/templates"),
|
||||||
@ -51,43 +51,37 @@ class NewGameWizard(QtWidgets.QWizard):
|
|||||||
logging.info("New Game Wizard accept")
|
logging.info("New Game Wizard accept")
|
||||||
logging.info("======================")
|
logging.info("======================")
|
||||||
|
|
||||||
blueFaction = [c for c in db.FACTIONS][self.field("blueFaction")]
|
campaign = self.field("selectedCampaign")
|
||||||
redFaction = [c for c in db.FACTIONS][self.field("redFaction")]
|
if campaign is None:
|
||||||
|
campaign = self.campaigns[0]
|
||||||
selectedCampaign = self.field("selectedCampaign")
|
|
||||||
if selectedCampaign is None:
|
|
||||||
selectedCampaign = self.campaigns[0]
|
|
||||||
|
|
||||||
conflictTheater = selectedCampaign.load_theater()
|
|
||||||
|
|
||||||
timePeriod = db.TIME_PERIODS[list(db.TIME_PERIODS.keys())[self.field("timePeriod")]]
|
|
||||||
midGame = self.field("midGame")
|
|
||||||
# QSlider forces integers, so we use 1 to 50 and divide by 10 to give
|
|
||||||
# 0.1 to 5.0.
|
|
||||||
multiplier = self.field("multiplier") / 10
|
|
||||||
no_carrier = self.field("no_carrier")
|
|
||||||
no_lha = self.field("no_lha")
|
|
||||||
supercarrier = self.field("supercarrier")
|
|
||||||
no_player_navy = self.field("no_player_navy")
|
|
||||||
no_enemy_navy = self.field("no_enemy_navy")
|
|
||||||
invertMap = self.field("invertMap")
|
|
||||||
starting_money = int(self.field("starting_money"))
|
|
||||||
|
|
||||||
player_name = blueFaction
|
|
||||||
enemy_name = redFaction
|
|
||||||
|
|
||||||
settings = Settings(
|
settings = Settings(
|
||||||
inverted=invertMap,
|
supercarrier=self.field("supercarrier"),
|
||||||
supercarrier=supercarrier,
|
)
|
||||||
do_not_generate_carrier=no_carrier,
|
generator_settings = GeneratorSettings(
|
||||||
do_not_generate_lha=no_lha,
|
start_date=db.TIME_PERIODS[
|
||||||
do_not_generate_player_navy=no_player_navy,
|
list(db.TIME_PERIODS.keys())[self.field("timePeriod")]],
|
||||||
do_not_generate_enemy_navy=no_enemy_navy
|
starting_budget=int(self.field("starting_money")),
|
||||||
|
# QSlider forces integers, so we use 1 to 50 and divide by 10 to
|
||||||
|
# give 0.1 to 5.0.
|
||||||
|
multiplier=self.field("multiplier") / 10,
|
||||||
|
midgame=self.field("midGame"),
|
||||||
|
inverted=self.field("invertMap"),
|
||||||
|
no_carrier=self.field("no_carrier"),
|
||||||
|
no_lha=self.field("no_lha"),
|
||||||
|
no_player_navy=self.field("no_player_navy"),
|
||||||
|
no_enemy_navy=self.field("no_enemy_navy")
|
||||||
)
|
)
|
||||||
|
|
||||||
generator = GameGenerator(player_name, enemy_name, conflictTheater,
|
blue_faction = [c for c in db.FACTIONS][self.field("blueFaction")]
|
||||||
settings, timePeriod, starting_money,
|
red_faction = [c for c in db.FACTIONS][self.field("redFaction")]
|
||||||
multiplier, midGame)
|
generator = GameGenerator(
|
||||||
|
blue_faction,
|
||||||
|
red_faction,
|
||||||
|
campaign.load_theater(),
|
||||||
|
settings,
|
||||||
|
generator_settings
|
||||||
|
)
|
||||||
self.generatedGame = generator.generate()
|
self.generatedGame = generator.generate()
|
||||||
|
|
||||||
super(NewGameWizard, self).accept()
|
super(NewGameWizard, self).accept()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user