Frontline progression is now based on combat results.

This commit is contained in:
Khopa 2020-05-25 04:09:51 +02:00
parent f7d9c62afb
commit 7a3ee6b1a9
5 changed files with 91 additions and 35 deletions

View File

@ -22,6 +22,10 @@ DIFFICULTY_LOG_BASE = 1.1
EVENT_DEPARTURE_MAX_DISTANCE = 340000 EVENT_DEPARTURE_MAX_DISTANCE = 340000
MINOR_DEFEAT_INFLUENCE = 0.1
DEFEAT_INFLUENCE = 0.3
STRONG_DEFEAT_INFLUENCE = 0.5
class Event: class Event:
silent = False silent = False
informational = False informational = False
@ -153,12 +157,14 @@ class Event:
# ------------------------------ # ------------------------------
# Destroyed ground units # Destroyed ground units
killed_unit_count_by_cp = {cp.id: 0 for cp in self.game.theater.controlpoints}
cp_map = {cp.id: cp for cp in self.game.theater.controlpoints} cp_map = {cp.id: cp for cp in self.game.theater.controlpoints}
for killed_ground_unit in debriefing.killed_ground_units: for killed_ground_unit in debriefing.killed_ground_units:
try: try:
cpid = int(killed_ground_unit.split("|")[3]) cpid = int(killed_ground_unit.split("|")[3])
type = db.unit_type_from_name(killed_ground_unit.split("|")[4]) type = db.unit_type_from_name(killed_ground_unit.split("|")[4])
if cpid in cp_map.keys(): if cpid in cp_map.keys():
killed_unit_count_by_cp[cpid] = killed_unit_count_by_cp[cpid] + 1
cp = cp_map[cpid] cp = cp_map[cpid]
if type in cp.base.armor.keys(): if type in cp.base.armor.keys():
logging.info("Ground unit destroyed : " + str(type)) logging.info("Ground unit destroyed : " + str(type))
@ -195,7 +201,6 @@ class Event:
# ------------------------------ # ------------------------------
# Captured bases # Captured bases
if self.game.player_country in db.BLUEFOR_FACTIONS: if self.game.player_country in db.BLUEFOR_FACTIONS:
coalition = 2 # Value in DCS mission event for BLUE coalition = 2 # Value in DCS mission event for BLUE
else: else:
@ -225,6 +230,69 @@ class Event:
except Exception as e: except Exception as e:
print(e) print(e)
# -----------------------------------
# Compute damage to bases
for cp in self.game.theater.player_points():
enemy_cps = [e for e in cp.connected_points if not e.captured]
for enemy_cp in enemy_cps:
print("Compute frontline progression for : " + cp.name + " to " + enemy_cp.name)
delta = 0
player_won = True
ally_casualties = killed_unit_count_by_cp[cp.id]
enemy_casualties = killed_unit_count_by_cp[enemy_cp.id]
ally_units_alive = cp.base.total_armor
enemy_units_alive = enemy_cp.base.total_armor
print(ally_units_alive)
print(enemy_units_alive)
print(ally_casualties)
print(enemy_casualties)
ratio = (1.0 + enemy_casualties) / (1.0 + ally_casualties)
if ally_units_alive == 0:
player_won = False
delta = STRONG_DEFEAT_INFLUENCE
elif enemy_units_alive == 0:
player_won = True
delta = STRONG_DEFEAT_INFLUENCE
elif cp.stances[enemy_cp.id] == CombatStance.RETREAT:
player_won = False
delta = STRONG_DEFEAT_INFLUENCE
else:
if enemy_casualties > ally_casualties:
player_won = True
if cp.stances[enemy_cp.id] == CombatStance.BREAKTHROUGH:
delta = STRONG_DEFEAT_INFLUENCE
else:
if ratio > 3:
delta = STRONG_DEFEAT_INFLUENCE
elif ratio < 1.5:
delta = MINOR_DEFEAT_INFLUENCE
else:
delta = DEFEAT_INFLUENCE
elif ally_casualties > enemy_casualties:
player_won = False
if cp.stances[enemy_cp.id] == CombatStance.BREAKTHROUGH:
delta = STRONG_DEFEAT_INFLUENCE
else:
delta = STRONG_DEFEAT_INFLUENCE
# 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
if player_won:
print(cp.name + " won ! factor > " + str(delta))
cp.base.affect_strength(delta)
enemy_cp.base.affect_strength(-delta)
else:
print(enemy_cp.name + " won ! factor > " + str(delta))
enemy_cp.base.affect_strength(delta)
cp.base.affect_strength(-delta)
def skip(self): def skip(self):
pass pass

