Ground objects have 'Objective' name for easier search. Predefined Waypoint generator entirely reworked.

Added finances menu, and info panel.
This commit is contained in:
Khopa 2020-05-29 00:40:06 +02:00
parent 6dec5ea8f8
commit fc64e57495
29 changed files with 571 additions and 239 deletions

View File

@ -739,6 +739,14 @@ TIME_PERIODS = {
"Syrian War [2011]": datetime(2011, 8, 7),
}
REWARDS = {
"power": 4, "warehouse": 2, "fuel": 2, "ammo": 2,
"farp": 1, "fob": 1, "factory": 10, "comms": 10, "oil": 10
}
# Base post-turn bonus value
PLAYER_BUDGET_BASE = 20
CARRIER_CAPABLE = [
FA_18C_hornet,
F_14B,

View File

@ -8,6 +8,7 @@ from dcs.vehicles import AirDefence
from dcs.unittype import UnitType
from game import *
from game.infos.information import Information
from theater import *
from gen.environmentgen import EnvironmentSettings
from gen.conflictgen import Conflict
@ -220,6 +221,10 @@ class Event:
cp.base.aa = {}
for g in cp.ground_objects:
g.groups = []
info = Information(cp.name + " lost !",
"The ennemy took control of " + cp.name + "\nShame on us !",
self.game.turn)
self.game.informations.append(info)
elif not(cp.captured) and new_owner_coalition == coalition:
cp.captured = True
cp.base.aircraft = {}
@ -227,6 +232,10 @@ class Event:
cp.base.aa = {}
for g in cp.ground_objects:
g.groups = []
info = Information(cp.name + " captured !",
"The ennemy took control of " + cp.name + "\nShame on us !",
self.game.turn)
self.game.informations.append(info)
except Exception as e:
print(e)
@ -281,17 +290,25 @@ class Event:
# No progress with defensive strategies
if player_won and cp.stances[enemy_cp.id] in [CombatStance.DEFENSIVE, CombatStance.AMBUSH]:
print("Defensive stance, no progress")
delta = 0
print("Defensive stance, progress is limited")
delta = MINOR_DEFEAT_INFLUENCE
if player_won:
print(cp.name + " won ! factor > " + str(delta))
cp.base.affect_strength(delta)
enemy_cp.base.affect_strength(-delta)
info = Information("Frontline Report",
"Our ground forces from " + cp.name + " are making progress toward " + enemy_cp.name,
self.game.turn)
self.game.informations.append(info)
else:
print(enemy_cp.name + " won ! factor > " + str(delta))
print(cp.name + " lost ! factor > " + str(delta))
enemy_cp.base.affect_strength(delta)
cp.base.affect_strength(-delta)
info = Information("Frontline Report",
"Our ground forces from " + cp.name + " are losing ground against the enemy forces from" + enemy_cp.name,
self.game.turn)
self.game.informations.append(info)
def skip(self):
pass
@ -319,4 +336,9 @@ class UnitsDeliveryEvent(Event):
self.units[k] = self.units.get(k, 0) + v
def skip(self):
for k, v in self.units.items():
info = Information("Ally Reinforcement", str(k.id) + " x " + str(v) + " at " + self.to_cp.name, self.game.turn)
self.game.informations.append(info)
self.to_cp.base.commision_units(self.units)

View File

@ -4,7 +4,7 @@ from dcs.planes import *
from dcs.helicopters import *
Lybia_2011 = {
"country": "Libya",
"country": "Russia",
"side": "red",
"units": [

View File

@ -6,6 +6,7 @@ import math
from dcs.task import *
from dcs.vehicles import *
from game.db import REWARDS, PLAYER_BUDGET_BASE
from game.game_stats import GameStats
from game.infos.information import Information
from gen.conflictgen import Conflict
@ -50,10 +51,7 @@ ENEMY_BASE_STRENGTH_RECOVERY = 0.05
AWACS_BUDGET_COST = 4
# Initial budget value
PLAYER_BUDGET_INITIAL = 450
# Base post-turn bonus value
PLAYER_BUDGET_BASE = 20
PLAYER_BUDGET_INITIAL = 650
# Bonus multiplier logarithm base
PLAYER_BUDGET_IMPORTANCE_LOG = 2
@ -86,6 +84,7 @@ class Game:
self.planners = {}
self.ground_planners = {}
self.informations = []
self.informations.append(Information("Game Start", "-" * 40, 0))
def _roll(self, prob, mult):
if self.settings.version == "dev":
@ -111,10 +110,12 @@ class Game:
def _commision_units(self, cp: ControlPoint):
for for_task in [CAS, CAP, AirDefence]:
limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_LIMITS_SCALE) * self.settings.multiplier
limit = COMMISION_LIMITS_FACTORS[for_task] * math.pow(cp.importance,
COMMISION_LIMITS_SCALE) * self.settings.multiplier
missing_units = limit - cp.base.total_units(for_task)
if missing_units > 0:
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance, COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
awarded_points = COMMISION_AMOUNTS_FACTORS[for_task] * math.pow(cp.importance,
COMMISION_AMOUNTS_SCALE) * self.settings.multiplier
points_to_spend = cp.base.append_commision_points(for_task, awarded_points)
if points_to_spend > 0:
unittypes = self.commision_unit_types(cp, for_task)
@ -130,25 +131,8 @@ class Game:
reward = PLAYER_BUDGET_BASE * len(self.theater.player_points())
for cp in self.theater.player_points():
for g in cp.ground_objects:
# (Reward is per building)
if g.category == "power":
reward = reward + 4
elif g.category == "warehouse":
reward = reward + 2
elif g.category == "fuel":
reward = reward + 2
elif g.category == "ammo":
reward = reward + 2
elif g.category == "farp":
reward = reward + 1
elif g.category == "fob":
reward = reward + 1
elif g.category == "factory":
reward = reward + 10
elif g.category == "comms":
reward = reward + 10
elif g.category == "oil":
reward = reward + 10
if g.category in REWARDS.keys():
reward = reward + REWARDS[g.category]
return reward
else:
return reward
@ -197,9 +181,9 @@ class Game:
else:
return event.name == self.player_name
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")
self.informations.append(Information("End of turn #" + str(self.turn), "-" * 40, 0))
self.turn = self.turn + 1
for event in self.events:
@ -210,7 +194,6 @@ class Game:
else:
event.skip()
self._enemy_reinforcement()
self._budget_player()
@ -246,34 +229,17 @@ class Game:
gplanner.plan_groundwar()
self.ground_planners[cp.id] = gplanner
def _enemy_reinforcement(self):
MAX_ARMOR = 50 * self.settings.multiplier
MAX_AIRCRAFT = 50 * self.settings.multiplier
MAX_ARMOR = 30 * self.settings.multiplier
MAX_AIRCRAFT = 25 * self.settings.multiplier
production = 0
production = 0.0
for enemy_point in self.theater.enemy_points():
for g in enemy_point.ground_objects:
if g.category == "power":
production = production + 4
elif g.category == "warehouse":
production = production + 2
elif g.category == "fuel":
production = production + 2
elif g.category == "ammo":
production = production + 2
elif g.category == "farp":
production = production + 1
elif g.category == "fob":
production = production + 1
elif g.category == "factory":
production = production + 10
elif g.category == "comms":
production = production + 8
elif g.category == "oil":
production = production + 8
if g.category in REWARDS.keys():
production = production + REWARDS[g.category]
production = production * 0.75
budget_for_armored_units = production / 2
budget_for_aircraft = production / 2
@ -302,7 +268,7 @@ class Game:
if target_cp.base.total_armor >= MAX_ARMOR:
continue
unit = random.choice(potential_units)
price = db.PRICES[unit]*2
price = db.PRICES[unit] * 2
budget_for_armored_units -= price * 2
target_cp.base.armor[unit] = target_cp.base.armor.get(unit, 0) + 2
info = Information("Enemy Reinforcement", unit.id + " x 2 at " + target_cp.name, self.turn)
@ -312,7 +278,8 @@ class Game:
if budget_for_armored_units > 0:
budget_for_aircraft += budget_for_armored_units
potential_units = [u for u in db.FACTIONS[self.enemy_name]["units"] if u in db.UNIT_BY_TASK[CAS] or u in db.UNIT_BY_TASK[CAP]]
potential_units = [u for u in db.FACTIONS[self.enemy_name]["units"] if
u in db.UNIT_BY_TASK[CAS] or u in db.UNIT_BY_TASK[CAP]]
if len(potential_units) > 0 and len(potential_cp_armor) > 0:
while budget_for_aircraft > 0:
i = i + 1
@ -322,22 +289,20 @@ class Game:
if target_cp.base.total_planes >= MAX_AIRCRAFT:
continue
unit = random.choice(potential_units)
price = db.PRICES[unit]*2
price = db.PRICES[unit] * 2
budget_for_aircraft -= price * 2
target_cp.base.aircraft[unit] = target_cp.base.aircraft.get(unit, 0) + 2
info = Information("Enemy Reinforcement", unit.id + " x 2 at " + target_cp.name, self.turn)
print(str(info))
self.informations.append(info)
@property
def current_turn_daytime(self):
return ["dawn", "day", "dusk", "night"][self.turn % 4]
@property
def current_day(self):
return self.date + timedelta(days=self.turn//4)
return self.date + timedelta(days=self.turn // 4)
def next_unit_id(self):
"""

View File

@ -39,6 +39,8 @@ class FlightWaypoint():
self.name = ""
self.description = ""
self.targets = []
self.obj_name = ""
self.pretty_name = ""
class Flight:

View File

@ -1,9 +1,48 @@
from game import db
import random
ALPHA_MILITARY = ["Alpha","Bravo","Charlie","Delta","Echo","Foxtrot",
"Golf","Hotel","India","Juliet","Kilo","Lima","Mike",
"November","Oscar","Papa","Quebec","Romeo","Sierra",
"Tango","Uniform","Victor","Whisky","XRay","Yankee",
"Zulu","Zero"]
class NameGenerator:
number = 0
ANIMALS = [
"SHARK", "TORTOISE", "BAT", "PANGOLIN", "AARDWOLF",
"MONKEY", "BUFFALO", "DOG", "BOBCAT", "LYNX", "PANTHER", "TIGER",
"LION", "OWL", "BUTTERFLY", "BISON", "DUCK", "COBRA", "MAMBA",
"DOLPHIN", "PHEASANT", "ARMADILLLO", "RACOON", "ZEBRA", "COW", "COYOTE", "FOX",
"LIGHTFOOT", "COTTONMOUTH", "TAURUS", "VIPER", "CASTOR", "GIRAFFE", "SNAKE",
"MONSTER", "ALBATROSS", "HAWK", "DOVE", "MOCKINGBIRD", "GECKO", "ORYX", "GORILLA",
"HARAMBE", "GOOSE", "MAVERICK", "HARE", "JACKAL", "LEOPARD", "CAT", "MUSK", "ORCA",
"OCELOT", "BEAR", "PANDA", "GULL", "PENGUIN", "PYTHON", "RAVEN", "DEER", "MOOSE",
"REINDEER", "SHEEP", "GAZELLE", "INSECT", "VULTURE", "WALLABY", "KANGAROO", "KOALA",
"KIWI", "WHALE", "FISH", "RHINO", "HIPPO", "RAT", "WOODPECKER", "WORM", "BABOON",
"YAK", "SCORPIO", "HORSE", "POODLE", "CENTIPEDE", "CHICKEN", "CHEETAH", "CHAMELEON",
"CATFISH", "CATERPILLAR", "CARACAL", "CAMEL", "CAIMAN", "BARRACUDA", "BANDICOOT",
"ALLIGATOR", "BONGO", "CORAL", "ELEPHANT", "ANTELOPE", "CRAB", "DACHSHUND", "DODO",
"FLAMINGO", "FERRET", "FALCON", "BULLDOG", "DONKEY", "IGUANA", "TAMARIN", "HARRIER",
"GRIZZLY", "GREYHOUND", "GRASSHOPPER", "JAGUAR", "LADYBUG", "KOMODO", "DRAGON", "LIZARD",
"LLAMA", "LOBSTER", "OCTOPUS", "MANATEE", "MAGPIE", "MACAW", "OSTRICH", "OYSTER",
"MOLE", "MULE", "MOTH", "MONGOOSE", "MOLLY", "MEERKAT", "MOUSE", "PEACOCK", "PIKE", "ROBIN",
"RAGDOLL", "PLATYPUS", "PELICAN", "PARROT", "PORCUPINE", "PIRANHA", "PUMA", "PUG", "TAPIR",
"TERMITE", "URCHIN", "SHRIMP", "TURKEY", "TOUCAN", "TETRA", "HUSKY", "STARFISH", "SWAN",
"FROG", "SQUIRREL", "WALRUS", "WARTHOG", "CORGI", "WEASEL", "WOMBAT", "WOLVERINE", "MAMMOTH",
"TOAD", "WOLF", "ZEBU", "SEAL", "SKATE", "JELLYFISH", "MOSQUITO", "LOCUST", "SLUG", "SNAIL",
"HEDGEHOG", "PIGLET", "FENNEC", "BADGER", "ALPACA"
]
def __init__(self):
self.number = 0
self.ANIMALS = NameGenerator.ANIMALS.copy()
def reset(self):
self.number = 0
self.ANIMALS = NameGenerator.ANIMALS.copy()
def next_unit_name(self, country, parent_base_id, unit_type):
self.number += 1
return "unit|{}|{}|{}|{}|".format(country.id, self.number, parent_base_id, db.unit_type_name(unit_type))
@ -27,6 +66,16 @@ class NameGenerator:
self.number += 1
return "carrier|{}|{}|0|".format(country.id, self.number)
def random_objective_name(self):
if len(self.ANIMALS) == 0:
random.choice(ALPHA_MILITARY).upper() + " #" + str(random.randint(0, 100))
else:
animal = random.choice(self.ANIMALS)
self.ANIMALS.remove(animal)
return animal
namegen = NameGenerator()

View File

@ -88,12 +88,10 @@ EVENT_ICONS: Dict[str, QPixmap] = {}
def load_event_icons():
for category, image in {
"strike": "strike",
FrontlineAttackEvent: "attack",
UnitsDeliveryEvent: "delivery"}.items():
EVENT_ICONS[category] = QPixmap("./resources/ui/events/" + image + ".png")
for image in os.listdir("./resources/ui/events/"):
print(image)
if image.endswith(".PNG"):
EVENT_ICONS[image[:-4]] = QPixmap(os.path.join("./resources/ui/events/", image))
def load_aircraft_icons():
for aircraft in os.listdir("./resources/ui/units/aircrafts/"):

View File

@ -1,6 +1,7 @@
from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox
from PySide2.QtWidgets import QLabel, QHBoxLayout, QGroupBox, QPushButton
import qt_ui.uiconstants as CONST
from qt_ui.windows.finances.QFinancesMenu import QFinancesMenu
class QBudgetBox(QGroupBox):
@ -8,16 +9,22 @@ class QBudgetBox(QGroupBox):
UI Component to display current budget and player's money
"""
def __init__(self):
def __init__(self, game):
super(QBudgetBox, self).__init__("Budget")
self.game = game
self.money_icon = QLabel()
self.money_icon.setPixmap(CONST.ICONS["Money"])
self.money_amount = QLabel()
self.finances = QPushButton("Details")
self.finances.setProperty("style", "btn-primary")
self.finances.clicked.connect(self.openFinances)
self.layout = QHBoxLayout()
self.layout.addWidget(self.money_icon)
self.layout.addWidget(self.money_amount)
self.layout.addWidget(self.finances)
self.setLayout(self.layout)
def setBudget(self, budget, reward):
@ -26,4 +33,12 @@ class QBudgetBox(QGroupBox):
:param budget: Current money available
:param reward: Planned reward for next turn
"""
self.money_amount.setText(str(budget) + "M (+" + str(reward) + "M)")
self.money_amount.setText(str(budget) + "M (+" + str(reward) + "M)")
def setGame(self, game):
self.game = game
self.setBudget(self.game.budget, self.game.budget_reward_amount)
def openFinances(self):
self.subwindow = QFinancesMenu(self.game)
self.subwindow.show()

View File

@ -15,6 +15,7 @@ class QFactionsInfos(QGroupBox):
self.setGame(game)
self.layout = QGridLayout()
self.layout.setSpacing(0)
self.layout.addWidget(QLabel("<b>Player : </b>"),0,0)
self.layout.addWidget(self.player_name,0,1)
self.layout.addWidget(QLabel("<b>Enemy : </b>"),1,0)

View File

@ -0,0 +1,146 @@
from PySide2.QtCore import QSortFilterProxyModel, Qt, QModelIndex
from PySide2.QtGui import QStandardItem, QStandardItemModel
from PySide2.QtWidgets import QComboBox, QCompleter
from game import Game
from gen.flights.flight import FlightWaypoint
from theater import ControlPointType
class QPredefinedWaypointSelectionComboBox(QComboBox):
def __init__(self, game: Game, parent=None):
super(QPredefinedWaypointSelectionComboBox, self).__init__(parent)
self.game = game
self.setFocusPolicy(Qt.StrongFocus)
self.setEditable(True)
self.completer = QCompleter(self)
# always show all completions
self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
self.pFilterModel = QSortFilterProxyModel(self)
self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
self.completer.setPopup(self.view())
self.setCompleter(self.completer)
self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
self.completer.activated.connect(self.setTextIfCompleterIsClicked)
self.find_possible_waypoints()
def setModel(self, model):
super(QPredefinedWaypointSelectionComboBox, self).setModel(model)
self.pFilterModel.setSourceModel(model)
self.completer.setModel(self.pFilterModel)
def setModelColumn(self, column):
self.completer.setCompletionColumn(column)
self.pFilterModel.setFilterKeyColumn(column)
super(QPredefinedWaypointSelectionComboBox, self).setModelColumn(column)
def view(self):
return self.completer.popup()
def index(self):
return self.currentIndex()
def setTextIfCompleterIsClicked(self, text):
if text:
index = self.findText(text)
self.setCurrentIndex(index)
def get_selected_waypoints(self, include_all_from_same_location=False):
n = self.currentText()
first_waypoint = None
for w in self.wpts:
if w.pretty_name == n:
first_waypoint = w
break
if first_waypoint is None:
return []
waypoints = [first_waypoint]
if include_all_from_same_location:
for w in self.wpts:
if w is not first_waypoint and w.obj_name and w.obj_name == first_waypoint.obj_name:
waypoints.append(w)
return waypoints
def find_possible_waypoints(self):
self.wpts = []
model = QStandardItemModel()
i = 0
def add_model_item(i, model, name, wpt):
print(name)
item = QStandardItem(name)
model.setItem(i, 0, item)
self.wpts.append(wpt)
return i + 1
for cp in self.game.theater.controlpoints:
print(cp)
if cp.captured:
enemy_cp = [ecp for ecp in cp.connected_points if ecp.captured != cp.captured]
for ecp in enemy_cp:
wpt = FlightWaypoint((cp.position.x + ecp.position.x)/2, (cp.position.y + ecp.position.y)/2, 800)
wpt.name = "Frontline " + cp.name + "/" + ecp.name + " [CAS]"
wpt.pretty_name = wpt.name
wpt.description = "Frontline"
i = add_model_item(i, model, wpt.pretty_name, wpt)
for cp in self.game.theater.controlpoints:
for ground_object in cp.ground_objects:
if not ground_object.is_dead and not ground_object.dcs_identifier == "AA":
wpt = FlightWaypoint(ground_object.position.x,ground_object.position.y, 0)
wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + ground_object.category + " #" + str(ground_object.object_id)
wpt.pretty_name = wpt.name
wpt.obj_name = ground_object.obj_name
if cp.captured:
wpt.description = "Friendly Building"
else:
wpt.description = "Enemy Building"
i = add_model_item(i, model, wpt.pretty_name, wpt)
for cp in self.game.theater.controlpoints:
for ground_object in cp.ground_objects:
if not ground_object.is_dead and ground_object.dcs_identifier == "AA":
for g in ground_object.groups:
for j, u in enumerate(g.units):
wpt = FlightWaypoint(u.position.x, u.position.y, 0)
wpt.name = wpt.name = "[" + str(ground_object.obj_name) + "] : " + u.type + " #" + str(j)
wpt.pretty_name = wpt.name
wpt.obj_name = ground_object.obj_name
if cp.captured:
wpt.description = "Friendly unit : " + u.type
else:
wpt.description = "Enemy unit : " + u.type
i = add_model_item(i, model, wpt.pretty_name, wpt)
for cp in self.game.theater.controlpoints:
wpt = FlightWaypoint(cp.position.x, cp.position.y, 0)
wpt.name = cp.name
if cp.captured:
wpt.description = "Position of " + cp.name + " [Friendly Airbase]"
else:
wpt.description = "Position of " + cp.name + " [Enemy Airbase]"
if cp.cptype == ControlPointType.AIRCRAFT_CARRIER_GROUP:
wpt.pretty_name = cp.name + " (Aircraft Carrier Group)"
elif cp.cptype == ControlPointType.LHA_GROUP:
wpt.pretty_name = cp.name + " (LHA Group)"
else:
wpt.pretty_name = cp.name + " (Airbase)"
i = add_model_item(i, model, wpt.pretty_name, wpt)
self.setModel(model)

View File

@ -1,8 +1,9 @@
from PySide2.QtWidgets import QFrame, QHBoxLayout, QPushButton, QVBoxLayout
from PySide2.QtWidgets import QFrame, QHBoxLayout, QPushButton, QVBoxLayout, QGroupBox
from game import Game
from qt_ui.widgets.QBudgetBox import QBudgetBox
from qt_ui.widgets.QFactionsInfos import QFactionsInfos
from qt_ui.windows.finances.QFinancesMenu import QFinancesMenu
from qt_ui.windows.stats.QStatsWindow import QStatsWindow
from qt_ui.widgets.QTurnCounter import QTurnCounter
@ -17,13 +18,14 @@ class QTopPanel(QFrame):
def __init__(self, game: Game):
super(QTopPanel, self).__init__()
self.game = game
self.setMaximumHeight(70)
self.init_ui()
GameUpdateSignal.get_instance().gameupdated.connect(self.setGame)
def init_ui(self):
self.turnCounter = QTurnCounter()
self.budgetBox = QBudgetBox()
self.budgetBox = QBudgetBox(self.game)
self.passTurnButton = QPushButton("Pass Turn")
self.passTurnButton.setIcon(CONST.ICONS["PassTurn"])
@ -36,14 +38,9 @@ class QTopPanel(QFrame):
self.proceedButton.clicked.connect(self.proceed)
if self.game and self.game.turn == 0:
self.proceedButton.setEnabled(False)
elif not len(self.game.planners.keys()) == self.game.theater.controlpoints:
self.proceedButton.setEnabled(False)
else:
self.proceedButton.setEnabled(True)
self.factionsInfos = QFactionsInfos(self.game)
self.submenus = QVBoxLayout()
self.settings = QPushButton("Settings")
self.settings.setIcon(CONST.ICONS["Settings"])
self.settings.setProperty("style", "btn-primary")
@ -54,28 +51,40 @@ class QTopPanel(QFrame):
self.statistics.setProperty("style", "btn-primary")
self.statistics.clicked.connect(self.openStatisticsWindow)
self.submenus.addWidget(self.settings)
self.submenus.addWidget(self.statistics)
self.buttonBox = QGroupBox("Misc")
self.buttonBoxLayout = QHBoxLayout()
self.buttonBoxLayout.addWidget(self.settings)
self.buttonBoxLayout.addWidget(self.statistics)
self.buttonBox.setLayout(self.buttonBoxLayout)
self.proceedBox = QGroupBox("Proceed")
self.proceedBoxLayout = QHBoxLayout()
self.proceedBoxLayout.addWidget(self.passTurnButton)
self.proceedBoxLayout.addWidget(self.proceedButton)
self.proceedBox.setLayout(self.proceedBoxLayout)
self.layout = QHBoxLayout()
self.layout.addWidget(self.factionsInfos)
self.layout.addWidget(self.turnCounter)
self.layout.addWidget(self.budgetBox)
self.layout.addLayout(self.submenus)
self.layout.addWidget(self.buttonBox)
self.layout.addStretch(1)
self.layout.addWidget(self.passTurnButton)
self.layout.addWidget(self.proceedButton)
self.layout.addWidget(self.proceedBox)
self.layout.setContentsMargins(0,0,0,0)
self.setLayout(self.layout)
def setGame(self, game:Game):
self.game = game
if game is not None:
self.turnCounter.setCurrentTurn(self.game.turn, self.game.current_day)
self.budgetBox.setBudget(self.game.budget, self.game.budget_reward_amount)
self.budgetBox.setGame(self.game)
self.factionsInfos.setGame(self.game)
if not len(self.game.planners.keys()) == self.game.theater.controlpoints:
if not len(self.game.planners.keys()) == len(self.game.theater.controlpoints):
self.proceedButton.setEnabled(False)
else:
self.proceedButton.setEnabled(True)
def openSettings(self):
self.subwindow = QSettingsWindow(self.game)

View File

@ -76,13 +76,6 @@ class QLiberationMap(QGraphicsView):
scene.addItem(QMapControlPoint(self, pos[0] - CONST.CP_SIZE / 2, pos[1] - CONST.CP_SIZE / 2, CONST.CP_SIZE,
CONST.CP_SIZE, cp, self.game))
text = scene.addText(cp.name, font=QFont("Trebuchet MS", 10, weight=5, italic=False))
text.setPos(pos[0] + CONST.CP_SIZE, pos[1] - CONST.CP_SIZE / 2)
text = scene.addText(cp.name, font=QFont("Trebuchet MS", 10, weight=5, italic=False))
text.setDefaultTextColor(Qt.white)
text.setPos(pos[0] + CONST.CP_SIZE + 1, pos[1] - CONST.CP_SIZE / 2 + 1)
if cp.captured:
pen = QPen(brush=CONST.COLORS["blue"])
@ -105,7 +98,7 @@ class QLiberationMap(QGraphicsView):
go_pos = self._transform_point(ground_object.position)
if not ground_object.airbase_group:
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 16, 16, cp, ground_object))
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 12, 12, cp, ground_object))
if ground_object.category == "aa" and self.get_display_rule("sam"):
max_range = 0
@ -126,6 +119,7 @@ class QLiberationMap(QGraphicsView):
self.scene_create_lines_for_cp(cp)
for cp in self.game.theater.controlpoints:
pos = self._transform_point(cp.position)
if self.get_display_rule("flight_paths"):
if cp.id in self.game.planners.keys():
planner = self.game.planners[cp.id]
@ -139,6 +133,14 @@ class QLiberationMap(QGraphicsView):
prev_pos = list(new_pos)
scene.addLine(prev_pos[0] + 2, prev_pos[1] + 2, pos[0] + 2, pos[1] + 2, flight_path_pen)
for cp in self.game.theater.controlpoints:
pos = self._transform_point(cp.position)
text = scene.addText(cp.name, font=QFont("Trebuchet MS", 10, weight=5, italic=False))
text.setPos(pos[0] + CONST.CP_SIZE, pos[1] - CONST.CP_SIZE / 2)
text = scene.addText(cp.name, font=QFont("Trebuchet MS", 10, weight=5, italic=False))
text.setDefaultTextColor(Qt.white)
text.setPos(pos[0] + CONST.CP_SIZE + 1, pos[1] - CONST.CP_SIZE / 2 + 1)
def scene_create_lines_for_cp(self, cp: ControlPoint):
scene = self.scene()
pos = self._transform_point(cp.position)

View File

@ -27,12 +27,12 @@ class QMapGroundObject(QGraphicsRectItem):
units[u.type] = units[u.type]+1
else:
units[u.type] = 1
tooltip = ""
tooltip = "[" + self.model.obj_name + "]" + "\n"
for unit in units.keys():
tooltip = tooltip + str(unit) + "x" + str(units[unit]) + "\n"
self.setToolTip(tooltip[:-1])
else:
self.setToolTip(cp.name + "'s " + self.model.category)
self.setToolTip("[" + self.model.obj_name + "] : " + self.model.category)
def paint(self, painter, option, widget=None):

View File

@ -4,7 +4,8 @@ import webbrowser
from PySide2 import QtGui
from PySide2.QtCore import Qt
from PySide2.QtGui import QIcon
from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QMainWindow, QAction, QMessageBox, QDesktopWidget
from PySide2.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout, QMainWindow, QAction, QMessageBox, QDesktopWidget, \
QSplitter
import qt_ui.uiconstants as CONST
from game import Game
@ -14,6 +15,7 @@ from qt_ui.widgets.map.QLiberationMap import QLiberationMap
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal, DebriefingSignal
from qt_ui.windows.QDebriefingWindow import QDebriefingWindow
from qt_ui.windows.QNewGameWizard import NewGameWizard
from qt_ui.windows.infos.QInfoPanel import QInfoPanel
from userdata import persistency
@ -22,6 +24,7 @@ class QLiberationWindow(QMainWindow):
def __init__(self):
super(QLiberationWindow, self).__init__()
self.info_panel = None
self.setGame(persistency.restore_game())
self.setGeometry(300, 100, 270, 100)
@ -44,11 +47,16 @@ class QLiberationWindow(QMainWindow):
def initUi(self):
self.liberation_map = QLiberationMap(self.game)
self.info_panel = QInfoPanel(self.game)
hbox = QSplitter(Qt.Horizontal)
hbox.addWidget(self.info_panel)
hbox.addWidget(self.liberation_map)
vbox = QVBoxLayout()
vbox.setMargin(0)
vbox.addWidget(QTopPanel(self.game))
vbox.addWidget(self.liberation_map)
vbox.addWidget(hbox)
central_widget = QWidget()
central_widget.setLayout(vbox)
@ -164,6 +172,8 @@ class QLiberationWindow(QMainWindow):
def setGame(self, game: Game):
self.game = game
if self.info_panel:
self.info_panel.setGame(game)
def showAboutDialog(self):
text = "<h3>DCS Liberation</h3>" + \

View File

@ -1,20 +1,13 @@
import traceback
from PySide2.QtCore import Qt
from PySide2.QtGui import QCloseEvent
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QDialog, QVBoxLayout, QGridLayout, QPushButton, \
QGroupBox, QSizePolicy, QSpacerItem
from dcs.unittype import UnitType
from PySide2.QtWidgets import QHBoxLayout, QLabel, QWidget, QDialog, QGridLayout
from game.event import UnitsDeliveryEvent, ControlPointType
from qt_ui.widgets.QBudgetBox import QBudgetBox
from qt_ui.widgets.base.QAirportInformation import QAirportInformation
from qt_ui.widgets.base.QBaseInformation import QBaseInformation
from qt_ui.windows.basemenu.QBaseMenuTabs import QBaseMenuTabs
from qt_ui.windows.mission.QPlannedFlightsView import QPlannedFlightsView
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from theater import ControlPoint, CAP, Embarking, CAS, PinpointStrike, db
from game import Game
from game.event import ControlPointType
from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from qt_ui.windows.basemenu.QBaseMenuTabs import QBaseMenuTabs
from theater import ControlPoint
class QBaseMenu2(QDialog):
@ -38,6 +31,8 @@ class QBaseMenu2(QDialog):
if self.cp.captured:
self.deliveryEvent = None
self.setWindowIcon(EVENT_ICONS["capture"])
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.setMinimumSize(300, 200)
self.setModal(True)

View File

@ -0,0 +1,70 @@
from PySide2.QtWidgets import QDialog, QGridLayout, QLabel, QFrame, QSizePolicy
import qt_ui.uiconstants as CONST
from game.db import REWARDS, PLAYER_BUDGET_BASE
from game.game import Game
class QHorizontalSeparationLine(QFrame):
def __init__(self):
super().__init__()
self.setMinimumWidth(1)
self.setFixedHeight(20)
self.setFrameShape(QFrame.HLine)
self.setFrameShadow(QFrame.Sunken)
self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
class QFinancesMenu(QDialog):
def __init__(self, game: Game):
super(QFinancesMenu, self).__init__()
self.game = game
self.setModal(True)
self.setWindowTitle("Finances")
self.setWindowIcon(CONST.ICONS["Money"])
self.setMinimumSize(450, 200)
reward = PLAYER_BUDGET_BASE * len(self.game.theater.player_points())
layout = QGridLayout()
layout.addWidget(QLabel("<b>Control Points</b>"), 0, 0)
layout.addWidget(QLabel(str(len(self.game.theater.player_points())) + " bases x " + str(PLAYER_BUDGET_BASE) + "M"), 0, 1)
layout.addWidget(QLabel(str(reward) + "M"), 0, 2)
layout.addWidget(QHorizontalSeparationLine(), 1, 0, 1, 3)
i = 2
for cp in self.game.theater.player_points():
obj_names = []
[obj_names.append(ground_object.obj_name) for ground_object in cp.ground_objects if ground_object.obj_name not in obj_names]
for obj_name in obj_names:
reward = 0
g = None
cat = None
number = 0
for ground_object in cp.ground_objects:
if ground_object.obj_name != obj_name or ground_object.is_dead:
continue
else:
if g is None:
g = ground_object
cat = g.category
if cat in REWARDS.keys():
number = number + 1
reward += REWARDS[cat]
if g is not None and cat in REWARDS.keys():
layout.addWidget(QLabel("<b>" + g.category.upper() + " [" + obj_name + "]</b>"), i, 0)
layout.addWidget(QLabel(str(number) + " buildings x " + str(REWARDS[cat]) + "M"), i, 1)
rlabel = QLabel(str(reward) + "M")
rlabel.setProperty("style", "green")
layout.addWidget(rlabel, i, 2)
i = i + 1
self.setLayout(layout)
layout.addWidget(QHorizontalSeparationLine(), i+1, 0, 1, 3)
layout.addWidget(QLabel("<b>" + str(self.game.budget_reward_amount) + "M </b>"), i+2, 2)

View File

@ -0,0 +1,12 @@
from PySide2.QtGui import QStandardItem
from game.infos.information import Information
class QInfoItem(QStandardItem):
def __init__(self, info: Information):
super(QInfoItem, self).__init__()
self.info = info
self.setText("[%02d]" % self.info.turn + " " + self.info.title + ' : {:<16}'.format(info.text))
self.setEditable(False)

View File

@ -0,0 +1,33 @@
from PySide2.QtCore import QItemSelectionModel, QPoint
from PySide2.QtGui import QStandardItemModel
from PySide2.QtWidgets import QListView
from game import Game, game
from qt_ui.windows.infos.QInfoItem import QInfoItem
class QInfoList(QListView):
def __init__(self, game:Game):
super(QInfoList, self).__init__()
self.model = QStandardItemModel(self)
self.setModel(self.model)
self.game = game
self.update_list()
self.selectionModel().setCurrentIndex(self.indexAt(QPoint(1, 1)), QItemSelectionModel.Select)
self.selectionModel().selectionChanged.connect(self.on_selected_info_changed)
def on_selected_info_changed(self):
index = self.selectionModel().currentIndex().row()
def update_list(self):
self.model.clear()
if self.game is not None:
for i, info in enumerate(reversed(self.game.informations)):
self.model.appendRow(QInfoItem(info))
self.selectionModel().setCurrentIndex(self.indexAt(QPoint(1, 1)), QItemSelectionModel.Select)
def setGame(self, game):
self.game = game
self.update_list()

View File

@ -0,0 +1,28 @@
from PySide2.QtWidgets import QFrame, QVBoxLayout, QLabel, QGroupBox
from game import Game
from qt_ui.windows.infos.QInfoList import QInfoList
class QInfoPanel(QGroupBox):
def __init__(self, game: Game):
super(QInfoPanel, self).__init__("Info Panel")
self.informations_list = QInfoList(game)
self.init_ui()
def setGame(self, game):
self.game = game
self.informations_list.setGame(game)
def update(self):
self.informations_list.update_list()
def init_ui(self):
layout = QVBoxLayout()
layout.addWidget(self.informations_list)
layout.setSpacing(0)
layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(layout)

View File

@ -0,0 +1,21 @@
from PySide2.QtWidgets import QFrame, QLabel, QGridLayout
from game.infos.information import Information
class QInfoWidget(QFrame):
def __init__(self, info: Information):
super(QInfoWidget, self).__init__()
self.info = info
self.titleLabel = QLabel("<b>" + info.title + "</b>")
self.textLabel = QLabel(info.text)
self.init_ui()
def init_ui(self):
layout = QGridLayout()
layout.addWidget(self.titleLabel,0,0)
layout.addWidget(self.textLabel,1,0)
self.setLayout(layout)

View File

@ -16,7 +16,7 @@ class QMissionPlanning(QDialog):
super(QMissionPlanning, self).__init__()
self.game = game
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.setMinimumSize(750, 420)
self.setMinimumSize(800, 420)
self.setModal(True)
self.setWindowTitle("Mission Preparation")
self.setWindowIcon(EVENT_ICONS["strike"])
@ -133,8 +133,3 @@ class QMissionPlanning(QDialog):
waiting = QWaitingForMissionResultWindow(self.gameEvent, self.game)
waiting.show()
self.close()

View File

@ -5,7 +5,7 @@ from gen.flights.flight import FlightWaypoint
class QFlightWaypointInfoBox(QGroupBox):
def __init__(self, flight_wpt:FlightWaypoint):
def __init__(self, flight_wpt:FlightWaypoint = None):
super(QFlightWaypointInfoBox, self).__init__("Waypoint")
self.flight_wpt = flight_wpt
if flight_wpt is None:
@ -22,31 +22,31 @@ class QFlightWaypointInfoBox(QGroupBox):
layout = QVBoxLayout()
x_pos_layout = QHBoxLayout()
x_pos_layout.addWidget(QLabel("X : "))
x_pos_layout.addWidget(QLabel("<b>X : </b>"))
x_pos_layout.addWidget(self.x_position_label)
x_pos_layout.addStretch()
y_pos_layout = QHBoxLayout()
y_pos_layout.addWidget(QLabel("Y : "))
y_pos_layout.addWidget(QLabel("<b>Y : </b>"))
y_pos_layout.addWidget(self.y_position_label)
y_pos_layout.addStretch()
alt_layout = QHBoxLayout()
alt_layout.addWidget(QLabel("Alt : "))
alt_layout.addWidget(QLabel("<b>Alt : </b>"))
alt_layout.addWidget(self.alt_label)
alt_layout.addStretch()
name_layout = QHBoxLayout()
name_layout.addWidget(QLabel("Name : "))
name_layout.addWidget(QLabel("<b>Name : </b>"))
name_layout.addWidget(self.name_label)
name_layout.addStretch()
desc_layout = QHBoxLayout()
desc_layout.addWidget(QLabel("Description : "))
desc_layout.addWidget(QLabel("<b>Description : </b>"))
desc_layout.addWidget(self.desc_label)
desc_layout.addStretch()
layout.addLayout(name_layout)
#layout.addLayout(name_layout)
layout.addLayout(x_pos_layout)
layout.addLayout(y_pos_layout)
layout.addLayout(alt_layout)

View File

@ -7,7 +7,9 @@ from gen.flights.flight import FlightWaypoint
class QWaypointItem(QStandardItem):
def __init__(self, point: FlightWaypoint):
def __init__(self, point: FlightWaypoint, number):
super(QWaypointItem, self).__init__()
self.setText('{0: <16}'.format(point.description) + " -- [X: " + str(int(point.x)) + "; Y: " + str(int(point.y)) + "; Alt: " + str(int(point.alt)) + "m]")
self.number = number
self.setText("%02d" % self.number + ' | ' + '{:<16}'.format(point.pretty_name))
self.setEditable(False)

View File

@ -28,7 +28,8 @@ class QFlightWaypointList(QListView):
self.model.clear()
takeoff = FlightWaypoint(self.flight.from_cp.position.x, self.flight.from_cp.position.y, 0)
takeoff.description = "Take Off"
self.model.appendRow(QWaypointItem(takeoff))
takeoff.name = takeoff.pretty_name = "Take Off from " + self.flight.from_cp.name
self.model.appendRow(QWaypointItem(takeoff, 0))
for i, point in enumerate(self.flight.points):
self.model.appendRow(QWaypointItem(point))
self.model.appendRow(QWaypointItem(point, i + 1))
self.selectionModel().setCurrentIndex(self.indexAt(QPoint(1, 1)), QItemSelectionModel.Select)

View File

@ -1,11 +1,13 @@
from PySide2.QtCore import Qt
from PySide2.QtWidgets import QDialog, QGridLayout, QLabel, QComboBox, QHBoxLayout, QVBoxLayout, QPushButton
from PySide2.QtWidgets import QDialog, QGridLayout, QLabel, QComboBox, QHBoxLayout, QVBoxLayout, QPushButton, QCheckBox
from dcs import Point
from game import Game
from gen.flights.flight import Flight, FlightWaypoint
from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.widgets.QPredefinedWaypointSelectionComboBox import QPredefinedWaypointSelectionComboBox
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointInfoBox import QFlightWaypointInfoBox
from theater import ControlPointType
PREDEFINED_WAYPOINT_CATEGORIES = [
"Frontline (CAS AREA)",
@ -23,135 +25,64 @@ class QPredefinedWaypointSelectionWindow(QDialog):
self.game = game
self.flight = flight
self.setWindowFlags(Qt.WindowStaysOnTopHint)
self.setMinimumSize(450, 350)
self.setMinimumSize(400, 250)
self.setModal(True)
self.setWindowTitle("Add Predefined Waypoint")
self.setWindowIcon(EVENT_ICONS["strike"])
self.flight_waypoint_list = flight_waypoint_list
self.selected_cp = self.game.theater.controlpoints[0]
self.cp_selection_box = QComboBox()
for cp in self.game.theater.controlpoints:
self.cp_selection_box.addItem(cp.name)
self.wpt_type_selection_box = QComboBox()
for cat in PREDEFINED_WAYPOINT_CATEGORIES:
self.wpt_type_selection_box.addItem(cat)
self.cp_selection_box.currentTextChanged.connect(self.on_parameters_changed)
self.wpt_type_selection_box.currentTextChanged.connect(self.on_parameters_changed)
self.wpt_selection_box = QComboBox()
self.wpt_selection_box = QPredefinedWaypointSelectionComboBox(self.game)
self.wpt_selection_box.setMinimumWidth(200)
self.wpt_selection_box.currentTextChanged.connect(self.on_select_wpt_changed)
self.selected_waypoint = None
self.wpt_info = QFlightWaypointInfoBox(self.selected_waypoint)
self.selected_waypoints = []
self.wpt_info = QFlightWaypointInfoBox()
self.add_button = QPushButton("Add")
self.add_button.clicked.connect(self.add_waypoint)
self.include_all = QCheckBox()
self.include_all.stateChanged.connect(self.on_select_wpt_changed)
self.include_all.setChecked(True)
self.init_ui()
self.on_parameters_changed()
self.on_select_wpt_changed()
print("DONE")
def init_ui(self):
layout = QVBoxLayout()
near_layout = QHBoxLayout()
near_layout.addWidget(QLabel("Near : "))
near_layout.addWidget(self.cp_selection_box)
near_layout.addStretch()
type_layout = QHBoxLayout()
type_layout.addWidget(QLabel("Type : "))
type_layout.addWidget(self.wpt_type_selection_box)
type_layout.addStretch()
wpt_layout = QHBoxLayout()
wpt_layout.addWidget(QLabel("Waypoint : "))
wpt_layout.addWidget(self.wpt_selection_box)
wpt_layout.addStretch()
layout.addLayout(near_layout)
layout.addLayout(type_layout)
include_all = QHBoxLayout()
include_all.addWidget(QLabel("Include all objects from the same location : "))
include_all.addWidget(self.include_all)
include_all.addStretch()
layout.addLayout(wpt_layout)
layout.addWidget(self.wpt_info)
layout.addLayout(include_all)
layout.addStretch()
layout.addWidget(self.add_button)
self.setLayout(layout)
def on_select_wpt_changed(self):
self.selected_waypoint = self.wpt_selection_box.currentData()
self.wpt_info.set_flight_waypoint(self.selected_waypoint)
if self.selected_waypoint is None:
self.selected_waypoints = self.wpt_selection_box.get_selected_waypoints(self.include_all.isChecked())
if self.selected_waypoints is None or len(self.selected_waypoints) <= 0:
self.add_button.setDisabled(True)
else:
self.wpt_info.set_flight_waypoint(self.selected_waypoints[0])
self.add_button.setDisabled(False)
def on_parameters_changed(self):
self.wpt_selection_box.clear()
select_cp_text = self.cp_selection_box.currentText()
select_cp = None
for cp in self.game.theater.controlpoints:
if cp.name == select_cp_text:
select_cp = cp
break
if select_cp is not None:
selected_wpt_type = self.wpt_type_selection_box.currentText()
if selected_wpt_type == PREDEFINED_WAYPOINT_CATEGORIES[0]: # CAS
enemy_cp = [cp for cp in select_cp.connected_points if cp.captured != select_cp.captured]
for ecp in enemy_cp:
wpt = FlightWaypoint((select_cp.position.x + ecp.position.x)/2, (select_cp.position.y + ecp.position.y)/2, 800)
wpt.name = "Frontline with " + ecp.name + " [CAS]"
wpt.description = "Frontline"
self.wpt_selection_box.addItem(wpt.name, userData=wpt)
if len(enemy_cp) == 0:
self.wpt_selection_box.addItem("None", userData=None)
elif selected_wpt_type == PREDEFINED_WAYPOINT_CATEGORIES[1]: # Building
for ground_object in select_cp.ground_objects:
if not ground_object.is_dead and not ground_object.dcs_identifier == "AA":
wpt = FlightWaypoint(ground_object.position.x,ground_object.position.y, 0)
wpt.name = ground_object.category + " #" + str(ground_object.object_id) + " @ site #" + str(ground_object.group_id)
if select_cp.captured:
wpt.description = "Friendly Building"
else:
wpt.description = "Enemy Building"
self.wpt_selection_box.addItem(wpt.name, userData=wpt)
elif selected_wpt_type == PREDEFINED_WAYPOINT_CATEGORIES[2]: # Known units position
for ground_object in select_cp.ground_objects:
if not ground_object.is_dead and ground_object.dcs_identifier == "AA":
for g in ground_object.groups:
for u in g.units:
wpt = FlightWaypoint(ground_object.position.x, ground_object.position.y, 0)
wpt.name = u.type + " @ site #" + str(ground_object.group_id)
if select_cp.captured:
wpt.description = "Friendly unit :" + u.type
else:
wpt.description = "Enemy unit :" + u.type
self.wpt_selection_box.addItem(wpt.name, userData=wpt)
elif selected_wpt_type == PREDEFINED_WAYPOINT_CATEGORIES[3]: # CAS
wpt = FlightWaypoint(select_cp.position.x, select_cp.position.y, 0)
wpt.name = select_cp.name
if select_cp.captured:
wpt.description = "Position of " + select_cp.name + " [Friendly Airbase]"
else:
wpt.description = "Position of " + select_cp.name + " [Enemy Airbase]"
self.wpt_selection_box.addItem("Airbase", userData=wpt)
else:
self.wpt_selection_box.addItem("None", userData=None)
else:
self.wpt_selection_box.addItem("None", userData=None)
self.wpt_selection_box.setCurrentIndex(0)
def add_waypoint(self):
if not self.selected_waypoint is None:
self.flight.points.append(self.selected_waypoint)
for wpt in self.selected_waypoints:
self.flight.points.append(wpt)
self.flight_waypoint_list.update_list()
self.close()

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@ -166,16 +166,13 @@ class Emirates(ConflictTheater):
def __init__(self):
super(Emirates, self).__init__()
self.al_dhafra = ControlPoint.from_airport(persiangulf.Al_Dhafra_AB, LAND, SIZE_BIG, IMPORTANCE_LOW)
self.al_dhafra = ControlPoint.from_airport(persiangulf.Al_Dhafra_AB, LAND, SIZE_BIG, IMPORTANCE_MEDIUM)
self.al_maktoum = ControlPoint.from_airport(persiangulf.Al_Maktoum_Intl, LAND, SIZE_BIG, IMPORTANCE_LOW)
self.al_minhad = ControlPoint.from_airport(persiangulf.Al_Minhad_AB, LAND, SIZE_REGULAR, 1.1)
self.sir_abu_nuayr = ControlPoint.from_airport(persiangulf.Sir_Abu_Nuayr, [0, 330], SIZE_SMALL, 1.1, has_frontline=False)
self.dubai = ControlPoint.from_airport(persiangulf.Dubai_Intl, COAST_DL_E, SIZE_LARGE, IMPORTANCE_MEDIUM)
self.sharjah = ControlPoint.from_airport(persiangulf.Sharjah_Intl, LAND, SIZE_BIG, 1.0)
self.fujairah = ControlPoint.from_airport(persiangulf.Fujairah_Intl, COAST_V_W, SIZE_REGULAR, 1.0)
self.ras_al_khaimah = ControlPoint.from_airport(persiangulf.Ras_Al_Khaimah, LAND, SIZE_REGULAR,IMPORTANCE_MEDIUM)
self.al_ain = ControlPoint.from_airport(persiangulf.Al_Ain_International_Airport, LAND, SIZE_BIG,
IMPORTANCE_HIGH)
self.al_minhad = ControlPoint.from_airport(persiangulf.Al_Minhad_AB, LAND, SIZE_REGULAR, IMPORTANCE_LOW)
self.sharjah = ControlPoint.from_airport(persiangulf.Sharjah_Intl, LAND, SIZE_BIG, IMPORTANCE_LOW)
self.fujairah = ControlPoint.from_airport(persiangulf.Fujairah_Intl, COAST_V_W, SIZE_REGULAR, IMPORTANCE_LOW)
self.ras_al_khaimah = ControlPoint.from_airport(persiangulf.Ras_Al_Khaimah, LAND, SIZE_REGULAR,IMPORTANCE_LOW)
self.al_ain = ControlPoint.from_airport(persiangulf.Al_Ain_International_Airport, LAND, SIZE_BIG,IMPORTANCE_LOW)
self.east_carrier = ControlPoint.carrier("Carrier", Point(-61770, 69039), 1001)
self.tarawa_carrier = ControlPoint.lha("LHA Carrier", Point(-79770, 49430), 1002)
@ -183,12 +180,10 @@ class Emirates(ConflictTheater):
self.add_controlpoint(self.al_dhafra, connected_to=[self.al_ain, self.al_maktoum])
self.add_controlpoint(self.al_ain, connected_to=[self.fujairah, self.al_maktoum, self.al_dhafra])
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.dubai, connected_to=[self.al_minhad, self.sharjah])
self.add_controlpoint(self.sharjah, connected_to=[self.dubai, self.ras_al_khaimah, self.fujairah])
self.add_controlpoint(self.al_minhad, connected_to=[self.al_maktoum, self.sharjah])
self.add_controlpoint(self.sharjah, connected_to=[self.al_minhad, self.ras_al_khaimah, self.fujairah])
self.add_controlpoint(self.ras_al_khaimah, connected_to=[self.sharjah])
self.add_controlpoint(self.fujairah, connected_to=[self.sharjah, self.al_ain])
self.add_controlpoint(self.sir_abu_nuayr, connected_to=[])
self.add_controlpoint(self.tarawa_carrier)
self.add_controlpoint(self.east_carrier)

View File

@ -4,6 +4,7 @@ import random
import typing
import logging
from gen import namegen
from gen.defenses.armor_group_generator import generate_armor_group
from gen.fleet.ship_group_generator import generate_carrier_group, generate_lha_group
from gen.sam.sam_group_generator import generate_anti_air_group, generate_shorad_group
@ -79,6 +80,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
g.cp_id = cp.id
g.airbase_group = True
g.dcs_identifier = "CARRIER"
g.obj_name = namegen.random_objective_name()
g.heading = 0
g.position = Point(cp.position.x, cp.position.y)
group = generate_carrier_group(faction, game, g)
@ -98,6 +100,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
g.cp_id = cp.id
g.airbase_group = True
g.dcs_identifier = "LHA"
g.obj_name = namegen.random_objective_name()
g.heading = 0
g.position = Point(cp.position.x, cp.position.y)
group = generate_lha_group(faction, game, g)
@ -124,6 +127,7 @@ def generate_groundobjects(theater: ConflictTheater, game):
g.cp_id = cp.id
g.airbase_group = True
g.dcs_identifier = "AA"
g.obj_name = namegen.random_objective_name()
g.heading = 0
g.position = Point(point.x, point.y)
@ -160,6 +164,8 @@ def find_location(on_ground, near, theater, min, max, others) -> typing.Optional
"""
point = None
for _ in range(1000):
# Check if on land or sea
p = near.random_point_within(max, min)
if on_ground and theater.is_on_land(p):
point = p
@ -180,6 +186,20 @@ def find_location(on_ground, near, theater, min, max, others) -> typing.Optional
if other.position.distance_to_point(point) < 10000:
point = None
break
if point:
for other in theater.controlpoints:
if other.position != near:
if point is None:
break
if other.position.distance_to_point(point) < 30000:
point = None
break
for ground_obj in other.ground_objects:
if ground_obj.position.distance_to_point(point) < 10000:
point = None
break
if point:
return point
return None
@ -201,13 +221,16 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat
if cp.is_global:
return False
amount = random.randrange(1, 7)
amount = random.randrange(3, 8)
for i in range(0, amount):
available_categories = list(templates)
obj_name = namegen.random_objective_name()
if i >= amount - 1:
tpl_category = "aa"
else:
if random.randint(0, 2) == 0:
if random.randint(0, 3) == 0:
tpl_category = "aa"
else:
tpl_category = random.choice(available_categories)
@ -223,6 +246,7 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat
group_id = group_id + 1
logging.info("generated {} for {}".format(tpl_category, cp))
for object in tpl:
object_id += 1
@ -231,12 +255,12 @@ def generate_cp_ground_points(cp: ControlPoint, theater, game, group_id, templat
g.object_id = object_id
g.cp_id = cp.id
g.airbase_gorup = False
g.obj_name = obj_name
g.dcs_identifier = object["type"]
g.heading = object["heading"]
g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y)
if g.dcs_identifier == "AA":
if cp.captured:
faction = game.player_name

View File

@ -49,15 +49,13 @@ class TheaterGroundObject:
cp_id = 0
group_id = 0
object_id = 0
dcs_identifier = None # type: str
is_dead = False
airbase_group = False
heading = 0
position = None # type: Point
groups = []
obj_name = ""
@property
def category(self) -> str: