Ground objects are always generated and destroyable, even when it's not the current mission objective.

Fix : SAM site destruction status is saved correctly.
Added most SAM site to generator.
This commit is contained in:
Khopa 2019-10-06 16:14:13 +02:00
parent 17352bfcf7
commit 2167953b87
40 changed files with 808 additions and 68 deletions

View File

@ -1018,8 +1018,7 @@ def unit_task(unit: UnitType) -> Task:
return unit_task(SAM_CONVERT[unit]) return unit_task(SAM_CONVERT[unit])
print(unit.name + " cause issue") print(unit.name + " cause issue")
assert False return None
def find_unittype(for_task: Task, country_name: str) -> typing.List[UnitType]: def find_unittype(for_task: Task, country_name: str) -> typing.List[UnitType]:
return [x for x in UNIT_BY_TASK[for_task] if x in FACTIONS[country_name]["units"]] return [x for x in UNIT_BY_TASK[for_task] if x in FACTIONS[country_name]["units"]]

View File

@ -15,6 +15,8 @@ from game.db import assigned_units_from, unitdict_from
from userdata.debriefing import Debriefing from userdata.debriefing import Debriefing
from userdata import persistency from userdata import persistency
import game.db as db
DIFFICULTY_LOG_BASE = 1.1 DIFFICULTY_LOG_BASE = 1.1
EVENT_DEPARTURE_MAX_DISTANCE = 340000 EVENT_DEPARTURE_MAX_DISTANCE = 340000
@ -127,6 +129,23 @@ class Event:
self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn_quick.miz")) self.operation.current_mission.save(persistency.mission_path_for("liberation_nextturn_quick.miz"))
def commit(self, debriefing: Debriefing): def commit(self, debriefing: Debriefing):
for destroyed_unit_name in debriefing.dead_units_name:
for cp in self.game.theater.controlpoints:
for i, ground_object in enumerate(cp.ground_objects):
if ground_object.dcs_identifier == "AA":
for g in ground_object.groups:
for u in g.units:
if u.name == destroyed_unit_name:
g.units.remove(u)
ucount = sum([len(g.units) for g in ground_object.groups])
print(ucount)
if ucount == 0:
print("SET DEAD")
ground_object.is_dead = True
for country, losses in debriefing.destroyed_units.items(): for country, losses in debriefing.destroyed_units.items():
if country == self.attacker_name: if country == self.attacker_name:
cp = self.departure_cp cp = self.departure_cp

View File

