Debriefing and info on AA site and buildings destroyed. KC130 replace S3B

This commit is contained in:
Khopa 2020-06-06 04:10:22 +02:00
parent aa4b07d024
commit fcd81850cb
28 changed files with 195 additions and 83 deletions

View File

@ -6,12 +6,24 @@
* **[Mission Generator]** Add PP points for JF-17 on STRIKE missions
* **[Mission Generator]** Add ST point for F-14B on STRIKE missions
* **[Mission Generator]** Flights with client slots will never be delayed
* **[Mission Generator]** AI units can start from parking
* **[Mission Generator]** AI units can start from parking (Added a new setting)
* **[Mission Generator]** Tacan for carrier will only be in Mode X from now
* **[Mission Generator]** RTB waypoints for autogenerated flights
* **[Info Panel]** Added information about destroyed buildings in info panel
* **[Info Panel]** Added information about destroyed units at SAM site in info panel
* **[Info Panel]** Added information about units destroyed outside the frontline in the debriefing window
* **[Info Panel]** Added information about buildings destroyed in the debriefing window
* **[Map]** Tooltip now contains the list of building for Strike targets on the map
* **[Misc]** Made it possible to setup DCS Saved Games directory and DCS installation directory manually
##Fixed issues :
* **[Mission Generator]** When playing as RED the activation trigger would not be properly generated
* **[Mission Generator]** Changed "strike" payload for Su-24M
* **[Mission Generator]** FW-190A8 is now properly considered as flyable
* **[Mission Generator]** Changed "strike" payload for JF-17
* **[Mission Generator]** FW-190A8 is now properly considered as a flyable
* **[Maps/Campaign]** Now using Vasiani airport instead of Soganlung in North Caucasus campaign (More parking slots)
* **[Info Panel]** Message displayed on base capture event stated that the ennemy captured an airbase, while it was the player who captured it.
* **[Map]** Graphical glitch on map when one building of an objective was destroyed, but not the others
#2.0 RC 6
@ -19,7 +31,6 @@ Saves file from RC5 are not compatible with the new version.
Sorry :(
##Features/Improvements :
* **[Units/Factions]** Supercarrier support (You have to go to settings to enable it, if you have the supercarrier module)
* **[Units/Factions]** Added 'Modern Bluefor' factions, containing all most popular DCS flyable units
* **[Units/Factions]** Factions US 2005 / 1990 will now sometimes have Arleigh Burke class ships instead of Perry as carrier escorts
@ -34,7 +45,6 @@ Sorry :(
* **[UX]** : Improved flight selection behaviour in the Mission Planning Window
##Fixed issues :
* **[Mission Generator]** Payloads were not correctly assigned in the release version.
* **[Mission Generator]** Game generation does not work when "no night mission" settings was selected and the current time was "day"
* **[Mission Generator]** Game generation does not work when the player selected faction has no AWACS

View File

@ -150,6 +150,7 @@ PRICES = {
S_3B_Tanker: 13,
IL_78M: 13,
KC_135: 13,
KC130: 13,
A_50: 8,
E_3A: 8,
@ -359,6 +360,7 @@ UNIT_BY_TASK = {
Refueling: [
IL_78M,
KC_135,
KC130,
S_3B_Tanker,
],
AWACS: [E_3A, A_50, ],

View File

@ -127,17 +127,6 @@ class Event:
self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn.miz"))
self.environment_settings = self.operation.environment_settings
def generate_quick(self):
pass
# TODO : This is not needed anymore. The player can start mission in flight from the flight planner if he want it to be quick.
# TODO : remove this method
#self.operation.is_awacs_enabled = self.is_awacs_enabled
#self.operation.environment_settings = self.environment_settings
#
#self.operation.prepare(self.game.theater.terrain, is_quick=True)
#self.operation.generate()
#self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn_quick.miz"))
def commit(self, debriefing: Debriefing):
logging.info("Commiting mission results")
@ -190,16 +179,30 @@ class Event:
logging.info("cp {} killing ground object {}".format(cp, ground_object.string_identifier))
cp.ground_objects[i].is_dead = True
info = Information("Building destroyed",
ground_object.dcs_identifier + " has been destroyed at location " + ground_object.obj_name,
self.game.turn)
self.game.informations.append(info)
# -- AA Site groups
destroyed_units = 0
info = Information("Units destroyed at " + ground_object.obj_name,
"",
self.game.turn)
for i, ground_object in enumerate(cp.ground_objects):
if ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]:
for g in ground_object.groups:
for u in g.units:
if u.name == destroyed_ground_unit_name:
g.units.remove(u)
destroyed_units = destroyed_units + 1
info.text = u.type
ucount = sum([len(g.units) for g in ground_object.groups])
if ucount == 0:
ground_object.is_dead = True
if destroyed_units > 0:
self.game.informations.append(info)
# ------------------------------
# Captured bases

View File

@ -24,7 +24,7 @@ BLUEFOR_MODERN = {
AJS37,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -11,7 +11,7 @@ France_1995 = {
Mirage_2000_5,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ France_2005 = {
FA_18C_hornet, # Standing as Rafale M
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ Germany_1990 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -15,7 +15,7 @@ India_2010 = {
Su_30,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ Israel_2000 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -11,7 +11,7 @@ Netherlands_1990 = {
F_5E_3,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ Spain_1990 = {
C_101CC,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -11,7 +11,7 @@ Turkey_2005 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ UAE_2005 = {
F_16C_50,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ UnitedKingdom_1990 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -11,7 +11,7 @@ USA_1955 = {
P_51D,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -11,7 +11,7 @@ USA_1960 = {
P_51D,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,7 +12,7 @@ USA_1965 = {
F_4E,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -17,7 +17,7 @@ USA_1990 = {
B_1B,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -12,12 +12,11 @@ USA_2005 = {
FA_18C_hornet,
F_16C_50,
JF_17,
A_10C,
AV8BNA,
KC_135,
S_3B_Tanker,
KC130,
C_130,
E_3A,

View File

@ -145,11 +145,8 @@ class Game:
def initiate_event(self, event: Event):
assert event in self.events
logging.info("Generating {} (regular)".format(event))
event.generate()
logging.info("Generating {} (quick)".format(event))
event.generate_quick()
def finish_event(self, event: Event, debriefing: Debriefing):
logging.info("Finishing event {}".format(event))

View File

@ -351,8 +351,8 @@ class AircraftConflictGenerator:
def setup_flight_group(self, group, flight, flight_type):
if flight_type in [FlightType.CAP, FlightType.BARCAP, FlightType.TARCAP]:
group.task = CAP.name
self._setup_group(group, CAP, flight.client_count)
# group.points[0].tasks.clear()
# group.tasks.clear()
@ -360,12 +360,14 @@ class AircraftConflictGenerator:
# group.tasks.append(EngageTargets(max_distance=nm_to_meter(120), targets=[Targets.All.Air]))
pass
elif flight_type in [FlightType.CAS, FlightType.BAI]:
group.task = CAS.name
self._setup_group(group, CAS, flight.client_count)
group.points[0].tasks.clear()
group.points[0].tasks.append(CASTaskAction())
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree))
elif flight_type in [FlightType.SEAD, FlightType.DEAD]:
group.task = SEAD.name
self._setup_group(group, SEAD, flight.client_count)
group.points[0].tasks.clear()
group.points[0].tasks.append(SEADTaskAction())
@ -373,9 +375,16 @@ class AircraftConflictGenerator:
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFireWeaponFree))
group.points[0].tasks.append(OptRestrictJettison(True))
elif flight_type in [FlightType.STRIKE]:
self._setup_group(group, PinpointStrike, flight.client_count)
group.task = PinpointStrike.name
self._setup_group(group, GroundAttack, flight.client_count)
group.points[0].tasks.clear()
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire))
group.points[0].tasks.append(OptRestrictJettison(True))
elif flight_type in [FlightType.ANTISHIP]:
group.task = AntishipStrike.name
self._setup_group(group, AntishipStrike, flight.client_count)
group.points[0].tasks.clear()
group.points[0].tasks.append(CASTaskAction())
group.points[0].tasks.append(OptReactOnThreat(OptReactOnThreat.Values.EvadeFire))
group.points[0].tasks.append(OptROE(OptROE.Values.OpenFire))
group.points[0].tasks.append(OptRestrictJettison(True))
@ -393,19 +402,19 @@ class AircraftConflictGenerator:
elif point.waypoint_type == FlightWaypointType.LANDING_POINT:
pt.type = "Land"
elif point.waypoint_type == FlightWaypointType.INGRESS_STRIKE:
print("TGTS :")
print(point.targets)
for j, t in enumerate(point.targets):
if hasattr(t, "obj_name"):
buildings = self.game.theater.find_ground_objects_by_obj_name(t.obj_name)
for j, building in enumerate(buildings):
group.points[i].tasks.append(Bombing(building.position))
if group.units[0].unit_type == JF_17 and j < 4:
group.add_nav_target_point(building.position, "PP" + str(j + 1))
if group.units[0].unit_type == F_14B and j == 0:
group.add_nav_target_point(building.position, "ST")
else:
group.points[i].tasks.append(Bombing(t.position))
print(t.position)
pt.tasks.append(Bombing(t.position))
if group.units[0].unit_type == JF_17 and j < 4:
group.add_nav_target_point(t.position, "PP" + str(j + 1))
if group.units[0].unit_type == F_14B and j == 0:
group.add_nav_target_point(t.position, "ST")
if pt is not None:
pt.alt_type = point.alt_type
pt.name = String(point.name)
self._setup_custom_payload(flight, group)

View File

@ -5,7 +5,7 @@ import random
from game import db
from gen import Conflict
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE
from gen.flights.ai_flight_planner_db import INTERCEPT_CAPABLE, CAP_CAPABLE, CAS_CAPABLE, SEAD_CAPABLE, STRIKE_CAPABLE
from gen.flights.flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
@ -267,7 +267,7 @@ class FlightPlanner:
center_point.alt_type = "RADIO"
center_point.description = "Provide CAS"
center_point.name = "CAS"
center_point.pretty_name = "INGRESS"
center_point.pretty_name = "CAS"
center_point.waypoint_type = FlightWaypointType.CAS
flight.points.append(center_point)
@ -375,7 +375,7 @@ class FlightPlanner:
"""
Pick some aircraft to assign them to STRIKE tasks
"""
possible_aircraft = [k for k, v in self.aircraft_inventory.items() if k in CAS_CAPABLE and v >= 2]
possible_aircraft = [k for k, v in self.aircraft_inventory.items() if k in STRIKE_CAPABLE and v >= 2]
inventory = dict({k: v for k, v in self.aircraft_inventory.items() if k in possible_aircraft})
if len(self.potential_strike_targets) > 0:
@ -411,27 +411,54 @@ class FlightPlanner:
ingress_point = FlightWaypoint(ingress_pos.x, ingress_pos.y, INGRESS_ALT)
ingress_point.pretty_name = "INGRESS on " + location.obj_name
ingress_point.description = "INGRESS on " + location.obj_name
ingress_point.name = "INGRESS"
ingress_point.waypoint_type = FlightWaypointType.INGRESS_STRIKE
flight.points.append(ingress_point)
if len(location.groups) > 0:
if len(location.groups) > 0 and location.dcs_identifier == "AA":
for g in location.groups:
for j, u in enumerate(g.units):
point = FlightWaypoint(u.position.x, u.position.y, 0)
point.description = "STRIKE " + "[" + str(location.obj_name) + "] : " + u.type + " #" + str(j)
point.pretty_name = "STRIKE " + "[" + str(location.obj_name) + "] : " + u.type + " #" + str(j)
point.name = location.obj_name + "#" + str(j)
point.only_for_player = True
ingress_point.targets.append(location)
flight.points.append(point)
else:
point = FlightWaypoint(location.position.x, location.position.y, 0)
point.description = "STRIKE on " + location.obj_name + " " + str(location.category)
point.pretty_name = "STRIKE on " + location.obj_name + " " + str(location.category)
point.targets.append(location)
flight.points.append(point)
if hasattr(location, "obj_name"):
buildings = self.game.theater.find_ground_objects_by_obj_name(location.obj_name)
print(buildings)
for building in buildings:
print("BUILDING " + str(building.is_dead) + " " + str(building.dcs_identifier))
if building.is_dead:
continue
point = FlightWaypoint(building.position.x, building.position.y, 0)
point.description = "STRIKE on " + building.obj_name + " " + str(building.category)
point.pretty_name = "STRIKE on " + building.obj_name + " " + str(building.category)
point.name = building.obj_name
point.only_for_player = True
ingress_point.targets.append(building)
flight.points.append(point)
else:
point = FlightWaypoint(location.position.x, location.position.y, 0)
point.description = "STRIKE on " + location.obj_name + " " + str(location.category)
point.pretty_name = "STRIKE on " + location.obj_name + " " + str(location.category)
point.name = location.obj_name
point.only_for_player = True
ingress_point.targets.append(location)
flight.points.append(point)
egress_pos = location.position.point_from_heading(egress_heading, INGRESS_EGRESS_DISTANCE)
egress_point = FlightWaypoint(egress_pos.x, egress_pos.y, EGRESS_ALT)
egress_point.name = "EGRESS"
egress_point.pretty_name = "EGRESS from " + location.obj_name
egress_point.description = "EGRESS from " + location.obj_name
egress_point.waypoint_type = FlightWaypointType.EGRESS
flight.points.append(egress_point)
descend = self.generate_descend_point(self.from_cp)
@ -559,8 +586,7 @@ class FlightPlanner:
return descend
def generate_rtb_waypoint(self, from_cp):
ascend_heading = from_cp.heading
rtb = from_cp.position.point_from_heading(ascend_heading - 180, 30000)
rtb = from_cp.position
rtb = FlightWaypoint(rtb.x, rtb.y, 0)
rtb.name = "LANDING"
rtb.alt_type = "RADIO"

View File

@ -167,8 +167,6 @@ STRIKE_CAPABLE = [
L_39ZA,
AJS37,
M_2000C,
P_51D_30_NA,
P_51D,
P_47D_30,

View File

@ -83,11 +83,16 @@ class QLiberationMap(QGraphicsView):
pen = QPen(brush=CONST.COLORS["red"])
brush = CONST.COLORS["red_transparent"]
added_objects = []
for ground_object in cp.ground_objects:
if ground_object.obj_name in added_objects:
continue
go_pos = self._transform_point(ground_object.position)
if not ground_object.airbase_group:
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 12, 12, cp, ground_object))
buildings = self.game.theater.find_ground_objects_by_obj_name(ground_object.obj_name)
scene.addItem(QMapGroundObject(self, go_pos[0], go_pos[1], 12, 12, cp, ground_object, buildings))
if ground_object.category == "aa" and self.get_display_rule("sam"):
max_range = 0
@ -99,6 +104,7 @@ class QLiberationMap(QGraphicsView):
max_range = unit.threat_range
if max_range >= 6000:
scene.addEllipse(go_pos[0] - max_range/300.0 + 8, go_pos[1] - max_range/300.0 + 8, max_range/150.0, max_range/150.0, pen, brush)
added_objects.append(ground_object.obj_name)
for cp in self.game.theater.enemy_points():
if self.get_display_rule("lines"):

View File

@ -9,13 +9,14 @@ from theater import TheaterGroundObject, ControlPoint
class QMapGroundObject(QGraphicsRectItem):
def __init__(self, parent, x: float, y: float, w: float, h: float, cp: ControlPoint, model: TheaterGroundObject):
def __init__(self, parent, x: float, y: float, w: float, h: float, cp: ControlPoint, model: TheaterGroundObject, buildings=[]):
super(QMapGroundObject, self).__init__(x, y, w, h)
self.model = model
self.cp = cp
self.parent = parent
self.setAcceptHoverEvents(True)
self.setZValue(2)
self.buildings = buildings
#self.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
if len(self.model.groups) > 0:
@ -32,7 +33,11 @@ class QMapGroundObject(QGraphicsRectItem):
tooltip = tooltip + str(unit) + "x" + str(units[unit]) + "\n"
self.setToolTip(tooltip[:-1])
else:
self.setToolTip("[" + self.model.obj_name + "] : " + self.model.category)
tooltip = "[" + self.model.obj_name + "]" + "\n"
for building in buildings:
if not building.is_dead:
tooltip = tooltip + str(building.dcs_identifier) + "\n"
self.setToolTip(tooltip[:-1])
def paint(self, painter, option, widget=None):

View File

@ -57,6 +57,14 @@ class QDebriefingWindow(QDialog):
except:
print("Issue adding " + str(unit_type) + " to debriefing information")
for building, count in self.debriefing.player_dead_buildings_dict.items():
try:
lostUnitsLayout.addWidget(QLabel(building, row, 0))
lostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
row += 1
except:
print("Issue adding " + str(building) + " to debriefing information")
self.layout.addWidget(lostUnits)
# Enemy lost units
@ -87,6 +95,14 @@ class QDebriefingWindow(QDialog):
enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
row += 1
for building, count in self.debriefing.enemy_dead_buildings_dict.items():
try:
enemylostUnitsLayout.addWidget(QLabel(building), row, 0)
enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
row += 1
except:
print("Issue adding " + str(building) + " to debriefing information")
self.layout.addWidget(enemylostUnits)
# confirm button

View File

@ -73,33 +73,29 @@ local unitPayloads = {
["name"] = "STRIKE",
["pylons"] = {
[1] = {
["CLSID"] = "DIS_WMD7",
["num"] = 4,
["CLSID"] = "DIS_LS_6_500",
["num"] = 6,
},
[2] = {
["CLSID"] = "DIS_LS_6_500",
["num"] = 5,
},
[3] = {
["CLSID"] = "DIS_LS_6_500",
["num"] = 3,
},
[4] = {
["CLSID"] = "DIS_LS_6_500",
["num"] = 2,
},
[5] = {
["CLSID"] = "DIS_PL-5EII",
["num"] = 1,
},
[3] = {
[6] = {
["CLSID"] = "DIS_PL-5EII",
["num"] = 7,
},
[4] = {
["CLSID"] = "DIS_GBU_12_DUAL",
["num"] = 6,
},
[5] = {
["CLSID"] = "DIS_GBU_12_DUAL",
["num"] = 2,
},
[6] = {
["CLSID"] = "DIS_GBU_16",
["num"] = 3,
},
[7] = {
["CLSID"] = "DIS_GBU_16",
["num"] = 5,
},
},
["tasks"] = {
[1] = 10,

View File

@ -47,6 +47,8 @@ class Debriefing:
self.dead_aircraft = []
self.dead_units = []
self.dead_aaa_groups = []
self.dead_buildings = []
for aircraft in self.killed_aircrafts:
try:
@ -70,10 +72,36 @@ class Debriefing:
except Exception as e:
print(e)
for unit in self.killed_ground_units:
for cp in game.theater.controlpoints:
print(cp.name)
print(cp.captured)
if cp.captured:
country = self.player_country_id
else:
country = self.enemy_country_id
player_unit = (country == self.player_country_id)
for i, ground_object in enumerate(cp.ground_objects):
print(unit)
print(ground_object.string_identifier)
if ground_object.matches_string_identifier(unit):
unit = DebriefingDeadUnitInfo(country, player_unit, ground_object.dcs_identifier)
self.dead_buildings.append(unit)
elif ground_object.dcs_identifier in ["AA", "CARRIER", "LHA"]:
for g in ground_object.groups:
for u in g.units:
if u.name == unit:
unit = DebriefingDeadUnitInfo(country, player_unit, db.unit_type_from_name(u.type))
self.dead_units.append(unit)
self.player_dead_aircraft = [a for a in self.dead_aircraft if a.country_id == self.player_country_id]
self.enemy_dead_aircraft = [a for a in self.dead_aircraft if a.country_id == self.enemy_country_id]
self.player_dead_units = [a for a in self.dead_units if a.country_id == self.player_country_id]
self.enemy_dead_units = [a for a in self.dead_units if a.country_id == self.enemy_country_id]
self.player_dead_buildings = [a for a in self.dead_buildings if a.country_id == self.player_country_id]
self.enemy_dead_buildings = [a for a in self.dead_buildings if a.country_id == self.enemy_country_id]
print(self.player_dead_aircraft)
print(self.enemy_dead_aircraft)
@ -108,10 +136,27 @@ class Debriefing:
else:
self.enemy_dead_units_dict[a.type] = 1
self.player_dead_buildings_dict = {}
for a in self.player_dead_buildings:
if a.type in self.player_dead_buildings_dict.keys():
self.player_dead_buildings_dict[a.type] = self.player_dead_buildings_dict[a.type] + 1
else:
self.player_dead_buildings_dict[a.type] = 1
self.enemy_dead_buildings_dict = {}
for a in self.enemy_dead_buildings:
if a.type in self.enemy_dead_buildings_dict.keys():
self.enemy_dead_buildings_dict[a.type] = self.enemy_dead_buildings_dict[a.type] + 1
else:
self.enemy_dead_buildings_dict[a.type] = 1
print("DEBRIEFING PRE PROCESS")
print(self.player_dead_aircraft_dict)
print(self.enemy_dead_aircraft_dict)
print(self.player_dead_units_dict)
print(self.enemy_dead_units_dict)
print(self.player_dead_buildings_dict)
print(self.enemy_dead_buildings_dict)
def _poll_new_debriefing_log(callback: typing.Callable, game):