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
|
||||
|
||||
## Features :
|
||||
* **[UI/UX]** New UI Theme by Deus
|
||||
* **[UI/UX]** New map backgrounds
|
||||
* **[Units/Factions]** Added Community A-4E-C support for faction Bluefor Cold War
|
||||
* **[Units/Factions]** Added MB-339PAN support for faction Bluefor Cold War
|
||||
* **[Units/Factions]** Added Rafale AI mod support
|
||||
* **[Units/Factions]** Added faction "France Modded" with units from frenchpack v3.5 mod
|
||||
* **[Units/Factions]** Added faction "Insurgent modded" with Insurgent units from frenchpack v3.5 mod (Toyota truck)
|
||||
## Features/Improvements :
|
||||
* **[UI/UX]** New dark UI Theme and default theme improvement by Deus
|
||||
* **[UI/UX]** New satellite map backgrounds
|
||||
* **[UX]** Base menu is opened with a single mouse click
|
||||
* **[Units/Factions/Mods]** Added Community A-4E-C support for faction Bluefor Cold War
|
||||
* **[Units/Factions/Mods]** Added MB-339PAN support for faction Bluefor Cold War
|
||||
* **[Units/Factions/Mods]** Added Rafale AI mod support
|
||||
* **[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 :
|
||||
* **[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 group ships are more spread out
|
||||
|
||||
* **[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
|
||||
|
||||
|
||||
74
game/game.py
74
game/game.py
@ -1,7 +1,7 @@
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
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.ground_forces.ai_ground_planner import GroundPlanner
|
||||
from .event import *
|
||||
@ -73,7 +73,8 @@ class Game:
|
||||
self.informations = []
|
||||
self.informations.append(Information("Game Start", "-" * 40, 0))
|
||||
self.__culling_points = self.compute_conflicts_position()
|
||||
|
||||
self.__frontlineData = []
|
||||
self.__destroyed_units = []
|
||||
|
||||
@property
|
||||
def player_faction(self):
|
||||
@ -175,33 +176,6 @@ class Game:
|
||||
else:
|
||||
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):
|
||||
|
||||
logging.info("Pass turn")
|
||||
@ -383,6 +357,12 @@ class Game:
|
||||
|
||||
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):
|
||||
"""
|
||||
Check if unit can be generated at given position depending on culling performance settings
|
||||
@ -397,3 +377,39 @@ class Game:
|
||||
return False
|
||||
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
|
||||
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)
|
||||
self.airsupportgen.generate(self.is_awacs_enabled)
|
||||
|
||||
|
||||
@ -54,7 +54,6 @@ class BriefingGenerator:
|
||||
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"
|
||||
|
||||
|
||||
def generate(self):
|
||||
|
||||
self.description = ""
|
||||
@ -62,8 +61,7 @@ class BriefingGenerator:
|
||||
self.description += "DCS Liberation turn #" + str(self.game.turn) + "\n"
|
||||
self.description += "=" * 15 + "\n\n"
|
||||
|
||||
self.description += "Current situation:\n"
|
||||
self.description += "=" * 15 + "\n\n"
|
||||
self.generate_ongoing_war_text()
|
||||
|
||||
self.description += "\n"*2
|
||||
self.description += "Your flights:" + "\n"
|
||||
@ -93,7 +91,7 @@ class BriefingGenerator:
|
||||
for cp in self.game.theater.controlpoints:
|
||||
if cp.captured and cp.cptype in [ControlPointType.LHA_GROUP, ControlPointType.AIRCRAFT_CARRIER_GROUP]:
|
||||
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 += str(cp.tacanN)
|
||||
if cp.tacanY:
|
||||
@ -108,4 +106,72 @@ class BriefingGenerator:
|
||||
|
||||
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 = {}
|
||||
weapons_fired = {}
|
||||
base_capture_events = {}
|
||||
destroyed_objects_positions = {}
|
||||
mission_ended = false
|
||||
|
||||
local function messageAll(message)
|
||||
@ -21,6 +22,7 @@ end
|
||||
|
||||
write_state = function()
|
||||
--messageAll("Writing DCS Liberation State...")
|
||||
--logger.info("Writing DCS LIBERATION state")
|
||||
local fp = io.open(debriefing_file_location, 'w')
|
||||
local game_state = {
|
||||
["killed_aircrafts"] = killed_aircrafts,
|
||||
@ -28,9 +30,11 @@ write_state = function()
|
||||
["weapons_fired"] = weapons_fired,
|
||||
["base_capture_events"] = base_capture_events,
|
||||
["mission_ended"] = mission_ended,
|
||||
["destroyed_objects_positions"] = destroyed_objects_positions,
|
||||
}
|
||||
fp:write(json:encode(game_state))
|
||||
fp:close()
|
||||
--logger.info("Done writing DCS Liberation state")
|
||||
--messageAll("Done writing DCS Liberation state.")
|
||||
end
|
||||
|
||||
@ -45,6 +49,14 @@ local function onEvent(event)
|
||||
|
||||
if event.id == world.event.S_EVENT_DEAD and event.initiator then
|
||||
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
|
||||
|
||||
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.weapons_fired = state_data["weapons_fired"]
|
||||
self.mission_ended = state_data["mission_ended"]
|
||||
self.destroyed_units = state_data["destroyed_objects_positions"]
|
||||
|
||||
self.__destroyed_units = []
|
||||
logging.info("--------------------------------")
|
||||
logging.info("Starting Debriefing preprocessing")
|
||||
logging.info("--------------------------------")
|
||||
@ -44,6 +46,7 @@ class Debriefing:
|
||||
logging.info(self.killed_ground_units)
|
||||
logging.info(self.weapons_fired)
|
||||
logging.info(self.mission_ended)
|
||||
logging.info(self.destroyed_units)
|
||||
logging.info("--------------------------------")
|
||||
|
||||
self.player_country_id = db.country_id_from_name(game.player_country)
|
||||
@ -155,6 +158,9 @@ class Debriefing:
|
||||
else:
|
||||
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("Debriefing pre process results :")
|
||||
logging.info("--------------------------------")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user