@ -96,6 +96,9 @@ class Game:
turn = 0 turn = 0
game_stats: GameStats = None game_stats: GameStats = None
current_unit_id = 0
current_group_id = 0
def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater, start_date: datetime): def __init__(self, player_name: str, enemy_name: str, theater: ConflictTheater, start_date: datetime):
self.settings = Settings() self.settings = Settings()
self.events = [] self.events = []
@ -315,3 +318,16 @@ class Game:
def current_day(self): def current_day(self):
return self.date + timedelta(days=self.turn//4) return self.date + timedelta(days=self.turn//4)
def next_unit_id(self):
"""
Next unit id for pre-generated units
"""
self.current_unit_id += 1
return self.current_unit_id
def next_group_id(self):
"""
Next unit id for pre-generated units
"""
self.current_group_id += 1
return self.current_group_id

View File

@ -86,7 +86,9 @@ class Operation:
options_dict = loads(f.read())["options"] options_dict = loads(f.read())["options"]
dcs.Mission.aaa_vehicle_group = aaa.aaa_vehicle_group dcs.Mission.aaa_vehicle_group = aaa.aaa_vehicle_group
self.current_mission = dcs.Mission(terrain) self.current_mission = dcs.Mission(terrain)
if is_quick: if is_quick:
self.quick_mission = self.current_mission self.quick_mission = self.current_mission
else: else:
@ -117,6 +119,10 @@ class Operation:
self.defenders_starting_position = ship self.defenders_starting_position = ship
def generate(self): def generate(self):
# Generate ground object first
self.groundobjectgen.generate()
# air support # air support
self.airsupportgen.generate(self.is_awacs_enabled) self.airsupportgen.generate(self.is_awacs_enabled)
for i, tanker_type in enumerate(self.airsupportgen.generated_tankers): for i, tanker_type in enumerate(self.airsupportgen.generated_tankers):
@ -132,8 +138,6 @@ class Operation:
else: else:
self.current_mission.groundControl.red_tactical_commander = self.ca_slots self.current_mission.groundControl.red_tactical_commander = self.ca_slots
# ground infrastructure
self.groundobjectgen.generate()
self.extra_aagen.generate() self.extra_aagen.generate()
# triggers # triggers

View File

@ -1,6 +1,7 @@
import logging import logging
from game import db from game import db
from game.db import unit_type_from_name
from .conflictgen import * from .conflictgen import *
from .naming import * from .naming import *
@ -42,7 +43,6 @@ class GroundObjectsGenerator:
) )
def generate(self): def generate(self):
side = self.m.country(self.game.enemy_country)
cp = None # type: ControlPoint cp = None # type: ControlPoint
if self.conflict.attackers_country.name == self.game.player_country: if self.conflict.attackers_country.name == self.game.player_country:
@ -52,54 +52,58 @@ class GroundObjectsGenerator:
consumed_farps = set() consumed_farps = set()
for ground_object in cp.ground_objects:
if ground_object.dcs_identifier == "AA":
if ground_object.is_dead: for cp in self.game.theater.controlpoints:
continue
unit_type = random.choice(self.game.commision_unit_types(cp, AirDefence)) if cp.captured:
assert unit_type is not None, "Cannot find unit type for GroundObject defense ({})!".format(cp) country = self.game.player_country
group = self.m.aaa_vehicle_group(
country=side,
name=ground_object.string_identifier,
_type=unit_type,
position=ground_object.position,
heading=ground_object.heading,
)
logging.info("generated defense object identifier {} with mission id {}".format(group.name, group.id))
else: else:
if ground_object.dcs_identifier in warehouse_map: country = self.game.enemy_country
static_type = warehouse_map[ground_object.dcs_identifier] side = self.m.country(country)
for ground_object in cp.ground_objects:
if ground_object.dcs_identifier == "AA":
for g in ground_object.groups:
if len(g.units) > 0:
vg = self.m.vehicle_group(side, g.name, unit_type_from_name(g.units[0].type), position=g.position)
vg.units[0].name = self.m.string(g.units[0].name)
for i,u in enumerate(g.units):
if i > 0:
vehicle = Vehicle(self.m.next_unit_id(), self.m.string(u.name), u.type)
vehicle.position.x = u.position.x
vehicle.position.y = u.position.y
vehicle.heading = u.heading
vg.add_unit(vehicle)
else: else:
static_type = fortification_map[ground_object.dcs_identifier] if ground_object.dcs_identifier in warehouse_map:
static_type = warehouse_map[ground_object.dcs_identifier]
else:
static_type = fortification_map[ground_object.dcs_identifier]
if not static_type: if not static_type:
print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier)) print("Didn't find {} in static _map(s)!".format(ground_object.dcs_identifier))
continue continue
if ground_object.group_id not in consumed_farps: if ground_object.group_id not in consumed_farps:
consumed_farps.add(ground_object.group_id) consumed_farps.add(ground_object.group_id)
if random.randint(0, 100) > 50: if random.randint(0, 100) > 50:
farp_aa( farp_aa(
self.m, self.m,
side, side,
ground_object.string_identifier, ground_object.string_identifier,
ground_object.position, ground_object.position,
) )
group = self.m.static_group( group = self.m.static_group(
country=side, country=side,
name=ground_object.string_identifier, name=ground_object.string_identifier,
_type=static_type, _type=static_type,
position=ground_object.position, position=ground_object.position,
heading=ground_object.heading, heading=ground_object.heading,
dead=ground_object.is_dead, dead=ground_object.is_dead,
) )
logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id)) logging.info("generated {}object identifier {} with mission id {}".format("dead " if ground_object.is_dead else "", group.name, group.id))
def farp_aa(mission_obj, country, name, position: mapping.Point): def farp_aa(mission_obj, country, name, position: mapping.Point):
@ -116,7 +120,6 @@ def farp_aa(mission_obj, country, name, position: mapping.Point):
units = [ units = [
AirDefence.SPAAA_ZSU_23_4_Shilka, AirDefence.SPAAA_ZSU_23_4_Shilka,
AirDefence.AAA_ZU_23_Closed, AirDefence.AAA_ZU_23_Closed,
Armor.MBT_T_55,
] ]
v = mission_obj.vehicle(name + "_AAA", random.choice(units)) v = mission_obj.vehicle(name + "_AAA", random.choice(units))

View File

@ -0,0 +1,73 @@
import math
import random
from dcs import unitgroup
from dcs.point import PointAction
from dcs.unit import Vehicle
class AntiAirGroupGenerator():
def __init__(self, game, ground_object, group_object_group_id):
self.game = game
self.go = ground_object
self.position = ground_object.position
self.heading = random.randint(0, 359)
self.vg = unitgroup.VehicleGroup(self.game.next_group_id(), self.go.group_identifier)
wp = self.vg.add_waypoint(self.position, PointAction.OffRoad, 0)
wp.ETA_locked = True
def generate(self):
raise NotImplementedError
def get_generated_group(self):
return self.vg
def add_unit(self, unit_type, name, pos_x, pos_y, heading):
nn = "cgroup|" + str(self.go.cp_id) + '|' + str(self.go.group_id) + '|' + str(self.go.group_identifier) + "|" + name
unit = Vehicle(self.game.next_unit_id(),
nn, unit_type.id)
unit.position.x = pos_x
unit.position.y = pos_y
unit.heading = heading
self.vg.add_unit(unit)
return unit
def get_circular_position(self, num_units, launcher_distance, coverage=90):
"""
Given a position on the map, array a group of units in a circle a uniform distance from the unit
:param num_units:
number of units to play on the circle
:param launcher_distance:
distance the units should be from the center unit
:param coverage:
0-360
:return:
list of tuples representing each unit location
[(pos_x, pos_y, heading), ...]
"""
if coverage == 360:
# one of the positions is shared :'(
outer_offset = coverage / num_units
else:
outer_offset = coverage / (num_units - 1)
positions = []
if num_units % 2 == 0:
current_offset = self.heading - ((coverage / (num_units - 1)) / 2)
else:
current_offset = self.heading
current_offset -= outer_offset * (math.ceil(num_units / 2) - 1)
for x in range(1, num_units + 1):
positions.append((
self.position.x + launcher_distance * math.cos(math.radians(current_offset)),
self.position.y + launcher_distance * math.sin(math.radians(current_offset)),
current_offset,
))
current_offset += outer_offset
return positions