View File

@ -60,17 +60,6 @@ class FrontlineAttackEvent(Event):
def commit(self, debriefing: Debriefing): def commit(self, debriefing: Debriefing):
super(FrontlineAttackEvent, self).commit(debriefing) super(FrontlineAttackEvent, self).commit(debriefing)
if self.from_cp.captured:
if self.is_successfull(debriefing):
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(+self.STRENGTH_INFLUENCE)
else:
if self.is_successfull(debriefing):
self.from_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
else:
self.to_cp.base.affect_strength(-self.STRENGTH_INFLUENCE)
def skip(self): def skip(self):
if self.to_cp.captured: if self.to_cp.captured:
self.to_cp.base.affect_strength(-0.1) self.to_cp.base.affect_strength(-0.1)

View File

@ -25,7 +25,7 @@ class GroundConflictGenerator:
self.enemy_planned_combat_groups = enemy_planned_combat_groups self.enemy_planned_combat_groups = enemy_planned_combat_groups
self.player_planned_combat_groups = player_planned_combat_groups self.player_planned_combat_groups = player_planned_combat_groups
self.player_stance = CombatStance(player_stance) self.player_stance = CombatStance(player_stance)
self.enemy_stance = CombatStance.AGGRESIVE if len(enemy_planned_combat_groups) > len(player_planned_combat_groups) else CombatStance.DEFENSIVE self.enemy_stance = random.choice([CombatStance.AGGRESIVE, CombatStance.AGGRESIVE, CombatStance.AGGRESIVE, CombatStance.ELIMINATION, CombatStance.BREAKTHROUGH]) if len(enemy_planned_combat_groups) > len(player_planned_combat_groups) else random.choice([CombatStance.DEFENSIVE, CombatStance.DEFENSIVE, CombatStance.DEFENSIVE, CombatStance.AMBUSH, CombatStance.AGGRESIVE])
self.game = game self.game = game
def _group_point(self, point) -> Point: def _group_point(self, point) -> Point:
@ -283,7 +283,7 @@ class GroundConflictGenerator:
while i < 25: # 25 attempt for valid position while i < 25: # 25 attempt for valid position
heading_diff = -90 if isplayer else 90 heading_diff = -90 if isplayer else 90
shifted = conflict_position[0].point_from_heading(self.conflict.heading, shifted = conflict_position[0].point_from_heading(self.conflict.heading,
random.randint(-combat_width / 2, combat_width / 2)) random.randint((int)(-combat_width / 2), (int)(combat_width / 2)))
final_position = shifted.point_from_heading(self.conflict.heading + heading_diff, distance_from_frontline) final_position = shifted.point_from_heading(self.conflict.heading + heading_diff, distance_from_frontline)
if self.conflict.theater.is_on_land(final_position): if self.conflict.theater.is_on_land(final_position):

View File

@ -2,11 +2,10 @@ import logging
import os import os
import sys import sys
from shutil import copyfile from shutil import copyfile
from time import sleep
import dcs import dcs
from PySide2.QtGui import QPixmap from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QApplication, QLabel, QSplashScreen from PySide2.QtWidgets import QApplication, QSplashScreen
from dcs import installation from dcs import installation
from qt_ui import uiconstants from qt_ui import uiconstants

View File

