Merge remote-tracking branch 'remotes/dcs-retribution/dcs-retribution/dev' into pretense-generator

This commit is contained in:
MetalStormGhost 2024-07-20 19:21:06 +03:00
commit e88a4e1c51
18 changed files with 457 additions and 233 deletions

View File

@ -24,13 +24,13 @@ from game.theater import (
TheaterGroundObject, TheaterGroundObject,
TheaterUnit, TheaterUnit,
) )
from game.theater.theatergroup import TheaterGroup
from game.utils import Distance, meters, nautical_miles, feet from game.utils import Distance, meters, nautical_miles, feet
AGL_TRANSITION_ALT = 5000 AGL_TRANSITION_ALT = 5000
if TYPE_CHECKING: if TYPE_CHECKING:
from game.transfers import MultiGroupTransport from game.transfers import MultiGroupTransport
from game.theater.theatergroup import TheaterGroup
from game.ato.flight import Flight from game.ato.flight import Flight
@ -323,7 +323,9 @@ class WaypointBuilder:
return FlightWaypoint( return FlightWaypoint(
target.name, target.name,
FlightWaypointType.TARGET_POINT, FlightWaypointType.TARGET_POINT,
target.target.position, target.target.ground_object.position
if isinstance(target.target, (TheaterGroup, TheaterUnit))
else target.target.position,
meters(0), meters(0),
"RADIO", "RADIO",
description=description, description=description,

View File

@ -10,6 +10,8 @@ from dcs import Mission, Point
from dcs.coalition import Coalition from dcs.coalition import Coalition
from dcs.countries import country_dict from dcs.countries import country_dict
from dcs.task import OptReactOnThreat from dcs.task import OptReactOnThreat
from dcs.terrain import Airport
from dcs.unit import Static
from game.atcdata import AtcData from game.atcdata import AtcData
from game.dcs.beacons import Beacons from game.dcs.beacons import Beacons
@ -112,8 +114,8 @@ class MissionGenerator:
self.notify_info_generators() self.notify_info_generators()
# TODO: Shouldn't this be first?
namegen.reset_numbers() namegen.reset_numbers()
self.generate_warehouses()
self.mission.save(output) self.mission.save(output)
return self.unit_map return self.unit_map
@ -347,3 +349,33 @@ class MissionGenerator:
self.mission.groundControl.blue_tactical_commander = commanders self.mission.groundControl.blue_tactical_commander = commanders
self.mission.groundControl.blue_jtac = settings.jtac_count self.mission.groundControl.blue_jtac = settings.jtac_count
self.mission.groundControl.blue_observer = settings.observer_count self.mission.groundControl.blue_observer = settings.observer_count
def generate_warehouses(self) -> None:
settings = self.game.settings
for tmu in self.unit_map.theater_objects.values():
if (
tmu.theater_unit.is_ship
or isinstance(tmu.dcs_unit, Static)
and tmu.dcs_unit.category in ["Warehouses", "Heliports"]
):
# We'll serialize more than is actually necessary
# DCS will filter out warehouses as dynamic spawns so no need to worry there
# thus, if we serialize a ship as a warehouse that's not supported, DCS will filter it out
warehouse = Airport(
tmu.theater_unit.position,
self.mission.terrain,
).dict()
warehouse["coalition"] = (
"blue" if tmu.theater_unit.ground_object.coalition.player else "red"
)
warehouse["dynamicCargo"] = settings.dynamic_cargo
if tmu.theater_unit.is_ship or tmu.dcs_unit.category == "Heliports": # type: ignore
warehouse["dynamicSpawn"] = settings.dynamic_slots
warehouse["allowHotStart"] = settings.dynamic_slots_hot
self.mission.warehouses.warehouses[tmu.dcs_unit.id] = warehouse
# configure dynamic spawn, hot start of DS & dynamic cargo for airfields
for ap in self.mission.terrain.airports.values():
ap.dynamic_spawn = settings.dynamic_slots
ap.allow_hot_start = settings.dynamic_slots_hot
ap.dynamic_cargo = settings.dynamic_cargo

View File

@ -38,6 +38,7 @@ from dcs.task import (
FireAtPoint, FireAtPoint,
OptAlarmState, OptAlarmState,
) )
from dcs.terrain import Airport
from dcs.translation import String from dcs.translation import String
from dcs.triggers import ( from dcs.triggers import (
Event, Event,
@ -859,6 +860,14 @@ class HelipadGenerator:
cull_farp_statics = False cull_farp_statics = False
if not cull_farp_statics: if not cull_farp_statics:
warehouse = Airport(
pad.position,
self.m.terrain,
).dict()
warehouse["coalition"] = "blue" if self.cp.coalition.player else "red"
# configure dynamic spawn + hot start of DS, plus dynamic cargo?
self.m.warehouses.warehouses[pad.id] = warehouse
# Generate a FARP Ammo and Fuel stack for each pad # Generate a FARP Ammo and Fuel stack for each pad
self.m.static_group( self.m.static_group(
country=country, country=country,
@ -1095,6 +1104,14 @@ class GroundSpawnLargeGenerator:
country.id country.id
) )
warehouse = Airport(
pad.position,
self.m.terrain,
).dict()
warehouse["coalition"] = "blue" if self.cp.coalition.player else "red"
# configure dynamic spawn + hot start of DS, plus dynamic cargo?
self.m.warehouses.warehouses[pad.id] = warehouse
# Generate a FARP Ammo and Fuel stack for each pad # Generate a FARP Ammo and Fuel stack for each pad
if self.game.settings.ground_start_trucks: if self.game.settings.ground_start_trucks:
self.m.vehicle_group( self.m.vehicle_group(
@ -1231,6 +1248,14 @@ class GroundSpawnGenerator:
cull_farp_statics = False cull_farp_statics = False
if not cull_farp_statics: if not cull_farp_statics:
warehouse = Airport(
pad.position,
self.m.terrain,
).dict()
warehouse["coalition"] = "blue" if self.cp.coalition.player else "red"
# configure dynamic spawn + hot start of DS, plus dynamic cargo?
self.m.warehouses.warehouses[pad.id] = warehouse
# Generate a FARP Ammo and Fuel stack for each pad # Generate a FARP Ammo and Fuel stack for each pad
if self.game.settings.ground_start_trucks: if self.game.settings.ground_start_trucks:
self.m.vehicle_group( self.m.vehicle_group(

View File

@ -238,7 +238,13 @@ RADIOS: List[Radio] = [
# MiG-19P # MiG-19P
Radio("RSIU-4V", (RadioRange(MHz(100), MHz(150), kHz(25), Modulation.AM),)), Radio("RSIU-4V", (RadioRange(MHz(100), MHz(150), kHz(25), Modulation.AM),)),
# MiG-21bis # MiG-21bis
Radio("RSIU-5V", (RadioRange(MHz(118), MHz(140), kHz(25), Modulation.AM),)), Radio(
"R-832",
(
RadioRange(MHz(118), MHz(140), kHz(100), Modulation.AM),
RadioRange(MHz(220), MHz(390), kHz(100), Modulation.AM),
),
),
# Ka-50 # Ka-50
# Note: Also capable of 100MHz-150MHz, but we can't model gaps. # Note: Also capable of 100MHz-150MHz, but we can't model gaps.
Radio("R-800L1", (RadioRange(MHz(220), MHz(400), kHz(25), Modulation.AM),)), Radio("R-800L1", (RadioRange(MHz(220), MHz(400), kHz(25), Modulation.AM),)),

View File

@ -921,6 +921,29 @@ class Settings:
" and reapplied at split/racetrack end for applicable flights. " " and reapplied at split/racetrack end for applicable flights. "
), ),
) )
dynamic_slots: bool = boolean_option(
"Dynamic slots",
MISSION_GENERATOR_PAGE,
GAMEPLAY_SECTION,
default=False,
detail=(
"Enables dynamic slots. Please note that losses from dynamic slots won't be registered."
),
)
dynamic_slots_hot: bool = boolean_option(
"Allow dynamic slot hot start",
MISSION_GENERATOR_PAGE,
GAMEPLAY_SECTION,
default=True,
detail=("Enables hot start for dynamic slots."),
)
dynamic_cargo: bool = boolean_option(
"Dynamic cargo",
MISSION_GENERATOR_PAGE,
GAMEPLAY_SECTION,
default=True,
detail=("Enables dynamic cargo for airfields, ships, FARPs & warehouses."),
)
# Performance # Performance
perf_smoke_gen: bool = boolean_option( perf_smoke_gen: bool = boolean_option(

View File

@ -957,7 +957,6 @@ class A_4E_C(PlaneType):
LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M274__Practice_Smk = ( LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M274__Practice_Smk = (
1, 1,
Weapons.LAU_68___7_x_UnGd_Rkts__70_mm_Hydra_70_M274_TP_SM, Weapons.LAU_68___7_x_UnGd_Rkts__70_mm_Hydra_70_M274_TP_SM,
Weapons.LAU_68___7_x_UnGd_Rkts__70_mm_Hydra_70_M274_TP_SM,
) )
LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_Mk1__Practice = ( LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_Mk1__Practice = (
1, 1,

View File

@ -45,7 +45,7 @@ from game.dcs.aircrafttype import AircraftType
from game.persistency import airwing_dir from game.persistency import airwing_dir
from game.squadrons import AirWing, Pilot, Squadron from game.squadrons import AirWing, Pilot, Squadron
from game.squadrons.squadrondef import SquadronDef from game.squadrons.squadrondef import SquadronDef
from game.theater import ControlPoint, ParkingType from game.theater import ControlPoint, ParkingType, Airfield
from qt_ui.uiconstants import AIRCRAFT_ICONS, ICONS from qt_ui.uiconstants import AIRCRAFT_ICONS, ICONS
from qt_ui.widgets.combos.QSquadronLiverySelector import SquadronLiverySelector from qt_ui.widgets.combos.QSquadronLiverySelector import SquadronLiverySelector
from qt_ui.widgets.combos.primarytaskselector import PrimaryTaskSelector from qt_ui.widgets.combos.primarytaskselector import PrimaryTaskSelector
@ -127,7 +127,9 @@ class SquadronBaseSelector(QComboBox):
self.clear() self.clear()
if aircraft_type: if aircraft_type:
for base in self.bases: for base in self.bases:
if not base.can_operate(aircraft_type): if not base.can_operate(aircraft_type) and not isinstance(
base, Airfield
):
continue continue
self.addItem(base.name, base) self.addItem(base.name, base)
self.model().sort(0) self.model().sort(0)

View File

@ -215,7 +215,11 @@ class SquadronDestinationComboBox(QComboBox):
f"Consider moving these squadrons to different airfield " f"Consider moving these squadrons to different airfield "
"to avoid possible air-starts.", "to avoid possible air-starts.",
) )
return len(ap.free_parking_slots(dcs_unit_type)) return (
len(ap.free_parking_slots(dcs_unit_type))
+ free_helicopter_slots
+ free_ground_spawns
)
else: else:
parking_type = ParkingType().from_aircraft( parking_type = ParkingType().from_aircraft(
next(AircraftType.for_dcs_type(dcs_unit_type)), next(AircraftType.for_dcs_type(dcs_unit_type)),

View File

@ -33,7 +33,7 @@ pluggy==1.5.0
pre-commit==3.7.1 pre-commit==3.7.1
pydantic==2.7.4 pydantic==2.7.4
pydantic-settings==2.3.3 pydantic-settings==2.3.3
pydcs @ git+https://github.com/dcs-retribution/pydcs@800d8fd887a20ecbe811f9c9bde8f1648fea5588 pydcs @ git+https://github.com/dcs-retribution/pydcs@987dadca2faa9e4b7ce10a4c3fcb935b1bc8e91b
pyinstaller==5.13.2 pyinstaller==5.13.2
pyinstaller-hooks-contrib==2024.0 pyinstaller-hooks-contrib==2024.0
pyparsing==3.1.2 pyparsing==3.1.2

Binary file not shown.

View File

@ -1,150 +1,176 @@
--- ---
name: Afghanistan - The Second Afghan War name: Afghanistan - Graveyard of Empires
theater: Afghanistan theater: Afghanistan
authors: Starfire authors: Starfire
recommended_player_faction: Bluefor Modern recommended_player_faction: Bluefor Modern
recommended_enemy_faction: Redfor (Russia) 2010 recommended_enemy_faction: Redfor (Russia) 2010
description: description:
<p>Meow</p> <p>Following the 9/11 attacks, the United States and its NATO allies launched a
miz: second_afghan_war.miz full-scale invasion of Afghanistan to dismantle the Taliban regime and root out
performance: 1 Al-Qaeda. As the conflict progressed, Russia grew increasingly concerned that the
recommended_start_date: 2001-12-17 Western powers were using the War on Terror as a pretext for territorial expansion
version: "10.7" in Central Asia. The Kremlin viewed NATO's growing presence in Afghanistan as a
settings: direct threat to its sphere of influence and a potential encroachment on its
hercules: true southern borders.</p>
squadron_start_full: true <p>Shortly after the fall of Kandahar, which signalled the end of organised Taliban
squadrons: control of Afghanistan, Russia and a coalition of its allies with historical ties
#Kandahar to the Soviet Union decided to intervene under the guise of protecting regional
7: stability and sovereignty. While Russia did not openly ally with the insurgents,
- primary: OCA/Runway it covertly provided logistical support, intelligence, and military aid to
secondary: air-to-ground various anti-NATO factions within Afghanistan as part of a broader strategy to
aircraft: prevent NATO forces from gaining a foothold in the region.</p>
- B-1B Lancer <p>The conflict quickly escalated into a multi-faceted and very costly war. The
size: 4 United States and its allies found themselves not only battling insurgents but
- primary: Strike also facing direct confrontations with increasing numbers of conventional
secondary: air-to-ground Russian forces both in the air and on the ground. The ferocity of the war
aircraft: underscored once more the peril of foreign intervention in this historically
- B-52H Stratofortress unyielding land.</p>
size: 4 miz: graveyard_of_empires.miz
- primary: Transport performance: 1
secondary: any recommended_start_date: 2002-01-27
aircraft: version: "10.7"
- C-130J-30 Super Hercules settings:
- C-130 hercules: true
size: 2 squadron_start_full: true
- primary: Refueling squadrons:
aircraft: #Kandahar
- KC-135 Stratotanker 7:
size: 1 - primary: OCA/Runway
- primary: Refueling secondary: air-to-ground
aircraft: aircraft:
- KC-130J - B-1B Lancer
- KC-130 size: 4
size: 1 - primary: Strike
- primary: AEW&C secondary: air-to-ground
aircraft: aircraft:
- E-3A - B-52H Stratofortress
size: 2 size: 4
- primary: SEAD - primary: Transport
secondary: any secondary: any
aircraft: aircraft:
- F/A-18C Hornet (Lot 20) - C-130J-30 Super Hercules
size: 12 - C-130
- primary: DEAD size: 2
secondary: any - primary: Refueling
aircraft: aircraft:
- F-16CM Fighting Falcon (Block 50) - KC-135 Stratotanker
size: 16 size: 1
- primary: BAI - primary: AEW&C
secondary: any aircraft:
aircraft: - E-3A
- F-15E Strike Eagle (Suite 4+) size: 1
size: 12 - primary: DEAD
- primary: Escort secondary: any
secondary: any aircraft:
aircraft: - F-16CM Fighting Falcon (Block 50)
- F-15C Eagle size: 16
size: 12 - primary: BAI
# Kandahar Heliport secondary: any
15: aircraft:
- primary: Air Assault - F-15E Strike Eagle (Suite 4+)
secondary: any size: 8
aircraft: - primary: Escort
- UH-60A secondary: any
size: 4 aircraft:
- primary: Transport - F-15C Eagle
secondary: any size: 16
aircraft: # Kandahar Heliport
- CH-47D 15:
size: 4 - primary: Air Assault
#Camp Bastion secondary: any
10: aircraft:
- primary: BAI - UH-60A
secondary: air-to-ground size: 4
aircraft: - primary: Transport
- AV-8B Harrier II Night Attack secondary: any
size: 12 aircraft:
- primary: CAS - CH-47D
secondary: air-to-ground size: 4
aircraft: #Camp Bastion
- A-10C Thunderbolt II (Suite 7) 10:
size: 12 - primary: Refueling
#Camp Bastion Heliport aircraft:
13: - KC-130J
- primary: CAS - KC-130
secondary: any size: 1
aircraft: - primary: SEAD
- AH-64D Apache Longbow secondary: any
size: 8 aircraft:
- primary: CAS - F/A-18C Hornet (Lot 20)
secondary: any size: 16
aircraft: - primary: SEAD Escort
- OH-58D(R) Kiowa Warrior secondary: air-to-ground
size: 8 aircraft:
#Shindand - AV-8B Harrier II Night Attack
3: size: 8
- primary: BAI - primary: CAS
secondary: air-to-ground secondary: air-to-ground
aircraft: aircraft:
- Su-25T Frogfoot - A-10C Thunderbolt II (Suite 7)
size: 16 size: 8
- primary: TARCAP #Camp Bastion Heliport
secondary: air-to-air 13:
aircraft: - primary: CAS
- Su-27 Flanker-B secondary: any
size: 12 aircraft:
- primary: SEAD - AH-64D Apache Longbow
secondary: air-to-ground size: 4
aircraft: - primary: CAS
- Su-24M Fencer-D secondary: any
size: 16 aircraft:
#Shindand Heliport - OH-58D(R) Kiowa Warrior
14: size: 4
- primary: Air Assault #Shindand
secondary: any 3:
aircraft: - primary: BAI
- Mi-24P Hind-F secondary: air-to-ground
size: 4 aircraft:
- primary: CAS - Su-25T Frogfoot
secondary: any size: 16
aircraft: - primary: TARCAP
- Ka-50 Hokum III secondary: air-to-air
- Ka-50 Hokum (Blackshark 3) aircraft:
size: 4 - Su-27 Flanker-B
- primary: Transport size: 12
secondary: any - primary: SEAD
aircraft: secondary: air-to-ground
- Mi-8MTV2 Hip aircraft:
size: 4 - Su-24M Fencer-D
#Herat size: 16
1: #Shindand Heliport
- primary: DEAD 14:
secondary: air-to-ground - primary: Air Assault
aircraft: secondary: any
- Su-34 Fullback aircraft:
size: 12 - Mi-24P Hind-F
- primary: Escort size: 4
secondary: air-to-air - primary: Transport
aircraft: secondary: any
- MiG-29S Fulcrum-C aircraft:
size: 12 - Mi-8MTV2 Hip
size: 4
#Herat
1:
- primary: DEAD
secondary: air-to-ground
aircraft:
- Su-34 Fullback
size: 12
- primary: Escort
secondary: air-to-air
aircraft:
- MiG-29S Fulcrum-C
size: 10
- primary: SEAD Escort
secondary: any
aircraft:
- JF-17 Thunder
size: 8
#Farah
2:
- primary: CAS
secondary: any
aircraft:
- Ka-50 Hokum III
- Ka-50 Hokum (Blackshark 3)
size: 4

Binary file not shown.

View File

@ -0,0 +1,76 @@
---
name: Afghanistan - Operation Shattered Dagger
theater: Afghanistan
authors: Starfire
recommended_player_faction: USA 2005
recommended_enemy_faction: Toyota Al Gaib 2001
description:
<p>In the spring of 2006, insurgents initiated a well-coordinated offensive in southern Afghanistan,
focusing their efforts on the strategically vital provinces of Helmand and Kandahar. Insurgent
operations extended beyond small skirmishes, including major assaults on multiple Forward Operating
Bases (FOBs) that were crucial for coalition operations. The loss or isolation of these bases would
have significantly hindered NATO forces' ability to maintain control in the region, severely impacting
the overall stability and security of the region.</p>
<p>With multiple FOBs under siege and cut off from friendly forces, the situation for the coalition
troops became increasingly dire. In response to these attacks, Apache and Kiowa Warrior helicopters were
tasked with providing close air support, targeting insurgent positions, and neutralising enemy forces
surrounding the FOBs. Once cleared of enemy forces, Blackhawk and Chinook helicopters can then deliver
much needed reinforcements and supplies to coalition troops.</p>
miz: operation_shattered_dagger.miz
performance: 1
recommended_start_date: 2006-04-24
recommended_enemy_money: 0
recommended_enemy_income_multiplier: 0.0
version: "10.7"
settings:
hercules: true
squadron_start_full: true
squadrons:
#Kandahar
7:
- primary: Transport
secondary: any
aircraft:
- C-130J-30 Super Hercules
- C-130
size: 4
- primary: CAS
secondary: air-to-ground
aircraft:
- A-10C Thunderbolt II (Suite 7)
size: 4
# Kandahar Heliport
15:
- primary: Air Assault
secondary: any
aircraft:
- UH-60A
size: 4
- primary: CAS
secondary: any
aircraft:
- OH-58D(R) Kiowa Warrior
size: 4
#Camp Bastion
10:
- primary: BAI
secondary: air-to-ground
aircraft:
- AV-8B Harrier II Night Attack
size: 4
- primary: AEW&C
aircraft:
- E-3A
size: 1
#Camp Bastion Heliport
13:
- primary: CAS
secondary: any
aircraft:
- AH-64D Apache Longbow
size: 4
- primary: Transport
secondary: any
aircraft:
- CH-47D
size: 4

View File

@ -26,22 +26,22 @@
"F-15E Strike Eagle (AI)", "F-15E Strike Eagle (AI)",
"F-15E Strike Eagle (Suite 4+)", "F-15E Strike Eagle (Suite 4+)",
"F-16CM Fighting Falcon (Block 50)", "F-16CM Fighting Falcon (Block 50)",
"F-16D Fighting Falcon (Block 52+)", "F-16D Fighting Falcon (Block 52+)",
"F-16D Fighting Falcon (Block 52)", "F-16D Fighting Falcon (Block 52)",
"F-16D Fighting Falcon (Block 50+)", "F-16D Fighting Falcon (Block 50+)",
"F-16D Fighting Falcon (Block 50)", "F-16D Fighting Falcon (Block 50)",
"F-22A Raptor", "F-22A Raptor",
"F/A-18C Hornet (Lot 20)", "F/A-18C Hornet (Lot 20)",
"F/A-18E Super Hornet", "F/A-18E Super Hornet",
"F/A-18F Super Hornet", "F/A-18F Super Hornet",
"EA-6B Prowler", "EA-6B Prowler",
"EA-18G Growler", "EA-18G Growler",
"OH-58D(R) Kiowa Warrior", "OH-58D(R) Kiowa Warrior",
"S-3B Viking", "S-3B Viking",
"SH-60B Seahawk", "SH-60B Seahawk",
"UH-1H Iroquois", "UH-1H Iroquois",
"UH-60A", "UH-60A",
"UH-60L" "UH-60L"
], ],
"awacs": [ "awacs": [
"E-2C Hawkeye", "E-2C Hawkeye",
@ -56,6 +56,8 @@
"F/A-18E Tanker" "F/A-18E Tanker"
], ],
"frontline_units": [ "frontline_units": [
"MBT M1A2C SEP v3 Abrams",
"APC MRAP MaxxPro",
"LAV-25", "LAV-25",
"M1043 HMMWV (M2 HMG)", "M1043 HMMWV (M2 HMG)",
"M1045 HMMWV (BGM-71 TOW)", "M1045 HMMWV (BGM-71 TOW)",
@ -135,4 +137,4 @@
"VMFA-323" "VMFA-323"
] ]
} }
} }

View File

@ -35,7 +35,7 @@ mist = {}
-- don't change these -- don't change these
mist.majorVersion = 4 mist.majorVersion = 4
mist.minorVersion = 5 mist.minorVersion = 5
mist.build = 122 mist.build = 125
-- forward declaration of log shorthand -- forward declaration of log shorthand
local log local log
@ -695,7 +695,6 @@ do -- the main scope
["FARP"] = "farps", ["FARP"] = "farps",
["Fueltank"] = "fueltank_cargo", ["Fueltank"] = "fueltank_cargo",
["Gate"] = "gate", ["Gate"] = "gate",
["FARP Fuel Depot"] = "gsm rus",
["Armed house"] = "home1_a", ["Armed house"] = "home1_a",
["FARP Command Post"] = "kp-ug", ["FARP Command Post"] = "kp-ug",
["Watch Tower Armed"] = "ohr-vyshka", ["Watch Tower Armed"] = "ohr-vyshka",
@ -704,7 +703,6 @@ do -- the main scope
["Pipes big"] = "pipes_big_cargo", ["Pipes big"] = "pipes_big_cargo",
["Oil platform"] = "plavbaza", ["Oil platform"] = "plavbaza",
["Tetrapod"] = "tetrapod_cargo", ["Tetrapod"] = "tetrapod_cargo",
["Fuel tank"] = "toplivo",
["Trunks long"] = "trunks_long_cargo", ["Trunks long"] = "trunks_long_cargo",
["Trunks small"] = "trunks_small_cargo", ["Trunks small"] = "trunks_small_cargo",
["Passenger liner"] = "yastrebow", ["Passenger liner"] = "yastrebow",
@ -1152,6 +1150,7 @@ do -- the main scope
end end
end end
end end
--dbLog:warn(newTable)
--mist.debug.writeData(mist.utils.serialize,{'msg', newTable}, timer.getAbsTime() ..'Group.lua') --mist.debug.writeData(mist.utils.serialize,{'msg', newTable}, timer.getAbsTime() ..'Group.lua')
newTable.timeAdded = timer.getAbsTime() -- only on the dynGroupsAdded table. For other reference, see start time newTable.timeAdded = timer.getAbsTime() -- only on the dynGroupsAdded table. For other reference, see start time
--mist.debug.dumpDBs() --mist.debug.dumpDBs()
@ -1493,7 +1492,7 @@ do -- the main scope
task.t = timer.getTime() + task.rep --schedule next run task.t = timer.getTime() + task.rep --schedule next run
local err, errmsg = pcall(task.f, unpack(task.vars, 1, table.maxn(task.vars))) local err, errmsg = pcall(task.f, unpack(task.vars, 1, table.maxn(task.vars)))
if not err then if not err then
log:error('Error in scheduled function: $1' .. errmsg) log:error('Error in scheduled function: $1', errmsg)
end end
--scheduledTasks[i].f(unpack(scheduledTasks[i].vars, 1, table.maxn(scheduledTasks[i].vars))) -- do the task --scheduledTasks[i].f(unpack(scheduledTasks[i].vars, 1, table.maxn(scheduledTasks[i].vars))) -- do the task
i = i + 1 i = i + 1
@ -1519,7 +1518,7 @@ do -- the main scope
id = tostring(original_id) .. ' #' .. tostring(id_ind) id = tostring(original_id) .. ' #' .. tostring(id_ind)
id_ind = id_ind + 1 id_ind = id_ind + 1
end end
local valid
if mist.DBs.aliveUnits and mist.DBs.aliveUnits[val.object.id_] then if mist.DBs.aliveUnits and mist.DBs.aliveUnits[val.object.id_] then
--log:info('object found in alive_units') --log:info('object found in alive_units')
val.objectData = mist.utils.deepCopy(mist.DBs.aliveUnits[val.object.id_]) val.objectData = mist.utils.deepCopy(mist.DBs.aliveUnits[val.object.id_])
@ -1532,6 +1531,7 @@ do -- the main scope
--trigger.action.outText('remove via death: ' .. Unit.getName(val.object),20) --trigger.action.outText('remove via death: ' .. Unit.getName(val.object),20)
mist.DBs.activeHumans[Unit.getName(val.object)] = nil mist.DBs.activeHumans[Unit.getName(val.object)] = nil
end]] end]]
valid = true
elseif mist.DBs.removedAliveUnits and mist.DBs.removedAliveUnits[val.object.id_] then -- it didn't exist in alive_units, check old_alive_units elseif mist.DBs.removedAliveUnits and mist.DBs.removedAliveUnits[val.object.id_] then -- it didn't exist in alive_units, check old_alive_units
--log:info('object found in old_alive_units') --log:info('object found in old_alive_units')
val.objectData = mist.utils.deepCopy(mist.DBs.removedAliveUnits[val.object.id_]) val.objectData = mist.utils.deepCopy(mist.DBs.removedAliveUnits[val.object.id_])
@ -1540,32 +1540,37 @@ do -- the main scope
val.objectPos = pos.p val.objectPos = pos.p
end end
val.objectType = mist.DBs.removedAliveUnits[val.object.id_].category val.objectType = mist.DBs.removedAliveUnits[val.object.id_].category
valid = true
else --attempt to determine if static object... else --attempt to determine if static object...
--log:info('object not found in alive units or old alive units') --log:info('object not found in alive units or old alive units')
local pos = Object.getPosition(val.object) if Object.isExist(val.object) then
if pos then local pos = Object.getPosition(val.object)
local static_found = false if pos then
for ind, static in pairs(mist.DBs.unitsByCat.static) do local static_found = false
if ((pos.p.x - static.point.x)^2 + (pos.p.z - static.point.y)^2)^0.5 < 0.1 then --really, it should be zero... for ind, static in pairs(mist.DBs.unitsByCat.static) do
--log:info('correlated dead static object to position') if ((pos.p.x - static.point.x)^2 + (pos.p.z - static.point.y)^2)^0.5 < 0.1 then --really, it should be zero...
val.objectData = static --log:info('correlated dead static object to position')
val.objectPos = pos.p val.objectData = static
val.objectType = 'static' val.objectPos = pos.p
static_found = true val.objectType = 'static'
break static_found = true
break
end
end end
if not static_found then
val.objectPos = pos.p
val.objectType = 'building'
val.typeName = Object.getTypeName(val.object)
end
else
val.objectType = 'unknown'
end end
if not static_found then valid = true
val.objectPos = pos.p
val.objectType = 'building'
val.typeName = Object.getTypeName(val.object)
end
else
val.objectType = 'unknown'
end end
end end
mist.DBs.deadObjects[id] = val if valid then
mist.DBs.deadObjects[id] = val
end
end end
end end
end end
@ -2019,7 +2024,7 @@ do -- the main scope
end end
end end
--mist.debug.writeData(mist.utils.serialize,{'msg', newGroup}, 'newGroupPushedToAddGroup.lua') --mist.debug.writeData(mist.utils.serialize,{'msg', newGroup}, newGroup.name ..'.lua')
--log:warn(newGroup) --log:warn(newGroup)
-- sanitize table -- sanitize table
newGroup.groupName = nil newGroup.groupName = nil
@ -3560,7 +3565,7 @@ function mist.getUnitsInMovingZones(unit_names, zone_unit_names, radius, zone_ty
end end
function mist.getUnitsLOS(unitset1, altoffset1, unitset2, altoffset2, radius) function mist.getUnitsLOS(unitset1, altoffset1, unitset2, altoffset2, radius)
log:info("$1, $2, $3, $4, $5", unitset1, altoffset1, unitset2, altoffset2, radius) --log:info("$1, $2, $3, $4, $5", unitset1, altoffset1, unitset2, altoffset2, radius)
radius = radius or math.huge radius = radius or math.huge
local unit_info1 = {} local unit_info1 = {}
local unit_info2 = {} local unit_info2 = {}
@ -3568,21 +3573,25 @@ function mist.getUnitsLOS(unitset1, altoffset1, unitset2, altoffset2, radius)
-- get the positions all in one step, saves execution time. -- get the positions all in one step, saves execution time.
for unitset1_ind = 1, #unitset1 do for unitset1_ind = 1, #unitset1 do
local unit1 = Unit.getByName(unitset1[unitset1_ind]) local unit1 = Unit.getByName(unitset1[unitset1_ind])
local lCat = Object.getCategory(unit1) if unit1 then
if unit1 and ((lCat == 1 and unit1:isActive()) or lCat ~= 1) and unit:isExist() == true then local lCat = Object.getCategory(unit1)
unit_info1[#unit_info1 + 1] = {} if ((lCat == 1 and unit1:isActive()) or lCat ~= 1) and unit1:isExist() == true then
unit_info1[#unit_info1].unit = unit1 unit_info1[#unit_info1 + 1] = {}
unit_info1[#unit_info1].pos = unit1:getPosition().p unit_info1[#unit_info1].unit = unit1
unit_info1[#unit_info1].pos = unit1:getPosition().p
end
end end
end end
for unitset2_ind = 1, #unitset2 do for unitset2_ind = 1, #unitset2 do
local unit2 = Unit.getByName(unitset2[unitset2_ind]) local unit2 = Unit.getByName(unitset2[unitset2_ind])
local lCat = Object.getCategory(unit2) if unit2 then
if unit2 and ((lCat == 1 and unit2:isActive()) or lCat ~= 1) and unit:isExist() == true then local lCat = Object.getCategory(unit2)
unit_info2[#unit_info2 + 1] = {} if ((lCat == 1 and unit2:isActive()) or lCat ~= 1) and unit2:isExist() == true then
unit_info2[#unit_info2].unit = unit2 unit_info2[#unit_info2 + 1] = {}
unit_info2[#unit_info2].pos = unit2:getPosition().p unit_info2[#unit_info2].unit = unit2
unit_info2[#unit_info2].pos = unit2:getPosition().p
end
end end
end end
@ -4012,13 +4021,14 @@ do -- group functions scope
if Group.getByName(gpName) and Group.getByName(gpName):isExist() == true then if Group.getByName(gpName) and Group.getByName(gpName):isExist() == true then
local newGroup = Group.getByName(gpName) local newGroup = Group.getByName(gpName)
local newData = {} local newData = mist.utils.deepCopy(dbData)
newData.name = gpName newData.name = gpName
newData.groupId = tonumber(newGroup:getID()) newData.groupId = tonumber(newGroup:getID())
newData.category = newGroup:getCategory() newData.category = newGroup:getCategory()
newData.groupName = gpName newData.groupName = gpName
newData.hidden = dbData.hidden newData.hidden = dbData.hidden
if newData.category == 2 then if newData.category == 2 then
newData.category = 'vehicle' newData.category = 'vehicle'
elseif newData.category == 3 then elseif newData.category == 3 then
@ -5193,7 +5203,8 @@ do -- mist.util scope
function mist.utils.getHeadingPoints(point1, point2, north) -- sick of writing this out. function mist.utils.getHeadingPoints(point1, point2, north) -- sick of writing this out.
if north then if north then
return mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3(point2), mist.utils.makeVec3(point1)), (mist.utils.makeVec3(point1))) local p1 = mist.utils.get3DDist(point1)
return mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3(point2), p1), p1)
else else
return mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3(point2), mist.utils.makeVec3(point1))) return mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3(point2), mist.utils.makeVec3(point1)))
end end
@ -5837,8 +5848,8 @@ do -- mist.debug scope
log:alert('insufficient libraries to run mist.debug.dump_G, you must disable the sanitization of the io and lfs libraries in ./Scripts/MissionScripting.lua') log:alert('insufficient libraries to run mist.debug.dump_G, you must disable the sanitization of the io and lfs libraries in ./Scripts/MissionScripting.lua')
--trigger.action.outText(errmsg, 10) --trigger.action.outText(errmsg, 10)
end end
end
end
--- Write debug data to file. --- Write debug data to file.
-- This function requires you to disable script sanitization -- This function requires you to disable script sanitization
-- in $DCS_ROOT\Scripts\MissionScripting.lua to access lfs and io -- in $DCS_ROOT\Scripts\MissionScripting.lua to access lfs and io
@ -7653,7 +7664,10 @@ do
--log:warn(s) --log:warn(s)
if type(s) == 'table' then if type(s) == 'table' then
local mType = s.markType local mType = s.markType
if mType == 'panel' then --log:echo(s)
if mType == 'panel' then
local markScope = s.markScope or "all"
if markScope == 'coa' then if markScope == 'coa' then
trigger.action.markToCoalition(s.markId, s.text, s.pos, s.markFor, s.readOnly) trigger.action.markToCoalition(s.markId, s.text, s.pos, s.markFor, s.readOnly)
elseif markScope == 'group' then elseif markScope == 'group' then
@ -7711,10 +7725,15 @@ do
local function validateColor(val) local function validateColor(val)
if type(val) == 'table' then if type(val) == 'table' then
for i = 1, #val do for i = 1, 4 do
if type(val[i]) == 'number' and val[i] > 1 then if val[i] then
val[i] = val[i]/255 -- convert RGB values from 0-255 to 0-1 equivilent. if type(val[i]) == 'number' and val[i] > 1 then
end val[i] = val[i]/255 -- convert RGB values from 0-255 to 0-1 equivilent.
end
else
val[i] = 0.8
log:warn("index $1 of color to mist.marker.add was missing, defaulted to 0.8", i)
end
end end
elseif type(val) == 'string' then elseif type(val) == 'string' then
val = mist.utils.hexToRGB(val) val = mist.utils.hexToRGB(val)
@ -7755,7 +7774,7 @@ do
--log:info('create maker DB: $1', e.idx) --log:info('create maker DB: $1', e.idx)
mist.DBs.markList[e.idx] = {time = e.time, pos = e.pos, groupId = e.groupId, mType = 'panel', text = e.text, markId = e.idx, coalition = e.coalition} mist.DBs.markList[e.idx] = {time = e.time, pos = e.pos, groupId = e.groupId, mType = 'panel', text = e.text, markId = e.idx, coalition = e.coalition}
if e.unit then if e.unit then
mist.DBs.markList[e.idx].unit = e.intiator:getName() mist.DBs.markList[e.idx].unit = e.initiator:getName()
end end
--log:info(mist.marker.list[e.idx]) --log:info(mist.marker.list[e.idx])
end end
@ -7778,7 +7797,7 @@ do
else else
for mEntry, mData in pairs(mist.DBs.markList) do for mEntry, mData in pairs(mist.DBs.markList) do
if id == mData.name or id == mData.id then if id == mData.name or id == mData.id then
return mData.id return mData.markId
end end
end end
end end
@ -7788,11 +7807,16 @@ do
local function removeMark(id) local function removeMark(id)
--log:info("Removing Mark: $1", id --log:info("Removing Mark: $1", id)
local removed = false local removed = false
if type(id) == 'table' then if type(id) == 'table' then
for ind, val in pairs(id) do for ind, val in pairs(id) do
local r = getMarkId(val) local r
if val.markId then
r = val.markId
else
r = getMarkId(val)
end
if r then if r then
trigger.action.removeMark(r) trigger.action.removeMark(r)
mist.DBs.markList[r] = nil mist.DBs.markList[r] = nil
@ -7802,9 +7826,11 @@ do
else else
local r = getMarkId(id) local r = getMarkId(id)
trigger.action.removeMark(r) if r then
mist.DBs.markList[r] = nil trigger.action.removeMark(r)
removed = true mist.DBs.markList[r] = nil
removed = true
end
end end
return removed return removed
end end
@ -7926,6 +7952,7 @@ do
if markForCoa then if markForCoa then
if type(markForCoa) == 'string' then if type(markForCoa) == 'string' then
--log:warn("coa is string")
if tonumber(markForCoa) then if tonumber(markForCoa) then
coa = coas[tonumber(markForCoa)] coa = coas[tonumber(markForCoa)]
markScope = 'coa' markScope = 'coa'
@ -7940,11 +7967,10 @@ do
end end
elseif type(markForCoa) == 'number' and markForCoa >=-1 and markForCoa <= #coas then elseif type(markForCoa) == 'number' and markForCoa >=-1 and markForCoa <= #coas then
coa = markForCoa coa = markForCoa
markScore = 'coa' --log:warn("coa is number")
markScope = 'coa'
end end
markFor = coa
elseif markFor then elseif markFor then
if type(markFor) == 'number' then -- groupId if type(markFor) == 'number' then -- groupId
if mist.DBs.groupsById[markFor] then if mist.DBs.groupsById[markFor] then
@ -8053,7 +8079,7 @@ do
end end
for i = 1, #markForTable do for i = 1, #markForTable do
local newId = iterate() local newId = iterate()
local data = {markId = newId, text = text, pos = pos[i], markFor = markForTable[i], markType = 'panel', name = name, readOnly = readOnly, time = timer.getTime()} local data = {markId = newId, text = text, pos = pos[i], markScope = markScope, markFor = markForTable[i], markType = 'panel', name = name, readOnly = readOnly, time = timer.getTime()}
mist.DBs.markList[newId] = data mist.DBs.markList[newId] = data
table.insert(list, data) table.insert(list, data)
@ -8177,6 +8203,7 @@ do
end end
function mist.marker.remove(id) function mist.marker.remove(id)
return removeMark(id) return removeMark(id)
end end
@ -8967,8 +8994,8 @@ do -- group tasks scope
minR = mist.utils.get2DDist(avg, zone[i]) minR = mist.utils.get2DDist(avg, zone[i])
end end
end end
--log:warn('Radius: $1', radius)
--log:warn('minR: $1', minR) --log:warn('minR: $1', minR)
--log:warn('Radius: $1', radius)
local lSpawnPos = {} local lSpawnPos = {}
for j = 1, 100 do for j = 1, 100 do
newCoord = mist.getRandPointInCircle(avg, radius) newCoord = mist.getRandPointInCircle(avg, radius)
@ -9200,7 +9227,7 @@ do -- group tasks scope
function mist.groupIsDead(groupName) -- copy more or less from on station function mist.groupIsDead(groupName) -- copy more or less from on station
local gp = Group.getByName(groupName) local gp = Group.getByName(groupName)
if gp then if gp then
if #gp:getUnits() > 0 or gp:isExist() == true then if #gp:getUnits() > 0 and gp:isExist() == true then
return false return false
end end
end end
@ -9503,4 +9530,4 @@ end
mist.init() mist.init()
env.info(('Mist version ' .. mist.majorVersion .. '.' .. mist.minorVersion .. '.' .. mist.build .. ' loaded.')) env.info(('Mist version ' .. mist.majorVersion .. '.' .. mist.minorVersion .. '.' .. mist.build .. ' loaded.'))
-- vim: noet:ts=2:sw=2 -- vim: noet:ts=2:sw=2

View File

@ -5,7 +5,7 @@
"specificOptions": [], "specificOptions": [],
"scriptsWorkOrders": [ "scriptsWorkOrders": [
{ {
"file": "mist_4_5_122.lua", "file": "mist_4_5_126.lua",
"mnemonic": "mist" "mnemonic": "mist"
}, },
{ {

View File

@ -20,8 +20,8 @@ variants:
origin: China origin: China
MiG-21bis Fishbed-N: {} MiG-21bis Fishbed-N: {}
radios: radios:
intra_flight: RSIU-5V intra_flight: R-832
inter_flight: RSIU-5V inter_flight: R-832
channels: channels:
type: common type: common
namer: single namer: single