19
gen/sam/sam_avenger.py Normal file
View File

@ -0,0 +1,19 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class AvengerGenerator(AntiAirGroupGenerator):
"""
This generate an Avenger group
"""
def generate(self):
num_launchers = random.randint(2, 3)
self.add_unit(Unarmed.Transport_M818, "TRUCK", self.position.x, self.position.y, self.heading)
positions = self.get_circular_position(num_launchers, launcher_distance=110, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_Avenger_M1097, "SPAA#" + str(i), position[0], position[1], position[2])

19
gen/sam/sam_chaparral.py Normal file
View File

@ -0,0 +1,19 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class ChaparralGenerator(AntiAirGroupGenerator):
"""
This generate a Chaparral group
"""
def generate(self):
num_launchers = random.randint(2, 4)
self.add_unit(Unarmed.Transport_M818, "TRUCK", self.position.x, self.position.y, self.heading)
positions = self.get_circular_position(num_launchers, launcher_distance=110, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_Chaparral_M48, "SPAA#" + str(i), position[0], position[1], position[2])

18
gen/sam/sam_gepard.py Normal file
View File

@ -0,0 +1,18 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class GepardGenerator(AntiAirGroupGenerator):
"""
This generate a Gepard group
"""
def generate(self):
self.add_unit(AirDefence.SPAAA_Gepard, "SPAAA", self.position.x, self.position.y, self.heading)
if random.randint(0, 1) == 1:
self.add_unit(AirDefence.SPAAA_Gepard, "SPAAA2", self.position.x, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_M818, "TRUCK", self.position.x + 80, self.position.y, self.heading)

View File

@ -0,0 +1,82 @@
import math
import random
from dcs import unitgroup
from dcs.point import PointAction
from dcs.unit import Vehicle
from dcs.unittype import UnitType
from dcs.vehicles import AirDefence
from game import db
from gen.sam.sam_avenger import AvengerGenerator
from gen.sam.sam_chaparral import ChaparralGenerator
from gen.sam.sam_gepard import GepardGenerator
from gen.sam.sam_hawk import HawkGenerator
from gen.sam.sam_linebacker import LinebackerGenerator
from gen.sam.sam_patriot import PatriotGenerator
from gen.sam.sam_rapier import RapierGenerator
from gen.sam.sam_roland import RolandGenerator
from gen.sam.sam_sa10 import SA10Generator
from gen.sam.sam_sa11 import SA11Generator
from gen.sam.sam_sa13 import SA13Generator
from gen.sam.sam_sa15 import SA15Generator
from gen.sam.sam_sa19 import SA19Generator
from gen.sam.sam_sa2 import SA2Generator
from gen.sam.sam_sa3 import SA3Generator
from gen.sam.sam_sa6 import SA6Generator
from gen.sam.sam_sa8 import SA8Generator
from gen.sam.sam_sa9 import SA9Generator
from gen.sam.sam_vulcan import VulcanGenerator
from gen.sam.sam_zsu23 import ZSU23Generator
from gen.sam.sam_zu23 import ZU23Generator
from gen.sam.sam_zu23_ural import ZU23UralGenerator
def generate_anti_air_group(game, parent_cp, ground_object, faction:str):
"""
This generate a SAM group
:param parentCp: The parent control point
:param ground_object: The ground object which will own the sam group
:param country: Owner country
:return: Nothing, but put the group reference inside the ground object
"""
SAM_MAP = {
AirDefence.SAM_Hawk_PCP:HawkGenerator,
AirDefence.AAA_ZU_23_Closed:ZU23Generator,
AirDefence.AAA_ZU_23_Insurgent_on_Ural_375:ZU23UralGenerator,
AirDefence.SPAAA_ZSU_23_4_Shilka:ZSU23Generator,
AirDefence.AAA_Vulcan_M163: VulcanGenerator,
AirDefence.SAM_Linebacker_M6: LinebackerGenerator,
AirDefence.Rapier_FSA_Launcher: RapierGenerator,
AirDefence.SAM_Avenger_M1097: AvengerGenerator,
AirDefence.SPAAA_Gepard: GepardGenerator,
AirDefence.SAM_Roland_ADS: RolandGenerator,
AirDefence.SAM_Patriot_LN_M901: PatriotGenerator,
AirDefence.SAM_Chaparral_M48: ChaparralGenerator,
AirDefence.SAM_SA_2_LN_SM_90: SA2Generator,
AirDefence.SAM_SA_3_S_125_LN_5P73: SA3Generator,
AirDefence.SAM_SA_6_Kub_LN_2P25: SA6Generator,
AirDefence.SAM_SA_8_Osa_9A33: SA8Generator,
AirDefence.SAM_SA_9_Strela_1_9P31: SA9Generator,
AirDefence.SAM_SA_10_S_300PS_LN_5P85C: SA10Generator,
AirDefence.SAM_SA_10_S_300PS_CP_54K6: SA10Generator,
AirDefence.SAM_SA_11_Buk_LN_9A310M1: SA11Generator,
AirDefence.SAM_SA_13_Strela_10M3_9A35M3: SA13Generator,
AirDefence.SAM_SA_15_Tor_9A331: SA15Generator,
AirDefence.SAM_SA_19_Tunguska_2S6: SA19Generator,
}
possible_sams = [u for u in db.FACTIONS[faction]["units"] if u in AirDefence.__dict__.values()]
if len(possible_sams) > 0:
sam = random.choice(possible_sams)
generator = SAM_MAP[sam](game, ground_object, 0)
generator.generate()
ground_object.groups = [generator.get_generated_group()]