@ -45,30 +45,30 @@ class QWaitingForMissionResultWindow(QDialog):
def initUi(self): def initUi(self):
self.layout = QGridLayout() self.layout = QGridLayout()
self.gridLayout = QVBoxLayout() self.gridLayout = QGridLayout()
self.gridLayout.addWidget(QLabel("<b>You are clear for takeoff</b>")) self.gridLayout.addWidget(QLabel("<b>You are clear for takeoff</b>"), 1, 0)
self.gridLayout.addWidget(QLabel("")) self.gridLayout.addWidget(QLabel(""), 2, 0)
self.gridLayout.addWidget(QLabel("<h2>For Singleplayer :</h2>")) self.gridLayout.addWidget(QLabel("<h2>For Singleplayer :</h2>"), 3, 0)
self.gridLayout.addWidget(QLabel("In DCS, open the Mission Editor, and load the file : ")) self.gridLayout.addWidget(QLabel("In DCS, open the Mission Editor, and load the file : "), 4, 0)
self.gridLayout.addWidget(QLabel("<i>liberation_nextturn</i>")) self.gridLayout.addWidget(QLabel("<i>liberation_nextturn</i>"), 5, 0)
self.gridLayout.addWidget(QLabel("Then once the mission is loaded in ME, in menu \"Flight\", click on FLY to launch")) self.gridLayout.addWidget(QLabel("Then once the mission is loaded in ME, in menu \"Flight\", click on FLY Mission to launch"), 6, 0)
self.gridLayout.addWidget(QLabel("")) self.gridLayout.addWidget(QLabel(""), 7, 0)
self.gridLayout.addWidget(QLabel("<h2>For Multiplayer</h2>")) self.gridLayout.addWidget(QLabel("<h2>For Multiplayer :</h2>"), 8, 0)
self.gridLayout.addWidget(QLabel("In DCS, open the Mission Editor, and load the file : ")) self.gridLayout.addWidget(QLabel("In DCS, open the Mission Editor, and load the file : "), 9, 0)
self.gridLayout.addWidget(QLabel("<i>liberation_nextturn</i>")) self.gridLayout.addWidget(QLabel("<i>liberation_nextturn</i>"), 10, 0)
self.gridLayout.addWidget(QLabel("Click on File/Save. Then exit the mission editor, and go to Multiplayer.")) self.gridLayout.addWidget(QLabel("Click on File/Save. Then exit the mission editor, and go to Multiplayer."), 11, 0)
self.gridLayout.addWidget(QLabel("Then host a server with the mission, and tell your friends to join !")) self.gridLayout.addWidget(QLabel("Then host a server with the mission, and tell your friends to join !"), 12, 0)
self.gridLayout.addWidget(QLabel("(The step in the mission editor is important, and fix a game breaking bug.)")) self.gridLayout.addWidget(QLabel("(The step in the mission editor is important, and fix a game breaking bug.)"), 13, 0)
self.gridLayout.addWidget(QLabel("")) self.gridLayout.addWidget(QLabel(""), 14, 0)
progress = QLabel("") progress = QLabel("")
progress.setAlignment(QtCore.Qt.AlignCenter) progress.setAlignment(QtCore.Qt.AlignCenter)
progressBar = QMovie("./resources/ui/loader.gif") progressBar = QMovie("./resources/ui/loader.gif")
progress.setMovie(progressBar) progress.setMovie(progressBar)
self.gridLayout.addWidget(progress) self.gridLayout.addWidget(progress, 15, 0)
self.gridLayout.addWidget(QLabel("")) self.gridLayout.addWidget(QLabel(""), 16, 0)
self.gridLayout.addWidget(QLabel("Once you have played the mission, this window will dissapear.")) self.gridLayout.addWidget(QLabel("Once you have played the mission, this window will dissapear."), 17, 0)
self.gridLayout.addWidget(QLabel("You will have to click on \"Accept Results\" to proceed")) self.gridLayout.addWidget(QLabel("You will have to click on \"Accept Results\" to proceed"), 18, 0)
progressBar.start() progressBar.start()
self.layout.addLayout(self.gridLayout,0,0) self.layout.addLayout(self.gridLayout,0,0)