diff --git a/game/ato/flightplans/waypointbuilder.py b/game/ato/flightplans/waypointbuilder.py index a9be6ee5..74b1bc8d 100644 --- a/game/ato/flightplans/waypointbuilder.py +++ b/game/ato/flightplans/waypointbuilder.py @@ -24,13 +24,13 @@ from game.theater import ( TheaterGroundObject, TheaterUnit, ) +from game.theater.theatergroup import TheaterGroup from game.utils import Distance, meters, nautical_miles, feet AGL_TRANSITION_ALT = 5000 if TYPE_CHECKING: from game.transfers import MultiGroupTransport - from game.theater.theatergroup import TheaterGroup from game.ato.flight import Flight @@ -323,7 +323,9 @@ class WaypointBuilder: return FlightWaypoint( target.name, FlightWaypointType.TARGET_POINT, - target.target.position, + target.target.ground_object.position + if isinstance(target.target, (TheaterGroup, TheaterUnit)) + else target.target.position, meters(0), "RADIO", description=description, diff --git a/game/missiongenerator/missiongenerator.py b/game/missiongenerator/missiongenerator.py index ce13a695..3426d8bc 100644 --- a/game/missiongenerator/missiongenerator.py +++ b/game/missiongenerator/missiongenerator.py @@ -10,6 +10,8 @@ from dcs import Mission, Point from dcs.coalition import Coalition from dcs.countries import country_dict from dcs.task import OptReactOnThreat +from dcs.terrain import Airport +from dcs.unit import Static from game.atcdata import AtcData from game.dcs.beacons import Beacons @@ -112,8 +114,8 @@ class MissionGenerator: self.notify_info_generators() - # TODO: Shouldn't this be first? namegen.reset_numbers() + self.generate_warehouses() self.mission.save(output) return self.unit_map @@ -347,3 +349,33 @@ class MissionGenerator: self.mission.groundControl.blue_tactical_commander = commanders self.mission.groundControl.blue_jtac = settings.jtac_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 diff --git a/game/missiongenerator/tgogenerator.py b/game/missiongenerator/tgogenerator.py index f2863459..993d84ab 100644 --- a/game/missiongenerator/tgogenerator.py +++ b/game/missiongenerator/tgogenerator.py @@ -38,6 +38,7 @@ from dcs.task import ( FireAtPoint, OptAlarmState, ) +from dcs.terrain import Airport from dcs.translation import String from dcs.triggers import ( Event, @@ -859,6 +860,14 @@ class HelipadGenerator: cull_farp_statics = False 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 self.m.static_group( country=country, @@ -1095,6 +1104,14 @@ class GroundSpawnLargeGenerator: 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 if self.game.settings.ground_start_trucks: self.m.vehicle_group( @@ -1231,6 +1248,14 @@ class GroundSpawnGenerator: cull_farp_statics = False 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 if self.game.settings.ground_start_trucks: self.m.vehicle_group( diff --git a/game/radio/radios.py b/game/radio/radios.py index d2cb3eea..2cab104f 100644 --- a/game/radio/radios.py +++ b/game/radio/radios.py @@ -238,7 +238,13 @@ RADIOS: List[Radio] = [ # MiG-19P Radio("RSIU-4V", (RadioRange(MHz(100), MHz(150), kHz(25), Modulation.AM),)), # 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 # Note: Also capable of 100MHz-150MHz, but we can't model gaps. Radio("R-800L1", (RadioRange(MHz(220), MHz(400), kHz(25), Modulation.AM),)), diff --git a/game/settings/settings.py b/game/settings/settings.py index 3e3f3724..63abc052 100644 --- a/game/settings/settings.py +++ b/game/settings/settings.py @@ -921,6 +921,29 @@ class Settings: " 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 perf_smoke_gen: bool = boolean_option( diff --git a/pydcs_extensions/a4ec/a4ec.py b/pydcs_extensions/a4ec/a4ec.py index 515eff43..c855ce87 100644 --- a/pydcs_extensions/a4ec/a4ec.py +++ b/pydcs_extensions/a4ec/a4ec.py @@ -957,7 +957,6 @@ class A_4E_C(PlaneType): LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_M274__Practice_Smk = ( 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, ) LAU_68_pod___7_x_2_75_Hydra__UnGd_Rkts_Mk1__Practice = ( 1, diff --git a/qt_ui/windows/AirWingConfigurationDialog.py b/qt_ui/windows/AirWingConfigurationDialog.py index 9765fea4..9f2b9dc1 100644 --- a/qt_ui/windows/AirWingConfigurationDialog.py +++ b/qt_ui/windows/AirWingConfigurationDialog.py @@ -45,7 +45,7 @@ from game.dcs.aircrafttype import AircraftType from game.persistency import airwing_dir from game.squadrons import AirWing, Pilot, Squadron 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.widgets.combos.QSquadronLiverySelector import SquadronLiverySelector from qt_ui.widgets.combos.primarytaskselector import PrimaryTaskSelector @@ -127,7 +127,9 @@ class SquadronBaseSelector(QComboBox): self.clear() if aircraft_type: 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 self.addItem(base.name, base) self.model().sort(0) diff --git a/qt_ui/windows/SquadronDialog.py b/qt_ui/windows/SquadronDialog.py index 98a25f6d..98ac5b40 100644 --- a/qt_ui/windows/SquadronDialog.py +++ b/qt_ui/windows/SquadronDialog.py @@ -215,7 +215,11 @@ class SquadronDestinationComboBox(QComboBox): f"Consider moving these squadrons to different airfield " "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: parking_type = ParkingType().from_aircraft( next(AircraftType.for_dcs_type(dcs_unit_type)), diff --git a/requirements.txt b/requirements.txt index 56de0454..537895b0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ pluggy==1.5.0 pre-commit==3.7.1 pydantic==2.7.4 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-hooks-contrib==2024.0 pyparsing==3.1.2 diff --git a/resources/campaigns/graveyard_of_empires.miz b/resources/campaigns/graveyard_of_empires.miz new file mode 100644 index 00000000..5b20713e Binary files /dev/null and b/resources/campaigns/graveyard_of_empires.miz differ diff --git a/resources/campaigns/second_afghan_war.yaml b/resources/campaigns/graveyard_of_empires.yaml similarity index 57% rename from resources/campaigns/second_afghan_war.yaml rename to resources/campaigns/graveyard_of_empires.yaml index 6e24d827..7a9ebad9 100644 --- a/resources/campaigns/second_afghan_war.yaml +++ b/resources/campaigns/graveyard_of_empires.yaml @@ -1,150 +1,176 @@ ---- -name: Afghanistan - The Second Afghan War -theater: Afghanistan -authors: Starfire -recommended_player_faction: Bluefor Modern -recommended_enemy_faction: Redfor (Russia) 2010 -description: -
Meow
-miz: second_afghan_war.miz -performance: 1 -recommended_start_date: 2001-12-17 -version: "10.7" -settings: - hercules: true - squadron_start_full: true -squadrons: - #Kandahar - 7: - - primary: OCA/Runway - secondary: air-to-ground - aircraft: - - B-1B Lancer - size: 4 - - primary: Strike - secondary: air-to-ground - aircraft: - - B-52H Stratofortress - size: 4 - - primary: Transport - secondary: any - aircraft: - - C-130J-30 Super Hercules - - C-130 - size: 2 - - primary: Refueling - aircraft: - - KC-135 Stratotanker - size: 1 - - primary: Refueling - aircraft: - - KC-130J - - KC-130 - size: 1 - - primary: AEW&C - aircraft: - - E-3A - size: 2 - - primary: SEAD - secondary: any - aircraft: - - F/A-18C Hornet (Lot 20) - size: 12 - - primary: DEAD - secondary: any - aircraft: - - F-16CM Fighting Falcon (Block 50) - size: 16 - - primary: BAI - secondary: any - aircraft: - - F-15E Strike Eagle (Suite 4+) - size: 12 - - primary: Escort - secondary: any - aircraft: - - F-15C Eagle - size: 12 - # Kandahar Heliport - 15: - - primary: Air Assault - secondary: any - aircraft: - - UH-60A - size: 4 - - primary: Transport - secondary: any - aircraft: - - CH-47D - size: 4 - #Camp Bastion - 10: - - primary: BAI - secondary: air-to-ground - aircraft: - - AV-8B Harrier II Night Attack - size: 12 - - primary: CAS - secondary: air-to-ground - aircraft: - - A-10C Thunderbolt II (Suite 7) - size: 12 - #Camp Bastion Heliport - 13: - - primary: CAS - secondary: any - aircraft: - - AH-64D Apache Longbow - size: 8 - - primary: CAS - secondary: any - aircraft: - - OH-58D(R) Kiowa Warrior - size: 8 - #Shindand - 3: - - primary: BAI - secondary: air-to-ground - aircraft: - - Su-25T Frogfoot - size: 16 - - primary: TARCAP - secondary: air-to-air - aircraft: - - Su-27 Flanker-B - size: 12 - - primary: SEAD - secondary: air-to-ground - aircraft: - - Su-24M Fencer-D - size: 16 - #Shindand Heliport - 14: - - primary: Air Assault - secondary: any - aircraft: - - Mi-24P Hind-F - size: 4 - - primary: CAS - secondary: any - aircraft: - - Ka-50 Hokum III - - Ka-50 Hokum (Blackshark 3) - size: 4 - - primary: Transport - secondary: any - aircraft: - - 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: 12 \ No newline at end of file +--- +name: Afghanistan - Graveyard of Empires +theater: Afghanistan +authors: Starfire +recommended_player_faction: Bluefor Modern +recommended_enemy_faction: Redfor (Russia) 2010 +description: +Following the 9/11 attacks, the United States and its NATO allies launched a + full-scale invasion of Afghanistan to dismantle the Taliban regime and root out + Al-Qaeda. As the conflict progressed, Russia grew increasingly concerned that the + Western powers were using the War on Terror as a pretext for territorial expansion + in Central Asia. The Kremlin viewed NATO's growing presence in Afghanistan as a + direct threat to its sphere of influence and a potential encroachment on its + southern borders.
+Shortly after the fall of Kandahar, which signalled the end of organised Taliban + control of Afghanistan, Russia and a coalition of its allies with historical ties + to the Soviet Union decided to intervene under the guise of protecting regional + stability and sovereignty. While Russia did not openly ally with the insurgents, + it covertly provided logistical support, intelligence, and military aid to + various anti-NATO factions within Afghanistan as part of a broader strategy to + prevent NATO forces from gaining a foothold in the region.
+The conflict quickly escalated into a multi-faceted and very costly war. The + United States and its allies found themselves not only battling insurgents but + also facing direct confrontations with increasing numbers of conventional + Russian forces both in the air and on the ground. The ferocity of the war + underscored once more the peril of foreign intervention in this historically + unyielding land.
+miz: graveyard_of_empires.miz +performance: 1 +recommended_start_date: 2002-01-27 +version: "10.7" +settings: + hercules: true + squadron_start_full: true +squadrons: + #Kandahar + 7: + - primary: OCA/Runway + secondary: air-to-ground + aircraft: + - B-1B Lancer + size: 4 + - primary: Strike + secondary: air-to-ground + aircraft: + - B-52H Stratofortress + size: 4 + - primary: Transport + secondary: any + aircraft: + - C-130J-30 Super Hercules + - C-130 + size: 2 + - primary: Refueling + aircraft: + - KC-135 Stratotanker + size: 1 + - primary: AEW&C + aircraft: + - E-3A + size: 1 + - primary: DEAD + secondary: any + aircraft: + - F-16CM Fighting Falcon (Block 50) + size: 16 + - primary: BAI + secondary: any + aircraft: + - F-15E Strike Eagle (Suite 4+) + size: 8 + - primary: Escort + secondary: any + aircraft: + - F-15C Eagle + size: 16 + # Kandahar Heliport + 15: + - primary: Air Assault + secondary: any + aircraft: + - UH-60A + size: 4 + - primary: Transport + secondary: any + aircraft: + - CH-47D + size: 4 + #Camp Bastion + 10: + - primary: Refueling + aircraft: + - KC-130J + - KC-130 + size: 1 + - primary: SEAD + secondary: any + aircraft: + - F/A-18C Hornet (Lot 20) + size: 16 + - primary: SEAD Escort + secondary: air-to-ground + aircraft: + - AV-8B Harrier II Night Attack + size: 8 + - primary: CAS + secondary: air-to-ground + aircraft: + - A-10C Thunderbolt II (Suite 7) + size: 8 + #Camp Bastion Heliport + 13: + - primary: CAS + secondary: any + aircraft: + - AH-64D Apache Longbow + size: 4 + - primary: CAS + secondary: any + aircraft: + - OH-58D(R) Kiowa Warrior + size: 4 + #Shindand + 3: + - primary: BAI + secondary: air-to-ground + aircraft: + - Su-25T Frogfoot + size: 16 + - primary: TARCAP + secondary: air-to-air + aircraft: + - Su-27 Flanker-B + size: 12 + - primary: SEAD + secondary: air-to-ground + aircraft: + - Su-24M Fencer-D + size: 16 + #Shindand Heliport + 14: + - primary: Air Assault + secondary: any + aircraft: + - Mi-24P Hind-F + size: 4 + - primary: Transport + secondary: any + aircraft: + - 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 \ No newline at end of file diff --git a/resources/campaigns/operation_shattered_dagger.miz b/resources/campaigns/operation_shattered_dagger.miz new file mode 100644 index 00000000..7728f37c Binary files /dev/null and b/resources/campaigns/operation_shattered_dagger.miz differ diff --git a/resources/campaigns/operation_shattered_dagger.yaml b/resources/campaigns/operation_shattered_dagger.yaml new file mode 100644 index 00000000..2511e2e9 --- /dev/null +++ b/resources/campaigns/operation_shattered_dagger.yaml @@ -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: +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.
+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.
+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 \ No newline at end of file diff --git a/resources/campaigns/second_afghan_war.miz b/resources/campaigns/second_afghan_war.miz deleted file mode 100644 index 2195d5de..00000000 Binary files a/resources/campaigns/second_afghan_war.miz and /dev/null differ diff --git a/resources/factions/usa_2005.json b/resources/factions/usa_2005.json index cd0a3a19..138aee94 100644 --- a/resources/factions/usa_2005.json +++ b/resources/factions/usa_2005.json @@ -26,22 +26,22 @@ "F-15E Strike Eagle (AI)", "F-15E Strike Eagle (Suite 4+)", "F-16CM Fighting Falcon (Block 50)", - "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 52+)", + "F-16D Fighting Falcon (Block 52)", + "F-16D Fighting Falcon (Block 50+)", + "F-16D Fighting Falcon (Block 50)", "F-22A Raptor", "F/A-18C Hornet (Lot 20)", - "F/A-18E Super Hornet", - "F/A-18F Super Hornet", + "F/A-18E Super Hornet", + "F/A-18F Super Hornet", "EA-6B Prowler", - "EA-18G Growler", + "EA-18G Growler", "OH-58D(R) Kiowa Warrior", "S-3B Viking", "SH-60B Seahawk", "UH-1H Iroquois", - "UH-60A", - "UH-60L" + "UH-60A", + "UH-60L" ], "awacs": [ "E-2C Hawkeye", @@ -56,6 +56,8 @@ "F/A-18E Tanker" ], "frontline_units": [ + "MBT M1A2C SEP v3 Abrams", + "APC MRAP MaxxPro", "LAV-25", "M1043 HMMWV (M2 HMG)", "M1045 HMMWV (BGM-71 TOW)", @@ -135,4 +137,4 @@ "VMFA-323" ] } -} \ No newline at end of file +} diff --git a/resources/plugins/base/mist_4_5_122.lua b/resources/plugins/base/mist_4_5_126.lua similarity index 99% rename from resources/plugins/base/mist_4_5_122.lua rename to resources/plugins/base/mist_4_5_126.lua index 97b656fb..e7730782 100644 --- a/resources/plugins/base/mist_4_5_122.lua +++ b/resources/plugins/base/mist_4_5_126.lua @@ -35,7 +35,7 @@ mist = {} -- don't change these mist.majorVersion = 4 mist.minorVersion = 5 -mist.build = 122 +mist.build = 125 -- forward declaration of log shorthand local log @@ -695,7 +695,6 @@ do -- the main scope ["FARP"] = "farps", ["Fueltank"] = "fueltank_cargo", ["Gate"] = "gate", - ["FARP Fuel Depot"] = "gsm rus", ["Armed house"] = "home1_a", ["FARP Command Post"] = "kp-ug", ["Watch Tower Armed"] = "ohr-vyshka", @@ -704,7 +703,6 @@ do -- the main scope ["Pipes big"] = "pipes_big_cargo", ["Oil platform"] = "plavbaza", ["Tetrapod"] = "tetrapod_cargo", - ["Fuel tank"] = "toplivo", ["Trunks long"] = "trunks_long_cargo", ["Trunks small"] = "trunks_small_cargo", ["Passenger liner"] = "yastrebow", @@ -1152,6 +1150,7 @@ do -- the main scope end end end + --dbLog:warn(newTable) --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 --mist.debug.dumpDBs() @@ -1493,7 +1492,7 @@ do -- the main scope task.t = timer.getTime() + task.rep --schedule next run local err, errmsg = pcall(task.f, unpack(task.vars, 1, table.maxn(task.vars))) if not err then - log:error('Error in scheduled function: $1' .. errmsg) + log:error('Error in scheduled function: $1', errmsg) end --scheduledTasks[i].f(unpack(scheduledTasks[i].vars, 1, table.maxn(scheduledTasks[i].vars))) -- do the task i = i + 1 @@ -1519,7 +1518,7 @@ do -- the main scope id = tostring(original_id) .. ' #' .. tostring(id_ind) id_ind = id_ind + 1 end - + local valid if mist.DBs.aliveUnits and mist.DBs.aliveUnits[val.object.id_] then --log:info('object found in alive_units') 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) mist.DBs.activeHumans[Unit.getName(val.object)] = nil 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 --log:info('object found in old_alive_units') val.objectData = mist.utils.deepCopy(mist.DBs.removedAliveUnits[val.object.id_]) @@ -1540,32 +1540,37 @@ do -- the main scope val.objectPos = pos.p end val.objectType = mist.DBs.removedAliveUnits[val.object.id_].category - + valid = true else --attempt to determine if static object... --log:info('object not found in alive units or old alive units') - local pos = Object.getPosition(val.object) - if pos then - local static_found = false - for ind, static in pairs(mist.DBs.unitsByCat.static) do - 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... - --log:info('correlated dead static object to position') - val.objectData = static - val.objectPos = pos.p - val.objectType = 'static' - static_found = true - break + if Object.isExist(val.object) then + local pos = Object.getPosition(val.object) + if pos then + local static_found = false + for ind, static in pairs(mist.DBs.unitsByCat.static) do + 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... + --log:info('correlated dead static object to position') + val.objectData = static + val.objectPos = pos.p + val.objectType = 'static' + static_found = true + break + 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 - if not static_found then - val.objectPos = pos.p - val.objectType = 'building' - val.typeName = Object.getTypeName(val.object) - end - else - val.objectType = 'unknown' + valid = true end end - mist.DBs.deadObjects[id] = val + if valid then + mist.DBs.deadObjects[id] = val + end end end end @@ -2019,7 +2024,7 @@ do -- the main scope 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) -- sanitize table newGroup.groupName = nil @@ -3560,7 +3565,7 @@ function mist.getUnitsInMovingZones(unit_names, zone_unit_names, radius, zone_ty end 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 local unit_info1 = {} 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. for unitset1_ind = 1, #unitset1 do local unit1 = Unit.getByName(unitset1[unitset1_ind]) - local lCat = Object.getCategory(unit1) - if unit1 and ((lCat == 1 and unit1:isActive()) or lCat ~= 1) and unit:isExist() == true then - unit_info1[#unit_info1 + 1] = {} - unit_info1[#unit_info1].unit = unit1 - unit_info1[#unit_info1].pos = unit1:getPosition().p + if unit1 then + local lCat = Object.getCategory(unit1) + if ((lCat == 1 and unit1:isActive()) or lCat ~= 1) and unit1:isExist() == true then + unit_info1[#unit_info1 + 1] = {} + unit_info1[#unit_info1].unit = unit1 + unit_info1[#unit_info1].pos = unit1:getPosition().p + end end end for unitset2_ind = 1, #unitset2 do local unit2 = Unit.getByName(unitset2[unitset2_ind]) - local lCat = Object.getCategory(unit2) - if unit2 and ((lCat == 1 and unit2:isActive()) or lCat ~= 1) and unit:isExist() == true then - unit_info2[#unit_info2 + 1] = {} - unit_info2[#unit_info2].unit = unit2 - unit_info2[#unit_info2].pos = unit2:getPosition().p + if unit2 then + local lCat = Object.getCategory(unit2) + if ((lCat == 1 and unit2:isActive()) or lCat ~= 1) and unit2:isExist() == true then + unit_info2[#unit_info2 + 1] = {} + unit_info2[#unit_info2].unit = unit2 + unit_info2[#unit_info2].pos = unit2:getPosition().p + end end end @@ -4012,13 +4021,14 @@ do -- group functions scope if Group.getByName(gpName) and Group.getByName(gpName):isExist() == true then local newGroup = Group.getByName(gpName) - local newData = {} + local newData = mist.utils.deepCopy(dbData) newData.name = gpName newData.groupId = tonumber(newGroup:getID()) newData.category = newGroup:getCategory() newData.groupName = gpName newData.hidden = dbData.hidden - + + if newData.category == 2 then newData.category = 'vehicle' 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. 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 return mist.utils.getDir(mist.vec.sub(mist.utils.makeVec3(point2), mist.utils.makeVec3(point1))) 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') --trigger.action.outText(errmsg, 10) end - end + end --- Write debug data to file. -- This function requires you to disable script sanitization -- in $DCS_ROOT\Scripts\MissionScripting.lua to access lfs and io @@ -7653,7 +7664,10 @@ do --log:warn(s) if type(s) == 'table' then 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 trigger.action.markToCoalition(s.markId, s.text, s.pos, s.markFor, s.readOnly) elseif markScope == 'group' then @@ -7711,10 +7725,15 @@ do local function validateColor(val) if type(val) == 'table' then - for i = 1, #val do - if type(val[i]) == 'number' and val[i] > 1 then - val[i] = val[i]/255 -- convert RGB values from 0-255 to 0-1 equivilent. - end + for i = 1, 4 do + if val[i] then + if type(val[i]) == 'number' and val[i] > 1 then + 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 elseif type(val) == 'string' then val = mist.utils.hexToRGB(val) @@ -7755,7 +7774,7 @@ do --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} if e.unit then - mist.DBs.markList[e.idx].unit = e.intiator:getName() + mist.DBs.markList[e.idx].unit = e.initiator:getName() end --log:info(mist.marker.list[e.idx]) end @@ -7778,7 +7797,7 @@ do else for mEntry, mData in pairs(mist.DBs.markList) do if id == mData.name or id == mData.id then - return mData.id + return mData.markId end end end @@ -7788,11 +7807,16 @@ do local function removeMark(id) - --log:info("Removing Mark: $1", id + --log:info("Removing Mark: $1", id) local removed = false if type(id) == 'table' then 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 trigger.action.removeMark(r) mist.DBs.markList[r] = nil @@ -7802,9 +7826,11 @@ do else local r = getMarkId(id) - trigger.action.removeMark(r) - mist.DBs.markList[r] = nil - removed = true + if r then + trigger.action.removeMark(r) + mist.DBs.markList[r] = nil + removed = true + end end return removed end @@ -7926,6 +7952,7 @@ do if markForCoa then if type(markForCoa) == 'string' then + --log:warn("coa is string") if tonumber(markForCoa) then coa = coas[tonumber(markForCoa)] markScope = 'coa' @@ -7940,11 +7967,10 @@ do end elseif type(markForCoa) == 'number' and markForCoa >=-1 and markForCoa <= #coas then coa = markForCoa - markScore = 'coa' + --log:warn("coa is number") + markScope = 'coa' end - - - + markFor = coa elseif markFor then if type(markFor) == 'number' then -- groupId if mist.DBs.groupsById[markFor] then @@ -8053,7 +8079,7 @@ do end for i = 1, #markForTable do 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 table.insert(list, data) @@ -8177,6 +8203,7 @@ do end function mist.marker.remove(id) + return removeMark(id) end @@ -8967,8 +8994,8 @@ do -- group tasks scope minR = mist.utils.get2DDist(avg, zone[i]) end end - --log:warn('Radius: $1', radius) --log:warn('minR: $1', minR) + --log:warn('Radius: $1', radius) local lSpawnPos = {} for j = 1, 100 do newCoord = mist.getRandPointInCircle(avg, radius) @@ -9200,7 +9227,7 @@ do -- group tasks scope function mist.groupIsDead(groupName) -- copy more or less from on station local gp = Group.getByName(groupName) if gp then - if #gp:getUnits() > 0 or gp:isExist() == true then + if #gp:getUnits() > 0 and gp:isExist() == true then return false end end @@ -9503,4 +9530,4 @@ end mist.init() env.info(('Mist version ' .. mist.majorVersion .. '.' .. mist.minorVersion .. '.' .. mist.build .. ' loaded.')) --- vim: noet:ts=2:sw=2 +-- vim: noet:ts=2:sw=2 \ No newline at end of file diff --git a/resources/plugins/base/plugin.json b/resources/plugins/base/plugin.json index ebb93361..ae42f463 100644 --- a/resources/plugins/base/plugin.json +++ b/resources/plugins/base/plugin.json @@ -5,7 +5,7 @@ "specificOptions": [], "scriptsWorkOrders": [ { - "file": "mist_4_5_122.lua", + "file": "mist_4_5_126.lua", "mnemonic": "mist" }, { diff --git a/resources/units/aircraft/MiG-21Bis.yaml b/resources/units/aircraft/MiG-21Bis.yaml index 46cf6e3d..2ec9eb4c 100644 --- a/resources/units/aircraft/MiG-21Bis.yaml +++ b/resources/units/aircraft/MiG-21Bis.yaml @@ -20,8 +20,8 @@ variants: origin: China MiG-21bis Fishbed-N: {} radios: - intra_flight: RSIU-5V - inter_flight: RSIU-5V + intra_flight: R-832 + inter_flight: R-832 channels: type: common namer: single