mirror of
https://github.com/iTracerFacer/DCS_MissionDev.git
synced 2025-12-03 04:14:46 +00:00
Added support for dual coalition.
This commit is contained in:
parent
9077c97917
commit
2c4bf36a47
@ -28,6 +28,7 @@ CTLD.Config = {
|
||||
},
|
||||
UseGroupMenus = true, -- if true, F10 menus per player group; otherwise coalition-wide
|
||||
UseCategorySubmenus = true, -- if true, organize crate requests by category submenu (menuCategory)
|
||||
UseBuiltinCatalog = false, -- if false, starts with an empty catalog; intended when you preload a global catalog and want only that
|
||||
RestrictFOBToZones = false, -- if true, recipes marked isFOB only build inside configured FOBZones
|
||||
AutoBuildFOBInZones = false, -- if true, CTLD auto-builds FOB recipes when required crates are inside a FOB zone
|
||||
BuildRadius = 60, -- meters around build point to collect crates
|
||||
@ -38,10 +39,21 @@ CTLD.Config = {
|
||||
|
||||
Zones = { -- Optional: supply by name (ME trigger zones) or define coordinates inline
|
||||
PickupZones = {
|
||||
-- examples:
|
||||
-- { name = 'PICKUP_BLUE_MAIN' },
|
||||
-- { name = 'Pickup-West', smoke = trigger.smokeColor.Green },
|
||||
-- { coord = { x = 12345, y = 0, z = 67890 }, radius = 150, name = 'ScriptPickup1' },
|
||||
-- Examples:
|
||||
-- Create 5 trigger zones in the Mission Editor named exactly as below to get started quickly.
|
||||
-- If you run separate CTLD instances for BLUE and RED, give each side its own set of uniquely named zones
|
||||
-- (recommended to avoid overlap). You can keep the simple "Pickup Zone #" pattern per side if you prefer,
|
||||
-- just ensure the names in the ME match what you configure here.
|
||||
--
|
||||
-- Uncomment the lines you want to use:
|
||||
-- { name = 'Pickup Zone 1', smoke = trigger.smokeColor.Green },
|
||||
-- { name = 'Pickup Zone 2', smoke = trigger.smokeColor.Blue },
|
||||
-- { name = 'Pickup Zone 3', smoke = trigger.smokeColor.Orange },
|
||||
-- { name = 'Pickup Zone 4', smoke = trigger.smokeColor.White },
|
||||
-- { name = 'Pickup Zone 5', smoke = trigger.smokeColor.Red },
|
||||
--
|
||||
-- Tip: You can also define zones purely in script (no ME zone needed):
|
||||
-- { coord = { x = 12345, y = 0, z = 67890 }, radius = 150, name = 'Pickup Zone 1' },
|
||||
},
|
||||
DropZones = {
|
||||
-- { name = 'DROP_BLUE_1' },
|
||||
@ -92,7 +104,7 @@ CTLD.Config = {
|
||||
end,
|
||||
},
|
||||
-- Example: FARP/FOB build from 4 crates (spawns helipads + support statics/vehicles)
|
||||
FOB = {
|
||||
FOB = {
|
||||
description = '4x Crates -> FARP/FOB',
|
||||
weight = 500,
|
||||
dcsCargoType = 'container_cargo',
|
||||
@ -100,7 +112,7 @@ CTLD.Config = {
|
||||
isFOB = true, -- mark as FOB recipe for zone restrictions/auto-build
|
||||
side = coalition.side.BLUE,
|
||||
category = Group.Category.GROUND,
|
||||
build = function(point, headingDeg)
|
||||
build = function(point, headingDeg, spawnSide)
|
||||
local heading = math.rad(headingDeg or 0)
|
||||
-- Spawn statics that provide FARP services
|
||||
local function addStatic(typeName, dx, dz, nameSuffix)
|
||||
@ -111,7 +123,7 @@ CTLD.Config = {
|
||||
x = p.x, y = p.z,
|
||||
heading = heading,
|
||||
}
|
||||
coalition.addStaticObject(coalition.side.BLUE, st)
|
||||
coalition.addStaticObject(spawnSide or coalition.side.BLUE, st)
|
||||
end
|
||||
-- Common FARP layout
|
||||
addStatic('FARP', 0, 0, 'PAD')
|
||||
@ -208,6 +220,33 @@ local function _vec3FromUnit(unit)
|
||||
return { x = p.x, y = p.y, z = p.z }
|
||||
end
|
||||
|
||||
-- Determine an approximate radius for a ZONE. Tries MOOSE radius, then trigger zone radius, then configured radius.
|
||||
function CTLD:_getZoneRadius(zone)
|
||||
if zone and zone.Radius then return zone.Radius end
|
||||
local name = zone and zone.GetName and zone:GetName() or nil
|
||||
if name and trigger and trigger.misc and trigger.misc.getZone then
|
||||
local z = trigger.misc.getZone(name)
|
||||
if z and z.radius then return z.radius end
|
||||
end
|
||||
if name and self._ZoneDefs and self._ZoneDefs.FOBZones and self._ZoneDefs.FOBZones[name] then
|
||||
local d = self._ZoneDefs.FOBZones[name]
|
||||
if d and d.radius then return d.radius end
|
||||
end
|
||||
return 150
|
||||
end
|
||||
|
||||
-- Check if a 2D point (x,z) lies within any FOB zone; returns (bool, zone)
|
||||
function CTLD:IsPointInFOBZones(point)
|
||||
for _,z in ipairs(self.FOBZones or {}) do
|
||||
local pz = z:GetPointVec3()
|
||||
local r = self:_getZoneRadius(z)
|
||||
local dx = (pz.x - point.x)
|
||||
local dz = (pz.z - point.z)
|
||||
if (dx*dx + dz*dz) <= (r*r) then return true, z end
|
||||
end
|
||||
return false, nil
|
||||
end
|
||||
|
||||
-- =========================
|
||||
-- Construction
|
||||
-- =========================
|
||||
@ -218,6 +257,24 @@ function CTLD:New(cfg)
|
||||
o.Side = o.Config.CoalitionSide
|
||||
o.MenuRoots = {}
|
||||
o.MenusByGroup = {}
|
||||
|
||||
-- If caller disabled builtin catalog, clear it before merging any globals
|
||||
if o.Config.UseBuiltinCatalog == false then
|
||||
o.Config.CrateCatalog = {}
|
||||
end
|
||||
|
||||
-- If a global catalog was loaded earlier (via DO SCRIPT FILE), merge it automatically
|
||||
-- Supported globals: _CTLD_EXTRACTED_CATALOG (our extractor), CTLD_CATALOG, MOOSE_CTLD_CATALOG
|
||||
do
|
||||
local globalsToCheck = { '_CTLD_EXTRACTED_CATALOG', 'CTLD_CATALOG', 'MOOSE_CTLD_CATALOG' }
|
||||
for _,gn in ipairs(globalsToCheck) do
|
||||
local t = rawget(_G, gn)
|
||||
if type(t) == 'table' then
|
||||
o:MergeCatalog(t)
|
||||
if o.Config.Debug then env.info('[Moose_CTLD] Merged crate catalog from global '..gn) end
|
||||
end
|
||||
end
|
||||
end
|
||||
o:InitZones()
|
||||
o:InitMenus()
|
||||
|
||||
@ -415,6 +472,12 @@ function CTLD:BuildAtGroup(group)
|
||||
local here = { x = p.x, z = p.z }
|
||||
local radius = self.Config.BuildRadius
|
||||
local nearby = self:GetNearbyCrates(here, radius)
|
||||
-- filter crates to coalition side for this CTLD instance
|
||||
local filtered = {}
|
||||
for _,c in ipairs(nearby) do
|
||||
if c.meta.side == self.Side then table.insert(filtered, c) end
|
||||
end
|
||||
nearby = filtered
|
||||
if #nearby == 0 then _msgGroup(group, 'No crates within '..radius..'m') return end
|
||||
|
||||
-- Count by key
|
||||
@ -437,24 +500,30 @@ function CTLD:BuildAtGroup(group)
|
||||
end
|
||||
end
|
||||
|
||||
local insideFOBZone, fz = self:IsPointInFOBZones(here)
|
||||
local fobBlocked = false
|
||||
-- Try composite recipes first (requires is a map of key->qty)
|
||||
for recipeKey,cat in pairs(self.Config.CrateCatalog) do
|
||||
if type(cat.requires) == 'table' and cat.build then
|
||||
local ok = true
|
||||
for reqKey,qty in pairs(cat.requires) do
|
||||
if (counts[reqKey] or 0) < qty then ok = false; break end
|
||||
end
|
||||
if ok then
|
||||
local hdg = unit:GetHeading()
|
||||
local gdata = cat.build({ x = here.x, z = here.z }, math.deg(hdg))
|
||||
local g = _coalitionAddGroup(cat.side or self.Side, cat.category or Group.Category.GROUND, gdata)
|
||||
if g then
|
||||
for reqKey,qty in pairs(cat.requires) do consumeCrates(reqKey, qty) end
|
||||
_msgGroup(group, string.format('Built %s at your location', cat.description or recipeKey))
|
||||
return
|
||||
else
|
||||
_msgGroup(group, 'Build failed: DCS group spawn error')
|
||||
return
|
||||
if cat.isFOB and self.Config.RestrictFOBToZones and not insideFOBZone then
|
||||
fobBlocked = true
|
||||
else
|
||||
local ok = true
|
||||
for reqKey,qty in pairs(cat.requires) do
|
||||
if (counts[reqKey] or 0) < qty then ok = false; break end
|
||||
end
|
||||
if ok then
|
||||
local hdg = unit:GetHeading()
|
||||
local gdata = cat.build({ x = here.x, z = here.z }, math.deg(hdg), cat.side or self.Side)
|
||||
local g = _coalitionAddGroup(cat.side or self.Side, cat.category or Group.Category.GROUND, gdata)
|
||||
if g then
|
||||
for reqKey,qty in pairs(cat.requires) do consumeCrates(reqKey, qty) end
|
||||
_msgGroup(group, string.format('Built %s at your location', cat.description or recipeKey))
|
||||
return
|
||||
else
|
||||
_msgGroup(group, 'Build failed: DCS group spawn error')
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -464,20 +533,29 @@ function CTLD:BuildAtGroup(group)
|
||||
for key,count in pairs(counts) do
|
||||
local cat = self.Config.CrateCatalog[key]
|
||||
if cat and cat.build and (not cat.requires) and count >= (cat.required or 1) then
|
||||
local hdg = unit:GetHeading()
|
||||
local gdata = cat.build({ x = here.x, z = here.z }, math.deg(hdg))
|
||||
local g = _coalitionAddGroup(cat.side or self.Side, cat.category or Group.Category.GROUND, gdata)
|
||||
if g then
|
||||
consumeCrates(key, cat.required or 1)
|
||||
_msgGroup(group, string.format('Built %s at your location', cat.description or key))
|
||||
return
|
||||
if cat.isFOB and self.Config.RestrictFOBToZones and not insideFOBZone then
|
||||
fobBlocked = true
|
||||
else
|
||||
_msgGroup(group, 'Build failed: DCS group spawn error')
|
||||
return
|
||||
local hdg = unit:GetHeading()
|
||||
local gdata = cat.build({ x = here.x, z = here.z }, math.deg(hdg), cat.side or self.Side)
|
||||
local g = _coalitionAddGroup(cat.side or self.Side, cat.category or Group.Category.GROUND, gdata)
|
||||
if g then
|
||||
consumeCrates(key, cat.required or 1)
|
||||
_msgGroup(group, string.format('Built %s at your location', cat.description or key))
|
||||
return
|
||||
else
|
||||
_msgGroup(group, 'Build failed: DCS group spawn error')
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if fobBlocked then
|
||||
_msgGroup(group, 'FOB building is restricted to designated FOB zones. Move inside a FOB zone to build.')
|
||||
return
|
||||
end
|
||||
|
||||
_msgGroup(group, 'Insufficient crates to build any asset here')
|
||||
end
|
||||
|
||||
@ -530,6 +608,78 @@ function CTLD:UnloadTroops(group)
|
||||
end
|
||||
end
|
||||
|
||||
-- =========================
|
||||
-- Public helpers
|
||||
-- =========================
|
||||
-- =========================
|
||||
-- Auto-build FOB in zones
|
||||
-- =========================
|
||||
function CTLD:AutoBuildFOBCheck()
|
||||
if not (self.FOBZones and #self.FOBZones > 0) then return end
|
||||
-- Find any FOB recipe definitions
|
||||
local fobDefs = {}
|
||||
for key,def in pairs(self.Config.CrateCatalog) do if def.isFOB and def.build then fobDefs[key] = def end end
|
||||
if next(fobDefs) == nil then return end
|
||||
|
||||
for _,zone in ipairs(self.FOBZones) do
|
||||
local center = zone:GetPointVec3()
|
||||
local radius = self:_getZoneRadius(zone)
|
||||
local nearby = self:GetNearbyCrates({ x = center.x, z = center.z }, radius)
|
||||
-- filter to this coalition side
|
||||
local filtered = {}
|
||||
for _,c in ipairs(nearby) do if c.meta.side == self.Side then table.insert(filtered, c) end end
|
||||
nearby = filtered
|
||||
if #nearby == 0 then goto continue end
|
||||
|
||||
local counts = {}
|
||||
for _,c in ipairs(nearby) do counts[c.meta.key] = (counts[c.meta.key] or 0) + 1 end
|
||||
|
||||
local function consumeCrates(key, qty)
|
||||
local removed = 0
|
||||
for _,c in ipairs(nearby) do
|
||||
if removed >= qty then break end
|
||||
if c.meta.key == key then
|
||||
local obj = StaticObject.getByName(c.name)
|
||||
if obj then obj:destroy() end
|
||||
CTLD._crates[c.name] = nil
|
||||
removed = removed + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Prefer composite recipes
|
||||
for recipeKey,cat in pairs(fobDefs) do
|
||||
if type(cat.requires) == 'table' then
|
||||
local ok = true
|
||||
for reqKey,qty in pairs(cat.requires) do if (counts[reqKey] or 0) < qty then ok = false; break end end
|
||||
if ok then
|
||||
local gdata = cat.build({ x = center.x, z = center.z }, 0, cat.side or self.Side)
|
||||
local g = _coalitionAddGroup(cat.side or self.Side, cat.category or Group.Category.GROUND, gdata)
|
||||
if g then
|
||||
for reqKey,qty in pairs(cat.requires) do consumeCrates(reqKey, qty) end
|
||||
_msgCoalition(self.Side, string.format('FOB auto-built at %s', zone:GetName()))
|
||||
goto continue -- move to next zone; avoid multiple builds per tick
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Then single-key FOB recipes
|
||||
for key,cat in pairs(fobDefs) do
|
||||
if not cat.requires and (counts[key] or 0) >= (cat.required or 1) then
|
||||
local gdata = cat.build({ x = center.x, z = center.z }, 0, cat.side or self.Side)
|
||||
local g = _coalitionAddGroup(cat.side or self.Side, cat.category or Group.Category.GROUND, gdata)
|
||||
if g then
|
||||
consumeCrates(key, cat.required or 1)
|
||||
_msgCoalition(self.Side, string.format('FOB auto-built at %s', zone:GetName()))
|
||||
goto continue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
-- =========================
|
||||
-- Public helpers
|
||||
-- =========================
|
||||
|
||||
@ -10,9 +10,10 @@ Pure-MOOSE CTLD-style logistics and FAC/RECCE without MIST or mission editor tem
|
||||
|
||||
## Quick start
|
||||
|
||||
1) Load `Moose.lua` first, then include these files (order matters):
|
||||
- `Moose_CTLD_Pure/Moose_CTLD.lua`
|
||||
- `Moose_CTLD_Pure/Moose_CTLD_FAC.lua` (optional, for FAC/RECCE)
|
||||
1) Load `Moose.lua` first, then include these files (order matters). Easiest path: load the crate catalog first so CTLD auto-detects it.
|
||||
- `Moose_CTLD_Pure/catalogs/CrateCatalog_CTLD_Extract.lua` (sets `_CTLD_EXTRACTED_CATALOG`)
|
||||
- `Moose_CTLD_Pure/Moose_CTLD.lua`
|
||||
- `Moose_CTLD_Pure/Moose_CTLD_FAC.lua` (optional, for FAC/RECCE)
|
||||
|
||||
2) Initialize CTLD with minimal config:
|
||||
|
||||
@ -20,15 +21,16 @@ Pure-MOOSE CTLD-style logistics and FAC/RECCE without MIST or mission editor tem
|
||||
local CTLD = dofile(lfs.writedir()..[[Scripts\Moose_CTLD_Pure\Moose_CTLD.lua]])
|
||||
local ctld = CTLD:New({
|
||||
CoalitionSide = coalition.side.BLUE,
|
||||
-- If you want to rely ONLY on the external catalog, disable built-ins
|
||||
-- UseBuiltinCatalog = false,
|
||||
Zones = {
|
||||
PickupZones = { { name = 'PICKUP_BLUE_MAIN' } },
|
||||
DropZones = { { name = 'DROP_BLUE_1' } },
|
||||
},
|
||||
})
|
||||
|
||||
-- Optionally load a larger crate catalog extracted from your CTLD.lua
|
||||
local extracted = dofile(lfs.writedir()..[[Scripts\Moose_CTLD_Pure\catalogs\CrateCatalog_CTLD_Extract.lua]])
|
||||
ctld:MergeCatalog(extracted)
|
||||
-- No manual merge needed if you loaded the catalog file before CTLD.lua.
|
||||
-- Supported globals that auto-merge: _CTLD_EXTRACTED_CATALOG, CTLD_CATALOG, MOOSE_CTLD_CATALOG
|
||||
```
|
||||
|
||||
- If you don't have ME trigger zones, define by coordinates:
|
||||
@ -96,6 +98,12 @@ CrateCatalog = {
|
||||
- Artillery marking uses `Controller.setTask('FireAtPoint')` on configured groups. Ensure those groups exist and are artillery-capable.
|
||||
- JTAC Auto-Lase helper provided: `fac:StartJTACOnGroup(groupName, laserCode, smokeColor)` uses `FAC_AUTO`.
|
||||
|
||||
### Catalog sources and precedence
|
||||
|
||||
- By default, CTLD includes a small built-in sample catalog so it works out-of-the-box.
|
||||
- If you load a catalog file before calling `CTLD:New()`, CTLD auto-merges the global catalog (no extra code needed).
|
||||
- To use only your external catalog and avoid sample entries, set `UseBuiltinCatalog = false` in the `CTLD:New({...})` config.
|
||||
|
||||
## Extending
|
||||
|
||||
- Add radio beacons, FOB build recipes, fuel/ammo crates, and CSAR hooks by registering more `CrateCatalog` entries and/or adding helper methods.
|
||||
|
||||
@ -160,7 +160,9 @@ cat['FOB_SMALL'] = { menuCategory='Support', menu='FOB Crate - Smal
|
||||
-- spawns a harmless placeholder truck for visibility; consumed by FOB_SITE build
|
||||
return singleUnit('Ural-375')(point, headingDeg)
|
||||
end }
|
||||
cat['FOB_SITE'] = { menuCategory='Support', menu='FOB Crates - All', description='FOB Site', dcsCargoType='container_cargo', requires={ FOB_SMALL=3 }, side=nil, category=Group.Category.GROUND,
|
||||
cat['FOB_SITE'] = { menuCategory='Support', menu='FOB Crates - All', description='FOB Site', isFOB=true, dcsCargoType='container_cargo', requires={ FOB_SMALL=3 }, side=nil, category=Group.Category.GROUND,
|
||||
build=multiUnits({ {type='HEMTT TFFT'}, {type='Ural-375 PBU', dx=10, dz=8}, {type='Ural-375', dx=-10, dz=8} }) }
|
||||
|
||||
-- Also export as a global for mission setups that load via DO SCRIPT FILE (no return capture)
|
||||
_CTLD_EXTRACTED_CATALOG = cat
|
||||
return cat
|
||||
|
||||
113
Moose_CTLD_Pure/init_mission_dual_coalition.lua
Normal file
113
Moose_CTLD_Pure/init_mission_dual_coalition.lua
Normal file
@ -0,0 +1,113 @@
|
||||
-- init_mission_dual_coalition.lua
|
||||
-- Use in Mission Editor with DO SCRIPT FILE load order:
|
||||
-- 1) Moose.lua
|
||||
-- 2) Moose_CTLD_Pure/Moose_CTLD.lua
|
||||
-- 3) Moose_CTLD_Pure/catalogs/CrateCatalog_CTLD_Extract.lua -- optional but recommended catalog with BLUE+RED items (_CTLD_EXTRACTED_CATALOG)
|
||||
-- 4) Moose_CTLD_Pure/Moose_CTLD_FAC.lua -- optional FAC/RECCE support
|
||||
-- 5) DO SCRIPT: dofile on this file OR paste the block below directly
|
||||
--
|
||||
-- Zones you should create in the Mission Editor (as trigger zones):
|
||||
-- BLUE: PICKUP_BLUE_MAIN, DROP_BLUE_1, FOB_BLUE_A
|
||||
-- RED : PICKUP_RED_MAIN, DROP_RED_1, FOB_RED_A
|
||||
-- Adjust names below if you use different zone names.
|
||||
|
||||
-- Create CTLD for BLUE
|
||||
ctldBlue = _MOOSE_CTLD:New({
|
||||
CoalitionSide = coalition.side.BLUE,
|
||||
UseCategorySubmenus = true,
|
||||
UseBuiltinCatalog = false, -- rely on external catalog (recommended)
|
||||
RestrictFOBToZones = true,
|
||||
AutoBuildFOBInZones = true,
|
||||
Zones = {
|
||||
PickupZones = { { name = 'PICKUP_BLUE_MAIN' } },
|
||||
DropZones = { { name = 'DROP_BLUE_1' } },
|
||||
FOBZones = { { name = 'FOB_BLUE_A' } },
|
||||
},
|
||||
})
|
||||
|
||||
-- Create CTLD for RED
|
||||
ctldRed = _MOOSE_CTLD:New({
|
||||
CoalitionSide = coalition.side.RED,
|
||||
UseCategorySubmenus = true,
|
||||
UseBuiltinCatalog = false, -- rely on external catalog (recommended)
|
||||
RestrictFOBToZones = true,
|
||||
AutoBuildFOBInZones = true,
|
||||
Zones = {
|
||||
PickupZones = { { name = 'PICKUP_RED_MAIN' } },
|
||||
DropZones = { { name = 'DROP_RED_1' } },
|
||||
FOBZones = { { name = 'FOB_RED_A' } },
|
||||
},
|
||||
})
|
||||
|
||||
-- If the external catalog was loaded (as _CTLD_EXTRACTED_CATALOG), both instances auto-merged it
|
||||
-- thanks to Moose_CTLD.lua. If you want to load it manually or from a different path, you can do:
|
||||
-- local extracted = dofile(lfs.writedir()..[[Scripts\Moose_CTLD_Pure\catalogs\CrateCatalog_CTLD_Extract.lua]])
|
||||
-- ctldBlue:MergeCatalog(extracted)
|
||||
-- ctldRed:MergeCatalog(extracted)
|
||||
|
||||
-- Optional: add a couple of small, side-specific examples if you don't use the big catalog
|
||||
-- (Uncomment to add a simple MANPADS and AAA on each side)
|
||||
-- ctldBlue:RegisterCrate('MANPADS', {
|
||||
-- menuCategory='Infantry', description='2x crates -> MANPADS (Stinger)', dcsCargoType='uh1h_cargo', required=2,
|
||||
-- side=coalition.side.BLUE, category=Group.Category.GROUND,
|
||||
-- build=function(point, headingDeg)
|
||||
-- local hdg = math.rad(headingDeg or 0)
|
||||
-- return { visible=false, lateActivation=false, tasks={}, task='Ground Nothing', route={}, name='CTLD_BP_MANPADS_'..math.random(1,999999),
|
||||
-- units={ { type='Soldier stinger', name='CTLD-Stinger-'..math.random(1,999999), x=point.x, y=point.z, heading=hdg } } }
|
||||
-- end,
|
||||
-- })
|
||||
-- ctldBlue:RegisterCrate('AAA', {
|
||||
-- menuCategory='AAA', description='3x crates -> ZU-23 site', dcsCargoType='container_cargo', required=3,
|
||||
-- side=coalition.side.BLUE, category=Group.Category.GROUND,
|
||||
-- build=function(point, headingDeg)
|
||||
-- local hdg = math.rad(headingDeg or 0)
|
||||
-- local function off(dx,dz) return { x=point.x+dx, z=point.z+dz } end
|
||||
-- local units={
|
||||
-- { type='ZU-23 Emplacement', name='CTLD-ZU23-'..math.random(1,999999), x=point.x, y=point.z, heading=hdg },
|
||||
-- { type='Ural-375', name='CTLD-TRK-'..math.random(1,999999), x=off(15,12).x, y=off(15,12).z, heading=hdg },
|
||||
-- { type='Infantry AK', name='CTLD-INF-'..math.random(1,999999), x=off(-12,-15).x, y=off(-12,-15).z, heading=hdg },
|
||||
-- }
|
||||
-- return { visible=false, lateActivation=false, tasks={}, task='Ground Nothing', units=units, route={}, name='CTLD_BP_AAA_'..math.random(1,999999) }
|
||||
-- end,
|
||||
-- })
|
||||
-- ctldRed:RegisterCrate('MANPADS', {
|
||||
-- menuCategory='Infantry', description='2x crates -> MANPADS (Igla)', dcsCargoType='uh1h_cargo', required=2,
|
||||
-- side=coalition.side.RED, category=Group.Category.GROUND,
|
||||
-- build=function(point, headingDeg)
|
||||
-- local hdg = math.rad(headingDeg or 0)
|
||||
-- -- Using generic infantry to avoid DCS type-name mismatches; replace with accurate manpad unit if desired
|
||||
-- return { visible=false, lateActivation=false, tasks={}, task='Ground Nothing', route={}, name='CTLD_RP_MANPADS_'..math.random(1,999999),
|
||||
-- units={ { type='Infantry AK', name='CTLD-Igla-'..math.random(1,999999), x=point.x, y=point.z, heading=hdg } } }
|
||||
-- end,
|
||||
-- })
|
||||
-- ctldRed:RegisterCrate('AAA', {
|
||||
-- menuCategory='AAA', description='3x crates -> ZU-23 site', dcsCargoType='container_cargo', required=3,
|
||||
-- side=coalition.side.RED, category=Group.Category.GROUND,
|
||||
-- build=function(point, headingDeg)
|
||||
-- local hdg = math.rad(headingDeg or 0)
|
||||
-- local function off(dx,dz) return { x=point.x+dx, z=point.z+dz } end
|
||||
-- local units={
|
||||
-- { type='ZU-23 Emplacement', name='CTLD-ZU23-'..math.random(1,999999), x=point.x, y=point.z, heading=hdg },
|
||||
-- { type='Ural-375', name='CTLD-TRK-'..math.random(1,999999), x=off(15,12).x, y=off(15,12).z, heading=hdg },
|
||||
-- { type='Infantry AK', name='CTLD-INF-'..math.random(1,999999), x=off(-12,-15).x, y=off(-12,-15).z, heading=hdg },
|
||||
-- }
|
||||
-- return { visible=false, lateActivation=false, tasks={}, task='Ground Nothing', units=units, route={}, name='CTLD_RP_AAA_'..math.random(1,999999) }
|
||||
-- end,
|
||||
-- })
|
||||
|
||||
-- Optional: FAC/RECCE for both sides (requires Moose_CTLD_FAC.lua)
|
||||
if _MOOSE_CTLD_FAC then
|
||||
facBlue = _MOOSE_CTLD_FAC:New(ctldBlue, {
|
||||
CoalitionSide = coalition.side.BLUE,
|
||||
Arty = { Enabled = false },
|
||||
})
|
||||
-- facBlue:AddRecceZone({ name = 'RECCE_BLUE_1' })
|
||||
facBlue:Run()
|
||||
|
||||
facRed = _MOOSE_CTLD_FAC:New(ctldRed, {
|
||||
CoalitionSide = coalition.side.RED,
|
||||
Arty = { Enabled = false },
|
||||
})
|
||||
-- facRed:AddRecceZone({ name = 'RECCE_RED_1' })
|
||||
facRed:Run()
|
||||
end
|
||||
46
Moose_CTLD_Pure/init_mission_example.lua
Normal file
46
Moose_CTLD_Pure/init_mission_example.lua
Normal file
@ -0,0 +1,46 @@
|
||||
-- init_mission_example.lua
|
||||
-- Use this with Mission Editor triggers as DO SCRIPT (no paths)
|
||||
-- Load order (Mission Start):
|
||||
-- Option A (catalog first):
|
||||
-- 1) DO SCRIPT FILE: Moose.lua
|
||||
-- 2) DO SCRIPT FILE: Moose_CTLD_Pure/catalogs/CrateCatalog_CTLD_Extract.lua -- sets _CTLD_EXTRACTED_CATALOG
|
||||
-- 3) DO SCRIPT FILE: Moose_CTLD_Pure/Moose_CTLD.lua
|
||||
-- 4) DO SCRIPT FILE: Moose_CTLD_Pure/Moose_CTLD_FAC.lua (optional)
|
||||
-- 5) DO SCRIPT: paste the block below
|
||||
-- Option B (catalog after CTLD file):
|
||||
-- 1) DO SCRIPT FILE: Moose.lua
|
||||
-- 2) DO SCRIPT FILE: Moose_CTLD_Pure/Moose_CTLD.lua
|
||||
-- 3) DO SCRIPT FILE: Moose_CTLD_Pure/catalogs/CrateCatalog_CTLD_Extract.lua -- still fine: load before ctld:New()
|
||||
-- 4) DO SCRIPT FILE: Moose_CTLD_Pure/Moose_CTLD_FAC.lua (optional)
|
||||
-- 5) DO SCRIPT: paste the block below
|
||||
|
||||
-- create CTLD instance for BLUE
|
||||
ctld = _MOOSE_CTLD:New({
|
||||
CoalitionSide = coalition.side.BLUE,
|
||||
UseCategorySubmenus = true,
|
||||
-- Set to false if you want ONLY the external catalog and no built-in examples
|
||||
-- UseBuiltinCatalog = false,
|
||||
RestrictFOBToZones = true,
|
||||
AutoBuildFOBInZones = true,
|
||||
Zones = {
|
||||
PickupZones = { { name = 'PICKUP_BLUE_MAIN' } },
|
||||
DropZones = { { name = 'DROP_BLUE_1' } },
|
||||
FOBZones = { { name = 'FOB_ALPHA' } },
|
||||
},
|
||||
})
|
||||
|
||||
-- No manual merge needed: Moose_CTLD auto-detects and merges global catalogs
|
||||
-- supported global names: _CTLD_EXTRACTED_CATALOG, CTLD_CATALOG, MOOSE_CTLD_CATALOG
|
||||
|
||||
-- set allowed transports (optional override)
|
||||
-- ctld:SetAllowedAircraft({'UH-1H','Mi-8MTV2','Mi-24P'})
|
||||
|
||||
-- FAC/RECCE (optional)
|
||||
if _MOOSE_CTLD_FAC then
|
||||
fac = _MOOSE_CTLD_FAC:New(ctld, {
|
||||
CoalitionSide = coalition.side.BLUE,
|
||||
Arty = { Enabled=true, Groups={'BLUE_ARTY_1'}, Rounds=2, Spread=80 },
|
||||
})
|
||||
fac:AddRecceZone({ name = 'RECCE_ZONE_1' })
|
||||
fac:Run()
|
||||
end
|
||||
Loading…
x
Reference in New Issue
Block a user