mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Previously destroyed units are added to the mission.
This commit is contained in:
parent
b34ede3795
commit
d5fb1f62f5
30
changelog.md
30
changelog.md
@ -1,18 +1,32 @@
|
|||||||
# 2.0.10
|
# 2.0.10
|
||||||
|
|
||||||
## Features :
|
## Features/Improvements :
|
||||||
* **[UI/UX]** New UI Theme by Deus
|
* **[UI/UX]** New dark UI Theme and default theme improvement by Deus
|
||||||
* **[UI/UX]** New map backgrounds
|
* **[UI/UX]** New satellite map backgrounds
|
||||||
* **[Units/Factions]** Added Community A-4E-C support for faction Bluefor Cold War
|
* **[UX]** Base menu is opened with a single mouse click
|
||||||
* **[Units/Factions]** Added MB-339PAN support for faction Bluefor Cold War
|
* **[Units/Factions/Mods]** Added Community A-4E-C support for faction Bluefor Cold War
|
||||||
* **[Units/Factions]** Added Rafale AI mod support
|
* **[Units/Factions/Mods]** Added MB-339PAN support for faction Bluefor Cold War
|
||||||
* **[Units/Factions]** Added faction "France Modded" with units from frenchpack v3.5 mod
|
* **[Units/Factions/Mods]** Added Rafale AI mod support
|
||||||
* **[Units/Factions]** Added faction "Insurgent modded" with Insurgent units from frenchpack v3.5 mod (Toyota truck)
|
* **[Units/Factions/Mods]** Added faction "France Modded" with units from frenchpack v3.5 mod
|
||||||
|
* **[Units/Factions/Mods]** Added faction "Insurgent modded" with Insurgent units from frenchpack v3.5 mod (Toyota truck)
|
||||||
|
* **[New Game Wizard]** Added the list of required mods for modded factions.
|
||||||
|
* **[Mission Generator]** Artillery units will start firing mission after a random delay. It should reduces lag spikes induced by artillery strikes by spreading them out.
|
||||||
|
* **[Mission Generator]** The briefing will now contain the carrier ATC frequency
|
||||||
|
* **[Mission Generator]** The briefing contains a small section about the war on the ground.
|
||||||
|
* **[Mission Generator]** DCS Liberation picture added to the in-game briefing
|
||||||
|
|
||||||
## Fixed issues :
|
## Fixed issues :
|
||||||
* **[Mission Generator]** Carrier will sail into the wind, not in the same direction
|
* **[Mission Generator]** Carrier will sail into the wind, not in the same direction
|
||||||
* **[Mission Generator]** Carrier cold start was not working (flight was starting warm even when cold was selected)
|
* **[Mission Generator]** Carrier cold start was not working (flight was starting warm even when cold was selected)
|
||||||
|
* **[Mission Generator]** Carrier group ships are more spread out
|
||||||
|
|
||||||
* **[Units/Factions]** Remove JF-17 from USA 2005 faction
|
* **[Units/Factions]** Remove JF-17 from USA 2005 faction
|
||||||
|
* **[Units/Factions]** Removed Oliver Hazard Perry from cold war factions (too powerful sam system)
|
||||||
|
* **[Bug]** On the persian gulf full map campaign, the two carriers were sharing the same id, this was causing a lot of bugs
|
||||||
|
* **[Performance]** Tuned the culling setting so that you cannot run into situation where no flights are generated
|
||||||
|
* **[Mission Generator]** Fixed radio frequency for german WW2 warbirds
|
||||||
|
|
||||||
|
* **[Other]** Other minor fixes
|
||||||
|
|
||||||
# 2.0 RC 9
|
# 2.0 RC 9
|
||||||
|
|
||||||
|
|||||||
74
game/game.py
74
game/game.py
@ -1,7 +1,7 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from game.db import REWARDS, PLAYER_BUDGET_BASE, sys
|
from game.db import REWARDS, PLAYER_BUDGET_BASE, sys
|
||||||
from game.game_stats import GameStats
|
from game.models.game_stats import GameStats
|
||||||
from gen.flights.ai_flight_planner import FlightPlanner
|
from gen.flights.ai_flight_planner import FlightPlanner
|
||||||
from gen.ground_forces.ai_ground_planner import GroundPlanner
|
from gen.ground_forces.ai_ground_planner import GroundPlanner
|
||||||
from .event import *
|
from .event import *
|
||||||
@ -73,7 +73,8 @@ class Game:
|
|||||||
self.informations = []
|
self.informations = []
|
||||||
self.informations.append(Information("Game Start", "-" * 40, 0))
|
self.informations.append(Information("Game Start", "-" * 40, 0))
|
||||||
self.__culling_points = self.compute_conflicts_position()
|
self.__culling_points = self.compute_conflicts_position()
|
||||||
|
self.__frontlineData = []
|
||||||
|
self.__destroyed_units = []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def player_faction(self):
|
def player_faction(self):
|
||||||
@ -175,33 +176,6 @@ class Game:
|
|||||||
else:
|
else:
|
||||||
return event.name == self.player_name
|
return event.name == self.player_name
|
||||||
|
|
||||||
# 1 = red, 2 = blue
|
|
||||||
def get_player_coalition_id(self):
|
|
||||||
if self.player_country in db.BLUEFOR_FACTIONS:
|
|
||||||
return 2
|
|
||||||
else:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def get_enemy_coalition_id(self):
|
|
||||||
if self.get_player_coalition_id() == 1:
|
|
||||||
return 2
|
|
||||||
else:
|
|
||||||
return 1
|
|
||||||
|
|
||||||
def get_player_color(self):
|
|
||||||
if self.get_player_coalition_id() == 1:
|
|
||||||
return "red"
|
|
||||||
else:
|
|
||||||
return "blue"
|
|
||||||
|
|
||||||
def get_enemy_color(self):
|
|
||||||
if self.get_player_coalition_id() == 1:
|
|
||||||
return "blue"
|
|
||||||
else:
|
|
||||||
return "red"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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")
|
logging.info("Pass turn")
|
||||||
@ -383,6 +357,12 @@ class Game:
|
|||||||
|
|
||||||
return points
|
return points
|
||||||
|
|
||||||
|
def add_destroyed_units(self, destroyed_unit_data):
|
||||||
|
self.__destroyed_units.append(destroyed_unit_data)
|
||||||
|
|
||||||
|
def get_destroyed_units(self):
|
||||||
|
return self.__destroyed_units
|
||||||
|
|
||||||
def position_culled(self, pos):
|
def position_culled(self, pos):
|
||||||
"""
|
"""
|
||||||
Check if unit can be generated at given position depending on culling performance settings
|
Check if unit can be generated at given position depending on culling performance settings
|
||||||
@ -397,3 +377,39 @@ class Game:
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# 1 = red, 2 = blue
|
||||||
|
def get_player_coalition_id(self):
|
||||||
|
if self.player_country in db.BLUEFOR_FACTIONS:
|
||||||
|
return 2
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def get_enemy_coalition_id(self):
|
||||||
|
if self.get_player_coalition_id() == 1:
|
||||||
|
return 2
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def get_player_coalition(self):
|
||||||
|
if self.player_country in db.BLUEFOR_FACTIONS:
|
||||||
|
return dcs.action.Coalition.Blue
|
||||||
|
else:
|
||||||
|
return dcs.action.Coalition.Red
|
||||||
|
|
||||||
|
def get_enemy_coalition(self):
|
||||||
|
if self.player_country == 1:
|
||||||
|
return dcs.action.Coalition.Blue
|
||||||
|
else:
|
||||||
|
return dcs.action.Coalition.Red
|
||||||
|
|
||||||
|
def get_player_color(self):
|
||||||
|
if self.get_player_coalition_id() == 1:
|
||||||
|
return "red"
|
||||||
|
else:
|
||||||
|
return "blue"
|
||||||
|
|
||||||
|
def get_enemy_color(self):
|
||||||
|
if self.get_player_coalition_id() == 1:
|
||||||
|
return "blue"
|
||||||
|
else:
|
||||||
|
return "red"
|
||||||
14
game/models/destroyed_units.py
Normal file
14
game/models/destroyed_units.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class DestroyedUnit:
|
||||||
|
"""
|
||||||
|
Store info about a destroyed unit
|
||||||
|
"""
|
||||||
|
|
||||||
|
x: int
|
||||||
|
y: int
|
||||||
|
name: str
|
||||||
|
|
||||||
|
def __init__(self, x , y, name):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.name = name
|
||||||
|
|
||||||
13
game/models/frontline_data.py
Normal file
13
game/models/frontline_data.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from theater import ControlPoint
|
||||||
|
|
||||||
|
|
||||||
|
class FrontlineData:
|
||||||
|
"""
|
||||||
|
This Data structure will store information about an existing frontline
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, from_cp:ControlPoint, to_cp: ControlPoint):
|
||||||
|
self.to_cp = to_cp
|
||||||
|
self.from_cp = from_cp
|
||||||
|
self.enemy_units_position = []
|
||||||
|
self.blue_units_position = []
|
||||||
@ -123,6 +123,21 @@ class Operation:
|
|||||||
# Generate ground object first
|
# Generate ground object first
|
||||||
self.groundobjectgen.generate()
|
self.groundobjectgen.generate()
|
||||||
|
|
||||||
|
# Generate destroyed units
|
||||||
|
for d in self.game.get_destroyed_units():
|
||||||
|
utype = db.unit_type_from_name(d["type"])
|
||||||
|
pos = Point(d["x"], d["z"])
|
||||||
|
if utype is not None and not self.game.position_culled(pos):
|
||||||
|
self.current_mission.static_group(
|
||||||
|
country=self.current_mission.country(self.game.player_country),
|
||||||
|
name="",
|
||||||
|
_type=utype,
|
||||||
|
hidden=True,
|
||||||
|
position=pos,
|
||||||
|
heading=d["orientation"],
|
||||||
|
dead=True,
|
||||||
|
)
|
||||||
|
|
||||||
# Air Support (Tanker & Awacs)
|
# Air Support (Tanker & Awacs)
|
||||||
self.airsupportgen.generate(self.is_awacs_enabled)
|
self.airsupportgen.generate(self.is_awacs_enabled)
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,6 @@ class BriefingGenerator:
|
|||||||
flight_unit_name = db.unit_type_name(flight.unit_type)
|
flight_unit_name = db.unit_type_name(flight.unit_type)
|
||||||
self.description += flight.flight_type.name + " " + flight_unit_name + " x " + str(flight.count) + ", departing in " + str(flight.scheduled_in) + " minutes \n"
|
self.description += flight.flight_type.name + " " + flight_unit_name + " x " + str(flight.count) + ", departing in " + str(flight.scheduled_in) + " minutes \n"
|
||||||
|
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
|
|
||||||
self.description = ""
|
self.description = ""
|
||||||
@ -62,8 +61,7 @@ class BriefingGenerator:
|
|||||||
self.description += "DCS Liberation turn #" + str(self.game.turn) + "\n"
|
self.description += "DCS Liberation turn #" + str(self.game.turn) + "\n"
|
||||||
self.description += "=" * 15 + "\n\n"
|
self.description += "=" * 15 + "\n\n"
|
||||||
|
|
||||||
self.description += "Current situation:\n"
|
self.generate_ongoing_war_text()
|
||||||
self.description += "=" * 15 + "\n\n"
|
|
||||||
|
|
||||||
self.description += "\n"*2
|
self.description += "\n"*2
|
||||||
self.description += "Your flights:" + "\n"
|
self.description += "Your flights:" + "\n"
|
||||||
@ -93,7 +91,7 @@ class BriefingGenerator:
|
|||||||
for cp in self.game.theater.controlpoints:
|
for cp in self.game.theater.controlpoints:
|
||||||
if cp.captured and cp.cptype in [ControlPointType.LHA_GROUP, ControlPointType.AIRCRAFT_CARRIER_GROUP]:
|
if cp.captured and cp.cptype in [ControlPointType.LHA_GROUP, ControlPointType.AIRCRAFT_CARRIER_GROUP]:
|
||||||
self.description += cp.name + "\n"
|
self.description += cp.name + "\n"
|
||||||
self.description += "RADIO : 127.5 Mhz AM"
|
self.description += "RADIO : 127.5 Mhz AM\n"
|
||||||
self.description += "TACAN : "
|
self.description += "TACAN : "
|
||||||
self.description += str(cp.tacanN)
|
self.description += str(cp.tacanN)
|
||||||
if cp.tacanY:
|
if cp.tacanY:
|
||||||
@ -108,4 +106,72 @@ class BriefingGenerator:
|
|||||||
|
|
||||||
self.m.set_description_text(self.description)
|
self.m.set_description_text(self.description)
|
||||||
|
|
||||||
|
#self.m.add_picture_blue(os.path.abspath("./resources/ui/splash_screen.png")) NOT working
|
||||||
|
|
||||||
|
|
||||||
|
def generate_ongoing_war_text(self):
|
||||||
|
|
||||||
|
self.description += "Current situation:\n"
|
||||||
|
self.description += "=" * 15 + "\n\n"
|
||||||
|
|
||||||
|
conflict_number = 0
|
||||||
|
|
||||||
|
for c in self.game.theater.conflicts():
|
||||||
|
conflict_number = conflict_number + 1
|
||||||
|
if c[0].captured:
|
||||||
|
player_base = c[0]
|
||||||
|
enemy_base = c[1]
|
||||||
|
else:
|
||||||
|
player_base = c[1]
|
||||||
|
enemy_base = c[0]
|
||||||
|
|
||||||
|
has_numerical_superiority = player_base.base.total_armor > enemy_base.base.total_armor
|
||||||
|
self.description += self.__random_frontline_sentence(player_base.name, enemy_base.name)
|
||||||
|
|
||||||
|
if enemy_base.id in player_base.stances.keys():
|
||||||
|
stance = player_base.stances[enemy_base.id]
|
||||||
|
|
||||||
|
if player_base.base.total_armor == 0:
|
||||||
|
self.description += "We do not have a single vehicle available to hold our position, the situation is critical, and we will lose ground inevitably.\n"
|
||||||
|
elif enemy_base.base.total_armor == 0:
|
||||||
|
self.description += "The enemy forces have been crushed, we will be able to make significant progress toward " + enemy_base.name + ". \n"
|
||||||
|
if stance == CombatStance.AGGRESIVE:
|
||||||
|
if has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces will try to make progress against the enemy"
|
||||||
|
self.description += ". As the enemy is outnumbered, our forces should have no issue making progress.\n"
|
||||||
|
elif has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces will try an audacious assault against enemies in superior numbers. The operation is risky, and the enemy might counter attack.\n"
|
||||||
|
elif stance == CombatStance.ELIMINATION:
|
||||||
|
if has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces will focus on the destruction of enemy assets, before attempting to make progress toward " + enemy_base.name + ". "
|
||||||
|
self.description += "The enemy is already outnumbered, and this maneuver might draw a final blow to their forces.\n"
|
||||||
|
elif has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces will try an audacious assault against enemies in superior numbers. The operation is risky, and the enemy might counter attack.\n"
|
||||||
|
elif stance == CombatStance.BREAKTHROUGH:
|
||||||
|
if has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces will focus on progression toward " + enemy_base.name + ".\n"
|
||||||
|
elif has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces have been ordered to rush toward " + enemy_base.name + ". Wish them luck... We are also expecting a counter attack.\n"
|
||||||
|
elif stance in [CombatStance.DEFENSIVE, CombatStance.AMBUSH]:
|
||||||
|
if has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces will hold position. We are not expecting an enemy assault.\n"
|
||||||
|
elif has_numerical_superiority:
|
||||||
|
self.description += "On this location, our ground forces have been ordered to hold still, and defend against enemy attacks. An enemy assault might be iminent.\n"
|
||||||
|
|
||||||
|
if conflict_number == 0:
|
||||||
|
self.description += "There are currently no fights on the ground.\n"
|
||||||
|
|
||||||
|
self.description += "\n\n"
|
||||||
|
|
||||||
|
|
||||||
|
def __random_frontline_sentence(self, player_base_name, enemy_base_name):
|
||||||
|
templates = [
|
||||||
|
"There are combats between {} and {}. ",
|
||||||
|
"The war on the ground is still going on between {} an {}. ",
|
||||||
|
"Our ground forces in {} are opposed to enemy forces based in {}. ",
|
||||||
|
"Our forces from {} are fighting enemies based in {}. ",
|
||||||
|
"There is an active frontline between {} and {}. ",
|
||||||
|
]
|
||||||
|
return random.choice(templates).format(player_base_name, enemy_base_name)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ killed_aircrafts = {}
|
|||||||
killed_ground_units = {}
|
killed_ground_units = {}
|
||||||
weapons_fired = {}
|
weapons_fired = {}
|
||||||
base_capture_events = {}
|
base_capture_events = {}
|
||||||
|
destroyed_objects_positions = {}
|
||||||
mission_ended = false
|
mission_ended = false
|
||||||
|
|
||||||
local function messageAll(message)
|
local function messageAll(message)
|
||||||
@ -21,6 +22,7 @@ end
|
|||||||
|
|
||||||
write_state = function()
|
write_state = function()
|
||||||
--messageAll("Writing DCS Liberation State...")
|
--messageAll("Writing DCS Liberation State...")
|
||||||
|
--logger.info("Writing DCS LIBERATION state")
|
||||||
local fp = io.open(debriefing_file_location, 'w')
|
local fp = io.open(debriefing_file_location, 'w')
|
||||||
local game_state = {
|
local game_state = {
|
||||||
["killed_aircrafts"] = killed_aircrafts,
|
["killed_aircrafts"] = killed_aircrafts,
|
||||||
@ -28,9 +30,11 @@ write_state = function()
|
|||||||
["weapons_fired"] = weapons_fired,
|
["weapons_fired"] = weapons_fired,
|
||||||
["base_capture_events"] = base_capture_events,
|
["base_capture_events"] = base_capture_events,
|
||||||
["mission_ended"] = mission_ended,
|
["mission_ended"] = mission_ended,
|
||||||
|
["destroyed_objects_positions"] = destroyed_objects_positions,
|
||||||
}
|
}
|
||||||
fp:write(json:encode(game_state))
|
fp:write(json:encode(game_state))
|
||||||
fp:close()
|
fp:close()
|
||||||
|
--logger.info("Done writing DCS Liberation state")
|
||||||
--messageAll("Done writing DCS Liberation state.")
|
--messageAll("Done writing DCS Liberation state.")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -45,6 +49,14 @@ local function onEvent(event)
|
|||||||
|
|
||||||
if event.id == world.event.S_EVENT_DEAD and event.initiator then
|
if event.id == world.event.S_EVENT_DEAD and event.initiator then
|
||||||
killed_ground_units[#killed_ground_units + 1] = event.initiator.getName(event.initiator)
|
killed_ground_units[#killed_ground_units + 1] = event.initiator.getName(event.initiator)
|
||||||
|
local position = event.initiator.getPosition(event.initiator)
|
||||||
|
local destruction = {}
|
||||||
|
destruction.x = position.p.x
|
||||||
|
destruction.y = position.p.y
|
||||||
|
destruction.z = position.p.z
|
||||||
|
destruction.type = event.initiator:getTypeName()
|
||||||
|
destruction.orientation = mist.getHeading(event.initiator) * 57.3
|
||||||
|
destroyed_objects_positions[#destroyed_objects_positions + 1] = destruction
|
||||||
end
|
end
|
||||||
|
|
||||||
if event.id == world.event.S_EVENT_SHOT and event.weapon then
|
if event.id == world.event.S_EVENT_SHOT and event.weapon then
|
||||||
|
|||||||
@ -35,7 +35,9 @@ class Debriefing:
|
|||||||
self.killed_ground_units = state_data["killed_ground_units"]
|
self.killed_ground_units = state_data["killed_ground_units"]
|
||||||
self.weapons_fired = state_data["weapons_fired"]
|
self.weapons_fired = state_data["weapons_fired"]
|
||||||
self.mission_ended = state_data["mission_ended"]
|
self.mission_ended = state_data["mission_ended"]
|
||||||
|
self.destroyed_units = state_data["destroyed_objects_positions"]
|
||||||
|
|
||||||
|
self.__destroyed_units = []
|
||||||
logging.info("--------------------------------")
|
logging.info("--------------------------------")
|
||||||
logging.info("Starting Debriefing preprocessing")
|
logging.info("Starting Debriefing preprocessing")
|
||||||
logging.info("--------------------------------")
|
logging.info("--------------------------------")
|
||||||
@ -44,6 +46,7 @@ class Debriefing:
|
|||||||
logging.info(self.killed_ground_units)
|
logging.info(self.killed_ground_units)
|
||||||
logging.info(self.weapons_fired)
|
logging.info(self.weapons_fired)
|
||||||
logging.info(self.mission_ended)
|
logging.info(self.mission_ended)
|
||||||
|
logging.info(self.destroyed_units)
|
||||||
logging.info("--------------------------------")
|
logging.info("--------------------------------")
|
||||||
|
|
||||||
self.player_country_id = db.country_id_from_name(game.player_country)
|
self.player_country_id = db.country_id_from_name(game.player_country)
|
||||||
@ -155,6 +158,9 @@ class Debriefing:
|
|||||||
else:
|
else:
|
||||||
self.enemy_dead_buildings_dict[a.type] = 1
|
self.enemy_dead_buildings_dict[a.type] = 1
|
||||||
|
|
||||||
|
for destroyed_unit in self.destroyed_units:
|
||||||
|
game.add_destroyed_units(destroyed_unit)
|
||||||
|
|
||||||
logging.info("--------------------------------")
|
logging.info("--------------------------------")
|
||||||
logging.info("Debriefing pre process results :")
|
logging.info("Debriefing pre process results :")
|
||||||
logging.info("--------------------------------")
|
logging.info("--------------------------------")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user