25
gen/sam/sam_hawk.py Normal file
View File

@ -0,0 +1,25 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class HawkGenerator(AntiAirGroupGenerator):
"""
This generate an HAWK group
"""
def generate(self):
self.add_unit(AirDefence.SAM_Hawk_PCP, "PCP", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_Hawk_SR_AN_MPQ_50, "SR", self.position.x + 20, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_Hawk_TR_AN_MPQ_46, "TR", self.position.x + 40, self.position.y, self.heading)
# Triple A for close range defense
self.add_unit(AirDefence.AAA_Vulcan_M163, "AAA", self.position.x + 20, self.position.y+30, self.heading)
num_launchers = random.randint(3, 6)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_Hawk_LN_M192, "LN#" + str(i), position[0], position[1], position[2])

19
gen/sam/sam_linebacker.py Normal file
View File

@ -0,0 +1,19 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class LinebackerGenerator(AntiAirGroupGenerator):
"""
This generate an m6 linebacker group
"""
def generate(self):
num_launchers = random.randint(2, 4)
self.add_unit(Unarmed.Transport_M818, "TRUCK", self.position.x, self.position.y, self.heading)
positions = self.get_circular_position(num_launchers, launcher_distance=110, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_Linebacker_M6, "M6#" + str(i), position[0], position[1], position[2])

30
gen/sam/sam_patriot.py Normal file
View File

@ -0,0 +1,30 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class PatriotGenerator(AntiAirGroupGenerator):
"""
This generate a Patriot group
"""
def generate(self):
# Command Post
self.add_unit(AirDefence.SAM_Patriot_AMG_AN_MRC_137, "MRC", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_Patriot_ECS_AN_MSQ_104, "MSQ", self.position.x + 30, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_Patriot_ICC, "ICC", self.position.x + 60, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_Patriot_EPP_III, "EPP", self.position.x, self.position.y + 30, self.heading)
self.add_unit(AirDefence.SAM_Patriot_STR_AN_MPQ_53, "ICC", self.position.x + 30, self.position.y + 30, self.heading)
num_launchers = random.randint(2, 4)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_Patriot_LN_M901, "LN#" + str(i), position[0], position[1], position[2])
# Short range protection for high value site
num_launchers = random.randint(2, 4)
positions = self.get_circular_position(num_launchers, launcher_distance=300, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.AAA_Vulcan_M163, "SPAAA#" + str(i), position[0], position[1], position[2])

21
gen/sam/sam_rapier.py Normal file
View File

@ -0,0 +1,21 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class RapierGenerator(AntiAirGroupGenerator):
"""
This generate a Rapier Group
"""
def generate(self):
self.add_unit(AirDefence.Rapier_FSA_Blindfire_Tracker, "BT", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.Rapier_FSA_Optical_Tracker, "OT", self.position.x + 20, self.position.y, self.heading)
num_launchers = random.randint(3, 6)
positions = self.get_circular_position(num_launchers, launcher_distance=80, coverage=240)
for i, position in enumerate(positions):
self.add_unit(AirDefence.Rapier_FSA_Launcher, "LN#" + str(i), position[0], position[1], position[2])

15
gen/sam/sam_roland.py Normal file
View File

@ -0,0 +1,15 @@
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class RolandGenerator(AntiAirGroupGenerator):
"""
This generate a Roland group
"""
def generate(self):
self.add_unit(AirDefence.SAM_Roland_ADS, "ADS", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_Roland_EWR, "EWR", self.position.x + 40, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_M818, "TRUCK", self.position.x + 80, self.position.y, self.heading)

43
gen/sam/sam_sa10.py Normal file
View File

@ -0,0 +1,43 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA10Generator(AntiAirGroupGenerator):
"""
This generate a SA-10 group
"""
def generate(self):
# Command Post
self.add_unit(AirDefence.SAM_SA_10_S_300PS_CP_54K6, "CP", self.position.x, self.position.y, self.heading)
# Search Radar
self.add_unit(AirDefence.SAM_SA_10_S_300PS_SR_5N66M, "SR", self.position.x, self.position.y, self.heading)
# Search radar for missiles (optionnal)
self.add_unit(AirDefence.SAM_SA_10_S_300PS_SR_64H6E, "SR", self.position.x, self.position.y, self.heading)
# 2 different launcher type (C & D)
num_launchers = random.randint(6, 8)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=360)
for i, position in enumerate(positions):
if i%2 == 0:
self.add_unit(AirDefence.SAM_SA_10_S_300PS_LN_5P85C, "LN#" + str(i), position[0], position[1], position[2])
else:
self.add_unit(AirDefence.SAM_SA_10_S_300PS_LN_5P85D, "LN#" + str(i), position[0], position[1], position[2])
# Then let's add short range protection to this high value site
# Sa-13 Strela are great for that
num_launchers = random.randint(2, 4)
positions = self.get_circular_position(num_launchers, launcher_distance=300, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_13_Strela_10M3_9A35M3, "IR#" + str(i), position[0], position[1], position[2])
# And even some AA
num_launchers = random.randint(6, 8)
positions = self.get_circular_position(num_launchers, launcher_distance=350, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.AAA_ZU_23_Emplacement, "AA#" + str(i), position[0], position[1], position[2])

