mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
#DYNAMICCARGO - Added functionalty
This commit is contained in:
parent
24264bd885
commit
19f6a8d8f6
@ -20,6 +20,7 @@
|
||||
-- * Manage database of hits to units and statics.
|
||||
-- * Manage database of destroys of units and statics.
|
||||
-- * Manage database of @{Core.Zone#ZONE_BASE} objects.
|
||||
-- * Manage database of @{Wrapper.DynamicCargo#DYNAMICCARGO} objects alive in the mission.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -39,6 +40,7 @@
|
||||
-- @field #table STORAGES DCS warehouse storages.
|
||||
-- @field #table STNS Used Link16 octal numbers for F16/15/18/AWACS planes.
|
||||
-- @field #table SADL Used Link16 octal numbers for A10/C-II planes.
|
||||
-- @field #table DYNAMICCARGO Dynamic Cargo objects.
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- Contains collections of wrapper objects defined within MOOSE that reflect objects within the simulator.
|
||||
@ -54,6 +56,7 @@
|
||||
-- * PLAYERS
|
||||
-- * CARGOS
|
||||
-- * STORAGES (DCS warehouses)
|
||||
-- * DYNAMICCARGO
|
||||
--
|
||||
-- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
||||
--
|
||||
@ -97,6 +100,7 @@ DATABASE = {
|
||||
STORAGES = {},
|
||||
STNS={},
|
||||
SADL={},
|
||||
DYNAMICCARGO={},
|
||||
}
|
||||
|
||||
local _DATABASECoalition =
|
||||
@ -143,6 +147,8 @@ function DATABASE:New()
|
||||
self:HandleEvent( EVENTS.DeleteZone )
|
||||
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||
-- DCS 2.9.7 Moose own dynamic cargo events
|
||||
self:HandleEvent( EVENTS.DynamicCargoRemoved, self._EventOnDynamicCargoRemoved)
|
||||
|
||||
self:_RegisterTemplates()
|
||||
self:_RegisterGroupsAndUnits()
|
||||
@ -173,16 +179,20 @@ end
|
||||
-- @param #boolean force
|
||||
-- @return Wrapper.Unit#UNIT The added unit.
|
||||
function DATABASE:AddUnit( DCSUnitName, force )
|
||||
|
||||
if not self.UNITS[DCSUnitName] or force == true then
|
||||
|
||||
local DCSunitName = DCSUnitName
|
||||
|
||||
if type(DCSunitName) == "number" then DCSunitName = string.format("%d",DCSUnitName) end
|
||||
|
||||
if not self.UNITS[DCSunitName] or force == true then
|
||||
-- Debug info.
|
||||
self:T( { "Add UNIT:", DCSUnitName } )
|
||||
self:T( { "Add UNIT:", DCSunitName } )
|
||||
|
||||
-- Register unit
|
||||
self.UNITS[DCSUnitName]=UNIT:Register(DCSUnitName)
|
||||
self.UNITS[DCSunitName]=UNIT:Register(DCSunitName)
|
||||
end
|
||||
|
||||
return self.UNITS[DCSUnitName]
|
||||
return self.UNITS[DCSunitName]
|
||||
end
|
||||
|
||||
|
||||
@ -224,6 +234,34 @@ function DATABASE:FindStatic( StaticName )
|
||||
return StaticFound
|
||||
end
|
||||
|
||||
--- Add a DynamicCargo to the database.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string Name Name of the dynamic cargo.
|
||||
-- @return Wrapper.DynamicCargo#DYNAMICCARGO The dynamic cargo object.
|
||||
function DATABASE:AddDynamicCargo( Name )
|
||||
if not self.DYNAMICCARGO[Name] then
|
||||
self.DYNAMICCARGO[Name] = DYNAMICCARGO:Register(Name)
|
||||
return self.DYNAMICCARGO[Name]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Finds a DYNAMICCARGO based on the Dynamic Cargo Name.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string DynamicCargoName
|
||||
-- @return Wrapper.DynamicCargo#DYNAMICCARGO The found DYNAMICCARGO.
|
||||
function DATABASE:FindDynamicCargo( DynamicCargoName )
|
||||
local StaticFound = self.DYNAMICCARGO[DynamicCargoName]
|
||||
return StaticFound
|
||||
end
|
||||
|
||||
--- Deletes a DYNAMICCARGO from the DATABASE based on the Dynamic Cargo Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeleteDynamicCargo( DynamicCargoName )
|
||||
self.DYNAMICCARGO[DynamicCargoName] = nil
|
||||
return self
|
||||
end
|
||||
|
||||
--- Adds a Airbase based on the Airbase Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string AirbaseName The name of the airbase.
|
||||
@ -818,12 +856,16 @@ end
|
||||
-- @param #boolean Force (optional) Force registration of client.
|
||||
-- @return Wrapper.Client#CLIENT The client object.
|
||||
function DATABASE:AddClient( ClientName, Force )
|
||||
|
||||
if not self.CLIENTS[ClientName] or Force == true then
|
||||
self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
|
||||
|
||||
local DCSUnitName = ClientName
|
||||
|
||||
if type(DCSUnitName) == "number" then DCSUnitName = string.format("%d",ClientName) end
|
||||
|
||||
if not self.CLIENTS[DCSUnitName] or Force == true then
|
||||
self.CLIENTS[DCSUnitName] = CLIENT:Register( DCSUnitName )
|
||||
end
|
||||
|
||||
return self.CLIENTS[ClientName]
|
||||
return self.CLIENTS[DCSUnitName]
|
||||
end
|
||||
|
||||
|
||||
@ -863,9 +905,11 @@ end
|
||||
--- Adds a player based on the Player Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:AddPlayer( UnitName, PlayerName )
|
||||
|
||||
|
||||
if type(UnitName) == "number" then UnitName = string.format("%d",UnitName) end
|
||||
|
||||
if PlayerName then
|
||||
self:T( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self:I( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self.PLAYERS[PlayerName] = UnitName
|
||||
self.PLAYERUNITS[PlayerName] = self:FindUnit( UnitName )
|
||||
self.PLAYERSJOINED[PlayerName] = PlayerName
|
||||
@ -873,6 +917,21 @@ function DATABASE:AddPlayer( UnitName, PlayerName )
|
||||
|
||||
end
|
||||
|
||||
--- Get a PlayerName by UnitName from PLAYERS in DATABASE.
|
||||
-- @param #DATABASE self
|
||||
-- @return #string PlayerName
|
||||
-- @return Wrapper.Unit#UNIT PlayerUnit
|
||||
function DATABASE:_FindPlayerNameByUnitName(UnitName)
|
||||
if UnitName then
|
||||
for playername,unitname in pairs(self.PLAYERS) do
|
||||
if unitname == UnitName and self.PLAYERUNITS[playername] and self.PLAYERUNITS[playername]:IsAlive() then
|
||||
return playername, self.PLAYERUNITS[playername]
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Deletes a player from the DATABASE based on the Player Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeletePlayer( UnitName, PlayerName )
|
||||
@ -1244,7 +1303,7 @@ function DATABASE:_GetGenericStaticCargoGroupTemplate(Name,Typename,Mass,Coaliti
|
||||
StaticTemplate.CategoryID = "static"
|
||||
StaticTemplate.CoalitionID = Coalition or coalition.side.BLUE
|
||||
StaticTemplate.CountryID = Country or country.id.GERMANY
|
||||
UTILS.PrintTableToLog(StaticTemplate)
|
||||
--UTILS.PrintTableToLog(StaticTemplate)
|
||||
return StaticTemplate
|
||||
end
|
||||
|
||||
@ -1417,7 +1476,7 @@ function DATABASE:_RegisterDynamicGroup(Groupname)
|
||||
|
||||
-- Add unit.
|
||||
self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
||||
self:AddUnit( DCSUnitName, true )
|
||||
self:AddUnit( tostring(DCSUnitName), true )
|
||||
|
||||
end
|
||||
else
|
||||
@ -1568,7 +1627,7 @@ end
|
||||
-- @param #DATABASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function DATABASE:_EventOnBirth( Event )
|
||||
self:F( { Event } )
|
||||
self:T( { Event } )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
|
||||
@ -1576,7 +1635,17 @@ function DATABASE:_EventOnBirth( Event )
|
||||
|
||||
-- Add static object to DB.
|
||||
self:AddStatic( Event.IniDCSUnitName )
|
||||
|
||||
elseif Event.IniObjectCategory == Object.Category.CARGO and string.match(Event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||
|
||||
-- Add dynamic cargo object to DB
|
||||
|
||||
local cargo = self:AddDynamicCargo(Event.IniDCSUnitName)
|
||||
|
||||
self:I(string.format("Adding dynamic cargo %s", tostring(Event.IniDCSUnitName)))
|
||||
|
||||
self:CreateEventNewDynamicCargo( cargo )
|
||||
|
||||
else
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.UNIT then
|
||||
@ -1762,6 +1831,15 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
||||
end
|
||||
end
|
||||
|
||||
--- Handles the OnDynamicCargoRemoved event to clean the active dynamic cargo table.
|
||||
-- @param #DATABASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function DATABASE:_EventOnDynamicCargoRemoved( Event )
|
||||
self:T( { Event } )
|
||||
if Event.IniDynamicCargoName then
|
||||
self:DeleteDynamicCargo(Event.IniDynamicCargoName)
|
||||
end
|
||||
end
|
||||
|
||||
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
|
||||
-- @param #DATABASE self
|
||||
|
||||
@ -194,6 +194,11 @@ world.event.S_EVENT_NEW_ZONE_GOAL = world.event.S_EVENT_MAX + 1004
|
||||
world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005
|
||||
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
|
||||
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
|
||||
-- dynamic cargo
|
||||
world.event.S_EVENT_NEW_DYNAMIC_CARGO = world.event.S_EVENT_MAX + 1008
|
||||
world.event.S_EVENT_DYNAMIC_CARGO_LOADED = world.event.S_EVENT_MAX + 1009
|
||||
world.event.S_EVENT_DYNAMIC_CARGO_UNLOADED = world.event.S_EVENT_MAX + 1010
|
||||
world.event.S_EVENT_DYNAMIC_CARGO_REMOVED = world.event.S_EVENT_MAX + 1011
|
||||
|
||||
|
||||
--- The different types of events supported by MOOSE.
|
||||
@ -275,7 +280,12 @@ EVENTS = {
|
||||
SimulationFreeze = world.event.S_EVENT_SIMULATION_FREEZE or -1,
|
||||
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,
|
||||
HumanAircraftRepairFinish = world.event.S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH or -1,
|
||||
-- dynamic cargo
|
||||
NewDynamicCargo = world.event.S_EVENT_NEW_DYNAMIC_CARGO or -1,
|
||||
DynamicCargoLoaded = world.event.S_EVENT_DYNAMIC_CARGO_LOADED or -1,
|
||||
DynamicCargoUnloaded = world.event.S_EVENT_DYNAMIC_CARGO_UNLOADED or -1,
|
||||
DynamicCargoRemoved = world.event.S_EVENT_DYNAMIC_CARGO_REMOVED or -1,
|
||||
}
|
||||
|
||||
|
||||
@ -334,6 +344,9 @@ EVENTS = {
|
||||
--
|
||||
-- @field Core.Zone#ZONE Zone The zone object.
|
||||
-- @field #string ZoneName The name of the zone.
|
||||
--
|
||||
-- @field Wrapper.DynamicCargo#DYNAMICCARGO IniDynamicCargo The dynamic cargo object.
|
||||
-- @field #string IniDynamicCargoName The dynamic cargo unit name.
|
||||
|
||||
|
||||
|
||||
@ -730,6 +743,31 @@ local _EVENTMETA = {
|
||||
Side = "I",
|
||||
Event = "OnEventHumanAircraftRepairFinish",
|
||||
Text = "S_EVENT_HUMAN_AIRCRAFT_REPAIR_FINISH"
|
||||
},
|
||||
-- dynamic cargo
|
||||
[EVENTS.NewDynamicCargo] = {
|
||||
Order = 1,
|
||||
Side = "I",
|
||||
Event = "OnEventNewDynamicCargo",
|
||||
Text = "S_EVENT_NEW_DYNAMIC_CARGO"
|
||||
},
|
||||
[EVENTS.DynamicCargoLoaded] = {
|
||||
Order = 1,
|
||||
Side = "I",
|
||||
Event = "OnEventDynamicCargoLoaded",
|
||||
Text = "S_EVENT_DYNAMIC_CARGO_LOADED"
|
||||
},
|
||||
[EVENTS.DynamicCargoUnloaded] = {
|
||||
Order = 1,
|
||||
Side = "I",
|
||||
Event = "OnEventDynamicCargoUnloaded",
|
||||
Text = "S_EVENT_DYNAMIC_CARGO_UNLOADED"
|
||||
},
|
||||
[EVENTS.DynamicCargoRemoved] = {
|
||||
Order = 1,
|
||||
Side = "I",
|
||||
Event = "OnEventDynamicCargoRemoved",
|
||||
Text = "S_EVENT_DYNAMIC_CARGO_REMOVED"
|
||||
},
|
||||
}
|
||||
|
||||
@ -1146,7 +1184,63 @@ do -- Event Creation
|
||||
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
|
||||
--- Creation of a S_EVENT_NEW_DYNAMIC_CARGO event.
|
||||
-- @param #EVENT self
|
||||
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||
function EVENT:CreateEventNewDynamicCargo(DynamicCargo)
|
||||
self:F({DynamicCargo})
|
||||
local Event = {
|
||||
id = EVENTS.NewDynamicCargo,
|
||||
time = timer.getTime(),
|
||||
dynamiccargo = DynamicCargo,
|
||||
initiator = DynamicCargo:GetDCSObject(),
|
||||
}
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
--- Creation of a S_EVENT_DYNAMIC_CARGO_LOADED event.
|
||||
-- @param #EVENT self
|
||||
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||
function EVENT:CreateEventDynamicCargoLoaded(DynamicCargo)
|
||||
self:F({DynamicCargo})
|
||||
local Event = {
|
||||
id = EVENTS.DynamicCargoLoaded,
|
||||
time = timer.getTime(),
|
||||
dynamiccargo = DynamicCargo,
|
||||
initiator = DynamicCargo:GetDCSObject(),
|
||||
}
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
--- Creation of a S_EVENT_DYNAMIC_CARGO_UNLOADED event.
|
||||
-- @param #EVENT self
|
||||
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||
function EVENT:CreateEventDynamicCargoUnloaded(DynamicCargo)
|
||||
self:F({DynamicCargo})
|
||||
local Event = {
|
||||
id = EVENTS.DynamicCargoUnloaded,
|
||||
time = timer.getTime(),
|
||||
dynamiccargo = DynamicCargo,
|
||||
initiator = DynamicCargo:GetDCSObject(),
|
||||
}
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
--- Creation of a S_EVENT_DYNAMIC_CARGO_REMOVED event.
|
||||
-- @param #EVENT self
|
||||
-- @param Wrapper.DynamicCargo#DYNAMICCARGO DynamicCargo the dynamic cargo object
|
||||
function EVENT:CreateEventDynamicCargoRemoved(DynamicCargo)
|
||||
self:F({DynamicCargo})
|
||||
local Event = {
|
||||
id = EVENTS.DynamicCargoRemoved,
|
||||
time = timer.getTime(),
|
||||
dynamiccargo = DynamicCargo,
|
||||
initiator = DynamicCargo:GetDCSObject(),
|
||||
}
|
||||
world.onEvent( Event )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Main event function.
|
||||
@ -1261,7 +1355,13 @@ function EVENT:onEvent( Event )
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
||||
if string.match(Event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||
Event.IniDynamicCargo = DYNAMICCARGO:FindByName(Event.IniUnitName)
|
||||
Event.IniDynamicCargoName = Event.IniUnitName
|
||||
Event.IniPlayerName = string.match(Event.IniUnitName,"^(.+)|%d%d:%d%d|PKG%d+")
|
||||
else
|
||||
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
||||
end
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
@ -1382,7 +1482,7 @@ function EVENT:onEvent( Event )
|
||||
end
|
||||
|
||||
-- Weapon.
|
||||
if Event.weapon and type(Event.weapon) == "table" then
|
||||
if Event.weapon and type(Event.weapon) == "table" and Event.weapon.isExist and Event.weapon:isExist() then
|
||||
Event.Weapon = Event.weapon
|
||||
Event.WeaponName = Event.weapon:isExist() and Event.weapon:getTypeName() or "Unknown Weapon"
|
||||
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
||||
@ -1425,6 +1525,13 @@ function EVENT:onEvent( Event )
|
||||
Event.Cargo = Event.cargo
|
||||
Event.CargoName = Event.cargo.Name
|
||||
end
|
||||
|
||||
-- Dynamic cargo Object
|
||||
if Event.dynamiccargo then
|
||||
Event.IniDynamicCargo = Event.dynamiccargo
|
||||
Event.IniDynamicCargoName = Event.IniDynamicCargo.StaticName
|
||||
Event.IniPlayerName = Event.IniDynamicCargo.Owner or string.match(Event.IniUnitName,"^(.+)|%d%d:%d%d|PKG%d+")
|
||||
end
|
||||
|
||||
-- Zone object.
|
||||
if Event.zone then
|
||||
|
||||
@ -1811,7 +1811,7 @@ function RANGE:OnEventBirth( EventData )
|
||||
if not EventData.IniPlayerName then return end
|
||||
|
||||
local _unitName = EventData.IniUnitName
|
||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName )
|
||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName, EventData.IniPlayerName )
|
||||
|
||||
self:T3( self.lid .. "BIRTH: unit = " .. tostring( EventData.IniUnitName ) )
|
||||
self:T3( self.lid .. "BIRTH: group = " .. tostring( EventData.IniGroupName ) )
|
||||
@ -1967,7 +1967,9 @@ end
|
||||
-- @param #number attackAlt Attack altitude.
|
||||
-- @param #number attackVel Attack velocity.
|
||||
function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackVel)
|
||||
|
||||
|
||||
if not playerData then return end
|
||||
|
||||
-- Get closet target to last position.
|
||||
local _closetTarget = nil -- #RANGE.BombTarget
|
||||
local _distance = nil
|
||||
@ -1984,13 +1986,13 @@ function RANGE._OnImpact(weapon, self, playerData, attackHdg, attackAlt, attackV
|
||||
-- Coordinate of impact point.
|
||||
local impactcoord = weapon:GetImpactCoordinate()
|
||||
|
||||
-- Check if impact happened in range zone.
|
||||
-- Check if impact happened in range zone.+
|
||||
local insidezone = self.rangezone:IsCoordinateInZone( impactcoord )
|
||||
|
||||
|
||||
-- Smoke impact point of bomb.
|
||||
if playerData.smokebombimpact and insidezone then
|
||||
if playerData.delaysmoke then
|
||||
if playerData and playerData.smokebombimpact and insidezone then
|
||||
if playerData and playerData.delaysmoke then
|
||||
timer.scheduleFunction( self._DelayedSmoke, { coord = impactcoord, color = playerData.smokecolor }, timer.getTime() + self.TdelaySmoke )
|
||||
else
|
||||
impactcoord:Smoke( playerData.smokecolor )
|
||||
@ -2115,7 +2117,7 @@ function RANGE:OnEventShot( EventData )
|
||||
local _unitName = EventData.IniUnitName
|
||||
|
||||
-- Get player unit and name.
|
||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName )
|
||||
local _unit, _playername = self:_GetPlayerUnitAndName( _unitName, EventData.IniPlayerName )
|
||||
|
||||
-- Distance Player-to-Range. Set this to larger value than the threshold.
|
||||
local dPR = self.BombtrackThreshold * 2
|
||||
@ -2127,11 +2129,13 @@ function RANGE:OnEventShot( EventData )
|
||||
end
|
||||
|
||||
-- Only track if distance player to range is < 25 km. Also check that a player shot. No need to track AI weapons.
|
||||
if _track and dPR <= self.BombtrackThreshold and _unit and _playername then
|
||||
if _track and dPR <= self.BombtrackThreshold and _unit and _playername and self.PlayerSettings[_playername] then
|
||||
|
||||
-- Player data.
|
||||
local playerData = self.PlayerSettings[_playername] -- #RANGE.PlayerData
|
||||
|
||||
|
||||
if not playerData then return end
|
||||
|
||||
-- Attack parameters.
|
||||
local attackHdg=_unit:GetHeading()
|
||||
local attackAlt=_unit:GetHeight()
|
||||
@ -4099,8 +4103,8 @@ end
|
||||
-- @return Wrapper.Unit#UNIT Unit of player.
|
||||
-- @return #string Name of the player.
|
||||
-- @return #boolean If true, group has > 1 player in it
|
||||
function RANGE:_GetPlayerUnitAndName( _unitName )
|
||||
self:F2( _unitName )
|
||||
function RANGE:_GetPlayerUnitAndName( _unitName, PlayerName )
|
||||
self:I( _unitName )
|
||||
|
||||
if _unitName ~= nil then
|
||||
|
||||
@ -4111,7 +4115,7 @@ function RANGE:_GetPlayerUnitAndName( _unitName )
|
||||
|
||||
if DCSunit and DCSunit.getPlayerName then
|
||||
|
||||
local playername = DCSunit:getPlayerName()
|
||||
local playername = DCSunit:getPlayerName() or PlayerName or "None"
|
||||
local unit = UNIT:Find( DCSunit )
|
||||
|
||||
self:T2( { DCSunit = DCSunit, unit = unit, playername = playername } )
|
||||
|
||||
@ -48,6 +48,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Marker.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Weapon.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Net.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/Storage.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Wrapper/DynamicCargo.lua' )
|
||||
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/Cargo.lua' )
|
||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Cargo/CargoUnit.lua' )
|
||||
|
||||
@ -78,6 +78,7 @@ CTLD_CARGO = {
|
||||
-- @field #string REPAIR
|
||||
-- @field #string ENGINEERS
|
||||
-- @field #string STATIC
|
||||
-- @field #string GCLOADABLE
|
||||
CTLD_CARGO.Enum = {
|
||||
VEHICLE = "Vehicle", -- #string vehicles
|
||||
TROOPS = "Troops", -- #string troops
|
||||
@ -86,6 +87,7 @@ CTLD_CARGO = {
|
||||
REPAIR = "Repair", -- #string repair
|
||||
ENGINEERS = "Engineers", -- #string engineers
|
||||
STATIC = "Static", -- #string statics
|
||||
GCLOADABLE = "GC_Loadable", -- #string dynamiccargo
|
||||
}
|
||||
|
||||
--- Function to create new CTLD_CARGO object.
|
||||
@ -770,7 +772,7 @@ do
|
||||
-- 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.
|
||||
-- my_ctld.RadioSoundFC3 = "beacon.ogg" -- this sound will be hearable by FC3 users (actually all UHF radios); change to something like "beaconsilent.ogg" and add the sound file to your miz if you don't want to annoy FC3 pilots.
|
||||
-- my_ctld.enableChinookGCLoading = true -- this will effectively suppress the crate load and drop menus for CTLD for the Chinook
|
||||
-- my_ctld.enableChinookGCLoading = true -- this will effectively suppress the crate load and drop for CTLD_CARGO.Enum.STATIc types for CTLD for the Chinook
|
||||
--
|
||||
-- ## 2.1 CH-47 Chinook support
|
||||
--
|
||||
@ -780,7 +782,7 @@ do
|
||||
--
|
||||
-- ## 2.1.1 Moose CTLD created crate cargo
|
||||
--
|
||||
-- Given the correct shape, Moose created cargo can be either loaded with the ground crew or via the F10 CTLD menu. **It is strongly recommend to either use the ground crew or CTLD to load/unload cargo**. Mix and match will not work here.
|
||||
-- Given the correct shape, Moose created cargo can be either loaded with the ground crew or via the F10 CTLD menu. **It is strongly recommend to either use the ground crew or CTLD to load/unload Moose created cargo**. Mix and match will not work here.
|
||||
-- Static shapes loadable *into* the Chinook are at the time of writing:
|
||||
--
|
||||
-- * Ammo crate (type "ammo_cargo")
|
||||
@ -1203,6 +1205,7 @@ CTLD = {
|
||||
wpZones = {},
|
||||
dropOffZones = {},
|
||||
pickupZones = {},
|
||||
DynamicCargo = {},
|
||||
}
|
||||
|
||||
------------------------------
|
||||
@ -1307,7 +1310,7 @@ CTLD.UnitTypeCapabilities = {
|
||||
|
||||
--- CTLD class version.
|
||||
-- @field #string version
|
||||
CTLD.version="1.0.58"
|
||||
CTLD.version="1.1.12"
|
||||
|
||||
--- Instantiate a new CTLD.
|
||||
-- @param #CTLD self
|
||||
@ -1590,7 +1593,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #CTLD_CARGO Cargo Cargo crate.
|
||||
-- @param #CTLD_CARGO Cargo Cargo crate. Can be a Wrapper.DynamicCargo#DYNAMICCARGO object, if ground crew loaded!
|
||||
-- @return #CTLD self
|
||||
|
||||
--- FSM Function OnBeforeTroopsDeployed.
|
||||
@ -1612,7 +1615,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #table Cargotable Table of #CTLD_CARGO objects dropped.
|
||||
-- @param #table Cargotable Table of #CTLD_CARGO objects dropped. Can be a Wrapper.DynamicCargo#DYNAMICCARGO object, if ground crew unloaded!
|
||||
-- @return #CTLD self
|
||||
|
||||
--- FSM Function OnBeforeCratesBuild.
|
||||
@ -1678,7 +1681,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #CTLD_CARGO Cargo Cargo crate.
|
||||
-- @param #CTLD_CARGO Cargo Cargo crate. Can be a Wrapper.DynamicCargo#DYNAMICCARGO object, if ground crew loaded!
|
||||
-- @return #CTLD self
|
||||
|
||||
--- FSM Function OnAfterTroopsDeployed.
|
||||
@ -1700,7 +1703,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #table Cargotable Table of #CTLD_CARGO objects dropped.
|
||||
-- @param #table Cargotable Table of #CTLD_CARGO objects dropped. Can be a Wrapper.DynamicCargo#DYNAMICCARGO object, if ground crew unloaded!
|
||||
-- @return #CTLD self
|
||||
|
||||
--- FSM Function OnAfterCratesBuild.
|
||||
@ -1879,7 +1882,7 @@ end
|
||||
-- @param #CTLD self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CTLD:_EventHandler(EventData)
|
||||
self:I(string.format("%s Event = %d",self.lid, EventData.id))
|
||||
self:T(string.format("%s Event = %d",self.lid, EventData.id))
|
||||
local event = EventData -- Core.Event#EVENTDATA
|
||||
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
|
||||
local _coalition = event.IniCoalition
|
||||
@ -1909,28 +1912,98 @@ function CTLD:_EventHandler(EventData)
|
||||
self.CtldUnits[unitname] = nil
|
||||
self.Loaded_Cargo[unitname] = nil
|
||||
self.MenusDone[unitname] = nil
|
||||
elseif event.id == EVENTS.Birth and event.IniObjectCategory == 6 and string.match(event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||
--UTILS.PrintTableToLog(event)
|
||||
--elseif event.id == EVENTS.NewDynamicCargo and event.IniObjectCategory == 6 and string.match(event.IniUnitName,".+|%d%d:%d%d|PKG%d+") then
|
||||
elseif event.id == EVENTS.NewDynamicCargo then
|
||||
self:T(self.lid.."GC New Event "..event.IniDynamicCargoName)
|
||||
---------------
|
||||
-- New dynamic cargo system Handling
|
||||
-- New dynamic cargo system Handling NEW
|
||||
--------------
|
||||
local function RegisterDynamicCargo()
|
||||
local static = _DATABASE:AddStatic(event.IniUnitName)
|
||||
if static then
|
||||
static.DCSCargoObject = event.IniDCSUnit
|
||||
local Mass = event.IniDCSUnit:getCargoWeight()
|
||||
local country = event.IniDCSUnit:getCountry()
|
||||
local template = _DATABASE:_GetGenericStaticCargoGroupTemplate(event.IniUnitName,event.IniTypeName,Mass,event.IniCoalition,country)
|
||||
_DATABASE:_RegisterStaticTemplate(template,event.IniCoalition,"static",country)
|
||||
self:I("**** Ground crew created static cargo added: "..event.IniUnitName .." | Weight in kgs: "..Mass)
|
||||
local cargotype = self:AddStaticsCargo(event.IniUnitName,Mass,1,nil,true)
|
||||
self.CrateCounter = self.CrateCounter + 1
|
||||
self.Spawned_Crates[self.CrateCounter] = static
|
||||
cargotype.Positionable = static
|
||||
table.insert(self.Spawned_Cargo, cargotype)
|
||||
self.DynamicCargo[event.IniDynamicCargoName] = event.IniDynamicCargo
|
||||
---------------
|
||||
-- End new dynamic cargo system Handling
|
||||
--------------
|
||||
elseif event.id == EVENTS.DynamicCargoLoaded then
|
||||
self:T(self.lid.."GC Loaded Event "..event.IniDynamicCargoName)
|
||||
---------------
|
||||
-- New dynamic cargo system Handling LOADING
|
||||
--------------
|
||||
local dcargo = event.IniDynamicCargo -- Wrapper.DynamicCargo#DYNAMICCARGO
|
||||
-- get client/unit object
|
||||
local client = CLIENT:FindByPlayerName(dcargo.Owner)
|
||||
if client and client:IsAlive() then
|
||||
-- add to unit load list
|
||||
local unitname = client:GetName() or "none"
|
||||
local loaded = {}
|
||||
if self.Loaded_Cargo[unitname] then
|
||||
loaded = self.Loaded_Cargo[unitname] -- #CTLD.LoadedCargo
|
||||
else
|
||||
loaded = {} -- #CTLD.LoadedCargo
|
||||
loaded.Troopsloaded = 0
|
||||
loaded.Cratesloaded = 0
|
||||
loaded.Cargo = {}
|
||||
end
|
||||
loaded.Cratesloaded = loaded.Cratesloaded+1
|
||||
table.insert(loaded.Cargo,dcargo)
|
||||
self.Loaded_Cargo[unitname] = nil
|
||||
self.Loaded_Cargo[unitname] = loaded
|
||||
local Group = client:GetGroup()
|
||||
self:_SendMessage(string.format("Crate %s loaded by ground crew!",event.IniDynamicCargoName), 10, false, Group)
|
||||
self:__CratesPickedUp(1, Group, client, dcargo)
|
||||
end
|
||||
self:ScheduleOnce(0.5,RegisterDynamicCargo)
|
||||
---------------
|
||||
-- End new dynamic cargo system Handling
|
||||
--------------
|
||||
elseif event.id == EVENTS.DynamicCargoUnloaded then
|
||||
self:T(self.lid.."GC Unload Event "..event.IniDynamicCargoName)
|
||||
---------------
|
||||
-- New dynamic cargo system Handling UNLOADING
|
||||
--------------
|
||||
local dcargo = event.IniDynamicCargo -- Wrapper.DynamicCargo#DYNAMICCARGO
|
||||
-- get client/unit object
|
||||
local client = CLIENT:FindByPlayerName(dcargo.Owner)
|
||||
if client and client:IsAlive() then
|
||||
-- add to unit load list
|
||||
local unitname = client:GetName() or "none"
|
||||
local loaded = {}
|
||||
if self.Loaded_Cargo[unitname] then
|
||||
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()))
|
||||
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
|
||||
loaded.Cargo = nil
|
||||
loaded.Cargo = Loaded
|
||||
self.Loaded_Cargo[unitname] = nil
|
||||
self.Loaded_Cargo[unitname] = loaded
|
||||
else
|
||||
loaded = {} -- #CTLD.LoadedCargo
|
||||
loaded.Troopsloaded = 0
|
||||
loaded.Cratesloaded = 0
|
||||
loaded.Cargo = {}
|
||||
self.Loaded_Cargo[unitname] = loaded
|
||||
end
|
||||
local Group = client:GetGroup()
|
||||
self:_SendMessage(string.format("Crate %s unloaded by ground crew!",event.IniDynamicCargoName), 10, false, Group)
|
||||
self:__CratesDropped(1,Group,client,{dcargo})
|
||||
end
|
||||
---------------
|
||||
-- End new dynamic cargo system Handling
|
||||
--------------
|
||||
elseif event.id == EVENTS.DynamicCargoRemoved then
|
||||
self:T(self.lid.."GC Remove Event "..event.IniDynamicCargoName)
|
||||
---------------
|
||||
-- New dynamic cargo system Handling REMOVE
|
||||
--------------
|
||||
self.DynamicCargo[event.IniDynamicCargoName] = nil
|
||||
---------------
|
||||
-- End new dynamic cargo system Handling
|
||||
--------------
|
||||
@ -2173,7 +2246,7 @@ end
|
||||
|
||||
function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
|
||||
self:T(self.lid .. " _FindRepairNearby")
|
||||
--self:I({Group:GetName(),Unit:GetName(),Repairtype})
|
||||
--self:T({Group:GetName(),Unit:GetName(),Repairtype})
|
||||
local unitcoord = Unit:GetCoordinate()
|
||||
|
||||
-- find nearest group of deployed groups
|
||||
@ -2191,7 +2264,7 @@ function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
|
||||
end
|
||||
end
|
||||
|
||||
--self:I("Distance: ".. nearestDistance)
|
||||
--self:T("Distance: ".. nearestDistance)
|
||||
|
||||
-- found one and matching distance?
|
||||
if nearestGroup == nil or nearestDistance > self.EngineerSearch then
|
||||
@ -2225,7 +2298,7 @@ function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
|
||||
-- walk through generics and find matching type
|
||||
local Cargotype = nil
|
||||
for k,v in pairs(self.Cargo_Crates) do
|
||||
--self:I({groupname,v.Templates,Repairtype})
|
||||
--self:T({groupname,v.Templates,Repairtype})
|
||||
if matchstring(groupname,v.Templates) and matchstring(groupname,Repairtype) then
|
||||
Cargotype = v -- #CTLD_CARGO
|
||||
break
|
||||
@ -2235,7 +2308,7 @@ function CTLD:_FindRepairNearby(Group, Unit, Repairtype)
|
||||
if Cargotype == nil then
|
||||
return nil, nil
|
||||
else
|
||||
--self:I({groupname,Cargotype})
|
||||
--self:T({groupname,Cargotype})
|
||||
return nearestGroup, Cargotype
|
||||
end
|
||||
|
||||
@ -2713,7 +2786,7 @@ function CTLD:_ListCratesNearby( _group, _unit)
|
||||
end
|
||||
text:Add("------------------------------------------------------------")
|
||||
if indexgc > 0 then
|
||||
text:Add("Probably ground crew loaded (F8)")
|
||||
text:Add("Probably ground crew loadable (F8)")
|
||||
for _,_entry in pairs (loadedbygc) do
|
||||
local entry = _entry -- #CTLD_CARGO
|
||||
local name = entry:GetName() --#string
|
||||
@ -2817,7 +2890,7 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight)
|
||||
local capabilities = {}
|
||||
local maxmass = 2000
|
||||
local maxloadable = 2000
|
||||
local IsNoHook = not self:IsHook(_unit)
|
||||
local IsHook = self:IsHook(_unit)
|
||||
if not _ignoreweight then
|
||||
maxloadable = self:_GetMaxLoadableMass(_unit)
|
||||
end
|
||||
@ -2828,9 +2901,10 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight)
|
||||
local weight = cargo:GetMass() -- weight in kgs of this cargo
|
||||
local staticid = cargo:GetID()
|
||||
self:T(self.lid .. " Found cargo mass: " .. weight)
|
||||
local cargoalive = false -- TODO dyn cargo spawn workaround
|
||||
local dcsunit = nil
|
||||
local dcsunitpos = nil
|
||||
--local cargoalive = false -- TODO dyn cargo spawn workaround
|
||||
--local dcsunit = nil
|
||||
--local dcsunitpos = nil
|
||||
--[[
|
||||
if static and static.DCSCargoObject then
|
||||
dcsunit = Unit.getByName(static.StaticName)
|
||||
if dcsunit then
|
||||
@ -2844,26 +2918,37 @@ function CTLD:_FindCratesNearby( _group, _unit, _dist, _ignoreweight)
|
||||
end
|
||||
end
|
||||
end
|
||||
if static and (static:IsAlive() or cargoalive) then
|
||||
local staticpos = static:GetCoordinate() or dcsunitpos
|
||||
--]]
|
||||
if static and static:IsAlive() then --or cargoalive) then
|
||||
local restricthooktononstatics = self.enableChinookGCLoading and IsHook
|
||||
self:T(self.lid .. " restricthooktononstatics: " .. tostring(restricthooktononstatics))
|
||||
local cargoisstatic = cargo:GetType() == CTLD_CARGO.Enum.STATIC and true or false
|
||||
self:T(self.lid .. " Cargo is static: " .. tostring(cargoisstatic))
|
||||
local restricted = cargoisstatic and restricthooktononstatics
|
||||
self:T(self.lid .. " Loading restricted: " .. tostring(restricted))
|
||||
local staticpos = static:GetCoordinate() --or dcsunitpos
|
||||
--[[
|
||||
--- Testing
|
||||
local landheight = staticpos:GetLandHeight()
|
||||
local agl = staticpos.y-landheight
|
||||
agl = UTILS.Round(agl,2)
|
||||
local GCloaded = agl > 0 and true or false
|
||||
if IsNoHook == true then GCloaded = false end
|
||||
if IsNoHook == true then GCloaded = false end
|
||||
--]]
|
||||
--- Testing
|
||||
local distance = self:_GetDistance(location,staticpos)
|
||||
self:T({name=static:GetName(),IsNoHook=IsNoHook,agl=agl,GCloaded=GCloaded,distance=string.format("%.2f",distance or 0)})
|
||||
if (not GCloaded) and distance <= finddist and static and (weight <= maxloadable or _ignoreweight) then
|
||||
--self:T({name=static:GetName(),IsHook=IsHook,agl=agl,GCloaded=GCloaded,distance=string.format("%.2f",distance or 0)})
|
||||
--if (not restricthooktononstatics) and distance <= finddist and static and (weight <= maxloadable or _ignoreweight) then
|
||||
self:T(self.lid .. string.format("Dist %dm/%dm | weight %dkg | maxloadable %dkg",distance,finddist,weight,maxloadable))
|
||||
if distance <= finddist and (weight <= maxloadable or _ignoreweight) and restricted == false then
|
||||
index = index + 1
|
||||
table.insert(found, staticid, cargo)
|
||||
maxloadable = maxloadable - weight
|
||||
--elseif restricthooktononstatics and distance < 10 and static then
|
||||
--indexg = indexg + 1
|
||||
--table.insert(LoadedbyGC,staticid, cargo)
|
||||
end
|
||||
if GCloaded == true and distance < 10 and static then
|
||||
indexg = indexg + 1
|
||||
table.insert(LoadedbyGC,staticid, cargo)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
return found, index, LoadedbyGC, indexg
|
||||
@ -2929,10 +3014,10 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
||||
if number == 0 and self.hoverautoloading then
|
||||
return self -- exit
|
||||
elseif number == 0 then
|
||||
self:_SendMessage("Sorry no loadable crates nearby or max cargo weight reached!", 10, false, Group)
|
||||
self:_SendMessage("Sorry, no loadable crates nearby or max cargo weight reached!", 10, false, Group)
|
||||
return self -- exit
|
||||
elseif numberonboard == cratelimit then
|
||||
self:_SendMessage("Sorry no fully loaded!", 10, false, Group)
|
||||
self:_SendMessage("Sorry, we are fully loaded!", 10, false, Group)
|
||||
return self -- exit
|
||||
else
|
||||
-- go through crates and load
|
||||
@ -3024,9 +3109,13 @@ function CTLD:_GetUnitCargoMass(Unit)
|
||||
if (type == CTLD_CARGO.Enum.TROOPS or type == CTLD_CARGO.Enum.ENGINEERS) and not cargo:WasDropped() then
|
||||
loadedmass = loadedmass + (cargo.PerCrateMass * cargo:GetCratesNeeded())
|
||||
end
|
||||
if type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and not cargo:WasDropped() then
|
||||
if type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and type ~= CTLD_CARGO.Enum.GCLOADABLE and not cargo:WasDropped() then
|
||||
loadedmass = loadedmass + cargo.PerCrateMass
|
||||
end
|
||||
if type == CTLD_CARGO.Enum.GCLOADABLE then
|
||||
local mass = cargo:GetCargoWeight()
|
||||
loadedmass = loadedmass+mass
|
||||
end
|
||||
end
|
||||
end
|
||||
return loadedmass
|
||||
@ -3073,8 +3162,8 @@ function CTLD:_ListCargo(Group, Unit)
|
||||
local loadedmass = self:_GetUnitCargoMass(Unit) -- #number
|
||||
local maxloadable = self:_GetMaxLoadableMass(Unit)
|
||||
local finddist = self.CrateDistance or 35
|
||||
local _,_,loadedgc,loadedno = self:_FindCratesNearby(Group,Unit,finddist,true)
|
||||
if self.Loaded_Cargo[unitname] or loadedno > 0 then
|
||||
--local _,_,loadedgc,loadedno = self:_FindCratesNearby(Group,Unit,finddist,true)
|
||||
if self.Loaded_Cargo[unitname] then
|
||||
local no_troops = loadedcargo.Troopsloaded or 0
|
||||
local no_crates = loadedcargo.Cratesloaded or 0
|
||||
local cargotable = loadedcargo.Cargo or {} -- #table
|
||||
@ -3099,17 +3188,22 @@ function CTLD:_ListCargo(Group, Unit)
|
||||
for _,_cargo in pairs(cargotable or {}) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
if (type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS) and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
||||
if (type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and type ~= CTLD_CARGO.Enum.GCLOADABLE) and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
||||
report:Add(string.format("Crate: %s size 1",cargo:GetName()))
|
||||
cratecount = cratecount + 1
|
||||
end
|
||||
if type == CTLD_CARGO.Enum.GCLOADABLE and not cargo:WasDropped() then
|
||||
report:Add(string.format("GC loaded Crate: %s size 1",cargo:GetName()))
|
||||
cratecount = cratecount + 1
|
||||
end
|
||||
end
|
||||
if cratecount == 0 then
|
||||
report:Add(" N O N E")
|
||||
end
|
||||
--[[
|
||||
if loadedno > 0 then
|
||||
report:Add("------------------------------------------------------------")
|
||||
report:Add(" -- CRATES loaded via F8 --")
|
||||
report:Add(" -- CRATES loaded via Ground Crew --")
|
||||
for _,_cargo in pairs(loadedgc or {}) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
@ -3119,6 +3213,7 @@ function CTLD:_ListCargo(Group, Unit)
|
||||
end
|
||||
end
|
||||
end
|
||||
--]]
|
||||
report:Add("------------------------------------------------------------")
|
||||
report:Add("Total Mass: ".. loadedmass .. " kg. Loadable: "..maxloadable.." kg.")
|
||||
local text = report:Text()
|
||||
@ -3453,7 +3548,7 @@ function CTLD:_UnloadCrates(Group, Unit)
|
||||
for _,_cargo in pairs (cargotable) do
|
||||
local cargo = _cargo -- #CTLD_CARGO
|
||||
local type = cargo:GetType() -- #CTLD_CARGO.Enum
|
||||
if type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
||||
if type ~= CTLD_CARGO.Enum.TROOPS and type ~= CTLD_CARGO.Enum.ENGINEERS and type ~= CTLD_CARGO.Enum.GCLOADABLE and (not cargo:WasDropped() or self.allowcratepickupagain) then
|
||||
-- unload crates
|
||||
self:_GetCrates(Group, Unit, cargo, 1, true)
|
||||
cargo:SetWasDropped(true)
|
||||
@ -3474,6 +3569,10 @@ function CTLD:_UnloadCrates(Group, Unit)
|
||||
table.insert(loaded.Cargo,_cargo)
|
||||
loaded.Troopsloaded = loaded.Troopsloaded + size
|
||||
end
|
||||
if type == CTLD_CARGO.Enum.GCLOADABLE and not cargo:WasDropped() then
|
||||
table.insert(loaded.Cargo,_cargo)
|
||||
loaded.Cratesloaded = loaded.Cratesloaded + size
|
||||
end
|
||||
end
|
||||
self.Loaded_Cargo[unitname] = nil
|
||||
self.Loaded_Cargo[unitname] = loaded
|
||||
@ -3906,7 +4005,8 @@ function CTLD:_RefreshF10Menus()
|
||||
local cantroops = capabilities.troops
|
||||
local cancrates = capabilities.crates
|
||||
local isHook = self:IsHook(_unit)
|
||||
local nohookswitch = not (isHook and self.enableChinookGCLoading)
|
||||
--local nohookswitch = not (isHook and self.enableChinookGCLoading)
|
||||
local nohookswitch = true
|
||||
-- top menu
|
||||
local topmenu = MENU_GROUP:New(_group,"CTLD",nil)
|
||||
local toptroops = nil
|
||||
@ -5537,7 +5637,11 @@ end
|
||||
self:HandleEvent(EVENTS.PlayerEnterUnit, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.PlayerLeaveUnit, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.UnitLost, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.Birth, self._EventHandler)
|
||||
--self:HandleEvent(EVENTS.Birth, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.NewDynamicCargo, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.DynamicCargoLoaded, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.DynamicCargoUnloaded, self._EventHandler)
|
||||
self:HandleEvent(EVENTS.DynamicCargoRemoved, self._EventHandler)
|
||||
self:__Status(-5)
|
||||
|
||||
-- AutoSave
|
||||
@ -5625,9 +5729,11 @@ end
|
||||
-- @return #CTLD self
|
||||
function CTLD:onafterStop(From, Event, To)
|
||||
self:T({From, Event, To})
|
||||
self:UnhandleEvent(EVENTS.PlayerEnterAircraft)
|
||||
self:UnhandleEvent(EVENTS.PlayerEnterUnit)
|
||||
self:UnhandleEvent(EVENTS.PlayerLeaveUnit)
|
||||
self:UnHandleEvent(EVENTS.PlayerEnterAircraft)
|
||||
self:UnHandleEvent(EVENTS.PlayerEnterUnit)
|
||||
self:UnHandleEvent(EVENTS.PlayerLeaveUnit)
|
||||
self:UnHandleEvent(EVENTS.UnitLost)
|
||||
self:UnHandleEvent(EVENTS.Shot)
|
||||
return self
|
||||
end
|
||||
|
||||
@ -5652,7 +5758,7 @@ end
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #CTLD_CARGO Cargo Cargo crate.
|
||||
-- @param #CTLD_CARGO Cargo Cargo crate. Can be a Wrapper.DynamicCargo#DYNAMICCARGO object, if ground crew loaded!
|
||||
-- @return #CTLD self
|
||||
function CTLD:onbeforeCratesPickedUp(From, Event, To, Group, Unit, Cargo)
|
||||
self:T({From, Event, To})
|
||||
@ -5734,7 +5840,7 @@ end
|
||||
-- @param #string To State.
|
||||
-- @param Wrapper.Group#GROUP Group Group Object.
|
||||
-- @param Wrapper.Unit#UNIT Unit Unit Object.
|
||||
-- @param #table Cargotable Table of #CTLD_CARGO objects dropped.
|
||||
-- @param #table Cargotable Table of #CTLD_CARGO objects dropped. Can be a Wrapper.DynamicCargo#DYNAMICCARGO object, if ground crew unloaded!
|
||||
-- @return #CTLD self
|
||||
function CTLD:onbeforeCratesDropped(From, Event, To, Group, Unit, Cargotable)
|
||||
self:T({From, Event, To})
|
||||
|
||||
457
Moose Development/Moose/Wrapper/DynamicCargo.lua
Normal file
457
Moose Development/Moose/Wrapper/DynamicCargo.lua
Normal file
@ -0,0 +1,457 @@
|
||||
--- **Wrapper** - Dynamic Cargo create from the F8 menu.
|
||||
--
|
||||
-- ## Main Features:
|
||||
--
|
||||
-- * Convenient access to DCS API functions
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ## Example Missions:
|
||||
--
|
||||
-- Demo missions can be found on [github](https://github.com/FlightControl-Master/MOOSE_Demos/tree/master/Wrapper/Storage).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **Applevangelist**
|
||||
--
|
||||
-- ===
|
||||
-- @module Wrapper.DynamicCargo
|
||||
-- @image Wrapper_Storage.png
|
||||
|
||||
|
||||
--- DYNAMICCARGO class.
|
||||
-- @type DYNAMICCARGO
|
||||
-- @field #string ClassName Name of the class.
|
||||
-- @field #number verbose Verbosity level.
|
||||
-- @field #string lid Class id string for output to DCS log file.
|
||||
-- @field Wrapper.Storage#STORAGE warehouse The STORAGE object.
|
||||
-- @field #string version.
|
||||
-- @field #string CargoState.
|
||||
-- @field #table DCS#Vec3 LastPosition.
|
||||
-- @field #number Interval Check Interval. 20 secs default.
|
||||
-- @field #boolean testing
|
||||
-- @field Core.Timer#TIMER timer Timmer to run intervals
|
||||
-- @field #string Owner The playername who has created, loaded or unloaded this cargo. Depends on state.
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
|
||||
--- *The capitalist cannot store labour-power in warehouses after he has bought it, as he may do with the raw material.* -- Karl Marx
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # The DYNAMICCARGO Concept
|
||||
--
|
||||
-- The DYNAMICCARGO class offers an easy-to-use wrapper interface to all DCS API functions of DCS dynamically spawned cargo crates.
|
||||
-- We named the class DYNAMICCARGO, because the name WAREHOUSE is already taken by another MOOSE class..
|
||||
--
|
||||
-- # Constructor
|
||||
--
|
||||
-- @field #DYNAMICCARGO
|
||||
DYNAMICCARGO = {
|
||||
ClassName = "DYNAMICCARGO",
|
||||
verbose = 0,
|
||||
testing = false,
|
||||
Interval = 10,
|
||||
|
||||
}
|
||||
|
||||
--- Liquid types.
|
||||
-- @type DYNAMICCARGO.Liquid
|
||||
-- @field #number JETFUEL Jet fuel (0).
|
||||
-- @field #number GASOLINE Aviation gasoline (1).
|
||||
-- @field #number MW50 MW50 (2).
|
||||
-- @field #number DIESEL Diesel (3).
|
||||
DYNAMICCARGO.Liquid = {
|
||||
JETFUEL = 0,
|
||||
GASOLINE = 1,
|
||||
MW50 = 2,
|
||||
DIESEL = 3,
|
||||
}
|
||||
|
||||
--- Liquid Names for the static cargo resource table.
|
||||
-- @type DYNAMICCARGO.LiquidName
|
||||
-- @field #number JETFUEL "jet_fuel".
|
||||
-- @field #number GASOLINE "gasoline".
|
||||
-- @field #number MW50 "methanol_mixture".
|
||||
-- @field #number DIESEL "diesel".
|
||||
DYNAMICCARGO.LiquidName = {
|
||||
GASOLINE = "gasoline",
|
||||
DIESEL = "diesel",
|
||||
MW50 = "methanol_mixture",
|
||||
JETFUEL = "jet_fuel",
|
||||
}
|
||||
|
||||
--- Storage types.
|
||||
-- @type DYNAMICCARGO.Type
|
||||
-- @field #number WEAPONS weapons.
|
||||
-- @field #number LIQUIDS liquids. Also see #list<#DYNAMICCARGO.Liquid> for types of liquids.
|
||||
-- @field #number AIRCRAFT aircraft.
|
||||
DYNAMICCARGO.Type = {
|
||||
WEAPONS = "weapons",
|
||||
LIQUIDS = "liquids",
|
||||
AIRCRAFT = "aircrafts",
|
||||
}
|
||||
|
||||
--- State types
|
||||
-- @type DYNAMICCARGO.State
|
||||
-- @field #string NEW
|
||||
-- @field #string LOADED
|
||||
-- @field #string UNLOADED
|
||||
-- @field #string REMOVED
|
||||
DYNAMICCARGO.State = {
|
||||
NEW = "NEW",
|
||||
LOADED = "LOADED",
|
||||
UNLOADED = "UNLOADED",
|
||||
REMOVED = "REMOVED",
|
||||
}
|
||||
|
||||
--- Helo types possible.
|
||||
-- @type DYNAMICCARGO.AircraftTypes
|
||||
DYNAMICCARGO.AircraftTypes = {
|
||||
["CH-47Fbl1"] = "CH-47Fbl1",
|
||||
}
|
||||
|
||||
--- Helo types possible.
|
||||
-- @type DYNAMICCARGO.AircraftDimensions
|
||||
DYNAMICCARGO.AircraftDimensions = {
|
||||
-- CH-47 model start coordinate is quite exactly in the middle of the model, so half values here
|
||||
["CH-47Fbl1"] = {
|
||||
["width"] = 4,
|
||||
["height"] = 6,
|
||||
["length"] = 11,
|
||||
["ropelength"] = 30,
|
||||
},
|
||||
}
|
||||
|
||||
--- DYNAMICCARGO class version.
|
||||
-- @field #string version
|
||||
DYNAMICCARGO.version="0.0.4"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: A lot...
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Create a new DYNAMICCARGO object from the DCS static cargo object.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @param #string CargoName Name of the Cargo.
|
||||
-- @return #DYNAMICCARGO self
|
||||
function DYNAMICCARGO:Register(CargoName)
|
||||
|
||||
-- Inherit everything from a BASE class.
|
||||
local self=BASE:Inherit(self, POSITIONABLE:New(CargoName)) -- #DYNAMICCARGO
|
||||
|
||||
self.StaticName = CargoName
|
||||
|
||||
self.LastPosition = self:GetCoordinate()
|
||||
|
||||
self.CargoState = DYNAMICCARGO.State.NEW
|
||||
|
||||
self.Interval = DYNAMICCARGO.Interval or 10
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
local warehouse = STORAGE:NewFromDynamicCargo(CargoName)
|
||||
self.warehouse = warehouse
|
||||
end
|
||||
|
||||
self.lid = string.format("DYNAMICCARGO %s", CargoName)
|
||||
|
||||
self.Owner = string.match(CargoName,"^(.+)|%d%d:%d%d|PKG%d+") or "None"
|
||||
|
||||
self.timer = TIMER:New(DYNAMICCARGO._UpdatePosition,self)
|
||||
self.timer:Start(self.Interval,self.Interval)
|
||||
|
||||
if not _DYNAMICCARGO_HELOS then
|
||||
_DYNAMICCARGO_HELOS = SET_CLIENT:New():FilterAlive():FilterFunction(DYNAMICCARGO._FilterHeloTypes):FilterStart()
|
||||
end
|
||||
|
||||
if self.testing then
|
||||
BASE:TraceOn()
|
||||
BASE:TraceClass("DYNAMICCARGO")
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get DCS object.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return DCS static object
|
||||
function DYNAMICCARGO:GetDCSObject()
|
||||
local DCSStatic = Unit.getByName( self.StaticName )
|
||||
if DCSStatic then
|
||||
return DCSStatic
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- User API Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Get last know owner (player) name of this DYNAMICCARGO
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return DCS#Vec3 Position in 3D space
|
||||
function DYNAMICCARGO:GetLastPosition()
|
||||
return self.Owner
|
||||
end
|
||||
|
||||
--- [CTLD] Get number of crates this DYNAMICCARGO consists of. Always one.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return #number crate number, always one
|
||||
function DYNAMICCARGO:GetCratesNeeded()
|
||||
return 1
|
||||
end
|
||||
|
||||
--- [CTLD] Get this DYNAMICCARGO drop state. True if DYNAMICCARGO.State.UNLOADED
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return #boolean Dropped
|
||||
function DYNAMICCARGO:WasDropped()
|
||||
return self.CargoState == DYNAMICCARGO.State.UNLOADED and true or false
|
||||
end
|
||||
|
||||
--- [CTLD] Get CTLD_CARGO.Enum type of this DYNAMICCARGO
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return #string Type, only one at the moment is CTLD_CARGO.Enum.GCLOADABLE
|
||||
function DYNAMICCARGO:GetType()
|
||||
return CTLD_CARGO.Enum.GCLOADABLE
|
||||
end
|
||||
|
||||
|
||||
--- Find last known position of this DYNAMICCARGO
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return DCS#Vec3 Position in 3D space
|
||||
function DYNAMICCARGO:GetLastPosition()
|
||||
return self.LastPosition
|
||||
end
|
||||
|
||||
--- Find current state of this DYNAMICCARGO
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return string The current state
|
||||
function DYNAMICCARGO:GetState()
|
||||
return self.CargoState
|
||||
end
|
||||
|
||||
--- Find a DYNAMICCARGO in the **_DATABASE** using the name associated with it.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @param #string Name The dynamic cargo name
|
||||
-- @return #DYNAMICCARGO self
|
||||
function DYNAMICCARGO:FindByName( Name )
|
||||
local storage = _DATABASE:FindDynamicCargo( Name )
|
||||
return storage
|
||||
end
|
||||
|
||||
--- Find the first(!) DYNAMICCARGO matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||
-- @return #DYNAMICCARGO The DYNAMICCARGO.
|
||||
-- @usage
|
||||
-- -- Find a dynamic cargo with a partial dynamic cargo name
|
||||
-- local grp = DYNAMICCARGO:FindByMatching( "Apple" )
|
||||
-- -- will return e.g. a dynamic cargo named "Apple|08:00|PKG08"
|
||||
--
|
||||
-- -- using a pattern
|
||||
-- local grp = DYNAMICCARGO:FindByMatching( ".%d.%d$" )
|
||||
-- -- will return the first dynamic cargo found ending in "-1-1" to "-9-9", but not e.g. "-10-1"
|
||||
function DYNAMICCARGO:FindByMatching( Pattern )
|
||||
local GroupFound = nil
|
||||
|
||||
for name,static in pairs(_DATABASE.DYNAMICCARGO) do
|
||||
if string.match(name, Pattern ) then
|
||||
GroupFound = static
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return GroupFound
|
||||
end
|
||||
|
||||
--- Find all DYNAMICCARGO objects matching using patterns. Note that this is **a lot** slower than `:FindByName()`!
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @param #string Pattern The pattern to look for. Refer to [LUA patterns](http://www.easyuo.com/openeuo/wiki/index.php/Lua_Patterns_and_Captures_\(Regular_Expressions\)) for regular expressions in LUA.
|
||||
-- @return #table Groups Table of matching #DYNAMICCARGO objects found
|
||||
-- @usage
|
||||
-- -- Find all dynamic cargo with a partial dynamic cargo name
|
||||
-- local grptable = DYNAMICCARGO:FindAllByMatching( "Apple" )
|
||||
-- -- will return all dynamic cargos with "Apple" in the name
|
||||
--
|
||||
-- -- using a pattern
|
||||
-- local grp = DYNAMICCARGO:FindAllByMatching( ".%d.%d$" )
|
||||
-- -- will return the all dynamic cargos found ending in "-1-1" to "-9-9", but not e.g. "-10-1" or "-1-10"
|
||||
function DYNAMICCARGO:FindAllByMatching( Pattern )
|
||||
local GroupsFound = {}
|
||||
|
||||
for name,static in pairs(_DATABASE.DYNAMICCARGO) do
|
||||
if string.match(name, Pattern ) then
|
||||
GroupsFound[#GroupsFound+1] = static
|
||||
end
|
||||
end
|
||||
|
||||
return GroupsFound
|
||||
end
|
||||
|
||||
--- Get the #STORAGE object from this dynamic cargo.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return Wrapper.Storage#STORAGE Storage The #STORAGE object
|
||||
function DYNAMICCARGO:GetStorageObject()
|
||||
return self.warehouse
|
||||
end
|
||||
|
||||
--- Get the weight in kgs from this dynamic cargo.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return #number Weight in kgs.
|
||||
function DYNAMICCARGO:GetCargoWeight()
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
local weight = DCSObject:getCargoWeight()
|
||||
return weight
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
--- Get the cargo display name from this dynamic cargo.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return #string The display name
|
||||
function DYNAMICCARGO:GetCargoDisplayName()
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
local weight = DCSObject:getCargoDisplayName()
|
||||
return weight
|
||||
else
|
||||
return self.StaticName
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Private Functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- [Internal] _Get Possible Player Helo Nearby
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @param Core.Point#COORDINATE pos
|
||||
-- @param #boolean loading If true measure distance for loading else for unloading
|
||||
-- @return #boolean Success
|
||||
-- @return Wrapper.Client#CLIENT Helo
|
||||
-- @return #string PlayerName
|
||||
function DYNAMICCARGO:_GetPossibleHeloNearby(pos,loading)
|
||||
local set = _DYNAMICCARGO_HELOS:GetAliveSet()
|
||||
local success = false
|
||||
local Helo = nil
|
||||
local Playername = nil
|
||||
for _,_helo in pairs (set or {}) do
|
||||
local helo = _helo -- Wrapper.Client#CLIENT
|
||||
local name = helo:GetPlayerName() or _DATABASE:_FindPlayerNameByUnitName(helo:GetName()) or "None"
|
||||
self:T(self.lid.." Checking: "..name)
|
||||
local hpos = helo:GetCoordinate()
|
||||
-- TODO Unloading via sling load?
|
||||
--local inair = hpos.y-hpos:GetLandHeight() > 4.5 and true or false -- Standard FARP is 4.5m
|
||||
local inair = helo:InAir()
|
||||
self:T(self.lid.." InAir: AGL/InAir: "..hpos.y-hpos:GetLandHeight().."/"..tostring(inair))
|
||||
local typename = helo:GetTypeName()
|
||||
if hpos and typename and inair == false then
|
||||
local dimensions = DYNAMICCARGO.AircraftDimensions[typename]
|
||||
if dimensions then
|
||||
local delta2D = hpos:Get2DDistance(pos)
|
||||
local delta3D = hpos:Get3DDistance(pos)
|
||||
if self.testing then
|
||||
self:T(string.format("Cargo relative position: 2D %dm | 3D %dm",delta2D,delta3D))
|
||||
self:T(string.format("Helo dimension: length %dm | width %dm | rope %dm",dimensions.length,dimensions.width,dimensions.ropelength))
|
||||
end
|
||||
if loading~=true and delta2D > dimensions.length or delta2D > dimensions.width or delta3D > dimensions.ropelength then
|
||||
success = true
|
||||
Helo = helo
|
||||
Playername = name
|
||||
end
|
||||
if loading == true and delta2D < dimensions.length or delta2D < dimensions.width or delta3D < dimensions.ropelength then
|
||||
success = true
|
||||
Helo = helo
|
||||
Playername = name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return success,Helo,Playername
|
||||
end
|
||||
|
||||
--- [Internal] Update internal states.
|
||||
-- @param #DYNAMICCARGO self
|
||||
-- @return #DYNAMICCARGO self
|
||||
function DYNAMICCARGO:_UpdatePosition()
|
||||
self:T(self.lid.." _UpdatePositionAndState")
|
||||
if self:IsAlive() then
|
||||
local pos = self:GetCoordinate()
|
||||
if self.testing then
|
||||
self:T(string.format("Cargo position: x=%d, y=%d, z=%d",pos.x,pos.y,pos.z))
|
||||
self:T(string.format("Last position: x=%d, y=%d, z=%d",self.LastPosition.x,self.LastPosition.y,self.LastPosition.z))
|
||||
end
|
||||
if UTILS.Round(UTILS.VecDist3D(pos,self.LastPosition),2) > 0.5 then
|
||||
---------------
|
||||
-- LOAD Cargo
|
||||
---------------
|
||||
if self.CargoState == DYNAMICCARGO.State.NEW then
|
||||
local isloaded, client, playername = self:_GetPossibleHeloNearby(pos,true)
|
||||
self:T(self.lid.." moved! NEW -> LOADED by "..tostring(playername))
|
||||
self.CargoState = DYNAMICCARGO.State.LOADED
|
||||
self.Owner = playername
|
||||
_DATABASE:CreateEventDynamicCargoLoaded(self)
|
||||
---------------
|
||||
-- UNLOAD Cargo
|
||||
---------------
|
||||
elseif self.CargoState == DYNAMICCARGO.State.LOADED then
|
||||
-- TODO add checker if we are in flight somehow
|
||||
-- ensure not just the helo is moving
|
||||
local count = _DYNAMICCARGO_HELOS:CountAlive()
|
||||
-- Testing
|
||||
local landheight = pos:GetLandHeight()
|
||||
local agl = pos.y-landheight
|
||||
agl = UTILS.Round(agl,2)
|
||||
self:T(self.lid.." AGL: "..agl or -1)
|
||||
local isunloaded = true
|
||||
local client
|
||||
local playername
|
||||
if count > 0 and (agl > 0 or self.testing) then
|
||||
self:T(self.lid.." Possible alive helos: "..count or -1)
|
||||
if agl ~= 0 or self.testing then
|
||||
isunloaded, client, playername = self:_GetPossibleHeloNearby(pos,false)
|
||||
end
|
||||
if isunloaded then
|
||||
self:T(self.lid.." moved! LOADED -> UNLOADED by "..tostring(playername))
|
||||
self.CargoState = DYNAMICCARGO.State.UNLOADED
|
||||
self.Owner = playername
|
||||
_DATABASE:CreateEventDynamicCargoUnloaded(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
self.LastPosition = pos
|
||||
end
|
||||
else
|
||||
---------------
|
||||
-- REMOVED Cargo
|
||||
---------------
|
||||
if self.timer and self.timer:IsRunning() then self.timer:Stop() end
|
||||
self:T(self.lid.." dead! " ..self.CargoState.."-> REMOVED")
|
||||
self.CargoState = DYNAMICCARGO.State.REMOVED
|
||||
_DATABASE:CreateEventDynamicCargoRemoved(self)
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- [Internal] Track helos for loaded/unloaded decision making.
|
||||
-- @param Wrapper.Client#CLIENT client
|
||||
-- @return #boolean IsIn
|
||||
function DYNAMICCARGO._FilterHeloTypes(client)
|
||||
if not client then return false end
|
||||
local typename = client:GetTypeName()
|
||||
local isinclude = DYNAMICCARGO.AircraftTypes[typename] ~= nil and true or false
|
||||
return isinclude
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -528,6 +528,7 @@ function NET:SendChatToPlayer(Message, ToPlayer, FromPlayer)
|
||||
return self
|
||||
end
|
||||
|
||||
--[[ not in 2.97 MSE any longer
|
||||
--- Load a specific mission.
|
||||
-- @param #NET self
|
||||
-- @param #string Path and Mission
|
||||
@ -550,6 +551,7 @@ function NET:LoadNextMission()
|
||||
outcome = net.load_next_mission()
|
||||
return outcome
|
||||
end
|
||||
--]]
|
||||
|
||||
--- Return a table of players currently connected to the server.
|
||||
-- @param #NET self
|
||||
|
||||
@ -226,6 +226,26 @@ function STORAGE:NewFromStaticCargo(StaticCargoName)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Create a new STORAGE object from an DCS static cargo object.
|
||||
-- @param #STORAGE self
|
||||
-- @param #string DynamicCargoName Unit name of the dynamic cargo.
|
||||
-- @return #STORAGE self
|
||||
function STORAGE:NewFromDynamicCargo(DynamicCargoName)
|
||||
|
||||
-- Inherit everything from BASE class.
|
||||
local self=BASE:Inherit(self, BASE:New()) -- #STORAGE
|
||||
|
||||
self.airbase=Unit.getByName(DynamicCargoName)
|
||||
|
||||
if Airbase.getWarehouse then
|
||||
self.warehouse=Warehouse.getCargoAsWarehouse(self.airbase)
|
||||
end
|
||||
|
||||
self.lid = string.format("STORAGE %s", DynamicCargoName)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Airbases only - Find a STORAGE in the **_DATABASE** using the name associated airbase.
|
||||
-- @param #STORAGE self
|
||||
|
||||
@ -1500,7 +1500,7 @@ function UNIT:InAir(NoHeloCheck)
|
||||
local UnitCategory = DCSUnit:getDesc().category
|
||||
|
||||
-- If DCS says that it is in air, check if this is really the case, since we might have landed on a building where inAir()=true but actually is not.
|
||||
-- This is a workaround since DCS currently does not acknoledge that helos land on buildings.
|
||||
-- This is a workaround since DCS currently does not acknowledge that helos land on buildings.
|
||||
-- Note however, that the velocity check will fail if the ground is moving, e.g. on an aircraft carrier!
|
||||
if UnitInAir==true and UnitCategory == Unit.Category.HELICOPTER and (not NoHeloCheck) then
|
||||
local VelocityVec3 = DCSUnit:getVelocity()
|
||||
|
||||
@ -49,6 +49,7 @@ Wrapper/Marker.lua
|
||||
Wrapper/Weapon.lua
|
||||
Wrapper/Net.lua
|
||||
Wrapper/Storage.lua
|
||||
Wrapper/DynamicCargo.lua
|
||||
|
||||
Cargo/Cargo.lua
|
||||
Cargo/CargoUnit.lua
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user