mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Merge remote-tracking branch 'khopa/develop' into helipads
This commit is contained in:
commit
1c813c0e0e
@ -6,12 +6,21 @@ Saves from 3.x are not compatible with 5.0.
|
||||
|
||||
## Fixes
|
||||
|
||||
# 4.0.1
|
||||
|
||||
Saves from 4.0.0 are compatible with 4.0.1.
|
||||
|
||||
## Features/Improvements
|
||||
|
||||
## Fixes
|
||||
|
||||
# 4.0.0
|
||||
|
||||
Saves from 3.x are not compatible with 4.0.
|
||||
|
||||
## Features/Improvements
|
||||
|
||||
* **[Engine]** Support for DCS 2.7.2.7910.1 and newer, including Cyprus, F-16 JDAMs, and the Hind.
|
||||
* **[Campaign]** Squadrons now (optionally, off by default) have a maximum size and killed pilots replenish at a limited rate.
|
||||
* **[Campaign]** Added an option to disable levelling up of AI pilots.
|
||||
* **[Campaign]** Added Russian Intervention 2015 campaign on Syria, for a small and somewhat realistic Russian COIN scenario.
|
||||
|
||||
@ -87,6 +87,14 @@ vehicle_map["Toyota_bleu"] = frenchpack.DIM__TOYOTA_BLUE
|
||||
vehicle_map["Toyota_vert"] = frenchpack.DIM__TOYOTA_GREEN
|
||||
vehicle_map["Toyota_desert"] = frenchpack.DIM__TOYOTA_DESERT
|
||||
vehicle_map["Kamikaze"] = frenchpack.DIM__KAMIKAZE
|
||||
vehicle_map["AMX1375"] = frenchpack.AMX_13_75mm
|
||||
vehicle_map["AMX1390"] = frenchpack.AMX_13_90mm
|
||||
vehicle_map["VBCI"] = frenchpack.VBCI
|
||||
vehicle_map["T62"] = frenchpack.Char_T_62
|
||||
vehicle_map["T64BV"] = frenchpack.Char_T_64BV
|
||||
vehicle_map["T72M"] = frenchpack.Char_T_72A
|
||||
vehicle_map["KORNET"] = frenchpack.KORNET_ATGM
|
||||
|
||||
|
||||
vehicle_map[highdigitsams.AAA_SON_9_Fire_Can.id] = highdigitsams.AAA_SON_9_Fire_Can
|
||||
vehicle_map[highdigitsams.AAA_100mm_KS_19.id] = highdigitsams.AAA_100mm_KS_19
|
||||
|
||||
@ -301,6 +301,13 @@ class Faction:
|
||||
self.remove_vehicle("Toyota_vert")
|
||||
self.remove_vehicle("Toyota_desert")
|
||||
self.remove_vehicle("Kamikaze")
|
||||
self.remove_vehicle("AMX1375")
|
||||
self.remove_vehicle("AMX1390")
|
||||
self.remove_vehicle("VBCI")
|
||||
self.remove_vehicle("T62")
|
||||
self.remove_vehicle("T64BV")
|
||||
self.remove_vehicle("T72M")
|
||||
self.remove_vehicle("KORNET")
|
||||
# high digit sams
|
||||
if not mod_settings.high_digit_sams:
|
||||
self.remove_air_defenses("SA10BGenerator")
|
||||
|
||||
@ -41,7 +41,7 @@ class Settings:
|
||||
#: the campaign has started will have no immediate effect; pilots already in the
|
||||
#: squadron will not be removed if the limit is lowered and pilots will not be
|
||||
#: immediately created if the limit is raised.
|
||||
squadron_pilot_limit: int = 4
|
||||
squadron_pilot_limit: int = 12
|
||||
|
||||
#: The number of pilots a squadron can replace per turn.
|
||||
squadron_replenishment_rate: int = 4
|
||||
|
||||
@ -158,15 +158,17 @@ class TransferOrder:
|
||||
)
|
||||
return self.transport.destination
|
||||
|
||||
def proceed(self) -> None:
|
||||
if self.transport is None:
|
||||
return
|
||||
def find_escape_route(self) -> Optional[ControlPoint]:
|
||||
if self.transport is not None:
|
||||
return self.transport.find_escape_route()
|
||||
return None
|
||||
|
||||
def proceed(self) -> None:
|
||||
if not self.destination.is_friendly(self.player):
|
||||
logging.info(f"Transfer destination {self.destination} was captured.")
|
||||
if self.position.is_friendly(self.player):
|
||||
self.disband_at(self.position)
|
||||
elif (escape_route := self.transport.find_escape_route()) is not None:
|
||||
elif (escape_route := self.find_escape_route()) is not None:
|
||||
self.disband_at(escape_route)
|
||||
else:
|
||||
logging.info(
|
||||
@ -176,6 +178,9 @@ class TransferOrder:
|
||||
self.kill_all()
|
||||
return
|
||||
|
||||
if self.transport is None:
|
||||
return
|
||||
|
||||
self.position = self.next_stop
|
||||
self.transport = None
|
||||
|
||||
|
||||
@ -256,8 +256,8 @@ class _53T2(unittype.VehicleType):
|
||||
id = "AA20"
|
||||
name = "53T2"
|
||||
detection_range = 5000
|
||||
threat_range = 2000
|
||||
air_weapon_dist = 2000
|
||||
threat_range = 4000
|
||||
air_weapon_dist = 4000
|
||||
|
||||
|
||||
class TRM_2000_53T2(unittype.VehicleType):
|
||||
@ -278,6 +278,71 @@ class TRM_2000_PAMELA(unittype.VehicleType):
|
||||
eplrs = True
|
||||
|
||||
|
||||
class Leclerc_Serie_XXI_Desert(unittype.VehicleType):
|
||||
id = "Leclerc_XXI_Desert"
|
||||
name = "Leclerc Série XXI Désert"
|
||||
detection_range = 0
|
||||
threat_range = 4000
|
||||
air_weapon_dist = 4000
|
||||
|
||||
|
||||
class AMX_13_75mm(unittype.VehicleType):
|
||||
id = "AMX1375"
|
||||
name = "AMX-13 75mm"
|
||||
detection_range = 0
|
||||
threat_range = 3500
|
||||
air_weapon_dist = 3500
|
||||
|
||||
|
||||
class AMX_13_90mm(unittype.VehicleType):
|
||||
id = "AMX1390"
|
||||
name = "AMX-13 90mm"
|
||||
detection_range = 0
|
||||
threat_range = 3500
|
||||
air_weapon_dist = 3500
|
||||
|
||||
|
||||
class VBCI(unittype.VehicleType):
|
||||
id = "VBCI"
|
||||
name = "VBCI"
|
||||
detection_range = 0
|
||||
threat_range = 3500
|
||||
air_weapon_dist = 3500
|
||||
eplrs = True
|
||||
|
||||
|
||||
class Char_T_62(unittype.VehicleType):
|
||||
id = "T62"
|
||||
name = "Char T-62"
|
||||
detection_range = 0
|
||||
threat_range = 4000
|
||||
air_weapon_dist = 4000
|
||||
|
||||
|
||||
class Char_T_64BV(unittype.VehicleType):
|
||||
id = "T64BV"
|
||||
name = "Char T-64BV"
|
||||
detection_range = 0
|
||||
threat_range = 4000
|
||||
air_weapon_dist = 4000
|
||||
|
||||
|
||||
class Char_T_72A(unittype.VehicleType):
|
||||
id = "T72M"
|
||||
name = "Char T-72A"
|
||||
detection_range = 0
|
||||
threat_range = 4000
|
||||
air_weapon_dist = 4000
|
||||
|
||||
|
||||
class KORNET_ATGM(unittype.VehicleType):
|
||||
id = "KORNET"
|
||||
name = "KORNET ATGM"
|
||||
detection_range = 0
|
||||
threat_range = 0
|
||||
air_weapon_dist = 0
|
||||
|
||||
|
||||
## INFANTRY
|
||||
|
||||
|
||||
|
||||
@ -49,6 +49,13 @@ MODDED_VEHICLES = [
|
||||
frenchpack.DIM__TOYOTA_GREEN,
|
||||
frenchpack.DIM__TOYOTA_DESERT,
|
||||
frenchpack.DIM__KAMIKAZE,
|
||||
frenchpack.VBCI,
|
||||
frenchpack.AMX_13_75mm,
|
||||
frenchpack.AMX_13_90mm,
|
||||
frenchpack.Char_T_62,
|
||||
frenchpack.Char_T_64BV,
|
||||
frenchpack.Char_T_72A,
|
||||
frenchpack.KORNET_ATGM,
|
||||
highdigitsams.AAA_SON_9_Fire_Can,
|
||||
highdigitsams.AAA_100mm_KS_19,
|
||||
highdigitsams.SAM_SA_10B_S_300PS_54K6_CP,
|
||||
|
||||
@ -121,6 +121,7 @@ class QTopPanel(QFrame):
|
||||
self.passTurnButton.setText("Pass Turn")
|
||||
|
||||
if game and game.turn == 0:
|
||||
self.passTurnButton.setText("Begin Campaign")
|
||||
self.proceedButton.setEnabled(False)
|
||||
else:
|
||||
self.proceedButton.setEnabled(True)
|
||||
|
||||
@ -178,6 +178,7 @@ class ControlPointJs(QObject):
|
||||
|
||||
class GroundObjectJs(QObject):
|
||||
nameChanged = Signal()
|
||||
controlPointNameChanged = Signal()
|
||||
unitsChanged = Signal()
|
||||
blueChanged = Signal()
|
||||
positionChanged = Signal()
|
||||
@ -214,6 +215,10 @@ class GroundObjectJs(QObject):
|
||||
def name(self) -> str:
|
||||
return self.tgo.name
|
||||
|
||||
@Property(str, notify=controlPointNameChanged)
|
||||
def controlPointName(self) -> str:
|
||||
return self.tgo.control_point.name
|
||||
|
||||
@Property(str, notify=categoryChanged)
|
||||
def category(self) -> str:
|
||||
return self.tgo.category
|
||||
|
||||
@ -234,10 +234,14 @@ class QLiberationWindow(QMainWindow):
|
||||
wizard.accepted.connect(lambda: self.onGameGenerated(wizard.generatedGame))
|
||||
|
||||
def openFile(self):
|
||||
if self.game is not None and self.game.savepath:
|
||||
save_dir = self.game.savepath
|
||||
else:
|
||||
save_dir = str(persistency.save_dir())
|
||||
file = QFileDialog.getOpenFileName(
|
||||
self,
|
||||
"Select game file to open",
|
||||
dir=self.game.savepath if self.game else persistency._dcs_saved_game_folder,
|
||||
dir=save_dir,
|
||||
filter="*.liberation",
|
||||
)
|
||||
if file is not None and file[0] != "":
|
||||
@ -257,10 +261,14 @@ class QLiberationWindow(QMainWindow):
|
||||
self.saveGameAs()
|
||||
|
||||
def saveGameAs(self):
|
||||
if self.game is not None and self.game.savepath:
|
||||
save_dir = self.game.savepath
|
||||
else:
|
||||
save_dir = str(persistency.save_dir())
|
||||
file = QFileDialog.getSaveFileName(
|
||||
self,
|
||||
"Save As",
|
||||
dir=self.game.savepath if self.game else persistency._dcs_saved_game_folder,
|
||||
dir=save_dir,
|
||||
filter="*.liberation",
|
||||
)
|
||||
if file is not None:
|
||||
|
||||
@ -56,7 +56,9 @@ class QGroundObjectMenu(QDialog):
|
||||
self.buildings = buildings
|
||||
self.cp = cp
|
||||
self.game = game
|
||||
self.setWindowTitle("Location " + self.ground_object.obj_name)
|
||||
self.setWindowTitle(
|
||||
f"Location - {self.ground_object.obj_name} ({self.cp.name})"
|
||||
)
|
||||
self.setWindowIcon(EVENT_ICONS["capture"])
|
||||
self.intelBox = QGroupBox("Units :")
|
||||
self.buildingBox = QGroupBox("Buildings :")
|
||||
|
||||
@ -705,7 +705,10 @@ class QSettingsWindow(QDialog):
|
||||
|
||||
start_type_label = QLabel(
|
||||
"Default start type for AI aircraft<br /><strong>Warning: "
|
||||
"Any option other than Cold breaks OCA/Aircraft missions.</strong>"
|
||||
"Options other than Cold will significantly reduce the<br />"
|
||||
"number of targets available for OCA/Aircraft missions,<br />"
|
||||
"and OCA/Aircraft flights will not be included in<br />"
|
||||
"automatically planned OCA packages.</strong>"
|
||||
)
|
||||
start_type_label.setToolTip(START_TYPE_TOOLTIP)
|
||||
start_type = StartTypeComboBox(self.game.settings)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
"recommended_player_faction": "Turkey 2005",
|
||||
"recommended_enemy_faction": "Greece 2005",
|
||||
"description": "<p>This is based on the Turkish invasion of Cyprus, and the Greek defense of the island. You must make sure to keep your beachhead at all costs, otherwise reclaiming it will be tricky. It is recommended to reduce the per-turn income rate for both factions in this scenario due to the large oil depots both sides have - setting it to around 15-20% is probably reasonable.</p>",
|
||||
"version": "6.0",
|
||||
"version": "7.0",
|
||||
"miz": "Operation_Atilla.miz",
|
||||
"performance": 2
|
||||
}
|
||||
Binary file not shown.
@ -4,8 +4,8 @@
|
||||
"authors": "Malakhit",
|
||||
"recommended_player_faction": "Russia 2010",
|
||||
"recommended_enemy_faction": "Insurgents (Hard)",
|
||||
"description": "<p>This short campaign is loosely based on the 2015 Russian military intervention in Syria. It should be perfect for COIN operations, especially with the Hind.</p>",
|
||||
"version": "6.0",
|
||||
"description": "<p>This short campaign is loosely based on the 2015 Russian military intervention in Syria. It should be perfect for COIN operations, especially with the Hind. Not designed for campaign inversion.</p>",
|
||||
"version": "7.0",
|
||||
"miz": "Russian_Intervention_2015.miz",
|
||||
"performance": 1
|
||||
}
|
||||
@ -7,5 +7,5 @@
|
||||
"description": "<p>In this scenario, you start in Israel in an high intensity conflict with Syria, backed by a Russian Expeditiary Force. Your goal is to take the heavily fortified city of Damascus, as fast as you can. The longer you wait, the more resources the enemy can pump into the defense of the city or even might try to take chunks of Israel. ATTENTION: CAMPAIGN INVERTING IS NOT YET IMPLEMENTED!!! Feedback: @Headiii in the DCSLiberation Discord</p>",
|
||||
"miz": "humble_helper.miz",
|
||||
"performance": 1,
|
||||
"version": "6.0"
|
||||
"version": "7.0"
|
||||
}
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "Syria - Inherent Resolve",
|
||||
"theater": "Syria",
|
||||
"authors": "Khopa",
|
||||
"recommended_player_faction": "USA 2005",
|
||||
"recommended_enemy_faction": "Insurgents (Hard)",
|
||||
"description": "<p>In this scenario, you start from Jordan, and have to fight your way through eastern Syria.</p>",
|
||||
"version": "6.1",
|
||||
"miz": "inherent_resolve.miz",
|
||||
"performance": 2
|
||||
}
|
||||
Binary file not shown.
@ -2,7 +2,7 @@
|
||||
"country": "France",
|
||||
"name": "France 1985",
|
||||
"authors": "Colonel Panic",
|
||||
"description": "<p>1980s French equipment using FrenchPack.</p>",
|
||||
"description": "<p>France 1985. Frenchpack 4.6+ mod is recommended to enable most of the ground units of this faction available.</p>",
|
||||
"locales": [
|
||||
"fr_FR"
|
||||
],
|
||||
@ -32,6 +32,9 @@
|
||||
"VAB Mephisto",
|
||||
"VAB T20/13",
|
||||
"VBL .50",
|
||||
"VBL AANF1",
|
||||
"AMX-13 75mm",
|
||||
"AMX-13 90mm",
|
||||
"VBL AANF1"
|
||||
],
|
||||
"artillery_units": [
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"country": "France",
|
||||
"name": "France 1995",
|
||||
"authors": "Khopa",
|
||||
"description": "<p>France in the late 90s before Rafale introduction. A Mirage-2000 centric faction choice.</p>",
|
||||
"description": "<p>France in the late 90s before Rafale introduction. A Mirage-2000 centric faction choice. Frenchpack 4.6+ mod is recommended to enable most of the ground units of this faction available.</p>",
|
||||
"locales": [
|
||||
"fr_FR"
|
||||
],
|
||||
@ -22,12 +22,19 @@
|
||||
"KC-135 Stratotanker"
|
||||
],
|
||||
"frontline_units": [
|
||||
"Cobra",
|
||||
"LAV-25",
|
||||
"AMX-10 RCR",
|
||||
"AMX-13 90mm",
|
||||
"AMX.30B2",
|
||||
"Leclerc S\u00e9ries 2",
|
||||
"Leclerc_XXI",
|
||||
"Pamela",
|
||||
"Panhard",
|
||||
"Roland 2 (Marder Chassis)",
|
||||
"TPz Fuchs",
|
||||
"VAB Mephisto"
|
||||
"VAB .50",
|
||||
"VAB Mephisto",
|
||||
"VAB T20/13",
|
||||
"VBL .50",
|
||||
"VBL AANF1"
|
||||
],
|
||||
"artillery_units": [
|
||||
"M109A6 Paladin",
|
||||
@ -71,4 +78,4 @@
|
||||
],
|
||||
"has_jtac": true,
|
||||
"jtac_unit": "MQ-9 Reaper"
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"country": "France",
|
||||
"name": "France 2005",
|
||||
"authors": "HerrTom",
|
||||
"description": "<p>French equipment using the Frenchpack, but without the Rafale mod.</p>",
|
||||
"description": "<p>France 2005. Frenchpack 4.6+ mod is recommended to enable most of the ground units of this faction available.</p>",
|
||||
"locales": [
|
||||
"fr_FR"
|
||||
],
|
||||
@ -23,7 +23,7 @@
|
||||
"KC-135 Stratotanker"
|
||||
],
|
||||
"frontline_units": [
|
||||
"AMX.30B2",
|
||||
"AMX-10RCR SEPAR",
|
||||
"Leclerc S\u00e9ries 2",
|
||||
"Leclerc_XXI",
|
||||
"Pamela",
|
||||
@ -33,7 +33,8 @@
|
||||
"VAB Mephisto",
|
||||
"VAB T20/13",
|
||||
"VBL .50",
|
||||
"VBL AANF1"
|
||||
"VBL AANF1",
|
||||
"VBCI"
|
||||
],
|
||||
"artillery_units": [
|
||||
"M109A6 Paladin",
|
||||
|
||||
@ -570,7 +570,7 @@ class TheaterGroundObject {
|
||||
}
|
||||
|
||||
L.marker(this.tgo.position, { icon: this.icon() })
|
||||
.bindTooltip(`${this.tgo.name}<br />${this.tgo.units.join("<br />")}`)
|
||||
.bindTooltip(`${this.tgo.name} (${this.tgo.controlPointName})<br />${this.tgo.units.join("<br />")}`)
|
||||
.on("click", () => this.tgo.showInfoDialog())
|
||||
.on("contextmenu", () => this.tgo.showPackageDialog())
|
||||
.addTo(this.layer());
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
class: SHORADS
|
||||
price: 4
|
||||
variants:
|
||||
53T2: null
|
||||
|
||||
9
resources/units/ground_units/AMX1375.yaml
Normal file
9
resources/units/ground_units/AMX1375.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
class: Tank
|
||||
description: "The AMX-13 is a French light tank produced from 1952 to 1987. It served with the French Army, as the Char 13t-75 Modèle 51, and was exported to more than 26 other nations. Named after its initial weight of 13 tonnes, and featuring a tough and reliable chassis,[1] it was fitted with an oscillating turret built by GIAT Industries (now Nexter) with revolver type magazines, which were also used on the Austrian SK-105 Kürassier.[1] Including prototypes and export versions, there are over a hundred variants including self-propelled guns, anti-aircraft systems, APCs, and ATGM versions. This specific version isan early one fitted with a 75mm gun."
|
||||
introduced: 1952
|
||||
manufacturer: Atelier de Construction d'Issy-les-Moulineaux
|
||||
origin: France
|
||||
price: 10
|
||||
role: Light Tank
|
||||
variants:
|
||||
AMX-13 75mm: {}
|
||||
9
resources/units/ground_units/AMX1390.yaml
Normal file
9
resources/units/ground_units/AMX1390.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
class: Tank
|
||||
description: "The AMX-13 is a French light tank produced from 1952 to 1987. It served with the French Army, as the Char 13t-75 Modèle 51, and was exported to more than 26 other nations. Named after its initial weight of 13 tonnes, and featuring a tough and reliable chassis,[1] it was fitted with an oscillating turret built by GIAT Industries (now Nexter) with revolver type magazines, which were also used on the Austrian SK-105 Kürassier.[1] Including prototypes and export versions, there are over a hundred variants including self-propelled guns, anti-aircraft systems, APCs, and ATGM versions. This specific version is a late one fitted with a 90mm gun."
|
||||
introduced: 1966
|
||||
manufacturer: Atelier de Construction d'Issy-les-Moulineaux
|
||||
origin: France
|
||||
price: 12
|
||||
role: Light Tank
|
||||
variants:
|
||||
AMX-13 90mm: {}
|
||||
@ -1,3 +1,4 @@
|
||||
class: SHORADS
|
||||
price: 8
|
||||
variants:
|
||||
TRM-2000 53T2: null
|
||||
TRM-2000 53T2: {}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
class: ATGM
|
||||
description: WIP - Mistral Missile on a Truck.
|
||||
class: SHORADS
|
||||
description: Mistral Missile on a Truck.
|
||||
introduced: 1993
|
||||
manufacturer: GIAT Industries
|
||||
origin: France
|
||||
|
||||
@ -7,4 +7,4 @@ origin: France
|
||||
price: 8
|
||||
role: ATGM Vehicle
|
||||
variants:
|
||||
VAB Mephisto: {}
|
||||
VAB Mephisto Frenchpack: {}
|
||||
|
||||
9
resources/units/ground_units/VBCI.yaml
Normal file
9
resources/units/ground_units/VBCI.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
class: IFV
|
||||
description: "The Véhicule Blindé de Combat d'Infanterie (VBCI : Armoured vehicle for infantry combat) is a French Infantry fighting vehicle designed to replace the AMX-10P."
|
||||
introduced: 2005
|
||||
manufacturer: Nexter Systems
|
||||
origin: France
|
||||
price: 14
|
||||
role: Infantry Fighting Vehicle
|
||||
variants:
|
||||
VBCI: {}
|
||||
@ -1,3 +1,9 @@
|
||||
price: 4
|
||||
class: Recon
|
||||
description: The Panhard Véhicule Blindé Léger ("Light armoured vehicle"), also known by its acronym Panhard VBL or simply VBL, is a French wheeled 4x4 all-terrain vehicle built by Panhard. The vehicle is offered in various configurations, and was designed to combine the agility of the Peugeot P4 liaison vehicle with adequate protection against small arms fire, artillery fragments, mines and NBC weapons. Produced between 1985 and 2010, the vehicle has been used by the French Army and other European, African and Central American armies in various conflicts since the 1980s. This variant is equiped with .50 cal gun.
|
||||
introduced: 1985
|
||||
manufacturer: Panhard
|
||||
origin: France
|
||||
price: 2
|
||||
role: Recon Vehicle
|
||||
variants:
|
||||
VBL .50: null
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
class: Recon
|
||||
description: The Panhard Véhicule Blindé Léger ("Light armoured vehicle"), also known by its acronym Panhard VBL or simply VBL, is a French wheeled 4x4 all-terrain vehicle built by Panhard. The vehicle is offered in various configurations, and was designed to combine the agility of the Peugeot P4 liaison vehicle with adequate protection against small arms fire, artillery fragments, mines and NBC weapons. Produced between 1985 and 2010, the vehicle has been used by the French Army and other European, African and Central American armies in various conflicts since the 1980s. This variant is equiped with the AN/F1 machine gun.
|
||||
introduced: 1985
|
||||
manufacturer: Panhard
|
||||
origin: France
|
||||
price: 2
|
||||
role: Recon Vehicle
|
||||
variants:
|
||||
VBL AANF1: null
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user