21
gen/sam/sam_sa11.py Normal file
View File

@ -0,0 +1,21 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA11Generator(AntiAirGroupGenerator):
"""
This generate a SA-11 group
"""
def generate(self):
self.add_unit(AirDefence.SAM_SA_11_Buk_CC_9S470M1, "CC", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_SA_11_Buk_SR_9S18M1, "SR", self.position.x+20, self.position.y, self.heading)
num_launchers = random.randint(2, 4)
positions = self.get_circular_position(num_launchers, launcher_distance=140, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_11_Buk_LN_9A310M1, "LN#" + str(i), position[0], position[1], position[2])

20
gen/sam/sam_sa13.py Normal file
View File

@ -0,0 +1,20 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class SA13Generator(AntiAirGroupGenerator):
"""
This generate a SA-13 group
"""
def generate(self):
self.add_unit(Unarmed.Transport_UAZ_469, "UAZ", self.position.x, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_KAMAZ_43101, "TRUCK", self.position.x+40, self.position.y, self.heading)
num_launchers = random.randint(2, 3)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_13_Strela_10M3_9A35M3, "LN#" + str(i), position[0], position[1], position[2])

14
gen/sam/sam_sa15.py Normal file
View File

@ -0,0 +1,14 @@
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class SA15Generator(AntiAirGroupGenerator):
"""
This generate a SA-15 group
"""
def generate(self):
self.add_unit(AirDefence.SAM_SA_15_Tor_9A331, "ADS", self.position.x, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_UAZ_469, "EWR", self.position.x + 40, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_KAMAZ_43101, "TRUCK", self.position.x + 80, self.position.y, self.heading)

21
gen/sam/sam_sa19.py Normal file
View File

@ -0,0 +1,21 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA19Generator(AntiAirGroupGenerator):
"""
This generate a SA-19 group
"""
def generate(self):
num_launchers = random.randint(1, 3)
if num_launchers == 1:
self.add_unit(AirDefence.SAM_SA_19_Tunguska_2S6, "LN#0", self.position.x, self.position.y, self.heading)
else:
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_19_Tunguska_2S6, "LN#" + str(i), position[0], position[1], position[2])

21
gen/sam/sam_sa2.py Normal file
View File

@ -0,0 +1,21 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA2Generator(AntiAirGroupGenerator):
"""
This generate a SA-2 group
"""
def generate(self):
self.add_unit(AirDefence.SAM_SR_P_19, "SR", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_SA_2_TR_SNR_75_Fan_Song, "TR", self.position.x + 20, self.position.y, self.heading)
num_launchers = random.randint(3, 6)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_2_LN_SM_90, "LN#" + str(i), position[0], position[1], position[2])

21
gen/sam/sam_sa3.py Normal file
View File

@ -0,0 +1,21 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA3Generator(AntiAirGroupGenerator):
"""
This generate a SA-3 group
"""
def generate(self):
self.add_unit(AirDefence.SAM_SR_P_19, "SR", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_SA_3_S_125_TR_SNR, "TR", self.position.x + 20, self.position.y, self.heading)
num_launchers = random.randint(3, 6)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_3_S_125_LN_5P73, "LN#" + str(i), position[0], position[1], position[2])

20
gen/sam/sam_sa6.py Normal file
View File

@ -0,0 +1,20 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA6Generator(AntiAirGroupGenerator):
"""
This generate a SA-6 group
"""
def generate(self):
self.add_unit(AirDefence.SAM_SA_6_Kub_STR_9S91, "STR", self.position.x, self.position.y, self.heading)
num_launchers = random.randint(2, 4)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_6_Kub_LN_2P25, "LN#" + str(i), position[0], position[1], position[2])

15
gen/sam/sam_sa8.py Normal file
View File

@ -0,0 +1,15 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class SA8Generator(AntiAirGroupGenerator):
"""
This generate a SA-8 group
"""
def generate(self):
self.add_unit(AirDefence.SAM_SA_8_Osa_9A33, "OSA", self.position.x, self.position.y, self.heading)
self.add_unit(AirDefence.SAM_SA_8_Osa_LD_9T217, "LD", self.position.x + 20, self.position.y, self.heading)

20
gen/sam/sam_sa9.py Normal file
View File

@ -0,0 +1,20 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class SA9Generator(AntiAirGroupGenerator):
"""
This generate a SA-9 group
"""
def generate(self):
self.add_unit(Unarmed.Transport_UAZ_469, "UAZ", self.position.x, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_KAMAZ_43101, "TRUCK", self.position.x+40, self.position.y, self.heading)
num_launchers = random.randint(2, 3)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SAM_SA_9_Strela_1_9P31, "LN#" + str(i), position[0], position[1], position[2])

