Compare commits

..

6 Commits

Author SHA1 Message Date
Frank e8f5214e0b Merge branch 'master-ng' into FF/Ops 2026-06-21 18:21:33 +02:00
Frank e4c7e809cb TARGET v0.8.0
- Added Element functions
- Improved handling of delayed dead events
2026-06-18 22:47:11 +02:00
Frank aab16dd966 Legion/Cohort Database
- moved to individual classes
2026-06-17 09:00:17 +02:00
Frank 8b356f0913 Merge branch 'master-ng' into FF/Ops 2026-06-15 20:48:57 +02:00
Frank c3086b0265 Update Database.lua
- fixed bug
2026-06-05 22:54:42 +02:00
Frank 599a2ba6fb Database
- Added COHORTs and LEGIONs to database
2026-06-05 22:50:52 +02:00
21 changed files with 361 additions and 1219 deletions
-22
View File
@@ -736,12 +736,6 @@ do -- Event Handling
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when an option is changed for an AI group.
-- The event identifies the initiating group, but does not provide the option ID or value.
-- @function [parent=#BASE] OnEventGroupChangeOption
-- @param #BASE self
-- @param Core.Event#EVENTDATA EventData The EventData structure.
--- Occurs when a player creates a dynamic cargo object from the F8 ground crew menu.
-- *** NOTE *** this is a workarounf for DCS not creating these events as of Aug 2024.
-- @function [parent=#BASE] OnEventNewDynamicCargo
@@ -887,22 +881,6 @@ end
world.onEvent(Event)
end
--- Creation of a `S_EVENT_GROUP_CHANGE_OPTION` event.
-- @param #BASE self
-- @param DCS#Time EventTime The time stamp of the event.
-- @param DCS#Group Initiator The initiating group of the event.
function BASE:CreateEventGroupChangeOption( EventTime, Initiator )
self:F( { EventTime, Initiator } )
local Event = {
id = EVENTS.GroupChangeOption,
time = EventTime,
initiator = Initiator,
}
world.onEvent( Event )
end
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
-- @param #BASE self
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
+36
View File
@@ -92,6 +92,8 @@ DATABASE = {
ZONES_GOAL = {},
WAREHOUSES = {},
FLIGHTGROUPS = {},
COHORTS={},
LEGIONS={},
FLIGHTCONTROLS = {},
OPSZONES = {},
PATHLINES = {},
@@ -2087,6 +2089,40 @@ function DATABASE:FindOpsGroupFromUnit(unitname)
end
end
--
--- Add an OPS COHORT (SQUADRON, PLATOON, FLOTILLA) to the data base.
-- @param #DATABASE self
-- @param Ops.Cohort#COHORT cohort The cohort added to the DB.
function DATABASE:AddCohort(cohort)
self.COHORTS[cohort.name]=cohort
end
--- Find an OPS COHORT (SQUADRON, PLATOON, FLOTILLA) in the data base.
-- @param #DATABASE self
-- @param #string cohortname Name of the cohort.
-- @return Ops.Cohort#COHORT Cohort object.
function DATABASE:FindCohort(cohortname)
return self.COHORTS[cohortname]
end
--- Add an OPS LEGION (AIRWING, BRIGADE, FLEET) to the data base.
-- @param #DATABASE self
-- @param Ops.Legion#LEGION legion The legion added to the DB.
function DATABASE:AddLegion(legion)
self.LEGIONS[legion.alias]=legion
end
--- Find an OPS LEGION (AIRWING, BRIGADE, FLEET) in the data base.
-- @param #DATABASE self
-- @param #string legionname Name of the legion.
-- @return Ops.Legion#LEGION Legion object.
function DATABASE:FindLegion(legionname)
return self.LEGIONS[legionname]
end
--
--- Add a flight control to the data base.
-- @param #DATABASE self
-- @param OPS.FlightControl#FLIGHTCONTROL flightcontrol
+7 -25
View File
@@ -278,7 +278,6 @@ EVENTS = {
SimulationUnfreeze = world.event.S_EVENT_SIMULATION_UNFREEZE or -1,
HumanAircraftRepairStart = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_START or -1,
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
GroupChangeOption = world.event.S_EVENT_GROUP_CHANGE_OPTION or -1,
-- dynamic cargo
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
@@ -292,25 +291,23 @@ EVENTS = {
--
-- * A (Object.Category.)UNIT : A UNIT object type is involved in the Event.
-- * A (Object.Category.)STATIC : A STATIC object type is involved in the Event.
-- * A GROUP : A DCS Group object is involved in the Event.
--
-- @type EVENTDATA
-- @field #number id The identifier of the event.
--
-- @field DCS#Unit initiator (UNIT/STATIC/SCENERY/GROUP) The initiating @{DCS#Unit} or @{DCS#StaticObject}. For `S_EVENT_GROUP_CHANGE_OPTION`, this is a DCS Group.
-- @field DCS#Unit initiator (UNIT/STATIC/SCENERY) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
-- @field DCS#Object.Category IniObjectCategory (UNIT/STATIC/SCENERY) The initiator object category ( Object.Category.UNIT or Object.Category.STATIC ).
-- @field DCS#Unit IniDCSUnit (UNIT/STATIC) The initiating @{DCS#Unit} or @{DCS#StaticObject}.
-- @field #string IniDCSUnitName (UNIT/STATIC) The initiating Unit name.
-- @field Wrapper.Unit#UNIT IniUnit (UNIT/STATIC) The initiating MOOSE wrapper @{Wrapper.Unit#UNIT} of the initiator Unit object.
-- @field #string IniUnitName (UNIT/STATIC) The initiating UNIT name (same as IniDCSUnitName).
-- @field DCS#Group IniDCSGroup (UNIT/GROUP) The initiating @{DCS#Group}.
-- @field #string IniDCSGroupName (UNIT/GROUP) The initiating Group name.
-- @field Wrapper.Group#GROUP IniGroup (UNIT/GROUP) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
-- @field #string IniGroupName (UNIT/GROUP) The initiating GROUP name (same as IniDCSGroupName).
-- @field DCS#Group.Category IniGroupCategory (GROUP) The category of the initiating group.
-- @field DCS#Group IniDCSGroup (UNIT) The initiating {DCSGroup#Group}.
-- @field #string IniDCSGroupName (UNIT) The initiating Group name.
-- @field Wrapper.Group#GROUP IniGroup (UNIT) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
-- @field #string IniGroupName UNIT) The initiating GROUP name (same as IniDCSGroupName).
-- @field #string IniPlayerName (UNIT) The name of the initiating player in case the Unit is a client or player slot.
-- @field #string IniPlayerUCID (UNIT) The UCID of the initiating player in case the Unit is a client or player slot and on a multi-player server.
-- @field DCS#coalition.side IniCoalition (UNIT/GROUP) The coalition of the initiator.
-- @field DCS#coalition.side IniCoalition (UNIT) The coalition of the initiator.
-- @field DCS#Unit.Category IniCategory (UNIT) The category of the initiator.
-- @field #string IniTypeName (UNIT) The type name of the initiator.
--
@@ -737,12 +734,6 @@ local _EVENTMETA = {
Side = "I",
Event = "OnEventHumanAircraftRepairFinish",
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
},
[EVENTS.GroupChangeOption] = {
Order = 1,
Side = "I",
Event = "OnEventGroupChangeOption",
Text = "S_EVENT_GROUP_CHANGE_OPTION"
},
-- dynamic cargo
[EVENTS.NewDynamicCargo] = {
@@ -1243,16 +1234,7 @@ function EVENT:onEvent( Event )
if Event.initiator then
if Event.id == EVENTS.GroupChangeOption then
Event.IniDCSGroup = Event.initiator
Event.IniDCSGroupName = Group.getName(Event.initiator)
Event.IniGroupName = Event.IniDCSGroupName
Event.IniGroup = GROUP:FindByName(Event.IniDCSGroupName)
Event.IniCoalition = Group.getCoalition(Event.initiator)
Event.IniGroupCategory = Group.getCategory(Event.initiator)
else
Event.IniObjectCategory = Object.getCategory(Event.initiator)
end
Event.IniObjectCategory = Object.getCategory(Event.initiator)
if Event.IniObjectCategory == Object.Category.STATIC then
---
@@ -246,11 +246,11 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
return ScheduleTime -- returns the next time the function needs to be called.
else
self:Stop( Scheduler, CallID )
self:_Reclaim( Scheduler, CallID )
end
else
self:Stop( Scheduler, CallID )
self:_Reclaim( Scheduler, CallID )
end
else
self:I( "<<<>" .. Name .. ":" .. Line .. " (" .. Source .. ")" )
+1 -2
View File
@@ -87,8 +87,7 @@ do -- world
-- @field S_EVENT_SIMULATION_UNFREEZE = 58
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_START = 59
-- @field S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH = 60
-- @field S_EVENT_GROUP_CHANGE_OPTION = 61
-- @field S_EVENT_MAX = 62
-- @field S_EVENT_MAX = 61
--- The birthplace enumerator is used to define where an aircraft or helicopter has spawned in association with birth events.
-- @type world.BirthPlace
File diff suppressed because it is too large Load Diff
+45 -28
View File
@@ -290,6 +290,9 @@ function AIRWING:New(warehousename, airwingname)
-- @param Ops.FlightGroup#FLIGHTGROUP FlightGroup The FLIGHTGROUP on mission.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- Add legion to DB
_DATABASE:AddLegion(self)
return self
end
@@ -541,6 +544,47 @@ function AIRWING:AddPayloadCapability(Payload, MissionTypes, Performance)
return self
end
--- Filter available payloads for a given aircraft type and mission type.
-- @param #AIRWING self
-- @param #string UnitType The type of the unit.
-- @param #string MissionType The mission type.
-- @param #table Payloads Specific payloads only to be considered.
-- @return #AIRWING.Payload Payload table or *nil*.
function AIRWING:_FilterPlayloads(UnitType, MissionType, Payloads)
local function _checkPayloads(payload)
if Payloads then
for _,Payload in pairs(Payloads) do
if Payload.uid==payload.uid then
return true
end
end
else
-- Payload was not specified.
return nil
end
return false
end
-- Pre-selection: filter out only those payloads that are valid for the airframe and mission type and are available.
local payloads={}
for _,_payload in pairs(self.payloads) do
local payload=_payload --#AIRWING.Payload
local specialpayload=_checkPayloads(payload)
local compatible=AUFTRAG.CheckMissionCapability(MissionType, payload.capabilities)
local goforit = specialpayload or (specialpayload==nil and compatible)
if payload.aircrafttype==UnitType and payload.navail>0 and goforit then
table.insert(payloads, payload)
end
end
return payloads
end
--- Fetch a payload from the airwing resources for a given unit and mission type.
-- The payload with the highest priority is preferred.
-- @param #AIRWING self
@@ -589,34 +633,7 @@ function AIRWING:FetchPayloadFromStock(UnitType, MissionType, Payloads)
end
end
local function _checkPayloads(payload)
if Payloads then
for _,Payload in pairs(Payloads) do
if Payload.uid==payload.uid then
return true
end
end
else
-- Payload was not specified.
return nil
end
return false
end
-- Pre-selection: filter out only those payloads that are valid for the airframe and mission type and are available.
local payloads={}
for _,_payload in pairs(self.payloads) do
local payload=_payload --#AIRWING.Payload
local specialpayload=_checkPayloads(payload)
local compatible=AUFTRAG.CheckMissionCapability(MissionType, payload.capabilities)
local goforit = specialpayload or (specialpayload==nil and compatible)
if payload.aircrafttype==UnitType and payload.navail>0 and goforit then
table.insert(payloads, payload)
end
end
local payloads=self:_FilterPlayloads(UnitType, MissionType, Payloads)
-- Debug.
if self.verbose>=4 then
+1 -3
View File
@@ -45,7 +45,7 @@
-- **Supported Aircraft:**
--
-- * [F/A-18C Hornet Lot 20](https://forums.eagle.ru/forumdisplay.php?f=557) (Player & AI)
-- * [F-14A/B/BU/A Early Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI)
-- * [F-14A/B/A Early Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI)
-- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI)
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI)
-- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI)
@@ -1276,7 +1276,6 @@ AIRBOSS = {
-- @field #string A4EC A-4E Community mod.
-- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics.
-- @field #string F14A F-14A by Heatblur.
-- @field #string F14BU F-14BU by Heatblur.
-- @field #string F14A_Early F-14A-135-GR-Early by Heatblur.
-- @field #string F14B F-14B by Heatblur.
-- @field #string F14A_AI F-14A Tomcat (AI).
@@ -1298,7 +1297,6 @@ AIRBOSS.AircraftCarrier={
F14A="F-14A-135-GR",
F14A_Early="F-14A-135-GR-Early",
F14B="F-14B",
F14BU="F-14BU",
F14A_AI="F-14A",
FA18C="F/A-18C",
T45C="T-45",
+1 -8
View File
@@ -5120,7 +5120,6 @@ end
-- FSM Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- On after "Planned" event.
-- @param #AUFTRAG self
-- @param #string From From state.
@@ -6466,13 +6465,7 @@ function AUFTRAG:GetDCSMissionTask(MissionGroup)
-- ESCORT Mission --
--------------------
local FollowGroup=self.engageTarget:GetObject()
local DCStask=nil
if next(self.engageTargetTypes)==nil then
DCStask=FollowGroup:TaskFollow(FollowGroup, self.escortVec3)
else
DCStask=CONTROLLABLE.TaskEscort(nil, FollowGroup, self.escortVec3, nil, self.engageMaxDistance, self.engageTargetTypes)
end
local DCStask=CONTROLLABLE.TaskEscort(nil, self.engageTarget:GetObject(), self.escortVec3, nil, self.engageMaxDistance, self.engageTargetTypes)
table.insert(DCStasks, DCStask)
+3
View File
@@ -150,6 +150,9 @@ function BRIGADE:New(WarehouseName, BrigadeName)
-- @param Ops.ArmyGroup#ARMYGROUP ArmyGroup The ARMYGROUP on mission.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- Add legion to DB
_DATABASE:AddLegion(self)
return self
end
+60 -66
View File
@@ -183,7 +183,6 @@ do
-- my_ctld.placeCratesAhead = false -- place crates straight ahead of the helicopter, in a random way. If true, crates are more neatly sorted.
-- my_ctld.nobuildinloadzones = true -- forbid players to build stuff in LOAD zones if set to `true`
-- my_ctld.movecratesbeforebuild = true -- crates must be moved once before they can be build. Set to false for direct builds.
-- my_ctld.useaircraftheadingforbuilds = false -- Matches the heading of the spawned groups from a crate build to the aircraft heading when starting the build. Default is false for template heading.
-- my_ctld.surfacetypes = {land.SurfaceType.LAND,land.SurfaceType.ROAD,land.SurfaceType.RUNWAY,land.SurfaceType.SHALLOW_WATER} -- surfaces for loading back objects.
-- my_ctld.nobuildmenu = false -- if set to true effectively enforces to have engineers build/repair stuff for you.
-- my_ctld.RadioSound = "beacon.ogg" -- -- this sound will be hearable if you tune in the beacon frequency. Add the sound file to your miz.
@@ -2038,7 +2037,7 @@ function CTLD:_C130DcAutoRegisterEntry(SetId, Cargo)
local pos = Cargo:GetPositionable()
local pname = pos and pos.GetName and pos:GetName() or nil
local pcoord = pos and pos.GetCoord and pos:GetCoord() or nil
local pcoord = pos and pos.GetCoordinate and pos:GetCoordinate() or nil
local entryId = string.format("%s#%d", SetId, #setData.entries + 1)
local entry = {
id = entryId,
@@ -2749,12 +2748,14 @@ function CTLD:_EventHandler(EventData)
loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo
loaded.Cratesloaded = loaded.Cratesloaded - 1
if loaded.Cratesloaded < 0 then loaded.Cratesloaded = 0 end
-- TODO zap cargo from list
local Loaded = {}
for _,_item in pairs (loaded.Cargo or {}) do
self:T(self.lid.."UNLOAD checking: ".._item:GetName())
self:T(self.lid.."UNLOAD state: ".. tostring(_item:WasDropped()))
local unloadedItem = _item and _item:GetType() == CTLD_CARGO.Enum.GCLOADABLE and event.IniDynamicCargoName and event.IniDynamicCargoName == _item:GetName()
if not unloadedItem then
if _item and _item:GetType() == CTLD_CARGO.Enum.GCLOADABLE and event.IniDynamicCargoName and event.IniDynamicCargoName ~= _item:GetName() and not _item:WasDropped() then
table.insert(Loaded,_item)
else
table.insert(Loaded,_item)
end
end
@@ -3124,14 +3125,14 @@ end
function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
self:T(self.lid .. " _FindRepairNearby")
--self:T({Group:GetName(),Unit:GetName(),Repairtype})
local unitcoord = Unit:GetCoord()
local unitcoord = Unit:GetCoordinate()
-- find nearest group of deployed groups
local nearestGroup = nil
local nearestGroupIndex = -1
local nearestDistance = 10000
for k,v in pairs(self.DroppedTroops) do
local distance = self:_GetDistance(v:GetCoord(),unitcoord)
local distance = self:_GetDistance(v:GetCoordinate(),unitcoord)
local unit = v:GetUnit(1) -- Wrapper.Unit#UNIT
local desc = unit:GetDesc() or nil
if distance < nearestDistance and distance ~= -1 and not desc.attributes.Infantry then
@@ -3276,7 +3277,7 @@ end
local capabilities = self:_GetUnitCapabilities(Unit)
local cantroops = capabilities.troops -- #boolean
local trooplimit = capabilities.trooplimit -- #number
local unitcoord = unit:GetCoord()
local unitcoord = unit:GetCoordinate()
-- find nearest group of deployed troops
local nearestGroup = nil
@@ -3287,7 +3288,7 @@ end
local distancekeys = {}
local extractdistance = self.CrateDistance * self.ExtractFactor
for k,v in pairs(self.DroppedTroops) do
local distance = self:_GetDistance(v:GetCoord(),unitcoord)
local distance = self:_GetDistance(v:GetCoordinate(),unitcoord)
local TNow = timer.getTime()
local vtime = v.ExtractTime or TNow-310
if distance <= extractdistance and distance ~= -1 and (TNow - vtime > 300) then
@@ -3375,7 +3376,7 @@ end
self:_UpdateUnitCargoMass(Unit)
local groupname = nearestGroup:GetName()
self:__TroopsExtracted(running,Group, Unit, nearestGroup, groupname)
local coord = Unit:GetCoord() or Group:GetCoord() -- Core.Point#COORDINATE
local coord = Unit:GetCoordinate() or Group:GetCoordinate() -- Core.Point#COORDINATE
local Point
if coord then
local heading = unit:GetHeading() or 0
@@ -3746,16 +3747,16 @@ function CTLD:_C130GetUnits(Group, Unit, Name)
return self
end
local coord = Unit:GetCoord() or Group:GetCoord()
local coord = Unit:GetCoordinate() or Group:GetCoordinate()
local capabilities = self:_GetUnitCapabilities(Unit)
local innerDist = (capabilities.length and capabilities.length/2) or 15
local maxUnitsNearby = self.maxUnitsNearby or 3
local searchRadius = self.UnitDistance or 90
local checkZone = ZONE_RADIUS:New("CTLD_C130UnitsZone",coord:GetVec2(),searchRadius,false)
local nearGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterZones({checkZone}):FilterOnce()
local nearGroups = SET_GROUP:New():FilterCoalitions("blue"):FilterZones({checkZone}):FilterOnce()
local nearbyCount = 0
for _,gr in pairs(nearGroups.Set) do
local gc = gr:GetCoord()
local gc = gr:GetCoordinate()
if gc then
local dist = coord:Get2DDistance(gc)
if dist > innerDist then
@@ -3805,7 +3806,6 @@ function CTLD:_C130GetUnits(Group, Unit, Name)
if canmove then
SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(true,10,2)
:InitCoalition(self.coalition)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits, 70)
:InitDelayOff()
:OnSpawnGroup(function(grp,TimeStamp)
@@ -3819,7 +3819,6 @@ function CTLD:_C130GetUnits(Group, Unit, Name)
SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(true,10,2)
:InitDelayOff()
:InitCoalition(self.coalition)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits, 70)
:OnSpawnGroup(function(grp,TimeStamp)
grp.spawntime = TimeStamp or timer.getTime()
@@ -3926,7 +3925,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
-- Check cargo location if available
local location = Cargo:GetLocation()
if location then
local unitcoord = Unit:GetCoord() or Group:GetCoord()
local unitcoord = Unit:GetCoordinate() or Group:GetCoordinate()
if unitcoord then
if not location:IsCoordinateInZone(unitcoord) then
-- no we're not at the right spot
@@ -3973,7 +3972,7 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
end
-- get position and heading of heli
local position = Unit:GetCoord()
local position = Unit:GetCoordinate()
local heading = Unit:GetHeading() + 1
local height = Unit:GetHeight()
local droppedcargo = {}
@@ -4137,8 +4136,8 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop, pack, quiet, suppress
if type(ship) == "string" then
self:T("Spawning on ship "..ship)
local Ship = UNIT:FindByName(ship)
local shipcoord = Ship:GetCoord()
local unitcoord = Unit:GetCoord()
local shipcoord = Ship:GetCoordinate()
local unitcoord = Unit:GetCoordinate()
local dist = shipcoord:Get2DDistance(unitcoord)
dist = dist - (20 + math.random(1, 10))
local halfwidth = (width or 20) / 2
@@ -4390,17 +4389,17 @@ end
function CTLD:_C130RemoveUnitsNearby(_group,_unit)
self:T(self.lid .. " _C130RemoveUnitsNearby")
if not _group or not _unit then return self end
local location = _group:GetCoord()
local location = _group:GetCoordinate()
if not location then return self end
local capabilities = self:_GetUnitCapabilities(_unit)
local innerDist = (capabilities.length and capabilities.length/2) or 15
local finddist = self.PackDistance or (self.CrateDistance or 35)
local zone = ZONE_RADIUS:New("CTLD_C130RemoveZone",location:GetVec2(),finddist,false)
local nearestGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterZones({zone}):FilterOnce()
local nearestGroups = SET_GROUP:New():FilterCoalitions("blue"):FilterZones({zone}):FilterOnce()
local removedAny = false
local removedTable = {}
for _, gr in pairs(nearestGroups.Set) do
local gc = gr:GetCoord()
local gc = gr:GetCoordinate()
if gc then
local dist = location:Get2DDistance(gc)
if dist > innerDist then
@@ -4534,7 +4533,7 @@ end
function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight, ignoretype, ignoreHercInner)
self:T(self.lid .. " _FindCratesNearby")
local finddist = _dist
local location = _group:GetCoord()
local location = _group:GetCoordinate()
local existingcrates = self.Spawned_Cargo -- #table
-- cycle
local index = 0
@@ -5160,6 +5159,7 @@ function CTLD:_UnloadTroops(Group, Unit)
-- unload troops
local name = cargo:GetName() or "none"
local temptable = cargo:GetTemplates() or {}
local position = Group:GetCoordinate()
local zoneradius = self.troopdropzoneradius or 100 -- drop zone radius
local factor = 1
if IsHerc then
@@ -5196,7 +5196,6 @@ function CTLD:_UnloadTroops(Group, Unit)
local Positions = self:_GetUnitPositions(randomcoord,rad,heading,_template)
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitDelayOff()
:InitCoalition(self.coalition)
:InitSetUnitAbsolutePositions(Positions)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp) grp.spawntime = timer.getTime() end)
@@ -5507,8 +5506,8 @@ function CTLD:_BuildCrates(Group, Unit,Engineering,MultiDrop,NotifyGroup)
local required = Crate:GetCratesNeeded()
local template = Crate:GetTemplates()
local ctype = Crate:GetType()
local ccoord = Crate:GetPositionable():GetCoord() -- Core.Point#COORDINATE
local distToUnit=Unit and ccoord:Get2DDistance(Unit:GetCoord())or 0
local ccoord = Crate:GetPositionable():GetCoordinate() -- Core.Point#COORDINATE
local distToUnit=Unit and ccoord:Get2DDistance(Unit:GetCoordinate())or 0
local isHercDrop=Crate:WasDropped(true)
if not isHercDrop and distToUnit>baseDist then
elseif self:IsC130J(Unit) and distToUnit<15 then
@@ -5527,7 +5526,6 @@ function CTLD:_BuildCrates(Group, Unit,Engineering,MultiDrop,NotifyGroup)
object.Found = 1
object.Template = template
object.CanBuild = false
object.Heading = Unit:GetHeading()
object.Type = ctype -- #CTLD_CARGO.Enum
object.Coord = ccoord:GetVec2()
buildables[name] = object
@@ -5613,7 +5611,7 @@ function CTLD:_BuildCrates(Group, Unit,Engineering,MultiDrop,NotifyGroup)
local sep = self.buildPairSeparation or 25
local hdg = (Unit:GetHeading()+180)%360
local lat = (hdg+90)%360
local base = Unit:GetCoord():Translate(20,hdg)
local base = Unit:GetCoordinate():Translate(20,hdg)
if full == 1 then
local cratesNow, numberNow = self:_FindCratesNearby(Group,Unit, finddist,true,true, not Engineering)
@@ -5647,7 +5645,7 @@ function CTLD:_BuildCrates(Group, Unit,Engineering,MultiDrop,NotifyGroup)
self:_RefreshPackMenus(Group,Unit)
local off = start + (n-1)*sep
local coord = base:Translate(off,lat):GetVec2()
local b = { Name=build.Name, Required=build.Required, Template=build.Template, CanBuild=true, Type=build.Type, Coord=coord, Heading=build.Heading }
local b = { Name=build.Name, Required=build.Required, Template=build.Template, CanBuild=true, Type=build.Type, Coord=coord }
if self.buildtime and self.buildtime > 0 then
local buildtimer = TIMER:New(self._BuildObjectFromCrates,self,Group,Unit,b,false,Group:GetCoordinate(),MultiDrop)
buildtimer:Start(self.buildtime)
@@ -5685,18 +5683,18 @@ end
-- @return #number Number
function CTLD:_FindPackableGroupsNearby(Group, Unit)
self:T(self.lid .. " _FindPackableGroupsNearby")
local location = Group:GetCoord()
local location = Group:GetCoordinate()
if not location then return {}, 0 end
local capabilities = self:_GetUnitCapabilities(Unit)
local innerDist = (capabilities.length and capabilities.length/2) or 15
local finddist = self.PackDistance or (self.CrateDistance or 35)
local zone = ZONE_RADIUS:New("CTLD_PackableZone", location:GetVec2(), finddist, false)
local nearestGroups = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterZones({zone}):FilterOnce()
local nearestGroups = SET_GROUP:New():FilterCoalitions("blue"):FilterZones({zone}):FilterOnce()
local packable = {}
for _, gr in pairs(nearestGroups.Set) do
if gr and gr:GetName() ~= Group:GetName() then
local gc = gr:GetCoord()
local gc = gr:GetCoordinate()
if gc then
local dist = location:Get2DDistance(gc)
if dist > innerDist and dist <= finddist then
@@ -5829,12 +5827,12 @@ function CTLD:_LoadPackedCratesByIds(Group, Unit, crateIds, cargoName)
local matchingCrates = {}
local finddist = self.CrateDistance or 35
local location = Group:GetCoord()
local location = Group:GetCoordinate()
for _, crateObj in pairs(self.Spawned_Cargo or {}) do
if crateObj and idLookup[crateObj:GetID()] then
local pos = crateObj:GetPositionable()
if pos and pos:IsAlive() then
local dist = location:Get2DDistance(pos:GetCoord())
local dist = location:Get2DDistance(pos:GetCoordinate())
if dist <= finddist then
matchingCrates[#matchingCrates + 1] = crateObj
end
@@ -5944,12 +5942,12 @@ function CTLD:_RemovePackedCratesByIds(Group, Unit, crateIds)
local crates = {}
local finddist = self.CrateDistance or 35
local location = Group:GetCoord()
local location = Group:GetCoordinate()
for _, entry in pairs(self.Spawned_Cargo or {}) do
if entry and idLookup[entry:GetID()] then
local pos = entry:GetPositionable()
if pos and pos:IsAlive() then
local dist = location:Get2DDistance(pos:GetCoord())
local dist = location:Get2DDistance(pos:GetCoordinate())
if dist <= finddist then
crates[#crates + 1] = entry
end
@@ -6199,31 +6197,28 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation,Mult
for _,_template in pairs(temptable) do
self.TroopCounter = self.TroopCounter + 1
local alias = string.format("%s-%d", _template, math.random(1,100000))
local spawn = SPAWN:NewWithAlias(_template,alias)
if canmove then
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
--:InitRandomizeUnits(true,20,2)
:InitDelayOff()
:InitCoalition(self.coalition)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp) grp.spawntime = timer.getTime() end)
if canmove then
--spawn:InitRandomizeUnits(true,20,2)
:SpawnFromVec2(randomcoord)
else -- don't random position of e.g. SAM units build as FOB
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitDelayOff()
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp) grp.spawntime = timer.getTime() end)
:SpawnFromVec2(randomcoord)
end
if Build.Heading and self.buildcrateswithaircraftheading then
spawn:InitGroupHeading(Build.Heading)
end
local spawnedGroup = spawn:SpawnFromVec2(randomcoord)
self.DroppedTroops[self.TroopCounter] = spawnedGroup
if Repair then
self:__CratesRepaired(1,Group,Unit,spawnedGroup)
self:__CratesRepaired(1,Group,Unit,self.DroppedTroops[self.TroopCounter])
else
self:__CratesBuild(1,Group,Unit,spawnedGroup)
self:__CratesBuild(1,Group,Unit,self.DroppedTroops[self.TroopCounter])
end
end -- template loop
if Group and Group:IsAlive() and Group:GetID() then
self:_RefreshLoadCratesMenu(Group, Unit)
self:_RefreshPackMenus(Group, Unit)
end
self:_RefreshLoadCratesMenu(Group, Unit)
self:_RefreshPackMenus(Group, Unit)
else
self:T(self.lid.."Group KIA while building!")
end
@@ -6246,11 +6241,14 @@ end
-- @param Wrapper.Group#GROUP Group The Group to move.
function CTLD:_MoveGroupToZone(Group)
self:T(self.lid .. " _MoveGroupToZone")
local groupname = Group:GetName() or "none"
local groupcoord = Group:GetCoordinate()
-- Get closest zone of type
local outcome, name, zone, distance = self:IsUnitInZone(Group,CTLD.CargoZoneType.MOVE)
self:T({canmove=outcome, name=name, zone=zone, dist=distance,max=self.movetroopsdistance})
if (distance <= self.movetroopsdistance) and outcome == true and zone~= nil then
-- yes, we can ;)
local groupname = Group:GetName()
local zonecoord = zone:GetRandomCoordinate(20,125) -- Core.Point#COORDINATE
local formation = self:_GetVehicleFormation()
--local coordinate = zonecoord:GetVec2()
@@ -7933,7 +7931,6 @@ function CTLD:_UnloadSingleTroopByID(Group, Unit, chunkID, qty)
local Positions = self:_GetUnitPositions(randomcoord, rad, heading, _template)
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template, alias)
:InitDelayOff()
:InitCoalition(self.coalition)
:InitSetUnitAbsolutePositions(Positions)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp) grp.spawntime = timer.getTime() end)
@@ -9011,7 +9008,7 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
local zoneret = nil
local zonewret = nil
local zonenameret = nil
local unitcoord = Unit:GetCoord()
local unitcoord = Unit:GetCoordinate()
if not unitcoord then
if Zonetype == CTLD.CargoZoneType.SHIP then
return false, nil, nil, 1000000, nil
@@ -9032,7 +9029,7 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
self:T("Checking Type Ship: "..zonename)
local ZoneUNIT = UNIT:FindByName(zonename)
if not ZoneUNIT then return false end
zonecoord = ZoneUNIT:GetCoord()
zonecoord = ZoneUNIT:GetCoordinate()
zoneradius = czone.shiplength
zonewidth = czone.shipwidth
zone = ZONE_UNIT:New( ZoneUNIT:GetName(), ZoneUNIT, zoneradius/2)
@@ -9081,7 +9078,7 @@ function CTLD:SmokePositionNow(Unit, Flare, SmokeColor)
end
local FlareColor = self.FlareColor or FLARECOLOR.Red
-- table of #CTLD.CargoZone table
local unitcoord = Unit:GetCoord() -- Core.Point#COORDINATE
local unitcoord = Unit:GetCoordinate() -- Core.Point#COORDINATE
local Group = Unit:GetGroup()
if Flare then
unitcoord:Flare(FlareColor, 90)
@@ -9100,7 +9097,7 @@ end
function CTLD:SmokeZoneNearBy(Unit, Flare)
self:T(self.lid .. " SmokeZoneNearBy")
-- table of #CTLD.CargoZone table
local unitcoord = Unit:GetCoord()
local unitcoord = Unit:GetCoordinate()
local Group = Unit:GetGroup()
local smokedistance = self.smokedistance
local smoked = false
@@ -9237,7 +9234,7 @@ end
-- get speed and height
local uspeed = Unit:GetVelocityMPS()
local uheight = Unit:GetHeight()
local ucoord = Unit:GetCoord()
local ucoord = Unit:GetCoordinate()
if not ucoord then
return false
end
@@ -9266,7 +9263,7 @@ end
-- get speed and height
local uspeed = Unit:GetVelocityMPS()
local uheight = Unit:GetHeight()
local ucoord = Unit:GetCoord()
local ucoord = Unit:GetCoordinate()
if not ucoord then
return false
end
@@ -9358,7 +9355,7 @@ end
minheight = 5.1 -- herc is 5m AGL on the ground
end
local uheight = Unit:GetHeight()
local ucoord = Unit:GetCoord()
local ucoord = Unit:GetCoordinate()
if not ucoord then
return false
end
@@ -10144,7 +10141,6 @@ end
local alias = string.format("%s-%d", _template, math.random(1,100000))
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(randompositions,20,2)
:InitCoalition(self.coalition)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:InitDelayOff()
:OnSpawnGroup(function(grp,TimeStamp) grp.spawntime = TimeStamp or timer.getTime() end,TimeStamp)
@@ -10299,7 +10295,6 @@ end
if canmove then
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitRandomizeUnits(true,20,2)
:InitCoalition(self.coalition)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:InitDelayOff()
:OnSpawnGroup(function(grp,TimeStamp) grp.spawntime = TimeStamp or timer.getTime() end,TimeStamp)
@@ -10307,7 +10302,6 @@ end
else -- don't random position of e.g. SAM units build as FOB
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
:InitDelayOff()
:InitCoalition(self.coalition)
:InitValidateAndRepositionGroundUnits(self.validateAndRepositionUnits)
:OnSpawnGroup(function(grp,TimeStamp) grp.spawntime = TimeStamp or timer.getTime() end,TimeStamp)
:SpawnFromVec2(randomcoord)
@@ -10589,7 +10583,7 @@ end
self:T({From, Event, To})
if Unit and Unit:IsPlayer() and self.PlayerTaskQueue then
local playername = Unit:GetPlayerName()
local dropcoord = Troops:GetCoord() or COORDINATE:New(0,0,0)
local dropcoord = Troops:GetCoordinate() or COORDINATE:New(0,0,0)
local dropvec2 = dropcoord:GetVec2()
self.PlayerTaskQueue:ForEach(
function (Task)
@@ -10646,7 +10640,7 @@ end
for _,_cargo in pairs(Cargotable) do
local Vehicle = _cargo.Positionable
if Vehicle then
local dropcoord = Vehicle:GetCoord() or COORDINATE:New(0,0,0)
local dropcoord = Vehicle:GetCoordinate() or COORDINATE:New(0,0,0)
local dropvec2 = dropcoord:GetVec2()
self.PlayerTaskQueue:ForEach(
function (Task)
@@ -10711,7 +10705,7 @@ end
self:T({From, Event, To})
if Unit and Unit:IsPlayer() and self.PlayerTaskQueue then
local playername = Unit:GetPlayerName()
local dropcoord = Vehicle:GetCoord() or COORDINATE:New(0,0,0)
local dropcoord = Vehicle:GetCoordinate() or COORDINATE:New(0,0,0)
local dropvec2 = dropcoord:GetVec2()
self.PlayerTaskQueue:ForEach(
function (Task)
+4 -32
View File
@@ -135,7 +135,6 @@
-- local mywing = EASYGCICAP:New("Blue CAP Operations",AIRBASE.Caucasus.Kutaisi,"blue","Blue EWR")
--
-- -- Add a CAP patrol point belonging to our airbase, we'll be at 30k ft doing 400 kn, initial direction 90 degrees (East), leg 20NM
-- -- NOTE - Skip this function and do not create CAP Points if you want GCI behaviour only.
-- mywing:AddPatrolPointCAP(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone 1"):GetCoordinate(),30000,400,90,20)
--
-- -- Add a Squadron with template "Blue Sq1 M2000c", 20 airframes, skill good, Modex starting with 102 and skin "Vendee Jeanne"
@@ -191,10 +190,9 @@
-- * @{#EASYGCICAP.SetDefaultResurrection}: Set how many seconds the AirWing stays inoperable after the AirWing STATIC HQ ist destroyed, default 900 secs.
-- * @{#EASYGCICAP.SetDefaultCAPSpeed}: Set how many knots the CAP flights should do (will be altitude corrected), default 300 kn.
-- * @{#EASYGCICAP.SetDefaultCAPAlt}: Set at which altitude (ASL) the CAP planes will fly, default 25,000 ft.
-- * @{#EASYGCICAP.SetDefaultINTERCEPTAlt}: Set at which altitude (ASL) the Intercept planes will fly, default 25,000 ft.
-- * @{#EASYGCICAP.SetDefaultCAPDirection}: Set the initial direction from the CAP point the planes will fly in degrees, default is 90°.
-- * @{#EASYGCICAP.SetDefaultCAPLeg}: Set the length of the CAP leg, default is 15 NM.
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CAP/GCI), defaults to 2.
-- * @{#EASYGCICAP.SetDefaultCAPGrouping}: Set how many planes will be spawned per mission (CVAP/GCI), defaults to 2.
-- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100.
-- * @{#EASYGCICAP.SetDefaultNumberAlert5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2.
-- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50.
@@ -288,7 +286,7 @@ EASYGCICAP = {
--- EASYGCICAP class version.
-- @field #string version
EASYGCICAP.version="0.1.38"
EASYGCICAP.version="0.1.36"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--
@@ -589,17 +587,6 @@ function EASYGCICAP:SetDefaultCAPAlt(Altitude)
return self
end
--- Set default INTERCEPT Altitude in feet
-- @param #EASYGCICAP self
-- @param #number Altitude (Optional) Altitude defaults to 25000
-- @return #EASYGCICAP self
function EASYGCICAP:SetDefaultINTERCEPTAlt(Altitude)
self:T(self.lid.."SetDefaultINTERCEPTAlt")
self.interceptalt = Altitude or 25000
return self
end
--
--- Set default CAP lieg initial direction in degrees
-- @param #EASYGCICAP self
-- @param #number Direction (Optional) Direction defaults to 90 (East)
@@ -767,15 +754,6 @@ end
function EASYGCICAP:_AddAirwing(Airbasename, Alias)
self:T(self.lid.."_AddAirwing "..Airbasename)
-- Gather Some Stats
local function counttable(tbl)
local count = 0
for _,_data in pairs(tbl) do
count = count + 1
end
return count
end
local CapFormation = self.CapFormation
local DespawnAfterLanding = self.DespawnAfterLanding
local DespawnAfterHolding = self.DespawnAfterHolding
@@ -794,11 +772,7 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
CAP_Wing:SetMarker(false)
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
CAP_Wing:SetRespawnAfterDestroyed()
--- #DONE avoid wings with no CAP points starting CAP anyhow; AirWing uses this to start CAP and creates points when there are none.
if counttable(self.ManagedCP) >0 then
CAP_Wing:SetNumberCAP(self.capgrouping)
end
CAP_Wing:SetNumberCAP(self.capgrouping)
CAP_Wing:SetCapCloseRaceTrack(true)
if self.showpatrolpointmarks then
@@ -1065,7 +1039,7 @@ function EASYGCICAP:_SetCAPPatrolPoints()
MESSAGE:New(self.lid.."You are trying to create a CAP point for which there is no wing! "..tostring(data.AirbaseName),30,"CHECK"):ToAllIf(self.debug):ToLog()
return
end
local Wing = self.wings[data.AirbaseName][1] -- Ops.AirWing#AIRWING
local Wing = self.wings[data.AirbaseName][1] -- Ops.Airwing#AIRWING
local Coordinate = data.Coordinate
local Altitude = data.Altitude
local Speed = data.Speed
@@ -1531,7 +1505,6 @@ function EASYGCICAP:_AssignIntercept(Cluster)
local overhead = self.overhead
local capspeed = self.capspeed + 100
local capalt = self.capalt
local interalt = self.interceptalt or self.capalt
local maxsize = self.maxinterceptsize
local repeatsonfailure = self.repeatsonfailure
@@ -1619,7 +1592,6 @@ function EASYGCICAP:_AssignIntercept(Cluster)
:SetRepeatOnFailure(repeats)
:SetMissionSpeed(UTILS.KnotsToAltKIAS(capspeed,capalt))
:SetMissionAltitude(capalt)
:SetEngageAltitude(interalt)
if nogozoneset:Count() > 0 then
InterceptAuftrag:AddConditionSuccess(
+3
View File
@@ -167,6 +167,9 @@ function FLEET:New(WarehouseName, FleetName)
-- @param Ops.NavyGroup#NAVYGROUP NavyGroup The NAVYGROUP on mission.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- Add legion to DB
_DATABASE:AddLegion(self)
return self
end
+3
View File
@@ -73,6 +73,9 @@ function FLOTILLA:New(TemplateGroupName, Ngroups, FlotillaName)
-- Get initial ammo.
self.ammo=self:_CheckAmmo()
-- Add cohort to DB
_DATABASE:AddCohort(self)
return self
end
-1
View File
@@ -306,7 +306,6 @@ function LEGION:New(WarehouseName, LegionName)
-- @param Ops.Cohort#COHORT Cohort The cohort the asset belongs to.
-- @param Functional.Warehouse#WAREHOUSE.Assetitem Asset The asset that returned.
return self
end
+3
View File
@@ -72,6 +72,9 @@ function PLATOON:New(TemplateGroupName, Ngroups, PlatoonName)
-- Get ammo.
self.ammo=self:_CheckAmmo()
-- Add cohort to DB
_DATABASE:AddCohort(self)
return self
end
+3
View File
@@ -116,6 +116,9 @@ function SQUADRON:New(TemplateGroupName, Ngroups, SquadronName)
-- See COHORT class
-- Add cohort to DB
_DATABASE:AddCohort(self)
return self
end
+92 -52
View File
@@ -153,7 +153,7 @@ _TARGETID=0
--- TARGET class version.
-- @field #string version
TARGET.version="0.7.1"
TARGET.version="0.8.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@@ -206,6 +206,9 @@ function TARGET:New(TargetObject)
self:AddTransition("*", "Status", "*") -- Status update.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
self:AddTransition("*", "ElementDestroyed", "*") -- A target element was destroyed.
self:AddTransition("*", "ElementDead", "*") -- A target element is dead (destroyed or despawned).
self:AddTransition("*", "ObjectDamaged", "*") -- A target object was damaged.
self:AddTransition("*", "ObjectDestroyed", "*") -- A target object was destroyed.
self:AddTransition("*", "ObjectDead", "*") -- A target object is dead (destroyed or despawned).
@@ -245,6 +248,19 @@ function TARGET:New(TargetObject)
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "ElementDestroyed".
-- @function [parent=#TARGET] ElementDestroyed
-- @param #TARGET self
-- @param #string ElementName Name of the element.
-- @param #TARGET.Object Target Target object.
--- Triggers the FSM event "ElementDead".
-- @function [parent=#TARGET] ElementDead
-- @param #TARGET self
-- @param #string ElementName Name of the element.
-- @param #TARGET.Object Target Target object.
--- Triggers the FSM event "ObjectDamaged".
-- @function [parent=#TARGET] ObjectDamaged
-- @param #TARGET self
@@ -643,6 +659,19 @@ function TARGET:onafterStatus(From, Event, To)
-- FSM state.
local fsmstate=self:GetState()
-- First we check any target has been destroyed and the dead/unitlost event was not fired
for i,_target in pairs(self.targets) do
local target=_target --#TARGET.Object
local life=self:GetTargetLife(target)
if life<1 and target.Status~=TARGET.ObjectStatus.DEAD then
self:E(self.lid..string.format("FF life is zero but no object dead event fired ==> waiting for target object %s events!", tostring(target.Name)))
-- We wait 60 seconds for the events to occur
self:__Status(-60)
return self
end
end
-- Update damage.
local damaged=false
for i,_target in pairs(self.targets) do
@@ -736,6 +765,61 @@ end
-- FSM Events
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- On after "ElementDestroyed" event.
-- @param #TARGET self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #string Name Name of the element.
-- @param #TARGET.Object Target Target object.
function TARGET:onafterElementDestroyed(From, Event, To, Name, Target)
-- Debug message.
self:T(self.lid..string.format("Element %s of target object %s destroyed", Name, Target.Name))
-- Increase destroyed counter.
Target.Ndestroyed=Target.Ndestroyed+1
-- Increase dead counter.
self.Ndestroyed=self.Ndestroyed+1
self:ElementDead(Name, Target)
return self
end
--- On after "ElementDead" event.
-- @param #TARGET self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #string Name Name of the element.
-- @param #TARGET.Object Target Target object.
function TARGET:onafterElementDead(From, Event, To, Name, Target)
-- Debug message.
self:T(self.lid..string.format("Element %s of target object %s dead", Name, Target.Name))
-- Increase dead counter.
Target.Ndead=Target.Ndead+1
-- Increase dead counter.
self.Ndead=self.Ndead+1
-- All dead ==> Trigger event.
if Target.Ndestroyed==Target.N0 then
self:ObjectDestroyed(Target)
elseif Target.Ndead==Target.N0 then
self:ObjectDead(Target)
end
return self
end
--- On after "ObjectDamaged" event.
-- @param #TARGET self
-- @param #string From From state.
@@ -761,11 +845,6 @@ function TARGET:onafterObjectDestroyed(From, Event, To, Target)
-- Debug message.
self:T(self.lid..string.format("Object %s destroyed", Target.Name))
-- Increase destroyed counter.
self.Ndestroyed=self.Ndestroyed+1
Target.Ndestroyed=Target.Ndestroyed+1
Target.Life=0
-- Call object dead event.
@@ -788,15 +867,9 @@ function TARGET:onafterObjectDead(From, Event, To, Target)
-- Set target status.
Target.Status=TARGET.ObjectStatus.DEAD
-- Increase dead object counter
Target.Ndead=Target.Ndead+1
-- Set target object life to 0.
Target.Life=0
-- Increase dead counter.
self.Ndead=self.Ndead+1
-- Check if anyone is alive?
local dead=true
for _,_target in pairs(self.targets) do
@@ -889,54 +962,21 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
-- Add to the list of casualties.
table.insert(self.casualties, Name)
-- Try to get target Group.
local target=self:GetTargetByName(EventData.IniGroupName)
-- Try unit target.
if not target then
target=self:GetTargetByName(EventData.IniUnitName)
end
-- Get target from Group or Unit.
local target=self:GetTargetByName(EventData.IniGroupName) or self:GetTargetByName(EventData.IniUnitName)
-- Check if we could find a target object.
if target then
local Ndead=target.Ndead
local Ndestroyed=target.Ndestroyed
-- Increase dead/destroyed counter
if EventData.id==EVENTS.RemoveUnit then
Ndead=Ndead+1
self:ElementDead(Name, target)
else
Ndestroyed=Ndestroyed+1
Ndead=Ndead+1
end
-- Check if ALL objects are dead
if Ndead==target.N0 then
if Ndestroyed>=target.N0 then
-- Debug message.
self:T2(self.lid..string.format("EVENT ID=%d: target %s dead/lost ==> destroyed", EventData.id, tostring(target.Name)))
target.Life = 0
-- Trigger object destroyed event. This sets the Life to zero and increases Ndestroyed
self:ObjectDestroyed(target)
else
-- Debug message.
self:T2(self.lid..string.format("EVENT ID=%d: target %s removed ==> dead", EventData.id, tostring(target.Name)))
target.Life = 0
-- Trigger object dead event. This sets the Life to zero and increases Ndead counter
self:ObjectDead(target)
end
self:ElementDestroyed(Name, target)
end
else
self:E(self.lid..string.format("ERROR: Could not get target from IniGroup or IniUnit name when event Dead or UnitLost occured! Stats are not correctly updated :("))
end -- Event belongs to this TARGET
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("%.3f",_f))
table.insert(ffs,string.format("%.1f",_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("%.3f",_f))
table.insert(ffs,string.format("%.1f",_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("%.3f",_f))
table.insert(ffs,string.format("%.1f",_f))
end
local freqs = table.concat(ffs, ",")
+2 -52
View File
@@ -523,7 +523,7 @@ ENUMS.ReportingName =
Tornado = "Tornado",
-- Transport / Bomber / Others
Atlas = "A400",
Lancer = "B-1B",
Lancer = "B1-B",
Stratofortress = "B-52H",
Herc = "C-130",
Hercules = "C-130J-30",
@@ -568,7 +568,7 @@ ENUMS.ReportingName =
Apache = "AH-64",
Chinook = "CH-47",
Sea_Stallion = "CH-53",
Kiowa = "OH58D",
Kiowa = "OH-58",
Seahawk = "SH-60",
Blackhawk = "UH-60",
Sea_King = "S-61",
@@ -2126,56 +2126,6 @@ ENUMS.Storage.weapons.containers.UH60_GAU19_RIGHT = 'weapons.containers.{UH60_GA
ENUMS.Storage.weapons.containers.UH60_M230_RIGHT = 'weapons.containers.{UH60_M230_RIGHT}'
ENUMS.Storage.weapons.containers.UH60L_M2_GUNNER = 'weapons.containers.{UH60L_M2_GUNNER}'
ENUMS.Storage.weapons.adapters.GD_F100_SUU_13 = 'weapons.adapters.GD_F100_SUU-13'
ENUMS.Storage.weapons.containers.GPU_5_POD = 'weapons.containers.{GPU_5_POD}'
ENUMS.Storage.weapons.bombs.BOLT_117 = 'weapons.bombs.BOLT-117'
ENUMS.Storage.weapons.shells.F100_M39_20_TP_T = 'weapons.shells.F100_M39_20_TP_T'
ENUMS.Storage.weapons.gunmounts.M_39_F_100 = 'weapons.gunmounts.M-39 F-100'
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_275_L = 'weapons.droptanks.GD_F100_TANK_275_L'
ENUMS.Storage.weapons.bombs.BLU_4B_R_GROUP_R = 'weapons.bombs.BLU-4B_R_GROUP_R'
ENUMS.Storage.weapons.containers.F100_CAMERA_P2 = 'weapons.containers.F100_CAMERA_P2'
ENUMS.Storage.weapons.containers.HB_ORD_SUU_7 = 'weapons.containers.HB_ORD_SUU_7'
ENUMS.Storage.weapons.adapters.SidewinderPylon = 'weapons.adapters.SidewinderPylon'
ENUMS.Storage.weapons.adapters.apu_470 = 'weapons.adapters.apu_470'
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_335_R = 'weapons.droptanks.GD_F100_TANK_335_R'
ENUMS.Storage.weapons.bombs.BLU_3B_R_GROUP_R = 'weapons.bombs.BLU-3B_R_GROUP_R'
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_335_L = 'weapons.droptanks.GD_F100_TANK_335_L'
ENUMS.Storage.weapons.adapters.mbdz_u2t = 'weapons.adapters.mbdz_u2t'
ENUMS.Storage.weapons.containers.ZellRocket = 'weapons.containers.ZellRocket'
ENUMS.Storage.weapons.containers.apu_73 = 'weapons.containers.apu-73'
ENUMS.Storage.weapons.gunmounts.GAU_13 = 'weapons.gunmounts.GAU-13'
ENUMS.Storage.weapons.shells.F100_M39_20_TP = 'weapons.shells.F100_M39_20_TP'
ENUMS.Storage.weapons.shells.F100_M39_20_API = 'weapons.shells.F100_M39_20_API'
ENUMS.Storage.weapons.adapters.bdz_umk2b = 'weapons.adapters.bdz_umk2b'
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_450 = 'weapons.droptanks.GD_F100_TANK_450'
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_275_R = 'weapons.droptanks.GD_F100_TANK_275_R'
ENUMS.Storage.weapons.bombs.BLU_18_B_GROUP = 'weapons.bombs.BLU-18/B_GROUP'
ENUMS.Storage.weapons.containers.ZELL_Booster = 'weapons.containers.ZELL Booster'
ENUMS.Storage.weapons.adapters.apu_60 = 'weapons.adapters.apu_60'
ENUMS.Storage.weapons.gunmounts.GPU_5_POD = 'weapons.gunmounts.{GPU_5_POD}'
ENUMS.Storage.weapons.containers.F100_CAMERA_KA71A = 'weapons.containers.F100_CAMERA_KA71A'
ENUMS.Storage.weapons.bombs.BLU_3_R_GROUP_R = 'weapons.bombs.BLU-3_R_GROUP_R'
ENUMS.Storage.weapons.shells.F100_M39_20_HEI = 'weapons.shells.F100_M39_20_HEI'
ENUMS.Storage.weapons.droptanks.GD_F100_TANK_200 = 'weapons.droptanks.GD_F100_TANK_200'
ENUMS.Storage.weapons.adapters.apu_73 = 'weapons.adapters.apu-73'
ENUMS.Storage.weapons.gunmounts.AKAN_NO_TRC = 'weapons.gunmounts.AKAN_NO_TRC'
ENUMS.Storage.weapons.gunmounts.AKAN = 'weapons.gunmounts.AKAN'
ENUMS.Storage.weapons.shells.F100_M39_20_HEI_T = 'weapons.shells.F100_M39_20_HEI_T'
ENUMS.Storage.weapons.shells.F100_M39_20_API_T = 'weapons.shells.F100_M39_20_API_T'
ENUMS.Storage.weapons.containers.GD_F100_STRIKE_CAMERA = 'weapons.containers.GD_F100_STRIKE_CAMERA'
ENUMS.Storage.weapons.bombs.BLU_49_B = 'weapons.bombs.BLU-49/B'
ENUMS.Storage.weapons.bombs.GBU_24E = 'weapons.bombs.GBU_24E'
ENUMS.Storage.weapons.containers.GD_F100_SUU_13 = 'weapons.containers.GD_F100_SUU-13'
ENUMS.Storage.weapons.gunmounts.AKAN = 'weapons.gunmounts.{AKAN}'
ENUMS.Storage.weapons.gunmounts.AKAN_NO_TRC = 'weapons.gunmounts.{AKAN_NO_TRC}'
ENUMS.Storage.weapons.gunmounts.SUU_23_POD_Wing = 'weapons.gunmounts.{SUU_23_POD_Wing}'
ENUMS.Storage.weapons.containers.SUU_23_POD_Wing = 'weapons.containers.{SUU_23_POD_Wing}'
ENUMS.Storage.weapons.containers.SUU_23_POD_Centerline = 'weapons.containers.{SUU_23_POD_Centerline}'
ENUMS.Storage.weapons.gunmounts.SUU_23_POD_Centerline = 'weapons.gunmounts.{SUU_23_POD_Centerline}'
ENUMS.Storage.weapons.containers.HB_F_4E_BRU_42 = 'weapons.containers.HB_F-4E_BRU-42'
---
-- @type ENUMS.FARPType
-- @field #string FARP
@@ -2379,11 +2379,6 @@ function UTILS.IsLoadingDoorOpen( unit_name )
return true
end
if type_name == "Ka-50_3" and unit:getDrawArgumentValue(38) == 1 then
BASE:T(unit_name .. " cockpit door is open")
return true
end
if type_name=="C-130J-30" and (unit:getDrawArgumentValue(86)==1)then
BASE:T(unit_name.." rear doors are open")
return true