mirror of
https://github.com/iTracerFacer/DCS_MissionDev.git
synced 2025-12-03 04:14:46 +00:00
-- Safety rules around Supply (Pickup) Zones
ForbidDropsInsidePickupZones = true, -- if true, players cannot drop crates while inside a Pickup Zone ForbidTroopDeployInsidePickupZones = true, -- if true, players cannot deploy troops while inside a Pickup Zone ForbidChecksActivePickupOnly = true, -- when true, restriction applies only to ACTIVE pickup zones; set false to block inside any configured pickup zone
This commit is contained in:
parent
4ec8f2b039
commit
ec1a066f42
@ -8,6 +8,23 @@
|
|||||||
-- Outputs: F10 menus for helo/transport groups; crate spawning/building; troop load/unload; optional JTAC hookup (via FAC module);
|
-- Outputs: F10 menus for helo/transport groups; crate spawning/building; troop load/unload; optional JTAC hookup (via FAC module);
|
||||||
-- Error modes: missing Moose -> abort; unknown crate key -> message; spawn blocked in enemy airbase; zone missing -> message.
|
-- Error modes: missing Moose -> abort; unknown crate key -> message; spawn blocked in enemy airbase; zone missing -> message.
|
||||||
|
|
||||||
|
-- Table of Contents (navigation)
|
||||||
|
-- 1) Config (version, messaging, main Config table)
|
||||||
|
-- 2) State
|
||||||
|
-- 3) Utilities
|
||||||
|
-- 4) Construction (zones, bindings, init)
|
||||||
|
-- 5) Menus (group/coalition, dynamic lists)
|
||||||
|
-- 6) Coalition Summary
|
||||||
|
-- 7) Crates (request/spawn, nearby, cleanup)
|
||||||
|
-- 8) Build logic
|
||||||
|
-- 9) Loaded crate management
|
||||||
|
-- 10) Hover pickup scanner
|
||||||
|
-- 11) Troops
|
||||||
|
-- 12) Auto-build FOB in zones
|
||||||
|
-- 13) Inventory helpers
|
||||||
|
-- 14) Public helpers (catalog registration/merge)
|
||||||
|
-- 15) Export
|
||||||
|
|
||||||
if not _G.BASE then
|
if not _G.BASE then
|
||||||
env.info('[Moose_CTLD] Moose (BASE) not detected. Ensure Moose.lua is loaded before Moose_CTLD.lua')
|
env.info('[Moose_CTLD] Moose (BASE) not detected. Ensure Moose.lua is loaded before Moose_CTLD.lua')
|
||||||
end
|
end
|
||||||
@ -63,6 +80,7 @@ CTLD.Version = '0.1.0-alpha'
|
|||||||
|
|
||||||
-- Immersive Hover Coach configuration (messages, thresholds, throttling)
|
-- Immersive Hover Coach configuration (messages, thresholds, throttling)
|
||||||
-- All user-facing text lives here; logic only fills placeholders.
|
-- All user-facing text lives here; logic only fills placeholders.
|
||||||
|
-- #region Messaging
|
||||||
CTLD.HoverCoachConfig = {
|
CTLD.HoverCoachConfig = {
|
||||||
enabled = true, -- master switch for hover coaching messages
|
enabled = true, -- master switch for hover coaching messages
|
||||||
coachOnByDefault = true, -- future per-player toggle; currently always on when enabled
|
coachOnByDefault = true, -- future per-player toggle; currently always on when enabled
|
||||||
@ -150,8 +168,14 @@ CTLD.Messages = {
|
|||||||
attack_enemy_announce = "{unit_name} deployed by {player} has spotted an enemy {enemy_type} at {brg}°, {rng} {rng_u}. Moving to engage!",
|
attack_enemy_announce = "{unit_name} deployed by {player} has spotted an enemy {enemy_type} at {brg}°, {rng} {rng_u}. Moving to engage!",
|
||||||
attack_base_announce = "{unit_name} deployed by {player} is moving to capture {base_name} at {brg}°, {rng} {rng_u}.",
|
attack_base_announce = "{unit_name} deployed by {player} is moving to capture {base_name} at {brg}°, {rng} {rng_u}.",
|
||||||
attack_no_targets = "{unit_name} deployed by {player} found no targets within {rng} {rng_u}. Holding position.",
|
attack_no_targets = "{unit_name} deployed by {player} found no targets within {rng} {rng_u}. Holding position.",
|
||||||
|
|
||||||
|
-- Zone restrictions
|
||||||
|
drop_forbidden_in_pickup = "Cannot drop crates inside a Supply Zone. Move outside the zone boundary.",
|
||||||
|
troop_deploy_forbidden_in_pickup = "Cannot deploy troops inside a Supply Zone. Move outside the zone boundary.",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- #endregion Messaging
|
||||||
|
|
||||||
CTLD.Config = {
|
CTLD.Config = {
|
||||||
CoalitionSide = coalition.side.BLUE, -- default coalition this instance serves (menus created for this side)
|
CoalitionSide = coalition.side.BLUE, -- default coalition this instance serves (menus created for this side)
|
||||||
AllowedAircraft = { -- transport-capable unit type names (case-sensitive as in DCS DB)
|
AllowedAircraft = { -- transport-capable unit type names (case-sensitive as in DCS DB)
|
||||||
@ -178,6 +202,10 @@ CTLD.Config = {
|
|||||||
RequirePickupZoneForCrateRequest = true, -- enforce that crate requests must be near a Supply (Pickup) Zone
|
RequirePickupZoneForCrateRequest = true, -- enforce that crate requests must be near a Supply (Pickup) Zone
|
||||||
RequirePickupZoneForTroopLoad = true, -- if true, troops can only be loaded while inside a Supply (Pickup) Zone
|
RequirePickupZoneForTroopLoad = true, -- if true, troops can only be loaded while inside a Supply (Pickup) Zone
|
||||||
PickupZoneMaxDistance = 10000, -- meters; nearest pickup zone must be within this distance to allow a request
|
PickupZoneMaxDistance = 10000, -- meters; nearest pickup zone must be within this distance to allow a request
|
||||||
|
-- Safety rules around Supply (Pickup) Zones
|
||||||
|
ForbidDropsInsidePickupZones = true, -- if true, players cannot drop crates while inside a Pickup Zone
|
||||||
|
ForbidTroopDeployInsidePickupZones = true, -- if true, players cannot deploy troops while inside a Pickup Zone
|
||||||
|
ForbidChecksActivePickupOnly = true, -- when true, restriction applies only to ACTIVE pickup zones; set false to block inside any configured pickup zone
|
||||||
|
|
||||||
-- Attack/Defend AI behavior for deployed troops and built vehicles
|
-- Attack/Defend AI behavior for deployed troops and built vehicles
|
||||||
AttackAI = {
|
AttackAI = {
|
||||||
@ -198,7 +226,7 @@ CTLD.Config = {
|
|||||||
FontSize = 18, -- label text size
|
FontSize = 18, -- label text size
|
||||||
ReadOnly = true, -- prevent clients from removing the shapes
|
ReadOnly = true, -- prevent clients from removing the shapes
|
||||||
ForAll = false, -- if true, draw shapes to all (-1) instead of coalition only (useful for testing/briefing)
|
ForAll = false, -- if true, draw shapes to all (-1) instead of coalition only (useful for testing/briefing)
|
||||||
OutlineColor = {1, 1, 0, 0.85}, -- RGBA 0..1 for outlines (bright yellow)
|
OutlineColor = {1, 1, 0, 0.85}, -- RGBA 0..1 for outlines (bright yellow)
|
||||||
-- Optional per-kind fill overrides
|
-- Optional per-kind fill overrides
|
||||||
FillColors = {
|
FillColors = {
|
||||||
Pickup = {0, 1, 0, 0.15}, -- light green fill for Pickup zones
|
Pickup = {0, 1, 0, 0.15}, -- light green fill for Pickup zones
|
||||||
@ -211,11 +239,11 @@ CTLD.Config = {
|
|||||||
Drop = 2, -- dashed
|
Drop = 2, -- dashed
|
||||||
FOB = 4, -- dot-dash
|
FOB = 4, -- dot-dash
|
||||||
},
|
},
|
||||||
-- Label placement tuning (simple):
|
-- Label placement tuning (simple):
|
||||||
-- Effective extra offset from the circle edge = r * LabelOffsetRatio + LabelOffsetFromEdge
|
-- Effective extra offset from the circle edge = r * LabelOffsetRatio + LabelOffsetFromEdge
|
||||||
LabelOffsetFromEdge = -50, -- meters beyond the zone radius to place the label (12 o'clock)
|
LabelOffsetFromEdge = -50, -- meters beyond the zone radius to place the label (12 o'clock)
|
||||||
LabelOffsetRatio = 0.5, -- fraction of the radius to add to the offset (e.g., 0.1 => +10% of r)
|
LabelOffsetRatio = 0.5, -- fraction of the radius to add to the offset (e.g., 0.1 => +10% of r)
|
||||||
LabelOffsetX = 200, -- meters: horizontal nudge; adjust if text appears left-anchored in your DCS build
|
LabelOffsetX = 200, -- meters: horizontal nudge; adjust if text appears left-anchored in your DCS build
|
||||||
-- Per-kind label prefixes
|
-- Per-kind label prefixes
|
||||||
LabelPrefixes = {
|
LabelPrefixes = {
|
||||||
Pickup = 'Supply Zone',
|
Pickup = 'Supply Zone',
|
||||||
@ -428,6 +456,22 @@ local function _nearestZonePoint(unit, list)
|
|||||||
return best, bestd
|
return best, bestd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Check if a unit is inside a Pickup Zone. Returns (inside:boolean, zone, dist, radius)
|
||||||
|
function CTLD:_isUnitInsidePickupZone(unit, activeOnly)
|
||||||
|
if not unit or not unit:IsAlive() then return false, nil, nil, nil end
|
||||||
|
local zone, dist
|
||||||
|
if activeOnly then
|
||||||
|
zone, dist = self:_nearestActivePickupZone(unit)
|
||||||
|
else
|
||||||
|
local defs = self.Config and self.Config.Zones and self.Config.Zones.PickupZones or {}
|
||||||
|
zone, dist = _nearestZonePoint(unit, defs)
|
||||||
|
end
|
||||||
|
if not zone or not dist then return false, nil, nil, nil end
|
||||||
|
local r = self:_getZoneRadius(zone)
|
||||||
|
if not r then return false, zone, dist, nil end
|
||||||
|
return dist <= r, zone, dist, r
|
||||||
|
end
|
||||||
|
|
||||||
-- Helper: get nearest ACTIVE pickup zone (by configured list), respecting CTLD's active flags
|
-- Helper: get nearest ACTIVE pickup zone (by configured list), respecting CTLD's active flags
|
||||||
function CTLD:_nearestActivePickupZone(unit)
|
function CTLD:_nearestActivePickupZone(unit)
|
||||||
local function _activePickupDefs()
|
local function _activePickupDefs()
|
||||||
@ -2362,6 +2406,7 @@ end
|
|||||||
-- =========================
|
-- =========================
|
||||||
-- Coalition Summary
|
-- Coalition Summary
|
||||||
-- =========================
|
-- =========================
|
||||||
|
-- #region Coalition Summary
|
||||||
function CTLD:ShowCoalitionSummary()
|
function CTLD:ShowCoalitionSummary()
|
||||||
-- Crate counts per type (this coalition)
|
-- Crate counts per type (this coalition)
|
||||||
local perType = {}
|
local perType = {}
|
||||||
@ -2458,11 +2503,13 @@ function CTLD:ShowCoalitionSummary()
|
|||||||
|
|
||||||
_msgCoalition(self.Side, table.concat(lines, '\n'), 25)
|
_msgCoalition(self.Side, table.concat(lines, '\n'), 25)
|
||||||
end
|
end
|
||||||
|
-- #endregion Coalition Summary
|
||||||
|
|
||||||
-- =========================
|
-- =========================
|
||||||
-- Crates
|
-- Crates
|
||||||
-- =========================
|
-- =========================
|
||||||
-- #region Crates
|
-- #region Crates
|
||||||
|
-- Note: Menu creation lives in the Menus region; this section handles crate request/spawn/nearby/cleanup only.
|
||||||
function CTLD:RequestCrateForGroup(group, crateKey)
|
function CTLD:RequestCrateForGroup(group, crateKey)
|
||||||
local cat = self.Config.CrateCatalog[crateKey]
|
local cat = self.Config.CrateCatalog[crateKey]
|
||||||
if not cat then _msgGroup(group, 'Unknown crate type: '..tostring(crateKey)) return end
|
if not cat then _msgGroup(group, 'Unknown crate type: '..tostring(crateKey)) return end
|
||||||
@ -2913,6 +2960,18 @@ function CTLD:DropLoadedCrates(group, howMany)
|
|||||||
if not lc or (lc.total or 0) == 0 then _eventSend(self, group, nil, 'no_loaded_crates', {}) return end
|
if not lc or (lc.total or 0) == 0 then _eventSend(self, group, nil, 'no_loaded_crates', {}) return end
|
||||||
local unit = group:GetUnit(1)
|
local unit = group:GetUnit(1)
|
||||||
if not unit or not unit:IsAlive() then return end
|
if not unit or not unit:IsAlive() then return end
|
||||||
|
-- Restrict dropping crates inside Pickup Zones if configured
|
||||||
|
if self.Config.ForbidDropsInsidePickupZones then
|
||||||
|
local activeOnly = (self.Config.ForbidChecksActivePickupOnly ~= false)
|
||||||
|
local inside = false
|
||||||
|
local ok, err = pcall(function()
|
||||||
|
inside = select(1, self:_isUnitInsidePickupZone(unit, activeOnly))
|
||||||
|
end)
|
||||||
|
if ok and inside then
|
||||||
|
_eventSend(self, group, nil, 'drop_forbidden_in_pickup', {})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
local p = unit:GetPointVec3()
|
local p = unit:GetPointVec3()
|
||||||
local here = { x = p.x, z = p.z }
|
local here = { x = p.x, z = p.z }
|
||||||
local initialTotal = lc.total or 0
|
local initialTotal = lc.total or 0
|
||||||
@ -3198,6 +3257,18 @@ function CTLD:UnloadTroops(group, opts)
|
|||||||
|
|
||||||
local unit = group:GetUnit(1)
|
local unit = group:GetUnit(1)
|
||||||
if not unit or not unit:IsAlive() then return end
|
if not unit or not unit:IsAlive() then return end
|
||||||
|
-- Restrict deploying troops inside Pickup Zones if configured
|
||||||
|
if self.Config.ForbidTroopDeployInsidePickupZones then
|
||||||
|
local activeOnly = (self.Config.ForbidChecksActivePickupOnly ~= false)
|
||||||
|
local inside = false
|
||||||
|
local ok, _ = pcall(function()
|
||||||
|
inside = select(1, self:_isUnitInsidePickupZone(unit, activeOnly))
|
||||||
|
end)
|
||||||
|
if ok and inside then
|
||||||
|
_eventSend(self, group, nil, 'troop_deploy_forbidden_in_pickup', {})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
local p = unit:GetPointVec3()
|
local p = unit:GetPointVec3()
|
||||||
local here = { x = p.x, z = p.z }
|
local here = { x = p.x, z = p.z }
|
||||||
local hdg = unit:GetHeading() or 0
|
local hdg = unit:GetHeading() or 0
|
||||||
@ -3343,6 +3414,7 @@ end
|
|||||||
-- =========================
|
-- =========================
|
||||||
-- Inventory helpers
|
-- Inventory helpers
|
||||||
-- =========================
|
-- =========================
|
||||||
|
-- #region Inventory helpers
|
||||||
function CTLD:InitInventory()
|
function CTLD:InitInventory()
|
||||||
if not (self.Config.Inventory and self.Config.Inventory.Enabled) then return end
|
if not (self.Config.Inventory and self.Config.Inventory.Enabled) then return end
|
||||||
-- Seed stock for each configured pickup zone (by name only)
|
-- Seed stock for each configured pickup zone (by name only)
|
||||||
@ -3381,6 +3453,7 @@ function CTLD:_CreateFOBPickupZone(point, cat, hdg)
|
|||||||
self:_SeedZoneStock(name, f)
|
self:_SeedZoneStock(name, f)
|
||||||
_msgCoalition(self.Side, string.format('FOB supply established: %s (stock seeded at %d%%)', name, math.floor(f*100+0.5)))
|
_msgCoalition(self.Side, string.format('FOB supply established: %s (stock seeded at %d%%)', name, math.floor(f*100+0.5)))
|
||||||
end
|
end
|
||||||
|
-- #endregion Inventory helpers
|
||||||
|
|
||||||
function CTLD:AddPickupZone(z)
|
function CTLD:AddPickupZone(z)
|
||||||
local mz = _findZone(z)
|
local mz = _findZone(z)
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user