18
gen/sam/sam_vulcan.py Normal file
View File

@ -0,0 +1,18 @@
import random
from dcs.vehicles import AirDefence, Unarmed
from gen.sam.group_generator import AntiAirGroupGenerator
class VulcanGenerator(AntiAirGroupGenerator):
"""
This generate a Vulcan group
"""
def generate(self):
self.add_unit(AirDefence.AAA_Vulcan_M163, "SPAAA", self.position.x, self.position.y, self.heading)
if random.randint(0, 1) == 1:
self.add_unit(AirDefence.AAA_Vulcan_M163, "SPAAA2", self.position.x, self.position.y, self.heading)
self.add_unit(Unarmed.Transport_M818, "TRUCK", self.position.x + 80, self.position.y, self.heading)

18
gen/sam/sam_zsu23.py Normal file
View File

@ -0,0 +1,18 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class ZSU23Generator(AntiAirGroupGenerator):
"""
This generate a ZSU 23 group
"""
def generate(self):
num_launchers = random.randint(2, 5)
positions = self.get_circular_position(num_launchers, launcher_distance=120, coverage=180)
for i, position in enumerate(positions):
self.add_unit(AirDefence.SPAAA_ZSU_23_4_Shilka, "SPAA#" + str(i), position[0], position[1], position[2])

25
gen/sam/sam_zu23.py Normal file
View File

@ -0,0 +1,25 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class ZU23Generator(AntiAirGroupGenerator):
"""
This generate a ZU23 flak artillery group
"""
def generate(self):
grid_x = random.randint(2, 4)
grid_y = random.randint(2, 4)
spacing = random.randint(10,40)
index = 0
for i in range(grid_x):
for j in range(grid_y):
index = index+1
self.add_unit(AirDefence.AAA_ZU_23_Closed, "AAA#" + str(index),
self.position.x + spacing*i,
self.position.y + spacing*j, self.heading)

18
gen/sam/sam_zu23_ural.py Normal file
View File

@ -0,0 +1,18 @@
import random
from dcs.vehicles import AirDefence
from gen.sam.group_generator import AntiAirGroupGenerator
class ZU23UralGenerator(AntiAirGroupGenerator):
"""
This generate a Zu23 Ural group
"""
def generate(self):
num_launchers = random.randint(2, 8)
positions = self.get_circular_position(num_launchers, launcher_distance=80, coverage=360)
for i, position in enumerate(positions):
self.add_unit(AirDefence.AAA_ZU_23_on_Ural_375, "SPAA#" + str(i), position[0], position[1], position[2])

63
qt_ui/main2.py Normal file
View File

@ -0,0 +1,63 @@
import datetime
from dcs import Mission
from dcs.terrain import Caucasus
from dcs.vehicles import AirDefence
from game import Game
from gen.sam.sam_avenger import AvengerGenerator
from gen.sam.sam_chaparral import ChaparralGenerator
from gen.sam.sam_gepard import GepardGenerator
from gen.sam.sam_hawk import HawkGenerator
from gen.sam.sam_linebacker import LinebackerGenerator
from gen.sam.sam_patriot import PatriotGenerator
from gen.sam.sam_rapier import RapierGenerator
from gen.sam.sam_roland import RolandGenerator
from gen.sam.sam_sa10 import SA10Generator
from gen.sam.sam_sa11 import SA11Generator
from gen.sam.sam_sa13 import SA13Generator
from gen.sam.sam_sa15 import SA15Generator
from gen.sam.sam_sa19 import SA19Generator
from gen.sam.sam_sa2 import SA2Generator
from gen.sam.sam_sa3 import SA3Generator
from gen.sam.sam_sa6 import SA6Generator
from gen.sam.sam_sa8 import SA8Generator
from gen.sam.sam_sa9 import SA9Generator
from gen.sam.sam_zsu23 import ZSU23Generator
from gen.sam.sam_zu23 import ZU23Generator
from gen.sam.sam_zu23_ural import ZU23UralGenerator
from theater import TheaterGroundObject
from theater.caucasus import WesternGeorgia
ter = Caucasus()
m = Mission()
game = Game("USA 1990", "Iran 2015", WesternGeorgia(), datetime.datetime.now())
generated_groups = []
for i,c in enumerate([SA3Generator, SA2Generator, SA6Generator, RapierGenerator,
HawkGenerator, SA10Generator, SA19Generator, ZU23Generator,
SA8Generator, SA11Generator, SA9Generator, SA13Generator,
ZSU23Generator, SA15Generator, GepardGenerator, RolandGenerator,
PatriotGenerator, ZU23UralGenerator, ChaparralGenerator,
AvengerGenerator, LinebackerGenerator]):
t = TheaterGroundObject()
t.position = ter.kutaisi().position
t.position.x += i*250
t.dcs_identifier = "AA"
gen = c(game, t)
gen.generate()
vehicle_group = gen.get_generated_group()
generated_groups.append(vehicle_group)
for g in generated_groups:
g.name = m.string(g.name)
for unit in g.units:
unit.name = m.string(unit.name)
m.country("USA").add_vehicle_group(g)
m.save("./test.miz")

View File

