Compare commits

...

61 Commits

Author SHA1 Message Date
Applevangelist 0f9921f16b #MSRS #HOUND - fixed frequency not formatted in a way allowing frequencys smaller the 10th after the decimal dot. 2026-06-27 10:51:01 +02:00
Applevangelist 82282ad2e4 Merge remote-tracking branch 'origin/develop' into branch 2026-06-27 10:13:33 +02:00
Applevangelist b33f17d3df Merge remote-tracking branch 'origin/master-ng' into branch 2026-06-27 10:13:22 +02:00
Applevangelist d4b0afa635 xx 2026-06-27 10:12:50 +02:00
Applevangelist 9820c26d4b Merge remote-tracking branch 'origin/develop' into branch 2026-06-21 12:55:52 +02:00
Applevangelist d1d94a99dc Merge remote-tracking branch 'origin/master-ng' into branch 2026-06-21 12:55:41 +02:00
Applevangelist 4767ad45cd xx 2026-06-21 12:55:09 +02:00
Applevangelist 7d4432fa47 #AIRBASE - Add Syria Airbases 2026-06-14 13:43:42 +02:00
Applevangelist 4b6e860512 Merge remote-tracking branch 'origin/develop' into branch 2026-06-14 12:08:23 +02:00
Applevangelist 2332440f81 Merge remote-tracking branch 'origin/master-ng' into branch 2026-06-14 12:08:16 +02:00
Applevangelist 5f64ac30f0 Merge remote-tracking branch 'origin/develop' into branch 2026-06-11 17:35:41 +02:00
Applevangelist b5e4846fb1 Merge remote-tracking branch 'origin/master-ng' into branch 2026-06-11 17:35:32 +02:00
Applevangelist 2146e92154 Merge remote-tracking branch 'origin/master' into branch
# Conflicts:
#	Moose Development/Moose/Utilities/Enums.lua
2026-06-05 14:26:43 +02:00
Applevangelist 6b1903466e Merge remote-tracking branch 'origin/master-ng' into branch 2026-06-05 14:26:22 +02:00
Applevangelist b430a3450e xx 2026-06-05 14:24:14 +02:00
Applevangelist 22ae3cf796 Merge remote-tracking branch 'origin/develop' into branch 2026-05-14 10:48:42 +02:00
Applevangelist 62cdcf5536 Merge remote-tracking branch 'origin/master-ng' into branch 2026-05-14 10:48:36 +02:00
Applevangelist ff55fd5a99 Merge remote-tracking branch 'origin/develop' into branch 2026-05-10 13:05:40 +02:00
Applevangelist 8ee86d3128 Merge remote-tracking branch 'origin/master-ng' into branch 2026-05-10 13:05:30 +02:00
Applevangelist 2ab3d7150d #SET - Added function to set Regex and Dash Replacement options on name filter (FilterPrefixes)
- Added pseudo-docu for some functions inherited from SET_BASE to show functions inherited from SET_BASE properly in intellisense
2026-05-01 12:45:59 +02:00
Applevangelist 957b72ab67 Merge remote-tracking branch 'origin/develop' into branch 2026-04-25 18:15:20 +02:00
Applevangelist d4a00e30e1 Merge remote-tracking branch 'origin/master-ng' into branch
# Conflicts:
#	Moose Development/Moose/Ops/TARS.lua
2026-04-25 18:15:09 +02:00
Applevangelist 74174906f3 xx 2026-04-25 16:50:15 +02:00
Applevangelist 4e8efc19ac Merge remote-tracking branch 'origin/develop' into branch 2026-04-21 18:29:05 +02:00
Applevangelist 21920f9d2e Merge remote-tracking branch 'origin/master-ng' into branch
# Conflicts:
#	Moose Development/Moose/Ops/TARS.lua
2026-04-21 18:28:56 +02:00
Applevangelist 9a938080b8 #TARS - Added some docu commentary, removed log noise, etc 2026-04-21 18:27:52 +02:00
Applevangelist dae4dc2d40 x 2026-04-21 18:19:22 +02:00
Applevangelist 85bb9a0566 #TARS
- Correct optical view projection implemented (ellipse bc of the angle of view)
- Duration now describes the number of expositions your camera has
- Interval of shots is dependent on the speed of the TARS unit
- Added platform parameters overlap (of shots, usually 25% for faster movers, 50% for slower ones), overlap is clamped by minimum interval — at high speeds the interval floor is reached and overlap effectively increases (and you go through shots really fast)
- Fixed zone draw for debug
2026-04-19 15:29:48 +02:00
Applevangelist 338d38d2a2 #TARS added option TARS_SESSION.debugunitsearch 2026-04-16 12:37:35 +02:00
Applevangelist dde08f2bbe Merge remote-tracking branch 'origin/develop' into branch 2026-04-16 11:20:51 +02:00
Applevangelist 55224c96ab Merge remote-tracking branch 'origin/master-ng' into branch
# Conflicts:
#	Moose Development/Moose/Ops/TARS.lua
#	Moose Setup/Moose.files
2026-04-16 11:20:43 +02:00
Applevangelist 257801edca xx 2026-04-16 11:19:21 +02:00
Applevangelist de71c1d903 #TARS Release 2026-04-12 12:52:07 +02:00
Applevangelist 6863398d52 Merge remote-tracking branch 'origin/develop' into branch 2026-04-08 15:19:04 +02:00
Applevangelist a019a511b1 Merge remote-tracking branch 'origin/master-ng' into branch 2026-04-08 15:18:58 +02:00
Applevangelist 85ee0ae38e Merge remote-tracking branch 'origin/develop' into branch 2026-04-08 14:44:56 +02:00
Applevangelist f26cbc5b13 Merge remote-tracking branch 'origin/master-ng' into branch 2026-04-08 14:44:49 +02:00
Applevangelist 23d142a4c9 xx 2026-04-08 14:40:58 +02:00
Applevangelist 4956809c3f xx 2026-04-07 12:19:18 +02:00
Applevangelist 04befd1b61 xx 2026-04-06 19:55:58 +02:00
Thomas 5facdd9363 Merge pull request #2572 from FlightControl-Master/Applevangelist-patch-1
Delete Moose Development/Moose/Functional/REDGCI.lua
2026-04-06 19:05:27 +02:00
Thomas 04bea41400 Create RedGCI.lua 2026-04-06 19:04:57 +02:00
Thomas a4c4913ead Delete Moose Development/Moose/Functional/REDGCI.lua 2026-04-06 19:04:11 +02:00
Applevangelist 1405e10257 xx 2026-04-06 19:01:11 +02:00
Applevangelist d042c778f4 xx 2026-04-06 18:53:30 +02:00
Applevangelist d136470149 xx 2026-04-06 18:47:29 +02:00
Applevangelist 29dfbbf314 Merge remote-tracking branch 'origin/develop' into branch 2026-04-04 17:18:38 +02:00
Applevangelist c54bd793f2 Merge remote-tracking branch 'origin/master-ng' into branch 2026-04-04 17:18:29 +02:00
Applevangelist fddac77c79 xx 2026-04-04 17:17:04 +02:00
Applevangelist 044a49a61a xx 2026-03-27 17:39:45 +01:00
Applevangelist 44aeed0cbd xx 2026-03-27 17:24:59 +01:00
Applevangelist 84e20dae29 #REDGCI 2026-03-27 15:10:23 +01:00
Applevangelist 0806d822ff xx 2026-03-26 11:08:05 +01:00
Applevangelist b577b3db29 Merge remote-tracking branch 'origin/master-ng' into branchxx 2026-03-26 09:20:27 +01:00
Applevangelist 64433394f5 Merge remote-tracking branch 'origin/Apple/Develop' into branch 2026-03-26 09:11:15 +01:00
Applevangelist 9fb9b6378e xx 2026-03-26 09:11:03 +01:00
Thomas a66290ab63 Merge pull request #2558 from FlightControl-Master/master-ng
Merge from master
2026-03-24 10:13:47 +01:00
Applevangelist 58eeabe3fa xx 2026-03-22 16:31:37 +01:00
Applevangelist 2cc7356520 xx 2026-03-21 15:43:46 +01:00
Thomas c335881b2d Merge pull request #2505 from shaji-Dev/master
[ADDED] 268 Missing Warehouse EQP ENUMS
2026-02-09 18:09:24 +01:00
smiki 993fc45e83 [ADDED] 268 Missing Warehouse EQP ENUMS 2026-02-09 16:48:32 +01:00
12 changed files with 4962 additions and 53 deletions
+1
View File
@@ -614,6 +614,7 @@ do -- Object
-- @field SCENERY
-- @field CARGO
---
-- @type Object.Desc
-- @extends #Desc
-- @field #number life initial life level
@@ -742,7 +742,6 @@ do
--
function MANTIS:New(name,samprefix,ewrprefix,hq,Coalition,dynamic,awacs, EmOnOff, Padding, Zones)
-- Inherit everything from BASE class.
local self = BASE:Inherit(self, FSM:New()) -- #MANTIS
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,760 @@
--- **Functional** - Enhanced Warsaw Pact GCI Controller.
--
-- ## Main Features:
--
-- * Guide AI and human pilots in Warsaw Pact Style. GCI Kernel Functions.
-- * Advanced Tactics for Groups.
-- * Many additional events that the mission designer can hook into.
--
-- ===
--
-- ### Author: **Applevangelist**
--
-- ===
-- @module Functional.REDGCI_KERNEL
-- @image Func_RedGCI.png
-- @version 1.0.0
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- REDGCI_KERNEL class
-- @type REDGCI_KERNEL
---
-- # RedGCI — Soviet GCI Doctrine & Player Guide
--
-- ## Philosophy: Централизованное управление (Centralized Control)
--
-- The fundamental difference between Soviet and NATO GCI is **who makes the tactical decision**.
--
-- In NATO doctrine, the GCI controller provides situational awareness — bearing, range, altitude, aspect — and the pilot decides how to prosecute the intercept. The pilot is an autonomous tactician. GCI is an advisor.
--
-- In Soviet doctrine, the GCI controller **directs**. The pilot executes. The controller selects the intercept geometry, assigns the heading, manages the radar, calls weapons free, and coordinates multi-ship tactics. The pilot's job is to fly the numbers and shoot when told. This is not a flaw — it is the system working as designed. Soviet fighter pilots were trained to be precise executors of GCI instructions, not independent tacticians. The ground radar network (PVO) was the brain; the aircraft was the weapon.
--
-- RedGCI models this philosophy faithfully.
--
-- ---
--
-- ## What to Expect as a Player
--
-- ### You will not be asked what you want to do.
--
-- There are no "recommend a vector" calls, no "at your discretion" callouts. The controller tells you your heading, your altitude, and your task. Your acknowledgement is assumed.
--
-- ### The controller manages your radar.
--
-- You do not decide when to turn your radar on. The GCI will tell you when to switch on (`локатор` / `Radar on`). Before that call, you fly cold and silent. This preserves your emissions discipline and prevents the target from getting an early RWR spike.
--
-- ### Weapons free is a controlled event.
--
-- You do not engage until the controller clears you (`цель разрешена` / `WEAPONS FREE`). The controller determines when geometry, range, and aspect are favorable. Shooting early breaks the coordinated intercept and may compromise your wingman's attack.
--
-- ### Radio calls are short and military.
--
-- Soviet GCI brevity is terse by design. Expect calls like:
--
-- - `"Сокол, курс 170, высота 4500."` — vector, altitude
-- - `"Сокол, цель, пара, истребитель. Локатор."` — picture call on commit: count, type, radar on
-- - `"Сокол, захват. Дальность 20. Цель разрешена."` — lock confirmed, range, weapons free
-- - `"Сокол, молодец. Домой."` — good kill, RTB
--
-- There are no "BOGEY DOPE" requests, no "BRAA" calls, no "DECLARE" queries. The controller has already done that work. You fly the vector.
--
-- ---
--
-- ## State Flow — What the GCI is Doing Behind the Scenes
--
-- RedGCI manages a state machine that progresses through six phases. Understanding these phases helps you anticipate what call is coming next.
--
-- ```
-- VECTOR → COMMIT → RADAR_CONTACT → VISUAL → MERGE → (SPLASH / ABORT / RTB)
-- ```
--
-- ### VECTOR
-- The controller has a track. You are being vectored onto an intercept geometry. Your radar is off. The controller is solving a collision course and updating your heading every tick. Altitude calls reflect the intercept geometry — you may be sent below the target (classic Soviet shoot-up doctrine for radar-limited types) or level/above (MiG-29/Su-27 lookdown geometry). Expect heading updates every 1015 seconds.
--
-- **What you should do:** Fly the heading. Don't deviate. Don't turn your radar on yet. Speed is expected at 900kph TAS (depending on airframe)
--
-- ### COMMIT
-- Range has closed to approximately 30km. The controller calls the picture: count and type. Your radar comes on. You are now committed to the intercept — turning away is no longer the default option. The controller is building your radar geometry toward a lock.
--
-- **What you should do:** Activate your radar. Acquire the target. Do not fire yet.
--
-- ### RADAR_CONTACT
-- You have radar lock (or the AI has achieved it). The controller confirms lock and calls range. If geometry and range are favorable, weapons free follows immediately. If not — for example if aspect angle is unfavorable for a stern conversion — the controller holds fire and waits for better geometry.
--
-- **What you should do:** Maintain lock. Track the target. Wait for the weapons free call.
--
-- ### VISUAL
-- Range has closed to approximately 5km — visual conditions. Weapons free is automatic at this point. You are now in the merge envelope.
--
-- **What you should do:** Engage.
--
-- ### MERGE
-- Inside 2km. The GCI transitions to merge control: bearing to target, overshoot calls, separation instructions, reattack vectors. At this range the controller cannot see fine-grained geometry — merge calls are based on relative bearing and closure.
--
-- **What you should do:** Fight. Listen for overshoot, separation, and reattack calls.
--
-- ### SPLASH / ABORT / RTB
-- - `SPLASH` — kill confirmed, RTB
-- - `ABORT (THREAT)` — your RWR is spiked or a threat geometry has developed; break off immediately on the given heading
-- - `ABORT (BINGO)` — fuel state critical; break off and return
--
-- ---
--
-- ## Multi-Ship (2v2) Tactics (REDGCI2v2)
--
-- When two fighters are dispatched against a threat, the GCI selects a tactic automatically based on the tactical situation. The tactic is applied at COMMIT — until then, both fighters are vectored together toward the intercept midpoint.
--
-- | Tactic | Description |
-- |--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
-- | **PINCER** | Classic bracket. F1 and F2 split left and right, attacking from opposite angles simultaneously. Forces the target to choose which threat to react to. |
-- | **HIGH-LOW** | Vertical split. One fighter attacks from below (radar up, clean sky background), one from above. Degrades the target's ability to acquire both simultaneously. |
-- | **STAGGER** | BVR timing offset. F1 fires first at long range, F2 follows 813km behind to engage a maneuvering or defending target. |
-- | **TRAIL** | Close trail. F1 is the shooter, F2 is support — ready to engage if F1 overshoots or is defeated. |
-- | **GIRAFFE** | *(Historical — Iraq/Iran War, Mirage F1 vs F-14A)* F1 attacks at normal altitude, binding the AWG-9 radar. F2 flies nap-of-earth |
-- | | (300600m AGL) using ground clutter to degrade radar detection, then pulls up and fires from close range. |
--
-- During a tactic split, you may receive a heading that seems unusual — a large lateral offset or an unexpected altitude change. **Trust the vector.** The controller is positioning you for the tactic geometry. The merge point will bring you back onto the target.
--
-- ---
--
-- ## Dispatcher & CAP Flow (REDGCI_DISPATCHER)
--
-- When using the dispatcher layer, the full operational flow is:
--
-- ```
-- Spawn at homeplate
-- → Taxi and takeoff (template-controlled)
-- → Transit to CAP zone
-- → Orbit in assigned zone (radar cold, weapons safe)
-- ↓ INTEL detects threat cluster
-- → "Attention, radar contact. Pair, fighter, 45 kilometers." (all CAP fighters)
-- ↓ Dispatcher assigns pair
-- → "101 102, intercept. Pair, fighter." (dispatched pair)
-- → VECTOR → COMMIT → RADAR_CONTACT → VISUAL → MERGE → SPLASH
-- ↓ Engagement complete
-- → AI: RTB waypoint → land → despawn → respawn after delay
-- → Human: "101, mission complete. RTB, refuel and rearm."
-- ↓ After RespawnDelay
-- → New AI pair spawns into same CAP zone
-- ```
--
-- Human players are dispatched first when available. If a human and AI are both in the CAP pool, the human is always assigned to the next intercept. AI fills gaps. The dispatcher does not send a single fighter if a pair is available — pairing is always preferred.
--
-- ---
--
-- ## Key Differences from NATO GCI at a Glance
--
-- | | Soviet (RedGCI) | NATO |
-- |--------------------|--------------------------------------|------------------------------------|
-- | Tactical decision | Controller | Pilot |
-- | Radar management | Controller-commanded | Pilot-initiated |
-- | Weapons free | Controller-called | Pilot-discretion (after WF) |
-- | Heading calls | Prescriptive | Advisory |
-- | Brevity style | Terse, military, positional | Standardized (BRAA, DECLARE, etc.) |
-- | Multi-ship tactics | Centrally planned, applied at COMMIT | Mutually briefed, pilot-executed |
-- | Pilot autonomy | Low (by design) | High |
--
-- **The Soviet system is not inferior** — it is optimized for a different kind of pilot and a different operational context. Mass interception of large NATO strike packages over defended Soviet airspace demanded centralized, efficient, high-throughput GCI control. RedGCI brings that experience to DCS.
--
-- @field #REDGCI_KERNEL
REDGCI_KERNEL = {}
REDGCI_KERNEL.version = "1.0.0"
-- ─────────────────────────────────────────────────────────────
-- Konstanten (aus gci_types.h)
-- ─────────────────────────────────────────────────────────────
REDGCI_KERNEL.C = {
RANGE_VECTOR_START = 60000.0,
RANGE_COMMIT = 30000.0,
RANGE_RADAR_FLOOR = 20000.0,
RANGE_VISUAL = 5000.0,
RANGE_MERGE = 2000.0,
WF_RANGE_MAX = 25000.0,
ALT_OFFSET_LOOKDOWN = 0.0,
ASPECT_NOTCH_MIN = 80.0,
ASPECT_NOTCH_MAX = 100.0,
ASPECT_REAR_ATTACK = 120.0,
MAX_TTI = 600.0,
TICK_INTERVAL = 15.0,
FUEL_BINGO = 0.25,
DELAY_MIN = 3.0,
DELAY_MAX = 8.0,
DELAY_MERGE_MIN = 2.0,
DELAY_MERGE_MAX = 4.0,
TACTIC_PINCER = 0,
TACTIC_HIGH_LOW = 1,
TACTIC_STAGGER = 2,
TACTIC_TRAIL = 3,
TACTIC_GIRAFFE = 4, -- Irak/Iran-Doktrin: F1=Decoy normal, F2=Nap-of-Earth im Groundclutter
PURSUIT_COLLISION = 0,
PURSUIT_LEAD = 1,
PURSUIT_PURE = 2,
PURSUIT_NO_SOLUTION = 3,
}
-- ─────────────────────────────────────────────────────────────
-- Hilfsfunktionen
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.clamp(v, lo, hi)
if v < lo then return lo end
if v > hi then return hi end
return v
end
function REDGCI_KERNEL.vec2len(x, z)
return math.sqrt(x*x + z*z)
end
function REDGCI_KERNEL.bearing(dx, dz)
local b = math.deg(math.atan2(dx, dz))
return b < 0.0 and b + 360.0 or b
end
function REDGCI_KERNEL.randDelay(lo, hi)
return lo + UTILS.LCGRandom() * (hi - lo)
end
-- ─────────────────────────────────────────────────────────────
-- Aspect Angle (0=Nose-on, 90=Beam, 180=Tail)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.aspectAngle(target, observer)
local dx = observer.x - target.x
local dz = observer.z - target.z
local range = REDGCI_KERNEL.vec2len(dx, dz)
if range < 1.0 then return 0.0 end
local nx = dx / range
local nz = dz / range
local spd = (target.speed or 1.0) + 1e-6
local tvx = (target.vx or 0.0) / spd
local tvz = (target.vz or 0.0) / spd
local dot = REDGCI_KERNEL.clamp(tvx*nx + tvz*nz, -1.0, 1.0)
return math.deg(math.acos(dot))
end
-- ─────────────────────────────────────────────────────────────
-- Closure Rate (positiv = Annäherung)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.closureRate(f, t)
local dx = t.x - f.x
local dz = t.z - f.z
local range = REDGCI_KERNEL.vec2len(dx, dz)
if range < 1.0 then return 0.0 end
local nx = dx / range
local nz = dz / range
local dvx = (t.vx or 0.0) - (f.vx or 0.0)
local dvz = (t.vz or 0.0) - (f.vz or 0.0)
return -(dvx*nx + dvz*nz)
end
-- ─────────────────────────────────────────────────────────────
-- _solveCollision (intern, GCI-Koordinaten)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL._solveCollision(f, t)
local C = REDGCI_KERNEL.C
local dx = t.x - f.x
local dz = t.z - f.z
local vtx = t.vx or 0.0
local vtz = t.vz or 0.0
local vf = f.speed or 1.0
local a = vtx*vtx + vtz*vtz - vf*vf
local b = 2.0 * (dx*vtx + dz*vtz)
local c = dx*dx + dz*dz
local sol_t = -1.0
if math.abs(a) < 1.0 then
if math.abs(b) > 0.01 then
sol_t = -c / b
else
return false
end
else
local disc = b*b - 4.0*a*c
if disc < 0.0 then return false end
local sq = math.sqrt(disc)
local t1 = (-b - sq) / (2.0 * a)
local t2 = (-b + sq) / (2.0 * a)
if t1 > 0.0 and t2 > 0.0 then sol_t = math.min(t1, t2)
elseif t1 > 0.0 then sol_t = t1
elseif t2 > 0.0 then sol_t = t2
else return false
end
end
if sol_t < 0.0 or sol_t > C.MAX_TTI then return false end
local ip = {
x = t.x + vtx * sol_t,
z = t.z + vtz * sol_t,
y = math.max(t.y + C.ALT_OFFSET_LOOKDOWN, 300.0),
}
local hdg = REDGCI_KERNEL.bearing(ip.x - f.x, ip.z - f.z)
return true, hdg, sol_t, ip
end
-- ─────────────────────────────────────────────────────────────
-- _solveLead (intern, GCI-Koordinaten)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL._solveLead(f, t)
local C = REDGCI_KERNEL.C
local dx = t.x - f.x
local dz = t.z - f.z
local range = REDGCI_KERNEL.vec2len(dx, dz)
if range < 1.0 then return 0.0, 0.0 end
local base_bearing = REDGCI_KERNEL.bearing(dx, dz)
local aspect_rad = math.rad(REDGCI_KERNEL.aspectAngle(t, f))
local speed_ratio = (t.speed or 1.0) / ((f.speed or 1.0) + 1e-6)
local sin_lead = REDGCI_KERNEL.clamp(speed_ratio * math.sin(aspect_rad), -1.0, 1.0)
local lead_deg = math.deg(math.asin(sin_lead))
local hdg
if math.abs(lead_deg) < 45.0 then
hdg = (base_bearing + lead_deg + 360.0) % 360.0
else
hdg = base_bearing
end
local closing = REDGCI_KERNEL.closureRate(f, t)
if closing < 50.0 then closing = 50.0 end
local tti = math.min(range / closing, C.MAX_TTI)
return hdg, tti
end
-- ─────────────────────────────────────────────────────────────
-- computeIntercept (GCI-Koordinaten intern)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.computeIntercept(fighter, target)
local C = REDGCI_KERNEL.C
local dx = target.x - fighter.x
local dz = target.z - fighter.z
local sol = {
heading_deg = 0.0,
time_to_intercept = C.MAX_TTI,
intercept_point = { x=target.x, z=target.z, y=target.y },
target_alt = target.y,
solution_found = false,
aspect_angle = REDGCI_KERNEL.aspectAngle(target, fighter),
range = REDGCI_KERNEL.vec2len(dx, dz),
mode = C.PURSUIT_NO_SOLUTION,
weapons_free = false,
}
local closure = REDGCI_KERNEL.closureRate(fighter, target)
local projected_range = sol.range - closure * C.TICK_INTERVAL
sol.weapons_free = (sol.range < C.WF_RANGE_MAX) or
(closure > 0.0 and projected_range < C.WF_RANGE_MAX)
local ok, hdg, tti, ip = REDGCI_KERNEL._solveCollision(fighter, target)
if ok then
sol.heading_deg = hdg
sol.time_to_intercept = tti
sol.intercept_point = ip
sol.solution_found = true
sol.mode = C.PURSUIT_COLLISION
return sol
end
local lhdg, ltti = REDGCI_KERNEL._solveLead(fighter, target)
sol.heading_deg = lhdg
sol.time_to_intercept = ltti
sol.solution_found = true
sol.mode = C.PURSUIT_LEAD
sol.intercept_point = {
x = target.x + (target.vx or 0.0) * ltti,
z = target.z + (target.vz or 0.0) * ltti,
y = math.max(target.y + C.ALT_OFFSET_LOOKDOWN, 300.0),
}
return sol
end
-- ─────────────────────────────────────────────────────────────
-- computeInterceptDCS (DCS-Koordinaten Ein/Aus)
-- Flat-Rückgabe kompatibel mit alter C-API
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.computeInterceptDCS(f, t)
local f_gci = { x=f.z, z=f.x, y=f.y, vx=f.vz, vz=f.vx, vy=f.vy, speed=f.spd }
local t_gci = { x=t.z, z=t.x, y=t.y, vx=t.vz, vz=t.vx, vy=t.vy, speed=t.spd }
local sol = REDGCI_KERNEL.computeIntercept(f_gci, t_gci)
-- GCI→DCS: ip.z(Nord)→DCS.x, ip.x(Ost)→DCS.z
return sol.heading_deg,
sol.time_to_intercept,
sol.mode,
sol.weapons_free,
sol.range,
sol.aspect_angle,
sol.intercept_point.z,
sol.intercept_point.x,
sol.intercept_point.y,
sol.target_alt
end
-- ─────────────────────────────────────────────────────────────
-- computeSplit (GCI-Koordinaten intern)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.computeSplit(f1, f2, tgt, tactic, variation)
local C = REDGCI_KERNEL.C
variation = REDGCI_KERNEL.clamp(variation or 0.5, 0.0, 1.0)
tactic = tactic or C.TACTIC_PINCER
local mid_x = (f1.x + f2.x) * 0.5
local mid_z = (f1.z + f2.z) * 0.5
local dx = tgt.x - mid_x
local dz = tgt.z - mid_z
local rng = REDGCI_KERNEL.vec2len(dx, dz)
if rng < 1.0 then rng = 1.0 end
local ax = dx / rng
local az = dz / rng
local px = -az
local pz = ax
local plan = {
tactic = tactic,
wp_f1 = { x=0, z=0, y=0 },
wp_f2 = { x=0, z=0, y=0 },
merge_f1 = { x=0, z=0, y=0 },
merge_f2 = { x=0, z=0, y=0 },
}
local function clamp_alt(pt)
if pt.y < 300.0 then pt.y = 300.0 end
end
local function clamp_alt_noe(pt)
if pt.y < 150.0 then pt.y = 150.0 end
end
-- GIRAFFE F2 fliegt NOE — separater clamp mit niedrigerer Mindesthöhe
local function clamp_alt_noe(pt)
if pt.y < 150.0 then pt.y = 150.0 end
end
if tactic == C.TACTIC_PINCER then
local spread = 12000.0 + variation * 5000.0
local approach = rng * 0.45
local merge_off = spread * 0.30
plan.wp_f1 = { x=mid_x+ax*approach+px*spread, z=mid_z+az*approach+pz*spread, y=tgt.y }
plan.wp_f2 = { x=mid_x+ax*approach-px*spread, z=mid_z+az*approach-pz*spread, y=tgt.y }
plan.merge_f1 = { x=tgt.x-ax*3000+px*merge_off, z=tgt.z-az*3000+pz*merge_off, y=tgt.y }
plan.merge_f2 = { x=tgt.x-ax*3000-px*merge_off, z=tgt.z-az*3000-pz*merge_off, y=tgt.y }
elseif tactic == C.TACTIC_HIGH_LOW then
local vert = 3000.0 + variation * 1500.0
local approach = rng * 0.50
local side_off = 2000.0
plan.wp_f1 = { x=mid_x+ax*approach+px*side_off, z=mid_z+az*approach+pz*side_off, y=tgt.y-500.0 }
plan.wp_f2 = { x=mid_x+ax*approach-px*side_off, z=mid_z+az*approach-pz*side_off, y=tgt.y+vert }
plan.merge_f1 = { x=tgt.x-ax*3000+px*side_off, z=tgt.z-az*3000+pz*side_off, y=plan.wp_f1.y }
plan.merge_f2 = { x=tgt.x-ax*3000-px*side_off, z=tgt.z-az*3000-pz*side_off, y=plan.wp_f2.y }
elseif tactic == C.TACTIC_STAGGER then
local lag = 8000.0 + variation * 3000.0
local lead_dist = rng * 0.85
plan.wp_f1 = { x=mid_x+ax*lead_dist, z=mid_z+az*lead_dist, y=tgt.y }
plan.wp_f2 = { x=mid_x+ax*(lead_dist-lag), z=mid_z+az*(lead_dist-lag), y=tgt.y }
plan.merge_f1 = { x=plan.wp_f1.x, z=plan.wp_f1.z, y=plan.wp_f1.y }
plan.merge_f2 = { x=plan.wp_f2.x, z=plan.wp_f2.z, y=plan.wp_f2.y }
elseif tactic == C.TACTIC_TRAIL then
local lag = 3000.0 + variation * 2000.0
local lead_dist = rng * 0.85
local side_off = 500.0
plan.wp_f1 = { x=mid_x+ax*lead_dist, z=mid_z+az*lead_dist, y=tgt.y }
plan.wp_f2 = { x=mid_x+ax*(lead_dist-lag)+px*side_off, z=mid_z+az*(lead_dist-lag)+pz*side_off, y=tgt.y }
plan.merge_f1 = { x=plan.wp_f1.x, z=plan.wp_f1.z, y=plan.wp_f1.y }
plan.merge_f2 = { x=plan.wp_f2.x, z=plan.wp_f2.z, y=plan.wp_f2.y }
elseif tactic == C.TACTIC_GIRAFFE then
-- ── GIRAFFE: Irak/Iran-Doktrin (Mirage F1 vs F-14A) ──────────────
--
-- F1 = Decoy: normale Höhe, direkter Anflug, bindet AWG-9 Radar.
-- Zieht Phoenixe auf sich — gibt F2 Zeit für Pull-up.
--
-- F2 = Killer: Nap-of-Earth (~300-600m AGL/MSL) weit seitlich versetzt.
-- Nutzt Groundclutter um AWG-9 Look-Down zu degradieren.
-- Nähert sich bis 10km vor Ziel, dann Pull-up und Schuss.
-- Seitlicher Versatz ~8-12km damit F2 nicht im Radarsektor
-- des AWG-9 liegt während F1 den Lock hält.
--
-- Historisch: Iran-Irak Krieg 1982-88. Irakische Mirage F1EQ nutzten
-- dieses Profil gegen F-14A/AIM-54 Phoenix — der AWG-9 hatte trotz
-- Look-Down-Fähigkeit bei sehr tiefen Zielen über unebenen Terrain
-- (Zagros-Berge, Khuzestan-Ebene) erhöhte Clutter-Probleme.
--
-- Höhen: neutral (0.0) — Lua addiert AltOffset + terrain-awareness.
-- Mindesthöhe 300m MSL wird am Ende geclampt.
local noe_alt = 300.0 + variation * 300.0 -- 300-600m MSL (Nap-of-Earth)
local side_off = 8000.0 + variation * 4000.0 -- 8-12km seitlich (aus AWG-9 Sektor)
local approach = rng * 0.60 -- F1 direkter Anflug, 60% des Weges
local noe_dist = rng * 0.75 -- F2 nähert sich weiter ran vor Pull-up
plan.wp_f1 = { x=mid_x+ax*approach+px*2000, z=mid_z+az*approach+pz*2000, y=tgt.y }
plan.merge_f1 = { x=tgt.x-ax*5000+px*2000, z=tgt.z-az*5000+pz*2000, y=tgt.y }
plan.wp_f2 = { x=mid_x+ax*noe_dist-px*side_off, z=mid_z+az*noe_dist-pz*side_off, y=noe_alt, absolute_alt=true }
plan.merge_f2 = { x=tgt.x-ax*10000-px*side_off*0.3, z=tgt.z-az*10000-pz*side_off*0.3, y=tgt.y }
else
plan.wp_f1 = { x=tgt.x, z=tgt.z, y=tgt.y }
plan.wp_f2 = { x=tgt.x, z=tgt.z, y=tgt.y }
plan.merge_f1 = { x=tgt.x, z=tgt.z, y=tgt.y }
plan.merge_f2 = { x=tgt.x, z=tgt.z, y=tgt.y }
end
clamp_alt(plan.wp_f1)
if tactic == C.TACTIC_GIRAFFE then
clamp_alt_noe(plan.wp_f2)
else
clamp_alt(plan.wp_f2)
end
clamp_alt(plan.merge_f1)
clamp_alt(plan.merge_f2)
return plan
end
-- ─────────────────────────────────────────────────────────────
-- computeSplitDCS (DCS-Koordinaten Ein/Aus)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.computeSplitDCS(f1, f2, tgt, tactic, variation)
local function dcs2gci(u)
return { x=u.z, z=u.x, y=u.y, vx=u.vz or 0, vz=u.vx or 0, speed=u.spd or 0 }
end
local function gci2dcs(pt)
return { x=pt.z, z=pt.x, y=pt.y, absolute_alt=pt.absolute_alt }
end
local tgt_gci = { x=tgt.z, z=tgt.x, y=tgt.y }
local plan = REDGCI_KERNEL.computeSplit(
dcs2gci(f1), dcs2gci(f2), tgt_gci, tactic, variation)
plan.wp_f1 = gci2dcs(plan.wp_f1)
plan.wp_f2 = gci2dcs(plan.wp_f2)
plan.merge_f1 = gci2dcs(plan.merge_f1)
plan.merge_f2 = gci2dcs(plan.merge_f2)
return plan
end
-- ─────────────────────────────────────────────────────────────
-- buildTransmission (Port von gci_build_transmission)
--
-- ctx/prev Felder: state, prev_state, ticks_in_state, range,
-- aspect_angle, closure_rate, altitude_delta, fuel_fraction
-- sol Felder: heading_deg, time_to_intercept, target_alt,
-- range, aspect_angle, weapons_free
-- Rückgabe: { token_str, delay_sec, weapons_free, silence }
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.buildTransmission(ctx, prev, sol)
local C = REDGCI_KERNEL.C
local tx = {
token_str = "",
delay_sec = REDGCI_KERNEL.clamp(
REDGCI_KERNEL.randDelay(C.DELAY_MIN, C.DELAY_MAX), 3.0, 8.0),
weapons_free = sol.weapons_free,
silence = false,
priority = 50,
}
local hdg_i = math.floor((sol.heading_deg or 0) + 0.5)
local alt_i = math.floor((sol.target_alt or 0) / 100.0 + 0.5) * 100
local rng_km = math.floor((ctx.range or 0) / 1000.0 + 0.5)
local aspect_i = math.floor((ctx.aspect_angle or 0) + 0.5)
local delay = tx.delay_sec
local state = ctx.state or "VECTOR"
local prev_state = prev.state or "VECTOR"
local ticks = ctx.ticks_in_state or 0
local function emit(fmt, ...)
tx.token_str = string.format(fmt, ...)
end
if state == "VECTOR" then
if prev_state ~= "VECTOR" then
local tti_m = math.floor((sol.time_to_intercept or 0) / 60.0)
local tti_s = math.floor(sol.time_to_intercept or 0) % 60
if tti_m > 0 then
emit("VECTOR_WITH_TTI|hdg=%d|alt=%d|rng=%d|tti_m=%d|tti_s=%d|delay=%.1f",
hdg_i, alt_i, rng_km, tti_m, tti_s, delay)
else
emit("VECTOR|hdg=%d|alt=%d|rng=%d|delay=%.1f",
hdg_i, alt_i, rng_km, delay)
end
else
local hdg_delta = math.abs((sol.heading_deg or 0) - (ctx.aspect_angle or 0))
if hdg_delta < 5.0 and ticks > 3 then
tx.silence = true
else
emit("VECTOR|hdg=%d|alt=%d|rng=%d|delay=%.1f",
hdg_i, alt_i, rng_km, delay)
end
end
elseif state == "COMMIT" then
if prev_state ~= "COMMIT" then
tx.priority = 100
emit("COMMIT_FIRST|hdg=%d|alt=%d|rng=%d|aspect=%d|delay=%.1f",
hdg_i, alt_i, rng_km, aspect_i, delay)
elseif ticks == 6 then
emit("COMMIT_NO_LOCK|hdg=%d|rng=%d|aspect=%d|delay=%.1f",
hdg_i, rng_km, aspect_i, delay)
elseif ticks > 8 then
emit("COMMIT_NUDGE|hdg=%d|aspect=%d|delay=%.1f",
hdg_i, aspect_i, delay)
else
tx.silence = true
end
elseif state == "RADAR_CONTACT" then
if prev_state ~= "RADAR_CONTACT" then
if sol.weapons_free then
tx.priority = 100
emit("RADAR_LOCK_WF|rng=%d|delay=%.1f", rng_km, delay)
tx.weapons_free = true
else
emit("RADAR_LOCK_HOLD|rng=%d|delay=%.1f", rng_km, delay)
end
elseif not sol.weapons_free
and (ctx.range or 0) < C.WF_RANGE_MAX
and (ctx.aspect_angle or 0) > C.ASPECT_REAR_ATTACK
and prev_state == "RADAR_CONTACT" then
emit("RADAR_WF_NOW|rng=%d|delay=%.1f", rng_km, delay)
tx.priority = 100
tx.weapons_free = true
else
tx.silence = true
end
elseif state == "VISUAL" then
if prev_state ~= "VISUAL" then
emit("VISUAL_CONFIRM|rng=%d|delay=%.1f", rng_km, delay)
tx.weapons_free = true
else
tx.silence = true
end
elseif state == "NOTCH" then
if prev_state ~= "NOTCH" then
emit("NOTCH_ENTRY|delay=1.5")
elseif ticks % 8 == 0 then
emit("NOTCH_UPDATE|rng=%d|aspect=%d|delay=%.1f",
rng_km, aspect_i, delay)
else
tx.silence = true
end
elseif state == "ABORT" then
tx.delay_sec = 1.5
if (ctx.fuel_fraction or 1.0) < C.FUEL_BINGO then
emit("ABORT_BINGO|hdg=%d|delay=1.5", hdg_i)
else
emit("ABORT_THREAT|hdg=%d|delay=1.5", hdg_i)
end
else
tx.silence = true
end
return tx
end
-- ─────────────────────────────────────────────────────────────
-- mergeTransition (Port von gci_merge_transition)
--
-- ctx Felder: phase, ticks_in_phase, range, bearing_to_target,
-- closure_rate, altitude_delta, pass_count, radar_lost
-- Rückgabe: phase string
-- "ENTRY"|"OVERSHOOT"|"SEPARATION"|"REATTACK"|"LOST"|"SPLASH"
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.mergeTransition(ctx, prev)
if ctx.radar_lost then return "LOST" end
if (ctx.closure_rate or 0) < -30.0 and (ctx.range or 0) > 3000.0 then
return "SEPARATION"
end
local brg = ctx.bearing_to_target or 0
if brg > 100.0 and brg < 260.0 and (ctx.range or 0) < 5000.0 then
return "OVERSHOOT"
end
if ctx.phase == "SEPARATION" and (ctx.pass_count or 0) < 3 then
return "REATTACK"
end
return ctx.phase
end
-- ─────────────────────────────────────────────────────────────
-- buildMergeTransmission (Port von gci_build_merge_transmission)
-- ─────────────────────────────────────────────────────────────
function REDGCI_KERNEL.buildMergeTransmission(ctx, prev)
local C = REDGCI_KERNEL.C
local tx = {
token_str = "",
delay_sec = REDGCI_KERNEL.clamp(
REDGCI_KERNEL.randDelay(C.DELAY_MERGE_MIN, C.DELAY_MERGE_MAX), 2.0, 5.0),
weapons_free = false,
silence = false,
priority = 50,
}
local brg = math.floor((ctx.bearing_to_target or 0) + 0.5)
local rng_km = math.floor((ctx.range or 0) / 1000.0 + 0.5)
local delay = tx.delay_sec
local phase = ctx.phase or "ENTRY"
local prev_phase = prev.phase or "ENTRY"
local ticks = ctx.ticks_in_phase or 0
local dir_rl = ((ctx.bearing_to_target or 0) < 180.0) and "right" or "left"
local alt_d = ctx.altitude_delta or 0
local alt_rel = ""
if alt_d > 400.0 then alt_rel = "low"
elseif alt_d < -400.0 then alt_rel = "high"
end
local function emit(fmt, ...)
tx.token_str = string.format(fmt, ...)
end
if phase == "ENTRY" then
tx.priority = 100
emit("MERGE_ENTRY|brg=%d|dir_rl=%s|delay=%.1f", brg, dir_rl, delay)
elseif phase == "OVERSHOOT" then
emit("MERGE_OVERSHOOT|brg=%d|dir_rl=%s|alt_rel=%s|delay=%.1f",
brg, dir_rl, alt_rel, delay)
elseif phase == "SEPARATION" then
if (ctx.pass_count or 0) < 3 then
emit("MERGE_REATTACK|brg=%d|rng=%d|delay=%.1f", brg, rng_km, delay)
else
emit("ABORT_THREAT|hdg=%d|delay=%.1f", brg, delay)
end
elseif phase == "REATTACK" then
if prev_phase ~= "REATTACK" or ticks % 3 == 0 then
emit("MERGE_REATTACK|brg=%d|rng=%d|delay=%.1f", brg, rng_km, delay)
else
tx.silence = true
end
elseif phase == "LOST" then
if prev_phase ~= "LOST" or ticks == 4 then
emit("MERGE_LOST|brg=%d|rng=%d|delay=%.1f", brg, rng_km, delay)
else
tx.silence = true
end
elseif phase == "SPLASH" then
tx.delay_sec = 1.5
tx.priority = 100
emit("MERGE_SPLASH|delay=1.5")
else
tx.silence = true
end
return tx
end
-------------------------------------------------------------------------------
-- END of Class
-------------------------------------------------------------------------------
+5
View File
@@ -80,6 +80,11 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Stratego.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ClientWatch.lua')
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Formation.lua')
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/RedGCIKernel.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/RedGCI.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/RedGCI2v2.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/RedGCIDispatcher.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Airboss.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RecoveryTanker.lua' )
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RescueHelo.lua' )
+1 -1
View File
@@ -2661,7 +2661,7 @@ function LEGION._CohortCan(Cohort, MissionType, Categories, Attributes, Properti
local RangeMax = RangeMax or 0
local InRange=(RangeMax and math.max(RangeMax, Rmax) or Rmax) >= TargetDistance and TargetDistance > RangeMin
--env.info(string.format("Range TargetDist=%.1f Rmax=%.1f RangeMax=%.1f InRange=%s", TargetDistance, Rmax, RangeMax, tostring(InRange)))
--env.info(string.format("Range TargetDist=%.1f Rmax=%.1f RangeMax=%.1f InRange=%s RangeMin=%s", TargetDistance, Rmax, RangeMax, tostring(InRange),tostring(RangeMin)))
return InRange
end
+3 -3
View File
@@ -2108,7 +2108,7 @@ function MSRS:_HoundTextToSpeech(Message,Frequencies,Modulations,Volume,Label,Co
local ffs = {}
for _,_f in pairs(Frequencies) do
table.insert(ffs,string.format("%.1f",_f))
table.insert(ffs,string.format("%.3f",_f))
end
local freqs = table.concat(ffs, ",")
@@ -2214,7 +2214,7 @@ function MSRS:_HoundTestTone(Frequencies, Modulations, Coalition)
local ffs = {}
for _,_f in pairs(Frequencies or self.frequencies) do
table.insert(ffs,string.format("%.1f",_f))
table.insert(ffs,string.format("%.3f",_f))
end
local freqs = table.concat(ffs, ",")
@@ -2291,7 +2291,7 @@ function MSRS:RadioJammerOn(Frequencies, Modulations, Coalition, Noisetype, Volu
local ffs = {}
for _,_f in pairs(Frequencies or self.frequencies) do
table.insert(ffs,string.format("%.1f",_f))
table.insert(ffs,string.format("%.3f",_f))
end
local freqs = table.concat(ffs, ",")
+11 -46
View File
@@ -131,24 +131,14 @@ ENUMS.WeaponFlag={
Cannons = 805306368, -- GUN_POD + BuiltInCannon
--- Torpedo
Torpedo = 4294967296,
--- Decoy
Decoys = 8589934592,
--- Shell
SmokeShell = 17179869184,
IlluminationShell = 34359738368,
MarkerShell = 51539607552,
MarkerWeapon = 51539620864,
SubmunitionDispenserShell = 68719476736,
ConventionalShell = 206963736576,
---
-- Even More Genral
Auto = 265214230526, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons + Torpedos)
AutoDCS = 1073741822, -- Something if often see
AnyAG = 2956984318, -- Any Air-To-Ground Weapon
AnyAA = 264241152, -- Any Air-To-Air Weapon
AnyUnguided = 2952822768, -- Any Unguided Weapon
AnyGuided = 268402702, -- Any Guided Weapon
AnyShell = 258503344128, -- Any Shell
Auto = 3221225470, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons)
AutoDCS = 1073741822, -- Something if often see
AnyAG = 2956984318, -- Any Air-To-Ground Weapon
AnyAA = 264241152, -- Any Air-To-Air Weapon
AnyUnguided = 2952822768, -- Any Unguided Weapon
AnyGuided = 268402702, -- Any Guided Weapon
}
--- Weapon types by category. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on hoggit wiki.
@@ -230,11 +220,11 @@ ENUMS.WeaponType.Torpedo={
}
ENUMS.WeaponType.Any={
-- General combinations
Weapon = 265214230526, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons + Torpedos)
AG = 2956984318, -- Any Air-To-Ground Weapon
AA = 264241152, -- Any Air-To-Air Weapon
Unguided = 2952822768, -- Any Unguided Weapon
Guided = 268402702, -- Any Guided Weapon
Weapon = 3221225470, -- Any Weapon (AnyBomb + AnyRocket + AnyMissile + Cannons)
AG = 2956984318, -- Any Air-To-Ground Weapon
AA = 264241152, -- Any Air-To-Air Weapon
Unguided = 2952822768, -- Any Unguided Weapon
Guided = 268402702, -- Any Guided Weapon
}
@@ -1808,21 +1798,13 @@ ENUMS.Storage.weapons.missiles.Igla_S = 'weapons.missiles.Igla_S'
ENUMS.Storage.weapons.gunmounts.AKAN_NO_TRC = 'weapons.gunmounts.{AKAN_NO_TRC}'
ENUMS.Storage.weapons.gunmounts.AKAN = 'weapons.gunmounts.{AKAN}'
ENUMS.Storage.weapons.shells.M882_9x19 = 'weapons.shells.9x19_m882'
ENUMS.Storage.weapons.droptanks.fuel_tank_370gal = "weapons.droptanks.fuel_tank_370gal"
ENUMS.Storage.weapons.droptanks.fuel_tank_300gal = "weapons.droptanks.fuel_tank_300gal"
-- NEW
ENUMS.Storage.weapons.adapters.HB_F_4E_ORD_LAU_77 = 'weapons.adapters.HB_F-4E_ORD_LAU_77'
ENUMS.Storage.weapons.adapters.hb_a_6e_lau7_adu299 = 'weapons.adapters.hb_a-6e_lau7_adu299'
ENUMS.Storage.weapons.adapters.CHAP_AIM92LN = 'weapons.adapters.CHAP_AIM92LN'
ENUMS.Storage.weapons.adapters.CHAP_HOT3LN = 'weapons.adapters.CHAP_HOT3LN'
ENUMS.Storage.weapons.adapters.CHAP_FZ225 = 'weapons.adapters.CHAP_FZ225'
ENUMS.Storage.weapons.bombs.AH6_SMOKE_BLUE = 'weapons.bombs.AH6_SMOKE_BLUE'
ENUMS.Storage.weapons.bombs.AH6_SMOKE_GREEN = 'weapons.bombs.AH6_SMOKE_GREEN'
ENUMS.Storage.weapons.bombs.AH6_SMOKE_RED = 'weapons.bombs.AH6_SMOKE_RED'
ENUMS.Storage.weapons.bombs.AH6_SMOKE_YELLOW = 'weapons.bombs.AH6_SMOKE_YELLOW'
ENUMS.Storage.weapons.bombs.AO_25SL = 'weapons.bombs.AO_25SL'
ENUMS.Storage.weapons.missiles.HB_AGM_78 = 'weapons.missiles.HB_AGM_78'
ENUMS.Storage.weapons.missiles.V_1 = 'weapons.missiles.V-1'
@@ -1869,10 +1851,6 @@ ENUMS.Storage.weapons.shells.M42A1_HE = 'weapons.shells.M42A1_HE'
ENUMS.Storage.weapons.shells.HE_20x138B = 'weapons.shells.20x138B_HE'
ENUMS.Storage.weapons.shells.HE_37x263 = 'weapons.shells.37x263_HE'
ENUMS.Storage.weapons.shells.HE_2A20_115mm = 'weapons.shells.2A20_115mm_HE'
ENUMS.Storage.weapons.shells.AP_20x99R = 'weapons.shells.20x99R_AP'
ENUMS.Storage.weapons.shells.IranFAC_DShK_API_T = 'weapons.shells.IranFAC_DShK_API_T'
ENUMS.Storage.weapons.shells.IranFAC_DShK_API = 'weapons.shells.IranFAC_DShK_API'
ENUMS.Storage.weapons.shells.HE_T_20x99R = 'weapons.shells.20x99R_HE_T'
ENUMS.Storage.weapons.gunmounts.B17_TailTurret_M2_L = 'weapons.gunmounts.B17_TailTurret_M2_L'
ENUMS.Storage.weapons.gunmounts.AH6_M134L = 'weapons.gunmounts.{AH6_M134L}'
@@ -1903,11 +1881,6 @@ ENUMS.Storage.weapons.gunmounts.AH_6_FN_HMP400 = 'weapons.gunmounts.{AH-6_FN_HMP
ENUMS.Storage.weapons.gunmounts.AH_6_M134L = 'weapons.gunmounts.AH-6_M134L'
ENUMS.Storage.weapons.gunmounts.AH_6_M134R = 'weapons.gunmounts.AH-6_M134R'
ENUMS.Storage.weapons.gunmounts.AH_6_HMP400 = 'weapons.gunmounts.AH-6_HMP400'
ENUMS.Storage.weapons.gunmounts.AKAN_NO_TRC = 'weapons.gunmounts.{AKAN_NO_TRC}'
ENUMS.Storage.weapons.gunmounts.AKAN = 'weapons.gunmounts.{AKAN}'
ENUMS.Storage.weapons.gunmounts.CHAP_HMP400LC = 'weapons.gunmounts.{CHAP_HMP400LC}'
ENUMS.Storage.weapons.gunmounts.HMP400LC = 'weapons.gunmounts.HMP400LC'
ENUMS.Storage.weapons.gunmounts.SHVAK_GUN = 'weapons.gunmounts.SHVAK_GUN'
ENUMS.Storage.weapons.droptanks.PTB_800 = 'weapons.droptanks.PTB-800'
ENUMS.Storage.weapons.droptanks.PTB_275 = 'weapons.droptanks.PTB-275'
@@ -1958,7 +1931,6 @@ ENUMS.Storage.weapons.droptanks.S_3_PTB = 'weapons.droptanks.S-3-PTB'
ENUMS.Storage.weapons.droptanks.fuel_tank_370gal = 'weapons.droptanks.fuel_tank_370gal'
ENUMS.Storage.weapons.droptanks.MIG_23_PTB = 'weapons.droptanks.MIG-23-PTB'
ENUMS.Storage.weapons.droptanks.f_18c_ptb = 'weapons.droptanks.f-18c-ptb'
ENUMS.Storage.weapons.droptanks.CHAP_TigerUHT_fueltank = 'weapons.droptanks.CHAP_TigerUHT_fueltank'
ENUMS.Storage.weapons.containers.FN_HMP400_100 = 'weapons.containers.{FN_HMP400_100}'
ENUMS.Storage.weapons.containers.AN_M3 = 'weapons.containers.{AN-M3}'
@@ -2090,13 +2062,6 @@ ENUMS.Storage.weapons.containers.GIAT_M621_AP = 'weapons.containers.{GIAT_M621_A
ENUMS.Storage.weapons.containers.M134_R = 'weapons.containers.M134_R'
ENUMS.Storage.weapons.containers.OH58D_M3P_L300 = 'weapons.containers.OH58D_M3P_L300'
ENUMS.Storage.weapons.containers.AH6_M134R = 'weapons.containers.{AH6_M134R}'
ENUMS.Storage.weapons.containers.CHAP_HMP400LC = 'weapons.containers.{CHAP_HMP400LC}'
ENUMS.Storage.weapons.missiles.C701_AShM = 'weapons.missiles.C701 AShM'
ENUMS.Storage.weapons.missiles.IGLA_9M39 = 'weapons.missiles.9M39_IGLA'
ENUMS.Storage.weapons.missiles.CHAP_AIM92 = 'weapons.missiles.CHAP_AIM92'
ENUMS.Storage.weapons.missiles.AM39 = 'weapons.missiles.AM39'
ENUMS.Storage.weapons.missiles.Shahed136_LM = 'weapons.missiles.Shahed136_LM'
ENUMS.Storage.weapons.torpedoes.G7A_T1 = 'weapons.torpedoes.G7A_T1'
+2 -2
View File
@@ -753,8 +753,8 @@ UTILS.KnotsToKmph = function(knots)
return knots * 1.852
end
UTILS.KmphToKnots = function(knots)
return knots / 1.852
UTILS.KmphToKnots = function(kmph)
return kmph / 1.852
end
UTILS.KmphToMps = function( kmph )
+4
View File
@@ -76,6 +76,10 @@ Functional/Tiresias.lua
Functional/Stratego.lua
Functional/ClientWatch.lua
Functional/Formation.lua
Functional/RedGCIKernel.lua
Functional/RedGCI.lua
Functional/RedGCI2v2.lua
Functional/RedGCIDispatcher.lua
Ops/Airboss.lua
Ops/RecoveryTanker.lua