Merge branch 'master' into develop

# Conflicts:
#	changelog.md
#	game/db.py
#	game/game.py
#	game/income.py
#	game/theater/theatergroundobject.py
#	game/version.py
#	qt_ui/windows/finances/QFinancesMenu.py
This commit is contained in:
Khopa 2021-01-05 19:50:29 +01:00
commit cf583bcd55
79 changed files with 133 additions and 134 deletions

View File

@ -37,15 +37,28 @@ Saves from 2.3 are not compatible with 2.4.
* **[Campaigns]** Reworked Golan Heights campaign on Syria, (Added FOB and preset locations for SAMS) * **[Campaigns]** Reworked Golan Heights campaign on Syria, (Added FOB and preset locations for SAMS)
* **[Campaigns]** Added a lite version of the Golan Heights campaign * **[Campaigns]** Added a lite version of the Golan Heights campaign
* **[Campaigns]** Reworked Syrian Civil War campaign (Added FOB and preset locations for SAMS) * **[Campaigns]** Reworked Syrian Civil War campaign (Added FOB and preset locations for SAMS)
* **[Campaigns]** Reworked Emirates campaign
* **[Campaigns]** AA units added to frontlines and updated all factions to include some frontline AA units.
* **[Mission Generator]** Infantry will only be generated for APC and IFV groups
* **[Mission Generator]** Infantry squads size is not randomized anymore
* **[Mission Generator]** Infantry squads can have a mortar.
* **[Mission Generator]** SCUD missiles sites will now fire on enemy controls points in range when possible
* **[Factions]** Updated Nato Desert Storm to include F-14A * **[Factions]** Updated Nato Desert Storm to include F-14A
* **[Factions]** Updated Iraq 1991 factions to include Zsu-57 and Mig-29A * **[Factions]** Updated Iraq 1991 factions to include Zsu-57 and Mig-29A
* **[Factions]** Germany 1944, added Stug III and Stug IV
* **[Factions]** Added factions Insurgents (Hard) with better and more weapons
* **[Plugins]** [The EWRS plugin](https://github.com/Bob7heBuilder/EWRS) is now included. * **[Plugins]** [The EWRS plugin](https://github.com/Bob7heBuilder/EWRS) is now included.
* **[UI]** Added enemy intelligence summary and details window. * **[UI]** Added enemy intelligence summary and details window.
## Fixes: ## Fixes:
* **[Factions]** AI would never buy artillery units for the frontline - fixed * **[Factions]** AI would never buy artillery units for the frontline - fixed
* **[Factions]** Removed the F-111 unit from the NATO desert storm faction. (Recruiting it would cause crashes in DCS, since it is not a valid unit) * **[Factions]** Removed the F-111 unit from the NATO desert storm faction. (Recruiting it would cause crashes in DCS, since it is not a valid unit)
* **[Campaign]** Automatic redeployment of ground units would sometimes fail - fixed
* **[Mission Generator]** Artillery groups would retreat in the wrong direction - fixed
* **[Units]** Fixed SPG_Stryker_M1128_MGS not being in db * **[Units]** Fixed SPG_Stryker_M1128_MGS not being in db
* **[UI]** Fixed and added many missing ground units icons
* **[UI]** Ship groups could be replaced by SAM sites in the UI, which would lead to broken mission being generated - fixed
* **[New Game Wizard]** Removed the "mid game" campaign generator option which is currently broken
* **[Mission Generator]** Empty navy groups will no longer be generated * **[Mission Generator]** Empty navy groups will no longer be generated
* **[Mission Generator]** Fixed BAI, SEAD, and DEAD flights ocassionally being assigned the wrong targets. * **[Mission Generator]** Fixed BAI, SEAD, and DEAD flights ocassionally being assigned the wrong targets.
* **[Flight Planner]** Fixed not being able to plan packages against opfor carriers * **[Flight Planner]** Fixed not being able to plan packages against opfor carriers

View File

@ -415,6 +415,7 @@ PRICES = {
Artillery.MLRS_BM_21_Grad: 15, Artillery.MLRS_BM_21_Grad: 15,
Artillery.MLRS_9K57_Uragan_BM_27: 50, Artillery.MLRS_9K57_Uragan_BM_27: 50,
Artillery.MLRS_9A52_Smerch: 40, Artillery.MLRS_9A52_Smerch: 40,
Artillery._2B11_mortar: 4,
Artillery.SpGH_Dana: 26, Artillery.SpGH_Dana: 26,
Unarmed.Transport_UAZ_469: 3, Unarmed.Transport_UAZ_469: 3,
@ -444,6 +445,7 @@ PRICES = {
Armor.LAC_M8_Greyhound: 8, Armor.LAC_M8_Greyhound: 8,
Armor.TD_M10_GMC: 14, Armor.TD_M10_GMC: 14,
Armor.StuG_III_Ausf__G: 12, Armor.StuG_III_Ausf__G: 12,
Armor.StuG_IV: 14,
Artillery.M12_GMC: 10, Artillery.M12_GMC: 10,
Artillery.Sturmpanzer_IV_Brummbär: 10, Artillery.Sturmpanzer_IV_Brummbär: 10,
Armor.Daimler_Armoured_Car: 8, Armor.Daimler_Armoured_Car: 8,
@ -835,6 +837,7 @@ UNIT_BY_TASK = {
Armor.TD_M10_GMC, Armor.TD_M10_GMC,
Armor.TD_M10_GMC, Armor.TD_M10_GMC,
Armor.StuG_III_Ausf__G, Armor.StuG_III_Ausf__G,
Armor.StuG_IV,
Artillery.M12_GMC, Artillery.M12_GMC,
Artillery.Sturmpanzer_IV_Brummbär, Artillery.Sturmpanzer_IV_Brummbär,
Armor.Daimler_Armoured_Car, Armor.Daimler_Armoured_Car,
@ -870,6 +873,13 @@ UNIT_BY_TASK = {
AirDefence.SAM_Avenger_M1097, AirDefence.SAM_Avenger_M1097,
AirDefence.SAM_Roland_ADS, AirDefence.SAM_Roland_ADS,
AirDefence.HQ_7_Self_Propelled_LN, AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_8_8cm_Flak_18,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_Bofors_40mm,
AirDefence.AAA_M1_37mm,
AirDefence.AA_gun_QF_3_7,
frenchpack.DIM__TOYOTA_BLUE, frenchpack.DIM__TOYOTA_BLUE,
frenchpack.DIM__TOYOTA_DESERT, frenchpack.DIM__TOYOTA_DESERT,
@ -1277,6 +1287,7 @@ INFANTRY: List[VehicleType] = [
Infantry.Soldier_RPG, Infantry.Soldier_RPG,
Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4, Infantry.Infantry_M4,
Infantry.Soldier_M249, Infantry.Soldier_M249,
Artillery._2B11_mortar,
Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK, Infantry.Soldier_AK,
Infantry.Paratrooper_RPG_16, Infantry.Paratrooper_RPG_16,
Infantry.Georgian_soldier_with_M4, Infantry.Georgian_soldier_with_M4, Infantry.Georgian_soldier_with_M4, Infantry.Georgian_soldier_with_M4, Infantry.Georgian_soldier_with_M4, Infantry.Georgian_soldier_with_M4,

View File

@ -114,11 +114,11 @@ class Base:
self.armor = {k: v for k, v in self.armor.items() if k in applicable_units} self.armor = {k: v for k, v in self.armor.items() if k in applicable_units}
def commision_units(self, units: typing.Dict[typing.Any, int]): def commision_units(self, units: typing.Dict[typing.Any, int]):
for value in units.values():
assert value > 0
assert value == math.floor(value)
for unit_type, unit_count in units.items(): for unit_type, unit_count in units.items():
if unit_count <= 0:
continue
for_task = db.unit_task(unit_type) for_task = db.unit_task(unit_type)
target_dict = None target_dict = None

View File

@ -50,6 +50,8 @@ FIGHT_DISTANCE = 3500
RANDOM_OFFSET_ATTACK = 250 RANDOM_OFFSET_ATTACK = 250
INFANTRY_GROUP_SIZE = 5
@dataclass(frozen=True) @dataclass(frozen=True)
class JtacInfo: class JtacInfo:
@ -226,7 +228,7 @@ class GroundConflictGenerator:
heading=forward_heading, heading=forward_heading,
move_formation=PointAction.OffRoad) move_formation=PointAction.OffRoad)
for i in range(random.randint(3, 10)): for i in range(INFANTRY_GROUP_SIZE):
u = random.choice(possible_infantry_units) u = random.choice(possible_infantry_units)
position = infantry_position.random_point_within(55, 5) position = infantry_position.random_point_within(55, 5)
self.mission.vehicle_group( self.mission.vehicle_group(
@ -281,7 +283,7 @@ class GroundConflictGenerator:
# Hold position # Hold position
dcs_group.points[1].tasks.append(Hold()) dcs_group.points[1].tasks.append(Hold())
retreat = self.find_retreat_point(dcs_group, heading_sum(forward_heading, 180), (int)(RETREAT_DISTANCE/3)) retreat = self.find_retreat_point(dcs_group, forward_heading, (int)(RETREAT_DISTANCE/3))
dcs_group.add_waypoint(dcs_group.position.point_from_heading(forward_heading, 1), PointAction.OffRoad) dcs_group.add_waypoint(dcs_group.position.point_from_heading(forward_heading, 1), PointAction.OffRoad)
dcs_group.points[2].tasks.append(Hold()) dcs_group.points[2].tasks.append(Hold())
dcs_group.add_waypoint(retreat, PointAction.OffRoad) dcs_group.add_waypoint(retreat, PointAction.OffRoad)

View File

@ -189,6 +189,8 @@ TYPE_SHORAD = [
AirDefence.HQ_7_Self_Propelled_LN, AirDefence.HQ_7_Self_Propelled_LN,
AirDefence.AAA_8_8cm_Flak_18, AirDefence.AAA_8_8cm_Flak_18,
AirDefence.AAA_8_8cm_Flak_36,
AirDefence.AAA_8_8cm_Flak_37,
AirDefence.AAA_8_8cm_Flak_41, AirDefence.AAA_8_8cm_Flak_41,
AirDefence.AAA_Bofors_40mm, AirDefence.AAA_Bofors_40mm,
AirDefence.AAA_M1_37mm, AirDefence.AAA_M1_37mm,

View File

@ -9,20 +9,21 @@ from __future__ import annotations
import logging import logging
import random import random
from typing import Dict, Iterator, Optional, TYPE_CHECKING, Type from typing import Dict, Iterator, Optional, TYPE_CHECKING, Type, List
from dcs import Mission from dcs import Mission, Point
from dcs.country import Country from dcs.country import Country
from dcs.statics import fortification_map, warehouse_map from dcs.statics import fortification_map, warehouse_map
from dcs.task import ( from dcs.task import (
ActivateBeaconCommand, ActivateBeaconCommand,
ActivateICLSCommand, ActivateICLSCommand,
EPLRS, EPLRS,
OptAlarmState, OptAlarmState, FireAtPoint,
) )
from dcs.unit import Ship, Unit, Vehicle from dcs.unit import Ship, Unit, Vehicle
from dcs.unitgroup import Group, ShipGroup, StaticGroup, VehicleGroup from dcs.unitgroup import Group, ShipGroup, StaticGroup, VehicleGroup
from dcs.unittype import StaticType, UnitType from dcs.unittype import StaticType, UnitType
from dcs.vehicles import vehicle_map
from game import db from game import db
from game.data.building_data import FORTIFICATION_UNITS, FORTIFICATION_UNITS_ID from game.data.building_data import FORTIFICATION_UNITS, FORTIFICATION_UNITS_ID
@ -31,7 +32,7 @@ from game.theater import ControlPoint, TheaterGroundObject
from game.theater.theatergroundobject import ( from game.theater.theatergroundobject import (
BuildingGroundObject, CarrierGroundObject, BuildingGroundObject, CarrierGroundObject,
GenericCarrierGroundObject, GenericCarrierGroundObject,
LhaGroundObject, ShipGroundObject, LhaGroundObject, ShipGroundObject, MissileSiteGroundObject,
) )
from game.unitmap import UnitMap from game.unitmap import UnitMap
from game.utils import knots, mps from game.utils import knots, mps
@ -50,7 +51,7 @@ AA_CP_MIN_DISTANCE = 40000
class GenericGroundObjectGenerator: class GenericGroundObjectGenerator:
"""An unspecialized ground object generator. """An unspecialized ground object generator.
Currently used only for SAM and missile (V1/V2) sites. Currently used only for SAM
""" """
def __init__(self, ground_object: TheaterGroundObject, country: Country, def __init__(self, ground_object: TheaterGroundObject, country: Country,
game: Game, mission: Mission, unit_map: UnitMap) -> None: game: Game, mission: Mission, unit_map: UnitMap) -> None:
@ -111,6 +112,58 @@ class GenericGroundObjectGenerator:
persistence_group, miz_group) persistence_group, miz_group)
class MissileSiteGenerator(GenericGroundObjectGenerator):
def generate(self) -> None:
super(MissileSiteGenerator, self).generate()
# Note : Only the SCUD missiles group can fire (V1 site cannot fire in game right now)
# TODO : Should be pre-planned ?
# TODO : Add delay to task to spread fire task over mission duration ?
for group in self.ground_object.groups:
vg = self.m.find_group(group.name)
if vg is not None:
targets = self.possible_missile_targets(vg)
if targets:
target = random.choice(targets)
real_target = target.point_from_heading(random.randint(0, 360), random.randint(0, 2500))
vg.points[0].add_task(FireAtPoint(real_target))
logging.info("Set up fire task for missile group.")
else:
logging.info("Couldn't setup missile site to fire, no valid target in range.")
else:
logging.info("Couldn't setup missile site to fire, group was not generated.")
def possible_missile_targets(self, vg: Group) -> List[Point]:
"""
Find enemy control points in range
:param vg: Vehicle group we are searching a target for (There is always only oe group right now)
:return: List of possible missile targets
"""
targets: List[Point] = []
for cp in self.game.theater.controlpoints:
if cp.captured != self.ground_object.control_point.captured:
distance = cp.position.distance_to_point(vg.position)
if distance < self.missile_site_range:
targets.append(cp.position)
return targets
@property
def missile_site_range(self) -> int:
"""
Get the missile site range
:return: Missile site range
"""
site_range = 0
for group in self.ground_object.groups:
vg = self.m.find_group(group.name)
if vg is not None:
for u in vg.units:
if u.type in vehicle_map:
if vehicle_map[u.type].threat_range > site_range:
site_range = vehicle_map[u.type].threat_range
return site_range
class BuildingSiteGenerator(GenericGroundObjectGenerator): class BuildingSiteGenerator(GenericGroundObjectGenerator):
"""Generator for building sites. """Generator for building sites.
@ -421,8 +474,11 @@ class GroundObjectsGenerator:
generator = ShipObjectGenerator( generator = ShipObjectGenerator(
ground_object, country, self.game, self.m, ground_object, country, self.game, self.m,
self.unit_map) self.unit_map)
elif isinstance(ground_object, MissileSiteGroundObject):
generator = MissileSiteGenerator(
ground_object, country, self.game, self.m,
self.unit_map)
else: else:
generator = GenericGroundObjectGenerator( generator = GenericGroundObjectGenerator(
ground_object, country, self.game, self.m, ground_object, country, self.game, self.m,
self.unit_map) self.unit_map)

View File

@ -21,6 +21,7 @@ from game import Game, db
from game.data.building_data import FORTIFICATION_BUILDINGS from game.data.building_data import FORTIFICATION_BUILDINGS
from game.db import PRICES, PinpointStrike, REWARDS, unit_type_of from game.db import PRICES, PinpointStrike, REWARDS, unit_type_of
from game.theater import ControlPoint, TheaterGroundObject from game.theater import ControlPoint, TheaterGroundObject
from game.theater.theatergroundobject import NavalGroundObject
from gen.defenses.armor_group_generator import \ from gen.defenses.armor_group_generator import \
generate_armor_group_of_type_and_size generate_armor_group_of_type_and_size
from gen.sam.sam_group_generator import get_faction_possible_sams_generator from gen.sam.sam_group_generator import get_faction_possible_sams_generator
@ -81,9 +82,10 @@ class QGroundObjectMenu(QDialog):
self.buy_replace.clicked.connect(self.buy_group) self.buy_replace.clicked.connect(self.buy_group)
self.buy_replace.setProperty("style", "btn-success") self.buy_replace.setProperty("style", "btn-success")
if self.total_value > 0: if not isinstance(self.ground_object, NavalGroundObject):
self.actionLayout.addWidget(self.sell_all_button) if self.total_value > 0:
self.actionLayout.addWidget(self.buy_replace) self.actionLayout.addWidget(self.sell_all_button)
self.actionLayout.addWidget(self.buy_replace)
if self.cp.captured and self.ground_object.dcs_identifier == "AA": if self.cp.captured and self.ground_object.dcs_identifier == "AA":
self.mainLayout.addLayout(self.actionLayout) self.mainLayout.addLayout(self.actionLayout)

View File

@ -81,7 +81,7 @@ class NewGameWizard(QtWidgets.QWizard):
enemy_budget=int(self.field("enemy_starting_money")), enemy_budget=int(self.field("enemy_starting_money")),
# QSlider forces integers, so we use 1 to 50 and divide by 10 to # QSlider forces integers, so we use 1 to 50 and divide by 10 to
# give 0.1 to 5.0. # give 0.1 to 5.0.
midgame=self.field("midGame"), midgame=False,
inverted=self.field("invertMap"), inverted=self.field("invertMap"),
no_carrier=self.field("no_carrier"), no_carrier=self.field("no_carrier"),
no_lha=self.field("no_lha"), no_lha=self.field("no_lha"),
@ -271,10 +271,10 @@ class TheaterConfiguration(QtWidgets.QWizardPage):
mapSettingsLayout.addWidget(QtWidgets.QLabel("Invert Map"), 0, 0) mapSettingsLayout.addWidget(QtWidgets.QLabel("Invert Map"), 0, 0)
mapSettingsLayout.addWidget(invertMap, 0, 1) mapSettingsLayout.addWidget(invertMap, 0, 1)
mapSettingsLayout.addWidget(QtWidgets.QLabel("Start at mid game"), 1, 0) #mapSettingsLayout.addWidget(QtWidgets.QLabel("Start at mid game"), 1, 0)
midgame = QtWidgets.QCheckBox() #midgame = QtWidgets.QCheckBox()
self.registerField('midGame', midgame) #self.registerField('midGame', midgame)
mapSettingsLayout.addWidget(midgame, 1, 1) #mapSettingsLayout.addWidget(midgame, 1, 1)
mapSettingsGroup.setLayout(mapSettingsLayout) mapSettingsGroup.setLayout(mapSettingsLayout)
# Time Period # Time Period

View File

@ -3,106 +3,5 @@
"theater": "Persian Gulf", "theater": "Persian Gulf",
"authors": "Khopa", "authors": "Khopa",
"description": "<p>In this scenario, you can play an invasion of the Emirates and Oman, where your forces starts in Fujairah.</p><p><strong>Note:</strong> Fujairah airfield has very few slots for aircrafts, so it recommended to operate from carriers at the start of the campaign. Thus, a carrier-capable faction is recommended.</p>", "description": "<p>In this scenario, you can play an invasion of the Emirates and Oman, where your forces starts in Fujairah.</p><p><strong>Note:</strong> Fujairah airfield has very few slots for aircrafts, so it recommended to operate from carriers at the start of the campaign. Thus, a carrier-capable faction is recommended.</p>",
"player_points": [ "miz": "emirates.miz"
{
"type": "airbase",
"id": "Fujairah Intl",
"radials": [
180,
225,
270,
315,
0
],
"size": 1000,
"importance": 1,
"captured_invert": true
},
{
"type": "lha",
"id": 1002,
"x": -79770,
"y": 49430,
"captured_invert": true
},
{
"type": "carrier",
"id": 1001,
"x": -61770,
"y": 69039,
"captured_invert": true
}
],
"enemy_points": [
{
"type": "airbase",
"id": "Al Dhafra AB",
"size": 2000,
"importance": 1.2
},
{
"type": "airbase",
"id": "Al Ain International Airport",
"size": 2000,
"importance": 1
},
{
"type": "airbase",
"id": "Al Maktoum Intl",
"size": 2000,
"importance": 1
},
{
"type": "airbase",
"id": "Al Minhad AB",
"size": 1000,
"importance": 1
},
{
"type": "airbase",
"id": "Sharjah Intl",
"size": 2000,
"importance": 1
},
{
"type": "airbase",
"id": "Ras Al Khaimah",
"size": 1000,
"importance": 1
}
],
"links": [
[
"Al Ain International Airport",
"Al Dhafra AB"
],
[
"Al Dhafra AB",
"Al Maktoum Intl"
],
[
"Al Ain International Airport",
"Fujairah Intl"
],
[
"Al Ain International Airport",
"Al Maktoum Intl"
],
[
"Al Maktoum Intl",
"Al Minhad AB"
],
[
"Al Minhad AB",
"Sharjah Intl"
],
[
"Ras Al Khaimah",
"Sharjah Intl"
],
[
"Fujairah Intl",
"Sharjah Intl"
]
]
} }

Binary file not shown.

View File

@ -37,7 +37,8 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"Stinger_MANPADS" "Stinger_MANPADS",
"_2B11_mortar"
], ],
"air_defenses": [ "air_defenses": [
"RolandGenerator", "RolandGenerator",

View File

@ -19,6 +19,8 @@
"Sd_Kfz_184_Elefant", "Sd_Kfz_184_Elefant",
"TD_Jagdpanther_G1", "TD_Jagdpanther_G1",
"TD_Jagdpanzer_IV", "TD_Jagdpanzer_IV",
"StuG_III_Ausf__G",
"StuG_IV",
"AAA_8_8cm_Flak_18", "AAA_8_8cm_Flak_18",
"AAA_8_8cm_Flak_41" "AAA_8_8cm_Flak_41"
], ],

View File

@ -33,6 +33,7 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"_2B11_mortar",
"Stinger_MANPADS" "Stinger_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

View File

@ -22,6 +22,7 @@
"infantry_units": [ "infantry_units": [
"Infantry_Soldier_Insurgents", "Infantry_Soldier_Insurgents",
"Soldier_RPG", "Soldier_RPG",
"_2B11_mortar",
"SAM_SA_18_Igla_MANPADS" "SAM_SA_18_Igla_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

View File

@ -1,6 +1,6 @@
{ {
"country": "Insurgents", "country": "Insurgents",
"name": "Insurgents", "name": "Insurgents (Hard)",
"authors": "Khopa", "authors": "Khopa",
"description": "<p>Insurgents faction.</p>", "description": "<p>Insurgents faction.</p>",
"aircrafts": [ "aircrafts": [
@ -14,7 +14,6 @@
"IFV_BMP_1", "IFV_BMP_1",
"MBT_T_55", "MBT_T_55",
"AAA_ZU_23_Insurgent_on_Ural_375", "AAA_ZU_23_Insurgent_on_Ural_375",
"AAA_ZSU_57_2",
"AAA_ZSU_57_2" "AAA_ZSU_57_2"
], ],
"artillery_units": [ "artillery_units": [
@ -28,6 +27,7 @@
"infantry_units": [ "infantry_units": [
"Infantry_Soldier_Insurgents", "Infantry_Soldier_Insurgents",
"Soldier_RPG", "Soldier_RPG",
"_2B11_mortar",
"SAM_SA_18_Igla_MANPADS" "SAM_SA_18_Igla_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

View File

@ -39,7 +39,8 @@
], ],
"infantry_units": [ "infantry_units": [
"Infantry_Soldier_Rus", "Infantry_Soldier_Rus",
"Soldier_RPG" "Soldier_RPG",
"_2B11_mortar"
], ],
"air_defenses": [ "air_defenses": [
"ColdWarFlakGenerator", "ColdWarFlakGenerator",

View File

@ -44,6 +44,7 @@
"Paratrooper_AKS", "Paratrooper_AKS",
"Infantry_Soldier_Rus", "Infantry_Soldier_Rus",
"Paratrooper_RPG_16", "Paratrooper_RPG_16",
"_2B11_mortar",
"SAM_SA_18_Igla_S_MANPADS" "SAM_SA_18_Igla_S_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

View File

@ -49,6 +49,7 @@
"Paratrooper_AKS", "Paratrooper_AKS",
"Infantry_Soldier_Rus", "Infantry_Soldier_Rus",
"Paratrooper_RPG_16", "Paratrooper_RPG_16",
"_2B11_mortar",
"SAM_SA_18_Igla_MANPADS" "SAM_SA_18_Igla_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

View File

@ -34,6 +34,7 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"_2B11_mortar",
"Stinger_MANPADS" "Stinger_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

View File

@ -45,7 +45,8 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"Stinger_MANPADS" "Stinger_MANPADS",
"_2B11_mortar"
], ],
"air_defenses": [ "air_defenses": [
"AvengerGenerator", "AvengerGenerator",

View File

@ -46,7 +46,8 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"Stinger_MANPADS" "Stinger_MANPADS",
"_2B11_mortar"
], ],
"air_defenses": [ "air_defenses": [
"AvengerGenerator", "AvengerGenerator",

View File

@ -47,7 +47,8 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"Stinger_MANPADS" "Stinger_MANPADS",
"_2B11_mortar"
], ],
"air_defenses": [ "air_defenses": [
"AvengerGenerator", "AvengerGenerator",

View File

@ -47,7 +47,8 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"Stinger_MANPADS" "Stinger_MANPADS",
"_2B11_mortar"
], ],
"air_defenses": [ "air_defenses": [
"AvengerGenerator", "AvengerGenerator",

View File

@ -33,6 +33,7 @@
"infantry_units": [ "infantry_units": [
"Infantry_M4", "Infantry_M4",
"Soldier_M249", "Soldier_M249",
"_2B11_mortar",
"Stinger_MANPADS" "Stinger_MANPADS"
], ],
"air_defenses": [ "air_defenses": [

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1012 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1001 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1023 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 B