@ -264,15 +264,6 @@ class QLiberationMap(QGraphicsView):
overlay.setGraphicsEffect(effect) overlay.setGraphicsEffect(effect)
@staticmethod @staticmethod
def set_display_rule(rule: str, value: bool): def set_display_rule(rule: str, value: bool):
QLiberationMap.display_rules[rule] = value QLiberationMap.display_rules[rule] = value

View File

@ -13,7 +13,21 @@ class QMapGroundObject(QGraphicsRectItem):
self.parent = parent self.parent = parent
self.setAcceptHoverEvents(True) self.setAcceptHoverEvents(True)
self.setZValue(2) self.setZValue(2)
self.setToolTip(cp.name + "'s " + self.model.category)
if len(self.model.groups) > 0:
units = {}
for g in self.model.groups:
for u in g.units:
if u.type in units.keys():
units[u.type] = units[u.type]+1
else:
units[u.type] = 1
tooltip = ""
for unit in units.keys():
tooltip = tooltip + str(unit) + "x" + str(units[unit]) + "\n"
self.setToolTip(tooltip + str(model.groups[0].id) + str(model.groups[0].name))
else:
self.setToolTip(cp.name + "'s " + self.model.category)
def paint(self, painter, option, widget=None): def paint(self, painter, option, widget=None):

View File

@ -67,11 +67,11 @@ class NewGameWizard(QtWidgets.QWizard):
conflicttheater.controlpoints[i].captured = True conflicttheater.controlpoints[i].captured = True
start_generator.generate_inital_units(conflicttheater, enemy_name, sams, multiplier) start_generator.generate_inital_units(conflicttheater, enemy_name, sams, multiplier)
start_generator.generate_groundobjects(conflicttheater)
game = Game(player_name=player_name, game = Game(player_name=player_name,
enemy_name=enemy_name, enemy_name=enemy_name,
theater=conflicttheater, theater=conflicttheater,
start_date=period) start_date=period)
start_generator.generate_groundobjects(conflicttheater, game)
game.budget = int(game.budget * multiplier) game.budget = int(game.budget * multiplier)
game.settings.multiplier = multiplier game.settings.multiplier = multiplier
game.settings.sams = sams game.settings.sams = sams

View File

