From b422fcc1153068bebcf4a7009411a5120a8f0d9e Mon Sep 17 00:00:00 2001 From: weyne Date: Wed, 15 Jul 2026 15:10:35 +0000 Subject: [PATCH] Dateien nach "Scripts" hochladen --- Scripts/A10_laste_Winds.lua | 204 ++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 Scripts/A10_laste_Winds.lua diff --git a/Scripts/A10_laste_Winds.lua b/Scripts/A10_laste_Winds.lua new file mode 100644 index 0000000..bdc5ad2 --- /dev/null +++ b/Scripts/A10_laste_Winds.lua @@ -0,0 +1,204 @@ +-- ======================================================= +-- SCRIPT: LASTE Wind/Temp Correction +-- VERSION: 14-06-2026 (ver. 1.6) +-- SCRIPTED BY: CaptMike +-- ======================================================= +-- DESCRIPTION: +-- In an A-10 Thunderbolt II, LASTE stands for Low Altitude Safety +-- and Targeting Enhancement. +-- +-- This script provides an in-cockpit weather data service +-- for the A-10C and A-10C II modules via the F10 Radio Menu. +-- It dynamically probes localized weather and pressure data +-- directly below the aircraft's current coordinate vector. +-- +-- The output formats data matching the 4 physical CDU entry +-- altitude tiers (00, 02, 08, 26). Wind parameters are +-- packed into a raw 5-digit string (e.g., 08001) with no +-- slashes, allowing direct entry into the CDU scratchpad. +-- Negative temperatures are prefixed with a minus sign (-). +-- +-- Displays data via native DCS group text blocks for 5 +-- minutes, with an on-demand option to clear the layout. +-- Uses the MOOSE framework engine to handle weather tracking. +-- MOOSE Framework: https://github.com/FlightControl-Master/MOOSE +-- +-- +-- ======================================================= +-- MISSION EDITOR SETUP INSTRUCTIONS: +-- ======================================================= +-- 1. Create a trigger to load the MOOSE framework: +-- - TYPE: 4 MISSION START +-- - NAME: Load MOOSE +-- - ACTION: DO SCRIPT FILE -> Select your "Moose.lua" file. +-- +-- 2. Create a delayed trigger to load this script file: +-- - TYPE: 1 ONCE +-- - NAME: Load LASTE Script +-- - CONDITION: TIME MORE (5) +-- (This 5-second delay ensures MOOSE initializes first) +-- - ACTION: DO SCRIPT FILE -> Select this saved script file. +-- +-- 3. In-Game Usage: +-- - Hop into any A-10C or A-10C II aircraft slot. +-- - Press your Communication Menu key (\) -> F10 Other. +-- - Select "LASTE" -> Opens the custom tool suite. +-- - Click "Request LASTE Winds" to view or "Clear LASTE Data" to close. +-- ======================================================= + +-- Print confirmation message directly to the dcs.log file upon execution +env.info("=== LASTE WIND/TEMP CORRECTION SYSTEM LOADED SUCCESSFULLY ===") + +-- Global tracking table to manage F10 items natively across network slots +if not _G.LasteMultiplayerTrack then + _G.LasteMultiplayerTrack = { + Menus = {} + } +end + +-- Helper function to fetch and format magnetic variation via MOOSE +-- UTILS.GetMagneticDeclination() returns degrees (positive=East, negative=West) +local function GetMagneticVariationString() + local ok, magVarDeg = pcall(function() + return UTILS.GetMagneticDeclination() + end) + + if not ok or magVarDeg == nil then return "N/A" end + + local sign = magVarDeg >= 0 and "+" or "-" + return string.format("%s%.1f deg", sign, math.abs(magVarDeg)) +end + +-- Function to fetch and display weather safely using native Group environment +local function ShowLasteToGroup(GroupName) + local dcsGroup = Group.getByName(GroupName) + + if dcsGroup and dcsGroup:isExist() then + local dcsUnits = dcsGroup:getUnits() + local dcsUnit = dcsUnits[1] + + if dcsUnit and dcsUnit:isExist() and dcsUnit:getLife() > 0 then + local unitPos = dcsUnit:getPosition().p + local PlayerPos = COORDINATE:NewFromVec3(unitPos) + + -- The 5 valid distinct physical CDU entry tiers + local AltitudesFeet = {0, 1000, 2000, 8000, 26000} + + -- Fetch local sea-level barometric pressure (QNH) via native DCS atmosphere engine + local sampleCoord = { x = unitPos.x, y = 0, z = unitPos.z } + local _, rawPressurePascal = atmosphere.getTemperatureAndPressure(sampleCoord) + + -- Convert Pascals to inches of Mercury (inHg) + local qnhInHg = rawPressurePascal * 0.000295300 + + -- Fetch magnetic variation via MOOSE UTILS (map-wide constant) + local magVarStr = GetMagneticVariationString() + + -- Clean, bold header style + local Message = "===========================================\n" + Message = Message .. " LASTE WIND/TEMP CORRECTION DATA \n" + Message = Message .. "===========================================\n" + Message = Message .. string.format("Location: %s\n", PlayerPos:ToStringMGRS()) + Message = Message .. string.format("Local Magnetic Variation: %s\n", magVarStr) + Message = Message .. string.format("Current Ground QNH: A%.2f\n\n", qnhInHg) + + -- Master-aligned headers calibrated to baseline tracking + Message = Message .. "ALT LAYER ALT WIND TEMP\n" + Message = Message .. "---------------------------------------------------------\n" + + -- Loop through altitudes, extract weather, and format + for _, AltFeet in ipairs(AltitudesFeet) do + local AltMeters = AltFeet * 0.3048 + local WindDir, WindSpeedms = PlayerPos:GetWind(AltMeters) + local TempC = math.floor(PlayerPos:GetTemperature(AltMeters)) + local WindKnots = math.floor(WindSpeedms * 1.94384) + local WindHeading = math.floor(WindDir) + + -- Format temperature for the CDU with consistent fixed-width alignment + -- Positive temps padded to 3 chars (e.g. " 20"), negatives keep minus sign (e.g. "-32") + local TempStr + if TempC < 0 then + TempStr = string.format("-%d", math.abs(TempC)) + else + TempStr = string.format("%3d", TempC) + end + + -- Format Wind Data string WITHOUT the slash (e.g., 08001) + local WindString = string.format("%03d%02d", WindHeading, WindKnots) + + -- Calibrated space layouts tailored to offset proportional text drift perfectly + if AltFeet == 0 then + Message = Message .. string.format("0000 ft 00 %s %s\n", WindString, TempStr) + elseif AltFeet == 1000 then + Message = Message .. string.format("1000 ft 01 %s %s\n", WindString, TempStr) + elseif AltFeet == 2000 then + Message = Message .. string.format("2000 ft 02 %s %s\n", WindString, TempStr) + elseif AltFeet == 8000 then + Message = Message .. string.format("8000 ft 08 %s %s\n", WindString, TempStr) + elseif AltFeet == 26000 then + Message = Message .. string.format("26000 ft 26 %s %s\n", WindString, TempStr) + end + end + + Message = Message .. "---------------------------------------------------------\n\n" + Message = Message .. "=== MANUAL DATA ENTRY STEPS ===\n" + Message = Message .. "1. Turn Altimeter Pressure knob to match Ground QNH.\n" + Message = Message .. "2. Press [SYS] on CDU -> OSB 06 [LASTE] -> OSB 07 [WIND].\n" + Message = Message .. "3. Select/Create Altitude Layer First:\n" + Message = Message .. " Type ALT value into scratchpad -> Press target ALT OSB.\n" + Message = Message .. "4. Enter Layer Editing Mode:\n" + Message = Message .. " Press OSB 07 [WNDEDIT] to open data fields for that altitude.\n" + Message = Message .. "5. Input Target Data:\n" + Message = Message .. " Type Wind Entry (e.g. 08001) -> Press OSB 02 [WIND].\n" + Message = Message .. " Type Temp Entry (e.g. 19 or -32) -> Press OSB 03 [TEMP].\n" + Message = Message .. "6. Press [WP] on the UFC to return to Steerpoint page." + + local groupID = dcsGroup:getID() + trigger.action.outTextForGroup(groupID, "", 1, true) + trigger.action.outTextForGroup(groupID, Message, 300, true) + end + end +end + +-- Function called by the F10 menu item to clear the display instantly +local function ClearLasteDisplay(GroupName) + local dcsGroup = Group.getByName(GroupName) + if dcsGroup then + local groupID = dcsGroup:getID() + trigger.action.outTextForGroup(groupID, "", 1, true) + end +end + +-- Dedicated Multiplayer Safe Loop Scheduler Engine +local LastePlayerFilter = SET_CLIENT:New():FilterCoalitions("blue"):FilterStart() + +SCHEDULER:New(nil, function() + -- Scan all active blue client slots via MOOSE tracking filters + LastePlayerFilter:ForEachClient(function(ClientUnit) + if ClientUnit and ClientUnit:IsAlive() then + local airframeType = ClientUnit:GetTypeName() + + if airframeType == "A-10C" or airframeType == "A-10C_2" then + local ClientGroup = ClientUnit:GetGroup() + + if ClientGroup and ClientGroup:IsAlive() then + local groupName = ClientGroup:GetName() + local dcsGroup = Group.getByName(groupName) + + if dcsGroup then + local groupID = dcsGroup:getID() + + -- If this group ID doesn't have an active F10 menu record, construct it natively + if not _G.LasteMultiplayerTrack.Menus[groupID] then + -- Insert menus directly into the DCS mission commands network array passing the raw GroupName string + local rootMenu = missionCommands.addSubMenuForGroup(groupID, "LASTE") + missionCommands.addCommandForGroup(groupID, "Request LASTE Winds", rootMenu, ShowLasteToGroup, groupName) + missionCommands.addCommandForGroup(groupID, "Clear LASTE Data", rootMenu, ClearLasteDisplay, groupName) + _G.LasteMultiplayerTrack.Menus[groupID] = rootMenu + end + end + end + end + end + end) +end, {}, 1, 2)