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