@ -22,8 +22,9 @@ def init(player_country: str, enemy_country: str, theater_klass: typing.Type[Con
persistency.setup("./tests/userfolder/") persistency.setup("./tests/userfolder/")
theater = theater_klass() theater = theater_klass()
start_generator.generate_inital_units(theater, ENEMY_COUNTRY, True, 1) start_generator.generate_inital_units(theater, ENEMY_COUNTRY, True, 1)
start_generator.generate_groundobjects(theater) game = Game(PLAYER_COUNTRY, ENEMY_COUNTRY, theater)
return Game(PLAYER_COUNTRY, ENEMY_COUNTRY, theater), theater start_generator.generate_groundobjects(theater, game)
return game, theater
def autoflights_for(event: Event, country: str) -> TaskForceDict: def autoflights_for(event: Event, country: str) -> TaskForceDict:
@ -55,7 +56,7 @@ def autodebrief_for(event: Event, type: AutodebriefType) -> Debriefing:
for unit in group.units: for unit in group.units:
dead_units.append(str(unit.name)) dead_units.append(str(unit.name))
return Debriefing(dead_units, []) return Debriefing(dead_units, [], [])
def event_state_save(e: Event) -> typing.Tuple[Base, Base]: def event_state_save(e: Event) -> typing.Tuple[Base, Base]:

View File

@ -58,7 +58,7 @@ class PersianGulfTheater(ConflictTheater):
self.add_controlpoint(self.al_ain, connected_to=[self.al_dhafra, self.al_maktoum]) self.add_controlpoint(self.al_ain, connected_to=[self.al_dhafra, self.al_maktoum])
self.add_controlpoint(self.al_maktoum, connected_to=[self.al_dhafra, self.al_minhad, self.sir_abu_nuayr, self.al_ain]) self.add_controlpoint(self.al_maktoum, connected_to=[self.al_dhafra, self.al_minhad, self.sir_abu_nuayr, self.al_ain])
self.add_controlpoint(self.al_minhad, connected_to=[self.al_maktoum, self.dubai]) self.add_controlpoint(self.al_minhad, connected_to=[self.al_maktoum, self.dubai])
self.add_controlpoint(self.dubai, connected_to=[self.al_minhad, self.sharjah]) self.add_controlpoint(self.dubai, connected_to=[self.al_minhad, self.sharjah, self.fujairah])
self.add_controlpoint(self.sharjah, connected_to=[self.dubai, self.ras_al_khaimah]) self.add_controlpoint(self.sharjah, connected_to=[self.dubai, self.ras_al_khaimah])
self.add_controlpoint(self.ras_al_khaimah, connected_to=[self.sharjah, self.khasab]) self.add_controlpoint(self.ras_al_khaimah, connected_to=[self.sharjah, self.khasab])
self.add_controlpoint(self.fujairah, connected_to=[self.dubai, self.khasab]) self.add_controlpoint(self.fujairah, connected_to=[self.dubai, self.khasab])

View File

@ -4,6 +4,7 @@ import random
import typing import typing
import logging import logging
from gen.sam.sam_group_generator import generate_anti_air_group
from theater.base import * from theater.base import *
from theater.conflicttheater import * from theater.conflicttheater import *
@ -52,7 +53,7 @@ def generate_inital_units(theater: ConflictTheater, enemy_country: str, sams: bo
cp.base.commision_units({unit_type: count_per_type}) cp.base.commision_units({unit_type: count_per_type})
def generate_groundobjects(theater: ConflictTheater): def generate_groundobjects(theater: ConflictTheater, game):
with open("resources/groundobject_templates.p", "rb") as f: with open("resources/groundobject_templates.p", "rb") as f:
tpls = pickle.load(f) tpls = pickle.load(f)
@ -131,4 +132,11 @@ def generate_groundobjects(theater: ConflictTheater):
g.heading = object["heading"] g.heading = object["heading"]
g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y) g.position = Point(point.x + object["offset"].x, point.y + object["offset"].y)
if g.dcs_identifier == "AA":
if cp.captured:
faction = game.player_name
else:
faction = game.enemy_name
generate_anti_air_group(game, cp, g, faction)
cp.ground_objects.append(g) cp.ground_objects.append(g)

View File

@ -55,6 +55,8 @@ class TheaterGroundObject:
heading = 0 heading = 0
position = None # type: Point position = None # type: Point
groups = []
@property @property
def category(self) -> str: def category(self) -> str:
for k, v in CATEGORY_MAP.items(): for k, v in CATEGORY_MAP.items():

View File

@ -122,7 +122,7 @@ class EventResultsMenu(Menu):
def simulate_result(self, player_factor: float, enemy_factor: float): def simulate_result(self, player_factor: float, enemy_factor: float):
def action(): def action():
debriefing = Debriefing({}) debriefing = Debriefing({}, [])
def count(country: Country) -> typing.Dict[UnitType, int]: def count(country: Country) -> typing.Dict[UnitType, int]:
result = {} result = {}

View File

@ -104,11 +104,11 @@ class Window:
conflicttheater.controlpoints[i].captured = True conflicttheater.controlpoints[i].captured = True
start_generator.generate_inital_units(conflicttheater, enemy_name, sams, multiplier) start_generator.generate_inital_units(conflicttheater, enemy_name, sams, multiplier)
start_generator.generate_groundobjects(conflicttheater)
game = Game(player_name=player_name, game = Game(player_name=player_name,
enemy_name=enemy_name, enemy_name=enemy_name,
theater=conflicttheater, theater=conflicttheater,
start_date=period) start_date=period)
start_generator.generate_groundobjects(conflicttheater, game)
game.budget = int(game.budget * multiplier) game.budget = int(game.budget * multiplier)
game.settings.multiplier = multiplier game.settings.multiplier = multiplier
game.settings.sams = sams game.settings.sams = sams

View File

@ -57,19 +57,21 @@ def parse_mutliplayer_debriefing(contents: str):
class Debriefing: class Debriefing:
def __init__(self, dead_units, trigger_state): def __init__(self, dead_units, dead_units_name, trigger_state):
self.destroyed_units = {} # type: typing.Dict[str, typing.Dict[UnitType, int]] self.destroyed_units = {} # type: typing.Dict[str, typing.Dict[UnitType, int]]
self.alive_units = {} # type: typing.Dict[str, typing.Dict[UnitType, int]] self.alive_units = {} # type: typing.Dict[str, typing.Dict[UnitType, int]]
self.destroyed_objects = [] # type: typing.List[str] self.destroyed_objects = [] # type: typing.List[str]
self._trigger_state = trigger_state self._trigger_state = trigger_state
self._dead_units = dead_units self._dead_units = dead_units
self.dead_units_name = dead_units_name
@classmethod @classmethod
def parse(cls, path: str): def parse(cls, path: str):
dead_units = [] dead_units = []
dead_units_name = []
def append_dead_object(object_mission_id_str): def append_dead_object(object_mission_id_str, object_name):
nonlocal dead_units nonlocal dead_units
object_mission_id = int(object_mission_id_str) object_mission_id = int(object_mission_id_str)
if object_mission_id in dead_units: if object_mission_id in dead_units:
@ -77,10 +79,12 @@ class Debriefing:
return return
dead_units.append(object_mission_id) dead_units.append(object_mission_id)
dead_units_name.append(object_name)
def parse_dead_object(event): def parse_dead_object(event):
print(event)
try: try:
append_dead_object(event["initiatorMissionID"]) append_dead_object(event["initiatorMissionID"], event["initiator"])
except Exception as e: except Exception as e:
logging.error(e) logging.error(e)
@ -99,7 +103,7 @@ class Debriefing:
trigger_state = table.get("debriefing", {}).get("triggers_state", {}) trigger_state = table.get("debriefing", {}).get("triggers_state", {})
return Debriefing(dead_units, trigger_state) return Debriefing(dead_units, dead_units_name, trigger_state)
def calculate_units(self, regular_mission: Mission, quick_mission: Mission, player_country: str, enemy_country: str): def calculate_units(self, regular_mission: Mission, quick_mission: Mission, player_country: str, enemy_country: str):
def count_groups(groups: typing.List[UnitType]) -> typing.Dict[UnitType, int]: def count_groups(groups: typing.List[UnitType]) -> typing.Dict[UnitType, int]: