mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge pull request #6 from svenvandevelde/Implement-cargo-initialization-upon-start-of-a-mission
Implement cargo initialization upon start of a mission
This commit is contained in:
commit
effc400a46
@ -1,42 +1,43 @@
|
|||||||
|
|
||||||
local base = _G
|
local base = _G
|
||||||
|
|
||||||
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
|
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
|
||||||
|
|
||||||
function script_path()
|
|
||||||
local str = debug.getinfo(2, "S").source
|
|
||||||
return str:match("(.*/)"):sub(1,-2)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
Include = {}
|
Include = {}
|
||||||
|
|
||||||
Include.MissionPath = script_path() .. "Mission\\"
|
Include.Path = function()
|
||||||
Include.ProgramPath = "Scripts\\Moose\\Moose\\"
|
local str = debug.getinfo(2, "S").source
|
||||||
|
return str:match("(.*/)"):sub(1,-2):gsub("\\","/")
|
||||||
env.info( "Include.MissionPath = " .. Include.MissionPath)
|
end
|
||||||
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
|
|
||||||
Include.Files = {}
|
|
||||||
|
|
||||||
Include.File = function( IncludeFile )
|
Include.File = function( IncludeFile )
|
||||||
if not Include.Files[ IncludeFile ] then
|
if not Include.Files[ IncludeFile ] then
|
||||||
Include.Files[IncludeFile] = IncludeFile
|
Include.Files[IncludeFile] = IncludeFile
|
||||||
local f = base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" )
|
env.info( "Include:" .. IncludeFile .. " from " .. Include.ProgramPath )
|
||||||
|
local f = assert( base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" ) )
|
||||||
if f == nil then
|
if f == nil then
|
||||||
local f = base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" )
|
env.info( "Include:" .. IncludeFile .. " from " .. Include.MissionPath )
|
||||||
|
local f = assert( base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" ) )
|
||||||
if f == nil then
|
if f == nil then
|
||||||
error ("Could not load MOOSE file " .. IncludeFile .. ".lua" )
|
error ("Could not load MOOSE file " .. IncludeFile .. ".lua" )
|
||||||
else
|
else
|
||||||
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath )
|
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath )
|
||||||
return f()
|
return f()
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath )
|
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath )
|
||||||
return f()
|
return f()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Include.ProgramPath = "Scripts/Moose/Moose/"
|
||||||
|
Include.MissionPath = Include.Path()
|
||||||
|
|
||||||
|
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
|
||||||
|
env.info( "Include.MissionPath = " .. Include.MissionPath)
|
||||||
|
|
||||||
|
Include.Files = {}
|
||||||
|
|
||||||
Include.File( "Database" )
|
Include.File( "Database" )
|
||||||
|
|
||||||
env.info("Loaded MOOSE Include Engine")
|
env.info("Loaded MOOSE Include Engine")
|
||||||
23
Loaders/Moose_Load_Embedded.lua
Normal file
23
Loaders/Moose_Load_Embedded.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
local base = _G
|
||||||
|
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
|
||||||
|
|
||||||
|
Include = {}
|
||||||
|
|
||||||
|
Include.Path = function()
|
||||||
|
local str = debug.getinfo(2, "S").source
|
||||||
|
return str:match("(.*/)"):sub(1,-2):gsub("\\","/")
|
||||||
|
end
|
||||||
|
|
||||||
|
Include.File = function( IncludeFile )
|
||||||
|
end
|
||||||
|
|
||||||
|
Include.ProgramPath = "Scripts/Moose/Moose/"
|
||||||
|
Include.MissionPath = Include.Path()
|
||||||
|
|
||||||
|
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
|
||||||
|
env.info( "Include.MissionPath = " .. Include.MissionPath)
|
||||||
|
|
||||||
|
Include.Files = {}
|
||||||
|
|
||||||
|
env.info("Loaded MOOSE Include Engine")
|
||||||
159
Loaders/Moose_Test.lua
Normal file
159
Loaders/Moose_Test.lua
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
|
||||||
|
local base = _G
|
||||||
|
|
||||||
|
local MOOSE_Version = "0.1.1.1"
|
||||||
|
|
||||||
|
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
|
||||||
|
|
||||||
|
function script_path()
|
||||||
|
local str = debug.getinfo(2, "S").source
|
||||||
|
return str:match("(.*/)"):sub(1,-2):gsub("\\","/")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Include = {}
|
||||||
|
|
||||||
|
Include.ProgramPath = "Scripts/Moose/Moose/"
|
||||||
|
Include.MissionPath = script_path()
|
||||||
|
|
||||||
|
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
|
||||||
|
env.info( "Include.MissionPath = " .. Include.MissionPath)
|
||||||
|
Include.Files = {}
|
||||||
|
|
||||||
|
Include.FileIn = function(fileName, table)
|
||||||
|
-- env.info( fileName )
|
||||||
|
local chunk, errMsg = base.loadfile(fileName)
|
||||||
|
if chunk ~= nil then
|
||||||
|
env.info( "chunk assigned " )
|
||||||
|
env.info( Include.oneLineSerialize( chunk ) )
|
||||||
|
base.setfenv(chunk, table)
|
||||||
|
chunk()
|
||||||
|
if table.MOOSE_Version then
|
||||||
|
env.info( table.MOOSE_Version )
|
||||||
|
end
|
||||||
|
return chunk
|
||||||
|
else
|
||||||
|
return nil, errMsg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Include.MisFiles = {}
|
||||||
|
|
||||||
|
Include.FileName = function( num )
|
||||||
|
local hexstr = '0123456789ABCDEF'
|
||||||
|
local s = ''
|
||||||
|
while num > 0 do
|
||||||
|
local mod = math.fmod(num, 16)
|
||||||
|
s = string.sub(hexstr, mod+1, mod+1) .. s
|
||||||
|
num = math.floor(num / 16)
|
||||||
|
end
|
||||||
|
if s == '' then s = '0' end
|
||||||
|
-- env.info( string.format( "~mis" .. "%8s", "00000000" .. s ) )
|
||||||
|
return string.format( "~mis" .. "%s", string.sub( "00000000" .. s, -8 ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
Include.ScanFiles = function()
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
while i <= 32767 do
|
||||||
|
local FileName = Include.FileName( i )
|
||||||
|
local FileChunk = {}
|
||||||
|
local FileChunk = Include.FileIn( Include.MissionPath .. FileName, FileChunk )
|
||||||
|
if FileChunk then
|
||||||
|
end
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Include.File = function( IncludeFile )
|
||||||
|
if not Include.Files[ IncludeFile ] then
|
||||||
|
Include.Files[IncludeFile] = IncludeFile
|
||||||
|
env.info( "Include:" .. IncludeFile .. " from " .. Include.ProgramPath )
|
||||||
|
local f = base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" )
|
||||||
|
if f == nil then
|
||||||
|
env.info( "Include:" .. IncludeFile .. " from " .. Include.MissionPath )
|
||||||
|
local f = base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" )
|
||||||
|
if f == nil then
|
||||||
|
error ("Could not load MOOSE file " .. IncludeFile .. ".lua" )
|
||||||
|
else
|
||||||
|
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath )
|
||||||
|
return f()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath )
|
||||||
|
return f()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--porting in Slmod's "safestring" basic serialize
|
||||||
|
Include.basicSerialize = function(s)
|
||||||
|
if s == nil then
|
||||||
|
return "\"\""
|
||||||
|
else
|
||||||
|
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'table') or (type(s) == 'userdata') ) then
|
||||||
|
return tostring(s)
|
||||||
|
elseif type(s) == 'string' then
|
||||||
|
s = string.format('%q', s)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- porting in Slmod's serialize_slmod2
|
||||||
|
Include.oneLineSerialize = function(tbl) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
||||||
|
if type(tbl) == 'table' then --function only works for tables!
|
||||||
|
|
||||||
|
local tbl_str = {}
|
||||||
|
|
||||||
|
tbl_str[#tbl_str + 1] = '{'
|
||||||
|
|
||||||
|
for ind,val in pairs(tbl) do -- serialize its fields
|
||||||
|
if type(ind) == "number" then
|
||||||
|
tbl_str[#tbl_str + 1] = '['
|
||||||
|
tbl_str[#tbl_str + 1] = tostring(ind)
|
||||||
|
tbl_str[#tbl_str + 1] = ']='
|
||||||
|
else --must be a string
|
||||||
|
tbl_str[#tbl_str + 1] = '['
|
||||||
|
tbl_str[#tbl_str + 1] = Include.basicSerialize(ind)
|
||||||
|
tbl_str[#tbl_str + 1] = ']='
|
||||||
|
end
|
||||||
|
|
||||||
|
if ((type(val) == 'number') or (type(val) == 'boolean')) then
|
||||||
|
tbl_str[#tbl_str + 1] = tostring(val)
|
||||||
|
tbl_str[#tbl_str + 1] = ','
|
||||||
|
elseif type(val) == 'string' then
|
||||||
|
tbl_str[#tbl_str + 1] = Include.basicSerialize(val)
|
||||||
|
tbl_str[#tbl_str + 1] = ','
|
||||||
|
elseif type(val) == 'nil' then -- won't ever happen, right?
|
||||||
|
tbl_str[#tbl_str + 1] = 'nil,'
|
||||||
|
elseif type(val) == 'table' then
|
||||||
|
if ind == "__index" then
|
||||||
|
tbl_str[#tbl_str + 1] = "__index"
|
||||||
|
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||||
|
else
|
||||||
|
tbl_str[#tbl_str + 1] = Include.oneLineSerialize(val)
|
||||||
|
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||||
|
end
|
||||||
|
elseif type(val) == 'function' then
|
||||||
|
tbl_str[#tbl_str + 1] = "function " .. tostring(ind)
|
||||||
|
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||||
|
else
|
||||||
|
env.info('unable to serialize value type ' .. Include.basicSerialize(type(val)) .. ' at index ' .. tostring(ind))
|
||||||
|
env.info( debug.traceback() )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
tbl_str[#tbl_str + 1] = '}'
|
||||||
|
return table.concat(tbl_str)
|
||||||
|
else
|
||||||
|
return tostring(tbl)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Include.ScanFiles( )
|
||||||
|
|
||||||
|
Include.File( "Database" )
|
||||||
|
|
||||||
|
env.info("Loaded MOOSE Include Engine")
|
||||||
@ -4,12 +4,22 @@
|
|||||||
|
|
||||||
Include.File( "Routines" )
|
Include.File( "Routines" )
|
||||||
|
|
||||||
|
_TraceOn = true
|
||||||
|
_TraceClass = {
|
||||||
|
DATABASE = true,
|
||||||
|
--SEAD = true,
|
||||||
|
--DESTROYBASETASK = true,
|
||||||
|
--MOVEMENT = true,
|
||||||
|
--SPAWN = true,
|
||||||
|
--GROUP = true,
|
||||||
|
--UNIT = true,
|
||||||
|
}
|
||||||
|
|
||||||
BASE = {
|
BASE = {
|
||||||
|
|
||||||
ClassName = "BASE",
|
ClassName = "BASE",
|
||||||
ClassID = 0,
|
ClassID = 0,
|
||||||
Events = {}
|
Events = {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--- The base constructor. This is the top top class of all classed defined within the MOOSE.
|
--- The base constructor. This is the top top class of all classed defined within the MOOSE.
|
||||||
@ -53,7 +63,7 @@ function BASE:Inherit( Child, Parent )
|
|||||||
Child.__index = Child
|
Child.__index = Child
|
||||||
end
|
end
|
||||||
--Child.ClassName = Child.ClassName .. '.' .. Child.ClassID
|
--Child.ClassName = Child.ClassName .. '.' .. Child.ClassID
|
||||||
trace.i( Child.ClassName, 'Inherited from ' .. Parent.ClassName )
|
self:T( 'Inherited from ' .. Parent.ClassName )
|
||||||
return Child
|
return Child
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -104,6 +114,7 @@ trace.f( self.ClassName )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
BaseEventCodes = {
|
BaseEventCodes = {
|
||||||
"S_EVENT_SHOT",
|
"S_EVENT_SHOT",
|
||||||
"S_EVENT_HIT",
|
"S_EVENT_HIT",
|
||||||
@ -129,7 +140,46 @@ BaseEventCodes = {
|
|||||||
"S_EVENT_SHOOTING_START",
|
"S_EVENT_SHOOTING_START",
|
||||||
"S_EVENT_SHOOTING_END",
|
"S_EVENT_SHOOTING_END",
|
||||||
"S_EVENT_MAX",
|
"S_EVENT_MAX",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--onEvent( {[1]="S_EVENT_BIRTH",[2]={["subPlace"]=5,["time"]=0,["initiator"]={["id_"]=16884480,},["place"]={["id_"]=5000040,},["id"]=15,["IniUnitName"]="US F-15C@RAMP-Air Support Mountains#001-01",},}
|
||||||
|
-- Event = {
|
||||||
|
-- id = enum world.event,
|
||||||
|
-- time = Time,
|
||||||
|
-- initiator = Unit,
|
||||||
|
-- target = Unit,
|
||||||
|
-- place = Unit,
|
||||||
|
-- subPlace = enum world.BirthPlace,
|
||||||
|
-- weapon = Weapon
|
||||||
|
-- }
|
||||||
|
|
||||||
|
|
||||||
|
function BASE:CreateEventBirth( EventTime, Initiator, IniUnitName, place, subplace )
|
||||||
|
trace.f( self.ClassName, { EventTime, Initiator, IniUnitName, place, subplace } )
|
||||||
|
|
||||||
|
local Event = {
|
||||||
|
id = world.event.S_EVENT_BIRTH,
|
||||||
|
time = EventTime,
|
||||||
|
initiator = Initiator,
|
||||||
|
IniUnitName = IniUnitName,
|
||||||
|
place = place,
|
||||||
|
subplace = subplace
|
||||||
|
}
|
||||||
|
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
|
function BASE:CreateEventCrash( EventTime, Initiator )
|
||||||
|
trace.f( self.ClassName, { EventTime, Initiator } )
|
||||||
|
|
||||||
|
local Event = {
|
||||||
|
id = world.event.S_EVENT_CRASH,
|
||||||
|
time = EventTime,
|
||||||
|
initiator = Initiator,
|
||||||
|
}
|
||||||
|
|
||||||
|
world.onEvent( Event )
|
||||||
|
end
|
||||||
|
|
||||||
function BASE:onEvent(event)
|
function BASE:onEvent(event)
|
||||||
--trace.f(self.ClassName, event )
|
--trace.f(self.ClassName, event )
|
||||||
@ -159,3 +209,22 @@ function BASE:onEvent(event)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Trace section
|
||||||
|
|
||||||
|
|
||||||
|
function BASE:T( Arguments )
|
||||||
|
|
||||||
|
if _TraceOn and _TraceClass[self.ClassName] then
|
||||||
|
|
||||||
|
local DebugInfo = debug.getinfo( 2, "nl" )
|
||||||
|
|
||||||
|
local Function = "function"
|
||||||
|
if DebugInfo.name then
|
||||||
|
Function = DebugInfo.name
|
||||||
|
end
|
||||||
|
|
||||||
|
local Line = DebugInfo.currentline
|
||||||
|
|
||||||
|
env.info( string.format( "%6d/%1s:%20s%05d.%s\(%s\)" , Line, "T", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
1015
Moose/Cargo.lua
1015
Moose/Cargo.lua
File diff suppressed because it is too large
Load Diff
280
Moose/Client.lua
280
Moose/Client.lua
@ -23,7 +23,6 @@ CLIENT = {
|
|||||||
ClientTransport = false,
|
ClientTransport = false,
|
||||||
ClientBriefingShown = false,
|
ClientBriefingShown = false,
|
||||||
_Menus = {},
|
_Menus = {},
|
||||||
_Cargos = {},
|
|
||||||
_Tasks = {},
|
_Tasks = {},
|
||||||
Messages = {
|
Messages = {
|
||||||
}
|
}
|
||||||
@ -45,10 +44,9 @@ CLIENT = {
|
|||||||
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
|
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
|
||||||
|
|
||||||
function CLIENT:New( ClientName, ClientBriefing )
|
function CLIENT:New( ClientName, ClientBriefing )
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T()
|
||||||
|
|
||||||
self.ClientName = ClientName
|
self.ClientName = ClientName
|
||||||
self:AddBriefing( ClientBriefing )
|
self:AddBriefing( ClientBriefing )
|
||||||
self.MessageSwitch = true
|
self.MessageSwitch = true
|
||||||
@ -59,29 +57,162 @@ end
|
|||||||
--- Resets a CLIENT.
|
--- Resets a CLIENT.
|
||||||
-- @tparam string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client.
|
-- @tparam string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client.
|
||||||
function CLIENT:Reset( ClientName )
|
function CLIENT:Reset( ClientName )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self._Menus = {}
|
self._Menus = {}
|
||||||
self._Cargos = {}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- ClientGroup returns the Group of a Client.
|
--- ClientGroup returns the Group of a Client.
|
||||||
|
-- This function is modified to deal with a couple of bugs in DCS 1.5.3
|
||||||
-- @treturn Group
|
-- @treturn Group
|
||||||
function CLIENT:ClientGroup()
|
function CLIENT:ClientGroup()
|
||||||
--trace.f(self.ClassName)
|
--self:T()
|
||||||
local ClientData = Group.getByName( self.ClientName )
|
|
||||||
if ClientData and ClientData:isExist() then
|
-- local ClientData = Group.getByName( self.ClientName )
|
||||||
trace.i( self.ClassName, self.ClientName .. " : group found!" )
|
-- if ClientData and ClientData:isExist() then
|
||||||
return ClientData
|
-- self:T( self.ClientName .. " : group found!" )
|
||||||
else
|
-- return ClientData
|
||||||
-- trace.x( self.ClassName, self.ClientName .. " : no group found!" )
|
-- else
|
||||||
return nil
|
-- return nil
|
||||||
|
-- end
|
||||||
|
|
||||||
|
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
|
||||||
|
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||||
|
--self:T( { "CoalitionData:", CoalitionData } )
|
||||||
|
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||||
|
--self:T( { "UnitData:", UnitData } )
|
||||||
|
if UnitData and UnitData:isExist() then
|
||||||
|
|
||||||
|
local ClientGroup = Group.getByName( self.ClientName )
|
||||||
|
if ClientGroup then
|
||||||
|
self:T( "ClientGroup = " .. self.ClientName )
|
||||||
|
if ClientGroup:isExist() then
|
||||||
|
if ClientGroup:getID() == UnitData:getGroup():getID() then
|
||||||
|
self:T( "Normal logic" )
|
||||||
|
self:T( self.ClientName .. " : group found!" )
|
||||||
|
return ClientGroup
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Now we need to resolve the bugs in DCS 1.5 ...
|
||||||
|
-- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil)
|
||||||
|
self:T( "Bug 1.5 logic" )
|
||||||
|
local ClientUnits = _Database.Groups[self.ClientName].Units
|
||||||
|
self:T( { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } )
|
||||||
|
for ClientUnitID, ClientUnitData in pairs( ClientUnits ) do
|
||||||
|
self:T( { tonumber(UnitData:getID()), ClientUnitData.unitId } )
|
||||||
|
if tonumber(UnitData:getID()) == ClientUnitData.unitId then
|
||||||
|
local ClientGroupTemplate = _Database.Groups[self.ClientName].Template
|
||||||
|
self.ClientGroupID = ClientGroupTemplate.groupId
|
||||||
|
self.ClientGroupUnit = UnitData
|
||||||
|
self:T( self.ClientName .. " : group found in bug 1.5 resolvement logic!" )
|
||||||
|
return ClientGroup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- else
|
||||||
|
-- error( "Client " .. self.ClientName .. " not found!" )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- For non player clients
|
||||||
|
local ClientGroup = Group.getByName( self.ClientName )
|
||||||
|
if ClientGroup then
|
||||||
|
self:T( "ClientGroup = " .. self.ClientName )
|
||||||
|
if ClientGroup:isExist() then
|
||||||
|
self:T( "Normal logic" )
|
||||||
|
self:T( self.ClientName .. " : group found!" )
|
||||||
|
return ClientGroup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.ClientGroupID = nil
|
||||||
|
self.ClientGroupUnit = nil
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function CLIENT:GetClientGroupID()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
ClientGroup = self:ClientGroup()
|
||||||
|
|
||||||
|
if ClientGroup then
|
||||||
|
if ClientGroup:isExist() then
|
||||||
|
return ClientGroup:getID()
|
||||||
|
else
|
||||||
|
return self.ClientGroupID
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function CLIENT:GetClientGroupName()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
ClientGroup = self:ClientGroup()
|
||||||
|
|
||||||
|
if ClientGroup then
|
||||||
|
if ClientGroup:isExist() then
|
||||||
|
self:T( ClientGroup:getName() )
|
||||||
|
return ClientGroup:getName()
|
||||||
|
else
|
||||||
|
self:T( self.ClientName )
|
||||||
|
return self.ClientName
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the Unit of the @{CLIENT}.
|
||||||
|
-- @treturn Unit
|
||||||
|
function CLIENT:GetClientGroupUnit()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
local ClientGroup = self:ClientGroup()
|
||||||
|
|
||||||
|
if ClientGroup then
|
||||||
|
if ClientGroup:isExist() then
|
||||||
|
return ClientGroup:getUnits()[1]
|
||||||
|
else
|
||||||
|
return self.ClientGroupUnit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLIENT:GetUnit()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
return UNIT:New( self:GetClientGroupUnit() )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Returns the Position of the @{CLIENT}.
|
||||||
|
-- @treturn Position
|
||||||
|
function CLIENT:ClientPosition()
|
||||||
|
--self:T()
|
||||||
|
|
||||||
|
ClientGroupUnit = self:GetClientGroupUnit()
|
||||||
|
|
||||||
|
if ClientGroupUnit then
|
||||||
|
if ClientGroupUnit:isExist() then
|
||||||
|
return ClientGroupUnit:getPosition()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Transport defines that the Client is a Transport.
|
--- Transport defines that the Client is a Transport.
|
||||||
-- @treturn CLIENT
|
-- @treturn CLIENT
|
||||||
function CLIENT:Transport()
|
function CLIENT:Transport()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
self.ClientTransport = true
|
self.ClientTransport = true
|
||||||
return self
|
return self
|
||||||
@ -91,7 +222,7 @@ end
|
|||||||
-- @tparam string ClientBriefing is the text defining the Mission briefing.
|
-- @tparam string ClientBriefing is the text defining the Mission briefing.
|
||||||
-- @treturn CLIENT
|
-- @treturn CLIENT
|
||||||
function CLIENT:AddBriefing( ClientBriefing )
|
function CLIENT:AddBriefing( ClientBriefing )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self.ClientBriefing = ClientBriefing
|
self.ClientBriefing = ClientBriefing
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -99,114 +230,29 @@ end
|
|||||||
--- IsTransport returns if a Client is a transport.
|
--- IsTransport returns if a Client is a transport.
|
||||||
-- @treturn bool
|
-- @treturn bool
|
||||||
function CLIENT:IsTransport()
|
function CLIENT:IsTransport()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
return self.ClientTransport
|
return self.ClientTransport
|
||||||
end
|
end
|
||||||
|
|
||||||
--- FindCargo finds loaded Cargo within a CLIENT instance.
|
|
||||||
-- Cargo is loaded when certain PICK-UP or DEPLOY Tasks are properly executed.
|
|
||||||
-- @tparam string CargoName is the name of the cargo.
|
|
||||||
-- @treturn CARGO_TYPE
|
|
||||||
function CLIENT:FindCargo( CargoName )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
return self._Cargos[CargoName]
|
|
||||||
end
|
|
||||||
|
|
||||||
--- ShowCargo shows the @{CARGO} within the CLIENT to the Player.
|
--- ShowCargo shows the @{CARGO} within the CLIENT to the Player.
|
||||||
-- The @{CARGO} is shown throught the MESSAGE system of DCS World.
|
-- The @{CARGO} is shown throught the MESSAGE system of DCS World.
|
||||||
function CLIENT:ShowCargo()
|
function CLIENT:ShowCargo()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
local CargoMsg = ""
|
local CargoMsg = ""
|
||||||
|
|
||||||
for CargoName, Cargo in pairs( self._Cargos ) do
|
for CargoName, Cargo in pairs( CARGOS ) do
|
||||||
if CargoMsg ~= "" then
|
if self == Cargo:IsLoadedInClient() then
|
||||||
CargoMsg = CargoMsg .. "\n"
|
CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight .. "\n"
|
||||||
end
|
end
|
||||||
CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType.TEXT .. " Weight: " .. Cargo.CargoWeight
|
|
||||||
end
|
|
||||||
|
|
||||||
if CargoMsg == '' then
|
|
||||||
CargoMsg = "empty"
|
|
||||||
end
|
|
||||||
|
|
||||||
self:Message( CargoMsg, 15, self.ClientName .. "/Cargo", "Co-Pilot: Cargo Status", 30 )
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- InitCargo allows to initialize @{CARGO} on the CLIENT when the client initializes.
|
|
||||||
-- @tparam string InitCargoNames is a string or a table containing the names of the @{CARGO}s initialized in the Mission.
|
|
||||||
-- @treturn CLIENT
|
|
||||||
function CLIENT:InitCargo( InitCargoNames )
|
|
||||||
trace.f(self.ClassName, { InitCargoNames } )
|
|
||||||
|
|
||||||
local Valid = true
|
|
||||||
|
|
||||||
if Valid then
|
|
||||||
if type( InitCargoNames ) == "table" then
|
|
||||||
self.InitCargoNames = InitCargoNames
|
|
||||||
else
|
|
||||||
self.InitCargoNames = { InitCargoNames }
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
if CargoMsg == "" then
|
||||||
|
CargoMsg = "empty"
|
||||||
end
|
|
||||||
|
|
||||||
--- AddCargo allows to add @{CARGO} on the CLIENT.
|
|
||||||
-- @tparam string CargoName is the name of the @{CARGO}.
|
|
||||||
-- @tparam string CargoGroupName is the name of an active Group defined within the Mission Editor or Dynamically Spawned. Note that this is only applicable for Unit @{CARGO} Types.
|
|
||||||
-- @tparam CARGO_TYPE CargoType is the Type of the @{CARGO}.
|
|
||||||
-- @tparam number CargoWeight is the weight of the cargo in Kg.
|
|
||||||
-- @tparam string CargoGroupTemplate is the name of an active Group defined within the Mission Editor with "Late Activation".
|
|
||||||
-- @treturn CLIENT
|
|
||||||
function CLIENT:AddCargo( CargoName, CargoGroupName, CargoType, CargoWeight, CargoGroupTemplate )
|
|
||||||
trace.f(self.ClassName, { CargoName, CargoGroupName, CargoType, CargoWeight, CargoGroupTemplate } )
|
|
||||||
|
|
||||||
local Valid = true
|
|
||||||
|
|
||||||
Valid = routines.ValidateString( CargoName, "CargoName", Valid )
|
|
||||||
Valid = routines.ValidateEnumeration( CargoType, "CargoType", CARGO_TYPE, Valid )
|
|
||||||
Valid = routines.ValidateNumber( CargoWeight, "CargoWeight", Valid )
|
|
||||||
|
|
||||||
if Valid then
|
|
||||||
local Cargo = {}
|
|
||||||
Cargo.CargoName = CargoName
|
|
||||||
Cargo.CargoGroupName = CargoGroupName
|
|
||||||
Cargo.CargoType = CargoType
|
|
||||||
Cargo.CargoWeight = CargoWeight
|
|
||||||
if CargoGroupTemplate then
|
|
||||||
Cargo.CargoGroupTemplate = CargoGroupTemplate
|
|
||||||
end
|
end
|
||||||
self._Cargos[CargoName] = Cargo
|
|
||||||
self:ShowCargo()
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
self:Message( CargoMsg, 15, self.ClientName .. "/Cargo", "Co-Pilot: Cargo Status", 30 )
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- RemoveCargo removes @{CARGO} from the CLIENT.
|
|
||||||
-- @tparam string CargoName is the name of the @{CARGO}.
|
|
||||||
-- @treturn Cargo
|
|
||||||
function CLIENT:RemoveCargo( CargoName )
|
|
||||||
trace.f(self.ClassName, { CargoName } )
|
|
||||||
|
|
||||||
|
|
||||||
local Valid = true
|
|
||||||
local Cargo = nil
|
|
||||||
|
|
||||||
Valid = routines.ValidateString( CargoName, "CargoName", Valid )
|
|
||||||
|
|
||||||
if Valid then
|
|
||||||
trace.i( "CLIENT", "RemoveCargo: CargoName = " .. CargoName )
|
|
||||||
Cargo = routines.utils.deepCopy( self._Cargos[CargoName] )
|
|
||||||
self._Cargos[CargoName] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return Cargo
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- SwitchMessages is a local function called by the DCS World Menu system to switch off messages.
|
--- SwitchMessages is a local function called by the DCS World Menu system to switch off messages.
|
||||||
@ -222,13 +268,13 @@ end
|
|||||||
-- @tparam string MessageCategory is the category of the message (the title).
|
-- @tparam string MessageCategory is the category of the message (the title).
|
||||||
-- @tparam number MessageInterval is the interval in seconds between the display of the Message when the CLIENT is in the air.
|
-- @tparam number MessageInterval is the interval in seconds between the display of the Message when the CLIENT is in the air.
|
||||||
function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, MessageInterval )
|
function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, MessageInterval )
|
||||||
trace.f( self.ClassName, { Message, MessageDuration, MessageId, MessageCategory, MessageInterval } )
|
self:T()
|
||||||
|
|
||||||
if not self.MenuMessages then
|
if not self.MenuMessages then
|
||||||
if self:ClientGroup() and self:ClientGroup():getID() then
|
if self:GetClientGroupID() then
|
||||||
self.MenuMessages = MENU_SUB_GROUP:New( self:ClientGroup():getID(), 'Messages' )
|
self.MenuMessages = MENU_SUB_GROUP:New( self:GetClientGroupID(), 'Messages' )
|
||||||
self.MenuRouteMessageOn = MENU_COMMAND_GROUP:New( self:ClientGroup():getID(), 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } )
|
self.MenuRouteMessageOn = MENU_COMMAND_GROUP:New( self:GetClientGroupID(), 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } )
|
||||||
self.MenuRouteMessageOff = MENU_COMMAND_GROUP:New( self:ClientGroup():getID(),'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } )
|
self.MenuRouteMessageOff = MENU_COMMAND_GROUP:New( self:GetClientGroupID(),'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -248,7 +294,7 @@ trace.f( self.ClassName, { Message, MessageDuration, MessageId, MessageCategory,
|
|||||||
end
|
end
|
||||||
MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self )
|
MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self )
|
||||||
else
|
else
|
||||||
if self:ClientGroup() and self:ClientGroup():getUnits() and self:ClientGroup():getUnits()[1] and not self:ClientGroup():getUnits()[1]:inAir() then
|
if self:GetClientGroupUnit() and not self:GetClientGroupUnit():inAir() then
|
||||||
if timer.getTime() - self.Messages[MessageId].MessageTime >= self.Messages[MessageId].MessageDuration + 10 then
|
if timer.getTime() - self.Messages[MessageId].MessageTime >= self.Messages[MessageId].MessageDuration + 10 then
|
||||||
MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self )
|
MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self )
|
||||||
self.Messages[MessageId].MessageTime = timer.getTime()
|
self.Messages[MessageId].MessageTime = timer.getTime()
|
||||||
|
|||||||
@ -13,6 +13,7 @@ DATABASE = {
|
|||||||
NavPoints = {},
|
NavPoints = {},
|
||||||
Statics = {},
|
Statics = {},
|
||||||
Players = {},
|
Players = {},
|
||||||
|
ActivePlayers = {},
|
||||||
ClientsByName = {},
|
ClientsByName = {},
|
||||||
ClientsByID = {},
|
ClientsByID = {},
|
||||||
}
|
}
|
||||||
@ -27,7 +28,7 @@ DATABASECategory =
|
|||||||
{
|
{
|
||||||
[Unit.Category.AIRPLANE] = "Plane",
|
[Unit.Category.AIRPLANE] = "Plane",
|
||||||
[Unit.Category.HELICOPTER] = "Helicopter",
|
[Unit.Category.HELICOPTER] = "Helicopter",
|
||||||
[Unit.Category.GROUND_UNIT] = "Ground",
|
[Unit.Category.GROUND_UNIT] = "Vehicle",
|
||||||
[Unit.Category.SHIP] = "Ship",
|
[Unit.Category.SHIP] = "Ship",
|
||||||
[Unit.Category.STRUCTURE] = "Structure",
|
[Unit.Category.STRUCTURE] = "Structure",
|
||||||
}
|
}
|
||||||
@ -39,7 +40,6 @@ DATABASECategory =
|
|||||||
-- -- Define a new DATABASE Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE.
|
-- -- Define a new DATABASE Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE.
|
||||||
-- DBObject = DATABASE:New()
|
-- DBObject = DATABASE:New()
|
||||||
function DATABASE:New()
|
function DATABASE:New()
|
||||||
trace.f(self.ClassName )
|
|
||||||
|
|
||||||
-- Inherits from BASE
|
-- Inherits from BASE
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
@ -120,14 +120,14 @@ trace.f(self.ClassName )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Instantiate new Groups within the DCSRTE.
|
--- Instantiate new Groups within the DCSRTE.
|
||||||
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
||||||
-- SpawnCountryID, SpawnCategoryID
|
-- SpawnCountryID, SpawnCategoryID
|
||||||
-- This method is used by the SPAWN class.
|
-- This method is used by the SPAWN class.
|
||||||
function DATABASE:Spawn( SpawnTemplate )
|
function DATABASE:Spawn( SpawnTemplate )
|
||||||
trace.f( self.ClassName, SpawnTemplate )
|
|
||||||
|
|
||||||
trace.i( self.ClassName, { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } )
|
self:T( { SpawnTemplate.SpawnCountryID, SpawnTemplate.SpawnCategoryID, SpawnTemplate.name } )
|
||||||
|
|
||||||
local SpawnCountryID = SpawnTemplate.SpawnCountryID
|
local SpawnCountryID = SpawnTemplate.SpawnCountryID
|
||||||
local SpawnCategoryID = SpawnTemplate.SpawnCategoryID
|
local SpawnCategoryID = SpawnTemplate.SpawnCategoryID
|
||||||
@ -140,16 +140,18 @@ trace.f( self.ClassName, SpawnTemplate )
|
|||||||
coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate )
|
coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set a status to a Group within the Database, this to check crossing events for example.
|
--- Set a status to a Group within the Database, this to check crossing events for example.
|
||||||
function DATABASE:SetStatusGroup( GroupName, Status )
|
function DATABASE:SetStatusGroup( GroupName, Status )
|
||||||
trace.f( self.ClassName, Status )
|
self:T( Status )
|
||||||
|
|
||||||
self.Groups[GroupName].Status = Status
|
self.Groups[GroupName].Status = Status
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get a status to a Group within the Database, this to check crossing events for example.
|
--- Get a status to a Group within the Database, this to check crossing events for example.
|
||||||
function DATABASE:GetStatusGroup( GroupName )
|
function DATABASE:GetStatusGroup( GroupName )
|
||||||
trace.f( self.ClassName, Status )
|
self:T( Status )
|
||||||
|
|
||||||
if self.Groups[GroupName] then
|
if self.Groups[GroupName] then
|
||||||
return self.Groups[GroupName].Status
|
return self.Groups[GroupName].Status
|
||||||
@ -162,6 +164,7 @@ end
|
|||||||
--- Private
|
--- Private
|
||||||
-- @section Private
|
-- @section Private
|
||||||
|
|
||||||
|
|
||||||
--- Registers new Group Templates within the DATABASE Object.
|
--- Registers new Group Templates within the DATABASE Object.
|
||||||
function DATABASE:_RegisterGroup( GroupTemplate )
|
function DATABASE:_RegisterGroup( GroupTemplate )
|
||||||
|
|
||||||
@ -175,7 +178,9 @@ function DATABASE:_RegisterGroup( GroupTemplate )
|
|||||||
self.Groups[GroupTemplateName].Template = GroupTemplate
|
self.Groups[GroupTemplateName].Template = GroupTemplate
|
||||||
self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId
|
self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId
|
||||||
self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
|
self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
|
||||||
trace.i( self.ClassName, { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } )
|
self.Groups[GroupTemplateName].Units = GroupTemplate.units
|
||||||
|
|
||||||
|
self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } )
|
||||||
|
|
||||||
for unit_num, UnitTemplate in pairs(GroupTemplate.units) do
|
for unit_num, UnitTemplate in pairs(GroupTemplate.units) do
|
||||||
|
|
||||||
@ -190,20 +195,24 @@ function DATABASE:_RegisterGroup( GroupTemplate )
|
|||||||
self.ClientsByName[UnitTemplateName] = UnitTemplate
|
self.ClientsByName[UnitTemplateName] = UnitTemplate
|
||||||
self.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
self.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
||||||
end
|
end
|
||||||
trace.i( self.ClassName, { "Unit", self.Units[UnitTemplateName].UnitName } )
|
self:T( { "Unit", self.Units[UnitTemplateName].UnitName } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Events
|
--- Events
|
||||||
-- @section Events
|
-- @section Events
|
||||||
|
|
||||||
|
|
||||||
--- Track DCSRTE DEAD or CRASH events for the internal scoring.
|
--- Track DCSRTE DEAD or CRASH events for the internal scoring.
|
||||||
function DATABASE:OnDeadOrCrash( event )
|
function DATABASE:OnDeadOrCrash( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
local TargetUnitName = nil
|
local TargetUnit = nil
|
||||||
local TargetGroupName = nil
|
local TargetGroup = nil
|
||||||
local TargetPlayerName = nil
|
local TargetUnitName = ""
|
||||||
|
local TargetGroupName = ""
|
||||||
|
local TargetPlayerName = ""
|
||||||
local TargetCoalition = nil
|
local TargetCoalition = nil
|
||||||
local TargetCategory = nil
|
local TargetCategory = nil
|
||||||
local TargetType = nil
|
local TargetType = nil
|
||||||
@ -212,30 +221,42 @@ trace.f( self.ClassName, { event } )
|
|||||||
local TargetUnitType = nil
|
local TargetUnitType = nil
|
||||||
|
|
||||||
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
||||||
TargetUnitName = event.initiator:getName()
|
|
||||||
TargetGroupName = Unit.getGroup(event.initiator):getName()
|
TargetUnit = event.initiator
|
||||||
TargetPlayerName = event.initiator:getPlayerName()
|
TargetGroup = Unit.getGroup( TargetUnit )
|
||||||
|
TargetUnitDesc = TargetUnit:getDesc()
|
||||||
|
|
||||||
|
TargetUnitName = TargetUnit:getName()
|
||||||
|
if TargetGroup and TargetGroup:isExist() then
|
||||||
|
TargetGroupName = TargetGroup:getName()
|
||||||
|
end
|
||||||
|
TargetPlayerName = TargetUnit:getPlayerName()
|
||||||
|
|
||||||
TargetCoalition = Unit.getGroup(event.initiator):getCoalition()
|
TargetCoalition = TargetUnit:getCoalition()
|
||||||
TargetCategory = Unit.getGroup(event.initiator):getCategory()
|
--TargetCategory = TargetUnit:getCategory()
|
||||||
TargetType = event.initiator:getTypeName()
|
TargetCategory = TargetUnitDesc.category -- Workaround
|
||||||
|
TargetType = TargetUnit:getTypeName()
|
||||||
|
|
||||||
TargetUnitCoalition = DATABASECoalition[TargetCoalition]
|
TargetUnitCoalition = DATABASECoalition[TargetCoalition]
|
||||||
TargetUnitCategory = DATABASECategory[TargetCategory]
|
TargetUnitCategory = DATABASECategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
trace.i( self.ClassName, { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
|
||||||
end
|
end
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
||||||
trace.i( self.ClassName, "Something got killed" )
|
self:T( "Something got killed" )
|
||||||
|
|
||||||
-- Some variables
|
-- Some variables
|
||||||
local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition]
|
|
||||||
local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory]
|
|
||||||
local InitUnitType = PlayerData.UnitType
|
|
||||||
local InitUnitName = PlayerData.UnitName
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
local InitUnitType = PlayerData.UnitType
|
||||||
|
local InitCoalition = PlayerData.UnitCoalition
|
||||||
|
local InitCategory = PlayerData.UnitCategory
|
||||||
|
local InitUnitCoalition = DATABASECoalition[InitCoalition]
|
||||||
|
local InitUnitCategory = DATABASECategory[InitCategory]
|
||||||
|
|
||||||
|
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
|
||||||
|
|
||||||
-- What is he hitting?
|
-- What is he hitting?
|
||||||
if TargetCategory then
|
if TargetCategory then
|
||||||
@ -251,17 +272,17 @@ trace.f( self.ClassName, { event } )
|
|||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
if PlayerData.UnitCoalition == TargetCoalition then
|
if InitCoalition == TargetCoalition then
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25
|
PlayerData.Kill[TargetCategory][TargetType].Penalty = PlayerData.Kill[TargetCategory][TargetType].Penalty + 25
|
||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' killed a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Penalty,
|
PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty,
|
||||||
"Game Status: Score", 20, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
"Game Status: Penalty", 20, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
else
|
else
|
||||||
PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10
|
PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10
|
||||||
PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill = PlayerData.Kill[TargetCategory][TargetType].ScoreKill + 1
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' killed a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
MESSAGE:New( "Player '" .. PlayerName .. "' killed an enemy " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score,
|
PlayerData.Kill[TargetCategory][TargetType].ScoreKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Score,
|
||||||
"Game Status: Score", 20, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
"Game Status: Score", 20, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
@ -272,12 +293,14 @@ trace.f( self.ClassName, { event } )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Scheduled
|
--- Scheduled
|
||||||
-- @section Scheduled
|
-- @section Scheduled
|
||||||
|
|
||||||
|
|
||||||
--- Follows new players entering Clients within the DCSRTE.
|
--- Follows new players entering Clients within the DCSRTE.
|
||||||
function DATABASE:_FollowPlayers()
|
function DATABASE:_FollowPlayers()
|
||||||
trace.scheduled( self.ClassName, "_FollowPlayers" )
|
self:T( "_FollowPlayers" )
|
||||||
|
|
||||||
local ClientUnit = 0
|
local ClientUnit = 0
|
||||||
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) }
|
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) }
|
||||||
@ -286,73 +309,73 @@ trace.scheduled( self.ClassName, "_FollowPlayers" )
|
|||||||
local AlivePlayerUnits = {}
|
local AlivePlayerUnits = {}
|
||||||
|
|
||||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||||
trace.l( self.ClassName, "_FollowPlayers", CoalitionData )
|
self:T( { "_FollowPlayers", CoalitionData } )
|
||||||
for UnitId, UnitData in pairs( CoalitionData ) do
|
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||||
self:_AddPlayerFromUnit( UnitData )
|
self:_AddPlayerFromUnit( UnitData )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Private
|
--- Private
|
||||||
-- @section Private
|
-- @section Private
|
||||||
|
|
||||||
|
|
||||||
--- Add a new player entering a Unit.
|
--- Add a new player entering a Unit.
|
||||||
function DATABASE:_AddPlayerFromUnit( UnitData )
|
function DATABASE:_AddPlayerFromUnit( UnitData )
|
||||||
trace.f( self.ClassName, UnitData )
|
self:T( UnitData )
|
||||||
|
|
||||||
if UnitData:isExist() then
|
if UnitData:isExist() then
|
||||||
local UnitName = UnitData:getName()
|
local UnitName = UnitData:getName()
|
||||||
local GroupData = UnitData:getGroup()
|
local PlayerName = UnitData:getPlayerName()
|
||||||
|
local UnitDesc = UnitData:getDesc()
|
||||||
|
local UnitCategory = UnitDesc.category
|
||||||
|
local UnitCoalition = UnitData:getCoalition()
|
||||||
|
local UnitTypeName = UnitData:getTypeName()
|
||||||
|
|
||||||
if GroupData and GroupData:isExist() then
|
self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } )
|
||||||
local GroupName = GroupData:getName()
|
|
||||||
local PlayerName = UnitData:getPlayerName()
|
|
||||||
|
|
||||||
trace.i(self.ClassName, "Player : " .. PlayerName .. " Unit : " .. UnitName .. " Group : " .. GroupName )
|
if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ...
|
||||||
|
self.Players[PlayerName] = {}
|
||||||
if self.Players[PlayerName] == nil then -- I believe this is the place where a Player gets a life in a mission when he enters a unit ...
|
self.Players[PlayerName].Hit = {}
|
||||||
self.Players[PlayerName] = {}
|
self.Players[PlayerName].Kill = {}
|
||||||
self.Players[PlayerName].Hit = {}
|
self.Players[PlayerName].Mission = {}
|
||||||
self.Players[PlayerName].Kill = {}
|
|
||||||
self.Players[PlayerName].Mission = {}
|
-- for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
||||||
|
-- self.Players[PlayerName].Hit[CategoryID] = {}
|
||||||
-- for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
-- self.Players[PlayerName].Kill[CategoryID] = {}
|
||||||
-- self.Players[PlayerName].Hit[CategoryID] = {}
|
-- end
|
||||||
-- self.Players[PlayerName].Kill[CategoryID] = {}
|
self.Players[PlayerName].HitPlayers = {}
|
||||||
-- end
|
self.Players[PlayerName].HitUnits = {}
|
||||||
self.Players[PlayerName].HitPlayers = {}
|
self.Players[PlayerName].Penalty = 0
|
||||||
self.Players[PlayerName].HitUnits = {}
|
self.Players[PlayerName].PenaltyCoalition = 0
|
||||||
self.Players[PlayerName].Penalty = 0
|
|
||||||
self.Players[PlayerName].PenaltyCoalition = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if not self.Players[PlayerName].UnitCoalition then
|
|
||||||
self.Players[PlayerName].UnitCoalition = Unit.getGroup(UnitData):getCoalition()
|
|
||||||
else
|
|
||||||
if self.Players[PlayerName].UnitCoalition ~= Unit.getGroup(UnitData):getCoalition() then
|
|
||||||
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
|
||||||
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
|
||||||
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. DATABASECoalition[Unit.getGroup(UnitData):getCoalition()] ..
|
|
||||||
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
|
||||||
"Game Status: Penalty", 20, "/PENALTYCOALITION" .. PlayerName ):ToAll()
|
|
||||||
self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, DATABASECoalition[self.Players[PlayerName].UnitCoalition], DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
|
|
||||||
UnitName, DATABASECategory[Unit.getGroup(UnitData):getCoalition()], DATABASECategory[Unit.getGroup(UnitData):getCategory()], UnitData:getTypeName() )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.Players[PlayerName].UnitName = UnitName
|
|
||||||
self.Players[PlayerName].GroupName = GroupName
|
|
||||||
|
|
||||||
self.Players[PlayerName].UnitCoalition = Unit.getGroup(UnitData):getCoalition()
|
|
||||||
self.Players[PlayerName].UnitCategory = Unit.getGroup(UnitData):getCategory()
|
|
||||||
self.Players[PlayerName].UnitType = UnitData:getTypeName()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not self.Players[PlayerName].UnitCoalition then
|
||||||
|
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
||||||
|
else
|
||||||
|
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
|
||||||
|
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
||||||
|
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
||||||
|
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. DATABASECoalition[UnitCoalition] ..
|
||||||
|
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
||||||
|
"Game Status: Penalty", 20, "/PENALTYCOALITION" .. PlayerName ):ToAll()
|
||||||
|
self:ScoreAdd( PlayerName, "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, DATABASECoalition[self.Players[PlayerName].UnitCoalition], DATABASECategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
|
||||||
|
UnitName, DATABASECoalition[UnitCoalition], DATABASECategory[UnitCategory], UnitData:getTypeName() )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.Players[PlayerName].UnitName = UnitName
|
||||||
|
self.Players[PlayerName].UnitCoalition = UnitCoalition
|
||||||
|
self.Players[PlayerName].UnitCategory = UnitCategory
|
||||||
|
self.Players[PlayerName].UnitType = UnitTypeName
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Registers Scores the players completing a Mission Task.
|
--- Registers Scores the players completing a Mission Task.
|
||||||
function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
|
||||||
trace.f( self.ClassName, { PlayerUnit, MissionName, Score } )
|
self:T( { PlayerUnit, MissionName, Score } )
|
||||||
|
|
||||||
local PlayerName = PlayerUnit:getPlayerName()
|
local PlayerName = PlayerUnit:getPlayerName()
|
||||||
|
|
||||||
@ -361,6 +384,9 @@ trace.f( self.ClassName, { PlayerUnit, MissionName, Score } )
|
|||||||
self.Players[PlayerName].Mission[MissionName].ScoreTask = 0
|
self.Players[PlayerName].Mission[MissionName].ScoreTask = 0
|
||||||
self.Players[PlayerName].Mission[MissionName].ScoreMission = 0
|
self.Players[PlayerName].Mission[MissionName].ScoreMission = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:T( PlayerName )
|
||||||
|
self:T( self.Players[PlayerName].Mission[MissionName] )
|
||||||
|
|
||||||
self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
||||||
|
|
||||||
@ -374,7 +400,7 @@ end
|
|||||||
|
|
||||||
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
|
||||||
function DATABASE:_AddMissionScore( MissionName, Score )
|
function DATABASE:_AddMissionScore( MissionName, Score )
|
||||||
trace.f( self.ClassName, { PlayerUnit, MissionName, Score } )
|
self:T( { PlayerUnit, MissionName, Score } )
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
|
||||||
@ -388,15 +414,18 @@ trace.f( self.ClassName, { PlayerUnit, MissionName, Score } )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Events
|
--- Events
|
||||||
-- @section Events
|
-- @section Events
|
||||||
|
|
||||||
function DATABASE:OnHit( event )
|
|
||||||
trace.f( self.ClassName, { event } )
|
|
||||||
|
|
||||||
local InitUnitName = nil
|
function DATABASE:OnHit( event )
|
||||||
local InitGroupName = nil
|
self:T( { event } )
|
||||||
local InitPlayerName = nil
|
|
||||||
|
local InitUnit = nil
|
||||||
|
local InitUnitName = ""
|
||||||
|
local InitGroupName = ""
|
||||||
|
local InitPlayerName = "dummy"
|
||||||
|
|
||||||
local InitCoalition = nil
|
local InitCoalition = nil
|
||||||
local InitCategory = nil
|
local InitCategory = nil
|
||||||
@ -405,9 +434,10 @@ trace.f( self.ClassName, { event } )
|
|||||||
local InitUnitCategory = nil
|
local InitUnitCategory = nil
|
||||||
local InitUnitType = nil
|
local InitUnitType = nil
|
||||||
|
|
||||||
local TargetUnitName = nil
|
local TargetUnit = nil
|
||||||
local TargetGroupName = nil
|
local TargetUnitName = ""
|
||||||
local TargetPlayerName = nil
|
local TargetGroupName = ""
|
||||||
|
local TargetPlayerName = ""
|
||||||
|
|
||||||
local TargetCoalition = nil
|
local TargetCoalition = nil
|
||||||
local TargetCategory = nil
|
local TargetCategory = nil
|
||||||
@ -419,49 +449,65 @@ trace.f( self.ClassName, { event } )
|
|||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
|
|
||||||
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
||||||
|
|
||||||
|
InitUnit = event.initiator
|
||||||
|
InitGroup = Unit.getGroup( InitUnit )
|
||||||
|
InitUnitDesc = InitUnit:getDesc()
|
||||||
|
|
||||||
InitUnitName = event.initiator:getName()
|
InitUnitName = InitUnit:getName()
|
||||||
InitGroupName = Unit.getGroup(event.initiator):getName()
|
if InitGroup and InitGroup:isExist() then
|
||||||
InitPlayerName = event.initiator:getPlayerName()
|
InitGroupName = InitGroup:getName()
|
||||||
|
end
|
||||||
|
InitPlayerName = InitUnit:getPlayerName()
|
||||||
|
|
||||||
InitCoalition = Unit.getGroup(event.initiator):getCoalition()
|
InitCoalition = InitUnit:getCoalition()
|
||||||
InitCategory = Unit.getGroup(event.initiator):getCategory()
|
--InitCategory = InitUnit:getCategory()
|
||||||
InitType = event.initiator:getTypeName()
|
InitCategory = InitUnitDesc.category -- Workaround
|
||||||
|
InitType = InitUnit:getTypeName()
|
||||||
|
|
||||||
InitUnitCoalition = DATABASECoalition[InitCoalition]
|
InitUnitCoalition = DATABASECoalition[InitCoalition]
|
||||||
InitUnitCategory = DATABASECategory[InitCategory]
|
InitUnitCategory = DATABASECategory[InitCategory]
|
||||||
InitUnitType = InitType
|
InitUnitType = InitType
|
||||||
|
|
||||||
trace.i( self.ClassName, { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType , InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
||||||
|
self:T( { InitUnitDesc } )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if event.target and Object.getCategory(event.target) == Object.Category.UNIT then
|
if event.target and Object.getCategory(event.target) == Object.Category.UNIT then
|
||||||
|
|
||||||
|
TargetUnit = event.target
|
||||||
|
TargetGroup = Unit.getGroup( TargetUnit )
|
||||||
|
TargetUnitDesc = TargetUnit:getDesc()
|
||||||
|
|
||||||
TargetUnitName = event.target:getName()
|
TargetUnitName = TargetUnit:getName()
|
||||||
TargetGroupName = Unit.getGroup(event.target):getName()
|
if TargetGroup and TargetGroup:isExist() then
|
||||||
TargetPlayerName = event.target:getPlayerName()
|
TargetGroupName = TargetGroup:getName()
|
||||||
|
end
|
||||||
|
TargetPlayerName = TargetUnit:getPlayerName()
|
||||||
|
|
||||||
TargetCoalition = Unit.getGroup(event.target):getCoalition()
|
TargetCoalition = TargetUnit:getCoalition()
|
||||||
TargetCategory = Unit.getGroup(event.target):getCategory()
|
--TargetCategory = TargetUnit:getCategory()
|
||||||
TargetType = event.target:getTypeName()
|
TargetCategory = TargetUnitDesc.category -- Workaround
|
||||||
|
TargetType = TargetUnit:getTypeName()
|
||||||
|
|
||||||
TargetUnitCoalition = DATABASECoalition[TargetCoalition]
|
TargetUnitCoalition = DATABASECoalition[TargetCoalition]
|
||||||
TargetUnitCategory = DATABASECategory[TargetCategory]
|
TargetUnitCategory = DATABASECategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
trace.i( self.ClassName, { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
||||||
|
self:T( { TargetUnitDesc } )
|
||||||
end
|
end
|
||||||
|
|
||||||
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
||||||
self:_AddPlayerFromUnit( event.initiator )
|
self:_AddPlayerFromUnit( InitUnit )
|
||||||
if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway.
|
if self.Players[InitPlayerName] then -- This should normally not happen, but i'll test it anyway.
|
||||||
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
||||||
self:_AddPlayerFromUnit( event.target )
|
self:_AddPlayerFromUnit( TargetUnit )
|
||||||
self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1
|
self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.i( self.ClassName, "Hitting Something" )
|
self:T( "Hitting Something" )
|
||||||
-- What is he hitting?
|
-- What is he hitting?
|
||||||
if TargetCategory then
|
if TargetCategory then
|
||||||
if not self.Players[InitPlayerName].Hit[TargetCategory] then
|
if not self.Players[InitPlayerName].Hit[TargetCategory] then
|
||||||
@ -479,7 +525,7 @@ trace.f( self.ClassName, { event } )
|
|||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty + 10
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1
|
||||||
MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
MESSAGE:New( "Player '" .. InitPlayerName .. "' hit a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: " .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty,
|
self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit .. " times. Penalty: -" .. self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].Penalty,
|
||||||
"Game Status: Penalty", 20, "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName ):ToAll()
|
"Game Status: Penalty", 20, "/PENALTY" .. InitPlayerName .. "/" .. InitUnitName ):ToAll()
|
||||||
self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
else
|
else
|
||||||
@ -498,14 +544,132 @@ trace.f( self.ClassName, { event } )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ReportScoreAll()
|
function DATABASE:ReportScoreAll()
|
||||||
|
|
||||||
|
env.info( "Hello World " )
|
||||||
|
|
||||||
local ScoreMessage = ""
|
local ScoreMessage = ""
|
||||||
local PlayerMessage = ""
|
local PlayerMessage = ""
|
||||||
|
|
||||||
|
self:T( "Score Report" )
|
||||||
|
|
||||||
for PlayerName, PlayerData in pairs( self.Players ) do
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
||||||
trace.i( self.ClassName, "Score" )
|
self:T( "Score Player: " .. PlayerName )
|
||||||
|
|
||||||
|
-- Some variables
|
||||||
|
local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition]
|
||||||
|
local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory]
|
||||||
|
local InitUnitType = PlayerData.UnitType
|
||||||
|
local InitUnitName = PlayerData.UnitName
|
||||||
|
|
||||||
|
local PlayerScore = 0
|
||||||
|
local PlayerPenalty = 0
|
||||||
|
|
||||||
|
ScoreMessage = ":\n"
|
||||||
|
|
||||||
|
local ScoreMessageHits = ""
|
||||||
|
|
||||||
|
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
||||||
|
self:T( CategoryName )
|
||||||
|
if PlayerData.Hit[CategoryID] then
|
||||||
|
local Score = 0
|
||||||
|
local ScoreHit = 0
|
||||||
|
local Penalty = 0
|
||||||
|
local PenaltyHit = 0
|
||||||
|
self:T( "Hit scores exist for player " .. PlayerName )
|
||||||
|
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
||||||
|
Score = Score + UnitData.Score
|
||||||
|
ScoreHit = ScoreHit + UnitData.ScoreHit
|
||||||
|
Penalty = Penalty + UnitData.Penalty
|
||||||
|
PenaltyHit = UnitData.PenaltyHit
|
||||||
|
end
|
||||||
|
local ScoreMessageHit = string.format( "%s:%d ", CategoryName, Score - Penalty )
|
||||||
|
self:T( ScoreMessageHit )
|
||||||
|
ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit
|
||||||
|
PlayerScore = PlayerScore + Score
|
||||||
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
|
else
|
||||||
|
--ScoreMessageHits = ScoreMessageHits .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ScoreMessageHits ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageKills = ""
|
||||||
|
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
||||||
|
self:T( "Kill scores exist for player " .. PlayerName )
|
||||||
|
if PlayerData.Kill[CategoryID] then
|
||||||
|
local Score = 0
|
||||||
|
local ScoreKill = 0
|
||||||
|
local Penalty = 0
|
||||||
|
local PenaltyKill = 0
|
||||||
|
|
||||||
|
for UnitName, UnitData in pairs( PlayerData.Kill[CategoryID] ) do
|
||||||
|
Score = Score + UnitData.Score
|
||||||
|
ScoreKill = ScoreKill + UnitData.ScoreKill
|
||||||
|
Penalty = Penalty + UnitData.Penalty
|
||||||
|
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageKill = string.format( " %s:%d ", CategoryName, Score - Penalty )
|
||||||
|
self:T( ScoreMessageKill )
|
||||||
|
ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill
|
||||||
|
|
||||||
|
PlayerScore = PlayerScore + Score
|
||||||
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
|
else
|
||||||
|
--ScoreMessageKills = ScoreMessageKills .. string.format( "%s:%d ", string.format(CategoryName, 1, 1), 0 )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ScoreMessageKills ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageCoalitionChangePenalties = ""
|
||||||
|
if PlayerData.PenaltyCoalition ~= 0 then
|
||||||
|
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
||||||
|
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
||||||
|
end
|
||||||
|
if ScoreMessageCoalitionChangePenalties ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Coalition Penalties: " .. ScoreMessageCoalitionChangePenalties .. "\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
local ScoreMessageMission = ""
|
||||||
|
local ScoreMission = 0
|
||||||
|
local ScoreTask = 0
|
||||||
|
for MissionName, MissionData in pairs( PlayerData.Mission ) do
|
||||||
|
ScoreMission = ScoreMission + MissionData.ScoreMission
|
||||||
|
ScoreTask = ScoreTask + MissionData.ScoreTask
|
||||||
|
ScoreMessageMission = ScoreMessageMission .. "'" .. MissionName .. "'; "
|
||||||
|
end
|
||||||
|
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
||||||
|
|
||||||
|
if ScoreMessageMission ~= "" then
|
||||||
|
ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ")\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score:%d (%d Score -%d Penalties)%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function DATABASE:ReportScorePlayer()
|
||||||
|
|
||||||
|
env.info( "Hello World " )
|
||||||
|
|
||||||
|
local ScoreMessage = ""
|
||||||
|
local PlayerMessage = ""
|
||||||
|
|
||||||
|
self:T( "Score Report" )
|
||||||
|
|
||||||
|
for PlayerName, PlayerData in pairs( self.Players ) do
|
||||||
|
if PlayerData then -- This should normally not happen, but i'll test it anyway.
|
||||||
|
self:T( "Score Player: " .. PlayerName )
|
||||||
|
|
||||||
-- Some variables
|
-- Some variables
|
||||||
local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition]
|
local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition]
|
||||||
@ -521,18 +685,22 @@ function DATABASE:ReportScoreAll()
|
|||||||
local ScoreMessageHits = ""
|
local ScoreMessageHits = ""
|
||||||
|
|
||||||
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
||||||
|
self:T( CategoryName )
|
||||||
if PlayerData.Hit[CategoryID] then
|
if PlayerData.Hit[CategoryID] then
|
||||||
local Score = 0
|
local Score = 0
|
||||||
local ScoreHit = 0
|
local ScoreHit = 0
|
||||||
local Penalty = 0
|
local Penalty = 0
|
||||||
local PenaltyHit = 0
|
local PenaltyHit = 0
|
||||||
|
self:T( "Hit scores exist for player " .. PlayerName )
|
||||||
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
for UnitName, UnitData in pairs( PlayerData.Hit[CategoryID] ) do
|
||||||
Score = Score + UnitData.Score
|
Score = Score + UnitData.Score
|
||||||
ScoreHit = ScoreHit + UnitData.ScoreHit
|
ScoreHit = ScoreHit + UnitData.ScoreHit
|
||||||
Penalty = Penalty + UnitData.Penalty
|
Penalty = Penalty + UnitData.Penalty
|
||||||
PenaltyHit = UnitData.PenaltyHit
|
PenaltyHit = UnitData.PenaltyHit
|
||||||
end
|
end
|
||||||
ScoreMessageHits = ScoreMessageHits .. string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit )
|
local ScoreMessageHit = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit )
|
||||||
|
self:T( ScoreMessageHit )
|
||||||
|
ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit
|
||||||
PlayerScore = PlayerScore + Score
|
PlayerScore = PlayerScore + Score
|
||||||
PlayerPenalty = PlayerPenalty + Penalty
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
else
|
else
|
||||||
@ -540,11 +708,12 @@ function DATABASE:ReportScoreAll()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if ScoreMessageHits ~= "" then
|
if ScoreMessageHits ~= "" then
|
||||||
ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. " "
|
ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " "
|
||||||
end
|
end
|
||||||
|
|
||||||
local ScoreMessageKills = ""
|
local ScoreMessageKills = ""
|
||||||
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
for CategoryID, CategoryName in pairs( DATABASECategory ) do
|
||||||
|
self:T( "Kill scores exist for player " .. PlayerName )
|
||||||
if PlayerData.Kill[CategoryID] then
|
if PlayerData.Kill[CategoryID] then
|
||||||
local Score = 0
|
local Score = 0
|
||||||
local ScoreKill = 0
|
local ScoreKill = 0
|
||||||
@ -557,8 +726,10 @@ function DATABASE:ReportScoreAll()
|
|||||||
Penalty = Penalty + UnitData.Penalty
|
Penalty = Penalty + UnitData.Penalty
|
||||||
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
PenaltyKill = PenaltyKill + UnitData.PenaltyKill
|
||||||
end
|
end
|
||||||
|
|
||||||
ScoreMessageKills = ScoreMessageKills .. string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill )
|
local ScoreMessageKill = string.format( "\n %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill )
|
||||||
|
self:T( ScoreMessageKill )
|
||||||
|
ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill
|
||||||
|
|
||||||
PlayerScore = PlayerScore + Score
|
PlayerScore = PlayerScore + Score
|
||||||
PlayerPenalty = PlayerPenalty + Penalty
|
PlayerPenalty = PlayerPenalty + Penalty
|
||||||
@ -567,16 +738,16 @@ function DATABASE:ReportScoreAll()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if ScoreMessageKills ~= "" then
|
if ScoreMessageKills ~= "" then
|
||||||
ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. " "
|
ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " "
|
||||||
end
|
end
|
||||||
|
|
||||||
local ScoreMessageCoalitionChangePenalties = ""
|
local ScoreMessageCoalitionChangePenalties = ""
|
||||||
if PlayerData.PenaltyCoalition ~= 0 then
|
if PlayerData.PenaltyCoalition ~= 0 then
|
||||||
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( "-%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
ScoreMessageCoalitionChangePenalties = ScoreMessageCoalitionChangePenalties .. string.format( " -%d (%d changed)", PlayerData.Penalty, PlayerData.PenaltyCoalition )
|
||||||
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
PlayerPenalty = PlayerPenalty + PlayerData.Penalty
|
||||||
end
|
end
|
||||||
if ScoreMessageCoalitionChangePenalties ~= "" then
|
if ScoreMessageCoalitionChangePenalties ~= "" then
|
||||||
ScoreMessage = ScoreMessage .. " Coalition: " .. ScoreMessageCoalitionChangePenalties .. " "
|
ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " "
|
||||||
end
|
end
|
||||||
|
|
||||||
local ScoreMessageMission = ""
|
local ScoreMessageMission = ""
|
||||||
@ -590,26 +761,26 @@ function DATABASE:ReportScoreAll()
|
|||||||
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
PlayerScore = PlayerScore + ScoreMission + ScoreTask
|
||||||
|
|
||||||
if ScoreMessageMission ~= "" then
|
if ScoreMessageMission ~= "" then
|
||||||
ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") "
|
ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") "
|
||||||
end
|
end
|
||||||
|
|
||||||
PlayerMessage = string.format( " Player '%s' Score = %d ( %d Score, -%d Penalties ):", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty )
|
PlayerMessage = PlayerMessage .. string.format( "Player '%s' Score = %d ( %d Score, -%d Penalties ):%s", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty, ScoreMessage )
|
||||||
MESSAGE:New( PlayerMessage .. ScoreMessage, "Player Scores", 30, "/SCORE/" .. PlayerName ):ToAll()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll()
|
||||||
|
|
||||||
function DATABASE:ReportScorePlayer()
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreMenu()
|
function DATABASE:ScoreMenu()
|
||||||
local ReportScore = SUBMENU:New( 'Scoring' )
|
local ReportScore = SUBMENU:New( 'Scoring' )
|
||||||
local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self )
|
local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self )
|
||||||
local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self )
|
local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- File Logic for tracking the scores
|
-- File Logic for tracking the scores
|
||||||
|
|
||||||
function DATABASE:SecondsToClock(sSeconds)
|
function DATABASE:SecondsToClock(sSeconds)
|
||||||
@ -625,6 +796,7 @@ local nSeconds = sSeconds
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreOpen()
|
function DATABASE:ScoreOpen()
|
||||||
if lfs then
|
if lfs then
|
||||||
local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv"
|
local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv"
|
||||||
@ -632,12 +804,13 @@ function DATABASE:ScoreOpen()
|
|||||||
if not self.StatFile then
|
if not self.StatFile then
|
||||||
error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() )
|
error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() )
|
||||||
end
|
end
|
||||||
self.StatFile:write( '"Run-ID";Time;"PlayerName";"ScoreType";"PlayerUnitCoaltion";"PlayerUnitCategory";"PlayerUnitType"; "PlayerUnitName";"TargetUnitCoalition";"TargetUnitCategory";"TargetUnitType";"TargetUnitName";Times;Score\n' )
|
self.StatFile:write( '"RunID";"Time";"PlayerName";"ScoreType";"PlayerUnitCoaltion";"PlayerUnitCategory";"PlayerUnitType";"PlayerUnitName";"TargetUnitCoalition";"TargetUnitCategory";"TargetUnitType";"TargetUnitName";"Times";"Score"\n' )
|
||||||
|
|
||||||
self.RunID = os.date("%y-%m-%d_%H-%M-%S")
|
self.RunID = os.date("%y-%m-%d_%H-%M-%S")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
--write statistic information to file
|
--write statistic information to file
|
||||||
local ScoreTime = self:SecondsToClock(timer.getTime())
|
local ScoreTime = self:SecondsToClock(timer.getTime())
|
||||||
@ -648,11 +821,12 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play
|
|||||||
|
|
||||||
if PlayerUnit then
|
if PlayerUnit then
|
||||||
if not PlayerUnitCategory then
|
if not PlayerUnitCategory then
|
||||||
PlayerUnitCategory = DATABASECategory[Unit.getGroup(PlayerUnit):getCategory()]
|
--PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()]
|
||||||
|
PlayerUnitCategory = DATABASECategory[PlayerUnit:getDesc().category]
|
||||||
end
|
end
|
||||||
|
|
||||||
if not PlayerUnitCoalition then
|
if not PlayerUnitCoalition then
|
||||||
PlayerUnitCoalition = DATABASECoalition[Unit.getGroup(PlayerUnit):getCoalition()]
|
PlayerUnitCoalition = DATABASECoalition[PlayerUnit:getCoalition()]
|
||||||
end
|
end
|
||||||
|
|
||||||
if not PlayerUnitType then
|
if not PlayerUnitType then
|
||||||
@ -695,6 +869,7 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play
|
|||||||
self.StatFile:write( "\n" )
|
self.StatFile:write( "\n" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function LogClose()
|
function LogClose()
|
||||||
if lfs then
|
if lfs then
|
||||||
|
|||||||
@ -13,39 +13,64 @@ DEPLOYTASK = {
|
|||||||
--- Creates a new DEPLOYTASK object, which models the sequence of STAGEs to unload a cargo.
|
--- Creates a new DEPLOYTASK object, which models the sequence of STAGEs to unload a cargo.
|
||||||
-- @tparam table{string,...}|string LandingZones Table or name of the zone(s) where Cargo is to be unloaded.
|
-- @tparam table{string,...}|string LandingZones Table or name of the zone(s) where Cargo is to be unloaded.
|
||||||
-- @tparam CARGO_TYPE CargoType Type of the Cargo.
|
-- @tparam CARGO_TYPE CargoType Type of the Cargo.
|
||||||
function DEPLOYTASK:New( LandingZones, CargoType )
|
function DEPLOYTASK:New( CargoType )
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, TASK:New() )
|
||||||
|
self:T()
|
||||||
|
|
||||||
-- Child holds the inherited instance of the DEPLOYTASK Class to the BASE class.
|
|
||||||
local Child = BASE:Inherit( self, TASK:New() )
|
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
Valid = routines.ValidateZone( LandingZones, "LandingZones", Valid )
|
|
||||||
Valid = routines.ValidateEnumeration( CargoType, "CargoType", CARGO_TYPE, Valid )
|
|
||||||
|
|
||||||
if Valid then
|
if Valid then
|
||||||
Child.Name = 'Deploy Cargo'
|
self.Name = 'Deploy Cargo'
|
||||||
Child.TaskBriefing = "Fly to one of the indicated landing zones and deploy " .. CargoType.TEXT .. ". Your co-pilot will provide you with the directions (required flight angle in degrees) and the distance (in km) to the deployment zone."
|
self.TaskBriefing = "Fly to one of the indicated landing zones and deploy " .. CargoType .. ". Your co-pilot will provide you with the directions (required flight angle in degrees) and the distance (in km) to the deployment zone."
|
||||||
if type( LandingZones ) == "table" then
|
self.CargoType = CargoType
|
||||||
Child.LandingZones = LandingZones
|
self.GoalVerb = CargoType .. " " .. self.GoalVerb
|
||||||
else
|
self.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGEUNLOAD:New(), STAGEDONE:New() }
|
||||||
Child.LandingZones = { LandingZones }
|
self.SetStage( self, 1 )
|
||||||
end
|
|
||||||
Child.CargoType = CargoType
|
|
||||||
Child.GoalVerb = CargoType.TEXT .. " " .. self.GoalVerb
|
|
||||||
Child.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGEUNLOAD:New(), STAGEDONE:New() }
|
|
||||||
Child.SetStage( Child, 1 )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return Child
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function DEPLOYTASK:ToZone( LandingZone )
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
self.LandingZones.LandingZoneNames[LandingZone.CargoZoneName] = LandingZone.CargoZoneName
|
||||||
|
self.LandingZones.LandingZones[LandingZone.CargoZoneName] = LandingZone
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function DEPLOYTASK:InitCargo( InitCargos )
|
||||||
|
self:T( { InitCargos } )
|
||||||
|
|
||||||
|
if type( InitCargos ) == "table" then
|
||||||
|
self.Cargos.InitCargos = InitCargos
|
||||||
|
else
|
||||||
|
self.Cargos.InitCargos = { InitCargos }
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function DEPLOYTASK:LoadCargo( LoadCargos )
|
||||||
|
self:T( { LoadCargos } )
|
||||||
|
|
||||||
|
if type( LoadCargos ) == "table" then
|
||||||
|
self.Cargos.LoadCargos = LoadCargos
|
||||||
|
else
|
||||||
|
self.Cargos.LoadCargos = { LoadCargos }
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- When the cargo is unloaded, it will move to the target zone name.
|
--- When the cargo is unloaded, it will move to the target zone name.
|
||||||
-- @tparam string TargetZoneName Name of the Zone to where the Cargo should move after unloading.
|
-- @tparam string TargetZoneName Name of the Zone to where the Cargo should move after unloading.
|
||||||
function DEPLOYTASK:SetCargoTargetZoneName( TargetZoneName )
|
function DEPLOYTASK:SetCargoTargetZoneName( TargetZoneName )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
@ -60,57 +85,68 @@ trace.f(self.ClassName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function DEPLOYTASK:AddCargoMenus( Client, Cargos, TransportRadius )
|
function DEPLOYTASK:AddCargoMenus( Client, Cargos, TransportRadius )
|
||||||
trace.f(self.ClassName, {Client, Cargos, TransportRadius})
|
self:T()
|
||||||
|
|
||||||
for CargoID, CargoData in pairs( Client._Cargos ) do
|
local ClientGroupID = Client:GetClientGroupID()
|
||||||
|
|
||||||
|
trace.i( self.ClassName, ClientGroupID )
|
||||||
|
|
||||||
|
for CargoID, Cargo in pairs( Cargos ) do
|
||||||
|
|
||||||
trace.i( self.ClassName, { CargoData.CargoName } )
|
trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo.CargoWeight } )
|
||||||
if Client._Menus[CargoData.CargoType] == nil then
|
|
||||||
Client._Menus[CargoData.CargoType] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
if not Client._Menus[CargoData.CargoType].DeployMenu then
|
if Cargo:IsStatusLoaded() and Client == Cargo:IsLoadedInClient() then
|
||||||
Client._Menus[CargoData.CargoType].DeployMenu = missionCommands.addSubMenuForGroup(
|
|
||||||
Client:ClientGroup():getID(),
|
if Client._Menus[Cargo.CargoType] == nil then
|
||||||
self.TEXT[1],
|
Client._Menus[Cargo.CargoType] = {}
|
||||||
nil
|
end
|
||||||
|
|
||||||
|
if not Client._Menus[Cargo.CargoType].DeployMenu then
|
||||||
|
Client._Menus[Cargo.CargoType].DeployMenu = missionCommands.addSubMenuForGroup(
|
||||||
|
ClientGroupID,
|
||||||
|
self.TEXT[1] .. " " .. Cargo.CargoType,
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
trace.i( self.ClassName, 'Added DeployMenu ' .. self.TEXT[1] )
|
||||||
|
end
|
||||||
|
|
||||||
|
if Client._Menus[Cargo.CargoType].DeploySubMenus == nil then
|
||||||
|
Client._Menus[Cargo.CargoType].DeploySubMenus = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if Client._Menus[Cargo.CargoType].DeployMenu == nil then
|
||||||
|
trace.i( self.ClassName, 'deploymenu is nil' )
|
||||||
|
end
|
||||||
|
|
||||||
|
Client._Menus[Cargo.CargoType].DeploySubMenus[ #Client._Menus[Cargo.CargoType].DeploySubMenus + 1 ] = missionCommands.addCommandForGroup(
|
||||||
|
ClientGroupID,
|
||||||
|
Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )",
|
||||||
|
Client._Menus[Cargo.CargoType].DeployMenu,
|
||||||
|
self.MenuAction,
|
||||||
|
{ ReferenceTask = self, CargoTask = Cargo }
|
||||||
)
|
)
|
||||||
trace.i( self.ClassName, 'Added DeployMenu ' .. self.TEXT[1] )
|
trace.i( self.ClassName, 'Added DeploySubMenu ' .. Cargo.CargoType .. ":" .. Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if Client._Menus[CargoData.CargoType].DeploySubMenus == nil then
|
|
||||||
Client._Menus[CargoData.CargoType].DeploySubMenus = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
if Client._Menus[CargoData.CargoType].DeployMenu == nil then
|
|
||||||
trace.i( self.ClassName, 'deploymenu is nil' )
|
|
||||||
end
|
|
||||||
|
|
||||||
Client._Menus[CargoData.CargoType].DeploySubMenus[ #Client._Menus[CargoData.CargoType].DeploySubMenus + 1 ].MenuPath = missionCommands.addCommandForGroup(
|
|
||||||
Client:ClientGroup():getID(),
|
|
||||||
CargoData.CargoName .. " ( " .. CargoData.CargoWeight .. "kg )",
|
|
||||||
Client._Menus[CargoData.CargoType].DeployMenu,
|
|
||||||
self.MenuAction,
|
|
||||||
{ ReferenceTask = self, CargoName = CargoData.CargoName }
|
|
||||||
)
|
|
||||||
trace.i( self.ClassName, 'Added DeploySubMenu ' .. CargoData.CargoType.TEXT .. ":" .. CargoData.CargoName .. " ( " .. CargoData.CargoWeight .. "kg )" )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function DEPLOYTASK:RemoveCargoMenus( Client )
|
function DEPLOYTASK:RemoveCargoMenus( Client )
|
||||||
trace.f(self.ClassName, { Client } )
|
self:T()
|
||||||
|
|
||||||
|
local ClientGroupID = Client:GetClientGroupID()
|
||||||
|
trace.i( self.ClassName, ClientGroupID )
|
||||||
|
|
||||||
for MenuID, MenuData in pairs( Client._Menus ) do
|
for MenuID, MenuData in pairs( Client._Menus ) do
|
||||||
if MenuData.DeploySubMenus ~= nil then
|
if MenuData.DeploySubMenus ~= nil then
|
||||||
for SubMenuID, SubMenuData in pairs( MenuData.DeploySubMenus ) do
|
for SubMenuID, SubMenuData in pairs( MenuData.DeploySubMenus ) do
|
||||||
missionCommands.removeItemForGroup( Client:ClientGroup():getID(), SubMenuData )
|
missionCommands.removeItemForGroup( ClientGroupID, SubMenuData )
|
||||||
trace.i( self.ClassName, "Removed DeploySubMenu " )
|
trace.i( self.ClassName, "Removed DeploySubMenu " )
|
||||||
SubMenuData = nil
|
SubMenuData = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if MenuData.DeployMenu then
|
if MenuData.DeployMenu then
|
||||||
missionCommands.removeItemForGroup( Client:ClientGroup():getID(), MenuData.DeployMenu )
|
missionCommands.removeItemForGroup( ClientGroupID, MenuData.DeployMenu )
|
||||||
trace.i( self.ClassName, "Removed DeployMenu " )
|
trace.i( self.ClassName, "Removed DeployMenu " )
|
||||||
MenuData.DeployMenu = nil
|
MenuData.DeployMenu = nil
|
||||||
end
|
end
|
||||||
|
|||||||
@ -20,51 +20,52 @@ DESTROYBASETASK = {
|
|||||||
-- @tparam ?number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}.
|
-- @tparam ?number DestroyPercentage defines the %-tage that needs to be destroyed to achieve mission success. eg. If in the Group there are 10 units, then a value of 75 would require 8 units to be destroyed from the Group to complete the @{TASK}.
|
||||||
-- @treturn DESTROYBASETASK
|
-- @treturn DESTROYBASETASK
|
||||||
function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPrefixes, DestroyPercentage )
|
function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPrefixes, DestroyPercentage )
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, TASK:New() )
|
||||||
|
self:T()
|
||||||
-- Inheritance
|
|
||||||
local Child = BASE:Inherit( self, TASK:New() )
|
|
||||||
|
|
||||||
Child.Name = 'Destroy'
|
self.Name = 'Destroy'
|
||||||
Child.Destroyed = 0
|
self.Destroyed = 0
|
||||||
Child.DestroyGroupPrefixes = DestroyGroupPrefixes
|
self.DestroyGroupPrefixes = DestroyGroupPrefixes
|
||||||
Child.DestroyGroupType = DestroyGroupType
|
self.DestroyGroupType = DestroyGroupType
|
||||||
Child.DestroyUnitType = DestroyUnitType
|
self.DestroyUnitType = DestroyUnitType
|
||||||
Child.TaskBriefing = "Task: Destroy " .. DestroyGroupType .. "."
|
self.TaskBriefing = "Task: Destroy " .. DestroyGroupType .. "."
|
||||||
Child.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEGROUPSDESTROYED:New(), STAGEDONE:New() }
|
self.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEGROUPSDESTROYED:New(), STAGEDONE:New() }
|
||||||
Child.SetStage( Child, 1 )
|
self.SetStage( self, 1 )
|
||||||
|
|
||||||
--Child.AddEvent( Child, world.event.S_EVENT_DEAD, Child.EventDead )
|
--self.AddEvent( self, world.event.S_EVENT_DEAD, self.EventDead )
|
||||||
|
|
||||||
--env.info( 'New Table Child = ' .. tostring(Child) )
|
--env.info( 'New Table self = ' .. tostring(self) )
|
||||||
--env.info( 'New Table self = ' .. tostring(self) )
|
--env.info( 'New Table self = ' .. tostring(self) )
|
||||||
|
|
||||||
return Child
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Handle the S_EVENT_DEAD events to validate the destruction of units for the task monitoring.
|
--- Handle the S_EVENT_DEAD events to validate the destruction of units for the task monitoring.
|
||||||
-- @param event Event structure of DCS world.
|
-- @param event Event structure of DCS world.
|
||||||
function DESTROYBASETASK:EventDead( event )
|
function DESTROYBASETASK:EventDead( event )
|
||||||
trace.f( self.ClassName, { 'EventDead', event } )
|
self:T( { 'EventDead', event } )
|
||||||
|
|
||||||
if event.initiator then
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
||||||
local DestroyGroup = Unit.getGroup( event.initiator )
|
|
||||||
local DestroyGroupName = DestroyGroup:getName()
|
|
||||||
local DestroyUnit = event.initiator
|
local DestroyUnit = event.initiator
|
||||||
local DestroyUnitName = DestroyUnit:getName()
|
local DestroyUnitName = DestroyUnit:getName()
|
||||||
|
local DestroyGroup = Unit.getGroup( DestroyUnit )
|
||||||
|
local DestroyGroupName = ""
|
||||||
|
if DestroyGroup and DestroyGroup:isExist() then
|
||||||
|
local DestroyGroupName = DestroyGroup:getName()
|
||||||
|
end
|
||||||
local UnitsDestroyed = 0
|
local UnitsDestroyed = 0
|
||||||
trace.i( self.ClassName, DestroyGroupName )
|
self:T( DestroyGroupName )
|
||||||
trace.i( self.ClassName, DestroyUnitName )
|
self:T( DestroyUnitName )
|
||||||
for DestroyGroupPrefixID, DestroyGroupPrefix in pairs( self.DestroyGroupPrefixes ) do
|
for DestroyGroupPrefixID, DestroyGroupPrefix in pairs( self.DestroyGroupPrefixes ) do
|
||||||
trace.i( self.ClassName, DestroyGroupPrefix )
|
self:T( DestroyGroupPrefix )
|
||||||
if string.find( DestroyGroupName, DestroyGroupPrefix, 1, true ) then
|
if string.find( DestroyGroupName, DestroyGroupPrefix, 1, true ) then
|
||||||
trace.i( self.ClassName, BASE:Inherited(self).ClassName )
|
self:T( BASE:Inherited(self).ClassName )
|
||||||
UnitsDestroyed = self:ReportGoalProgress( DestroyGroup, DestroyUnit )
|
UnitsDestroyed = self:ReportGoalProgress( DestroyGroup, DestroyUnit )
|
||||||
trace.i( self.ClassName, UnitsDestroyed )
|
self:T( UnitsDestroyed )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.i( self.ClassName, { UnitsDestroyed } )
|
self:T( { UnitsDestroyed } )
|
||||||
self:IncreaseGoalCount( UnitsDestroyed, self.GoalVerb )
|
self:IncreaseGoalCount( UnitsDestroyed, self.GoalVerb )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -73,7 +74,7 @@ end
|
|||||||
-- @param DestroyGroup Group structure describing the group to be evaluated.
|
-- @param DestroyGroup Group structure describing the group to be evaluated.
|
||||||
-- @param DestroyUnit Unit structure describing the Unit to be evaluated.
|
-- @param DestroyUnit Unit structure describing the Unit to be evaluated.
|
||||||
function DESTROYBASETASK:ReportGoalProgress( DestroyGroup, DestroyUnit )
|
function DESTROYBASETASK:ReportGoalProgress( DestroyGroup, DestroyUnit )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|||||||
177
Moose/Group.lua
Normal file
177
Moose/Group.lua
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
--- GROUP Classes
|
||||||
|
-- @classmod GROUP
|
||||||
|
|
||||||
|
Include.File( "Routines" )
|
||||||
|
Include.File( "Base" )
|
||||||
|
Include.File( "Message" )
|
||||||
|
Include.File( "Unit" )
|
||||||
|
|
||||||
|
GROUPS = {}
|
||||||
|
|
||||||
|
|
||||||
|
GROUP = {
|
||||||
|
ClassName="GROUP",
|
||||||
|
}
|
||||||
|
|
||||||
|
function GROUP:New( _Group )
|
||||||
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T( _Group:getName() )
|
||||||
|
|
||||||
|
self._Group = _Group
|
||||||
|
self.GroupName = _Group:getName()
|
||||||
|
self.GroupID = _Group:getID()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:NewFromName( GroupName )
|
||||||
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T( GroupName )
|
||||||
|
|
||||||
|
self._Group = Group.getByName( GroupName )
|
||||||
|
self.GroupName = self._Group:getName()
|
||||||
|
self.GroupID = self._Group:getID()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:GetName()
|
||||||
|
self:T( self.GroupName )
|
||||||
|
|
||||||
|
return self.GroupName
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:Destroy()
|
||||||
|
self:T( self.GroupName )
|
||||||
|
|
||||||
|
for Index, UnitData in pairs( self._Group:getUnits() ) do
|
||||||
|
self:CreateEventCrash( timer.getTime(), UnitData )
|
||||||
|
end
|
||||||
|
|
||||||
|
self._Group:destroy()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:GetUnit( UnitNumber )
|
||||||
|
self:T( self.GroupName )
|
||||||
|
return UNIT:New( self._Group:getUnit( UnitNumber ) )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:IsAir()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
local IsAirResult = self._Group:getCategory() == Group.Category.AIRPLANE or self._Group:getCategory() == Group.Category.HELICOPTER
|
||||||
|
|
||||||
|
self:T( IsAirResult )
|
||||||
|
return IsAirResult
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:AllOnGround()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
local AllOnGroundResult = true
|
||||||
|
|
||||||
|
for Index, UnitData in pairs( self._Group:getUnits() ) do
|
||||||
|
if UnitData:inAir() then
|
||||||
|
AllOnGroundResult = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( AllOnGroundResult )
|
||||||
|
return AllOnGroundResult
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:GetMaxVelocity()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
local MaxVelocity = 0
|
||||||
|
|
||||||
|
for Index, UnitData in pairs( self._Group:getUnits() ) do
|
||||||
|
|
||||||
|
local Velocity = UnitData:getVelocity()
|
||||||
|
local VelocityTotal = math.abs( Velocity.x ) + math.abs( Velocity.y ) + math.abs( Velocity.z )
|
||||||
|
|
||||||
|
if VelocityTotal < MaxVelocity then
|
||||||
|
MaxVelocity = VelocityTotal
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return MaxVelocity
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:GetHeight()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:Land( Point, Duration )
|
||||||
|
trace.f( self.ClassName, { self.GroupName, Point, Duration } )
|
||||||
|
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
if Duration and Duration > 0 then
|
||||||
|
Controller:pushTask( { id = 'Land', params = { point = Point, durationFlag = true, duration = Duration } } )
|
||||||
|
else
|
||||||
|
Controller:pushTask( { id = 'Land', params = { point = Point, durationFlag = false } } )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:Embarking( Point, Duration, EmbarkingGroup )
|
||||||
|
trace.f( self.ClassName, { self.GroupName, Point, Duration, EmbarkingGroup._Group } )
|
||||||
|
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
trace.i( self.ClassName, EmbarkingGroup.GroupID )
|
||||||
|
trace.i( self.ClassName, EmbarkingGroup._Group:getID() )
|
||||||
|
trace.i( self.ClassName, EmbarkingGroup._Group.id )
|
||||||
|
|
||||||
|
Controller:pushTask( { id = 'Embarking',
|
||||||
|
params = { x = Point.x,
|
||||||
|
y = Point.y,
|
||||||
|
duration = Duration,
|
||||||
|
groupsForEmbarking = { EmbarkingGroup.GroupID },
|
||||||
|
durationFlag = true,
|
||||||
|
distributionFlag = false,
|
||||||
|
distribution = {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:EmbarkToTransport( Point, Radius )
|
||||||
|
trace.f( self.ClassName, { self.GroupName, Point, Radius } )
|
||||||
|
|
||||||
|
local Controller = self:_GetController()
|
||||||
|
|
||||||
|
Controller:pushTask( { id = 'EmbarkToTransport',
|
||||||
|
params = { x = Point.x,
|
||||||
|
y = Point.y,
|
||||||
|
zoneRadius = Radius,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function GROUP:_GetController()
|
||||||
|
|
||||||
|
return self._Group:getController()
|
||||||
|
|
||||||
|
end
|
||||||
@ -74,16 +74,52 @@ end
|
|||||||
function MESSAGE:ToClient( Client )
|
function MESSAGE:ToClient( Client )
|
||||||
trace.f(self.ClassName )
|
trace.f(self.ClassName )
|
||||||
|
|
||||||
if Client and Client:ClientGroup() then
|
if Client and Client:GetClientGroupID() then
|
||||||
|
|
||||||
local ClientGroup = Client:ClientGroup()
|
local ClientGroupID = Client:GetClientGroupID()
|
||||||
trace.i( self.ClassName, self.MessageCategory .. '\n' .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
trace.i( self.ClassName, self.MessageCategory .. '\n' .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
||||||
trigger.action.outTextForGroup( ClientGroup:getID(), self.MessageCategory .. '\n' .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration )
|
trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. '\n' .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Sends a MESSAGE to the Blue coalition.
|
||||||
|
-- @treturn MESSAGE
|
||||||
|
-- @usage
|
||||||
|
-- -- Send a message created with the @{New} method to the BLUE coalition.
|
||||||
|
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
|
||||||
|
-- or
|
||||||
|
-- MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
|
||||||
|
-- or
|
||||||
|
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
||||||
|
-- MessageBLUE:ToBlue()
|
||||||
|
function MESSAGE:ToBlue()
|
||||||
|
trace.f(self.ClassName )
|
||||||
|
|
||||||
|
self:ToCoalition( coalition.side.BLUE )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Sends a MESSAGE to the Red Coalition.
|
||||||
|
-- @treturn MESSAGE
|
||||||
|
-- @usage
|
||||||
|
-- -- Send a message created with the @{New} method to the RED coalition.
|
||||||
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
|
||||||
|
-- or
|
||||||
|
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
|
||||||
|
-- or
|
||||||
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
||||||
|
-- MessageRED:ToRed()
|
||||||
|
function MESSAGE:ToRed( )
|
||||||
|
trace.f(self.ClassName )
|
||||||
|
|
||||||
|
self:ToCoalition( coalition.side.RED )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Sends a MESSAGE to a Coalition.
|
--- Sends a MESSAGE to a Coalition.
|
||||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
|
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
|
||||||
-- @treturn MESSAGE
|
-- @treturn MESSAGE
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
Include.File( "Routines" )
|
Include.File( "Routines" )
|
||||||
Include.File( "Base" )
|
Include.File( "Base" )
|
||||||
Include.File( "Mission" )
|
|
||||||
Include.File( "Client" )
|
Include.File( "Client" )
|
||||||
Include.File( "Task" )
|
Include.File( "Task" )
|
||||||
|
|
||||||
@ -16,7 +15,6 @@ MISSION = {
|
|||||||
_Clients = {},
|
_Clients = {},
|
||||||
_Tasks = {},
|
_Tasks = {},
|
||||||
_ActiveTasks = {},
|
_ActiveTasks = {},
|
||||||
_Cargos = {},
|
|
||||||
GoalFunction = nil,
|
GoalFunction = nil,
|
||||||
MissionReportTrigger = 0,
|
MissionReportTrigger = 0,
|
||||||
MissionProgressTrigger = 0,
|
MissionProgressTrigger = 0,
|
||||||
@ -30,23 +28,13 @@ MISSION = {
|
|||||||
_GoalTasks = {}
|
_GoalTasks = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
CARGOSTATUS = {
|
|
||||||
NONE = 0,
|
|
||||||
LOADED = 1,
|
|
||||||
UNLOADED = 2,
|
|
||||||
LOADING = 3,
|
|
||||||
LoadCount= 0,
|
|
||||||
UnloadCount = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function MISSION:Meta()
|
function MISSION:Meta()
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
-- Arrange meta tables
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
local Child = BASE:Inherit( self, BASE:New() )
|
self:T()
|
||||||
trace.r( self.ClassName, "", { Child } )
|
|
||||||
return Child
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||||
@ -66,8 +54,9 @@ end
|
|||||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Sling Load', 'Operational', 'Fly to the cargo pickup zone at Dzegvi or Kaspi, and sling the cargo to Soganlug airbase.', 'NATO' )
|
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Sling Load', 'Operational', 'Fly to the cargo pickup zone at Dzegvi or Kaspi, and sling the cargo to Soganlug airbase.', 'NATO' )
|
||||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical', 'In order to be in full control of the situation, we need you to rescue a secret agent from the woods behind enemy lines. Avoid the Russian defenses and rescue the agent. Keep south until Khasuri, and keep your eyes open for any SAM presence. The agent is located at waypoint 4 on your kneeboard.', 'NATO' )
|
-- local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical', 'In order to be in full control of the situation, we need you to rescue a secret agent from the woods behind enemy lines. Avoid the Russian defenses and rescue the agent. Keep south until Khasuri, and keep your eyes open for any SAM presence. The agent is located at waypoint 4 on your kneeboard.', 'NATO' )
|
||||||
function MISSION:New( MissionName, MissionPriority, MissionBriefing, MissionCoalition )
|
function MISSION:New( MissionName, MissionPriority, MissionBriefing, MissionCoalition )
|
||||||
trace.f(self.ClassName, { MissionName, MissionPriority, MissionBriefing, MissionCoalition } )
|
|
||||||
self = MISSION:Meta()
|
self = MISSION:Meta()
|
||||||
|
self:T({ MissionName, MissionPriority, MissionBriefing, MissionCoalition })
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
@ -83,20 +72,19 @@ trace.f(self.ClassName, { MissionName, MissionPriority, MissionBriefing, Mission
|
|||||||
self.MissionCoalition = MissionCoalition
|
self.MissionCoalition = MissionCoalition
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( self.ClassName, "" )
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns if a Mission has completed.
|
--- Returns if a Mission has completed.
|
||||||
-- @treturn bool
|
-- @treturn bool
|
||||||
function MISSION:IsCompleted()
|
function MISSION:IsCompleted()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
return self.MissionStatus == "ACCOMPLISHED"
|
return self.MissionStatus == "ACCOMPLISHED"
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a Mission to completed.
|
--- Set a Mission to completed.
|
||||||
function MISSION:Completed()
|
function MISSION:Completed()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self.MissionStatus = "ACCOMPLISHED"
|
self.MissionStatus = "ACCOMPLISHED"
|
||||||
self:StatusToClients()
|
self:StatusToClients()
|
||||||
end
|
end
|
||||||
@ -104,27 +92,27 @@ end
|
|||||||
--- Returns if a Mission is ongoing.
|
--- Returns if a Mission is ongoing.
|
||||||
-- treturn bool
|
-- treturn bool
|
||||||
function MISSION:IsOngoing()
|
function MISSION:IsOngoing()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
return self.MissionStatus == "ONGOING"
|
return self.MissionStatus == "ONGOING"
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a Mission to ongoing.
|
--- Set a Mission to ongoing.
|
||||||
function MISSION:Ongoing()
|
function MISSION:Ongoing()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self.MissionStatus = "ONGOING"
|
self.MissionStatus = "ONGOING"
|
||||||
self:StatusToClients()
|
--self:StatusToClients()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns if a Mission is pending.
|
--- Returns if a Mission is pending.
|
||||||
-- treturn bool
|
-- treturn bool
|
||||||
function MISSION:IsPending()
|
function MISSION:IsPending()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
return self.MissionStatus == "PENDING"
|
return self.MissionStatus == "PENDING"
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a Mission to pending.
|
--- Set a Mission to pending.
|
||||||
function MISSION:Pending()
|
function MISSION:Pending()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self.MissionStatus = "PENDING"
|
self.MissionStatus = "PENDING"
|
||||||
self:StatusToClients()
|
self:StatusToClients()
|
||||||
end
|
end
|
||||||
@ -132,31 +120,31 @@ end
|
|||||||
--- Returns if a Mission has failed.
|
--- Returns if a Mission has failed.
|
||||||
-- treturn bool
|
-- treturn bool
|
||||||
function MISSION:IsFailed()
|
function MISSION:IsFailed()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
return self.MissionStatus == "FAILED"
|
return self.MissionStatus == "FAILED"
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a Mission to failed.
|
--- Set a Mission to failed.
|
||||||
function MISSION:Failed()
|
function MISSION:Failed()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self.MissionStatus = "FAILED"
|
self.MissionStatus = "FAILED"
|
||||||
self:StatusToClients()
|
self:StatusToClients()
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Send the status of the MISSION to all Clients.
|
--- Send the status of the MISSION to all Clients.
|
||||||
function MISSION:StatusToClients()
|
function MISSION:StatusToClients()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
if timer.getTime() >= self.MissionReportTrigger then
|
if self.MissionReportFlash then
|
||||||
for ClientID, Client in pairs( self._Clients ) do
|
for ClientID, Client in pairs( self._Clients ) do
|
||||||
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, self.Name .. '/Status', "Mission Command: Mission Status")
|
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, self.Name .. '/Status', "Mission Command: Mission Status")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
trace.e()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Handles the reporting. After certain time intervals, a MISSION report MESSAGE will be shown to All Players.
|
--- Handles the reporting. After certain time intervals, a MISSION report MESSAGE will be shown to All Players.
|
||||||
function MISSION:ReportTrigger()
|
function MISSION:ReportTrigger()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
if self.MissionReportShow == true then
|
if self.MissionReportShow == true then
|
||||||
self.MissionReportShow = false
|
self.MissionReportShow = false
|
||||||
trace.r( "MISSION", "1", { true } )
|
trace.r( "MISSION", "1", { true } )
|
||||||
@ -181,16 +169,17 @@ end
|
|||||||
|
|
||||||
--- Report the status of all MISSIONs to all active Clients.
|
--- Report the status of all MISSIONs to all active Clients.
|
||||||
function MISSION:ReportToAll()
|
function MISSION:ReportToAll()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
local AlivePlayers = ''
|
local AlivePlayers = ''
|
||||||
for ClientID, Client in pairs( self._Clients ) do
|
for ClientID, Client in pairs( self._Clients ) do
|
||||||
if Client:ClientGroup() then
|
if Client:ClientGroup() then
|
||||||
if Client:ClientGroup():getUnit(1) then
|
if Client:GetClientGroupUnit() then
|
||||||
if Client:ClientGroup():getUnit(1):getLife() > 0.0 then
|
if Client:GetClientGroupUnit():getLife() > 0.0 then
|
||||||
if AlivePlayers == '' then
|
if AlivePlayers == '' then
|
||||||
AlivePlayers = ' Players: ' .. Client:ClientGroup():getUnit(1):getPlayerName()
|
AlivePlayers = ' Players: ' .. Client:GetClientGroupUnit():getPlayerName()
|
||||||
else
|
else
|
||||||
AlivePlayers = AlivePlayers .. ' / ' .. Client:ClientGroup():getUnit(1):getPlayerName()
|
AlivePlayers = AlivePlayers .. ' / ' .. Client:GetClientGroupUnit():getPlayerName()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -202,7 +191,6 @@ trace.f(self.ClassName)
|
|||||||
TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n"
|
TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n"
|
||||||
end
|
end
|
||||||
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), "Mission Command: Mission Report", 10, self.Name .. '/Status'):ToAll()
|
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), "Mission Command: Mission Report", 10, self.Name .. '/Status'):ToAll()
|
||||||
trace.e()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -243,27 +231,26 @@ end
|
|||||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Transport Troops', 'Operational', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.', 'NATO' )
|
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Transport Troops', 'Operational', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.', 'NATO' )
|
||||||
-- Mission:AddGoalFunction( DeployPatriotTroopsGoal )
|
-- Mission:AddGoalFunction( DeployPatriotTroopsGoal )
|
||||||
function MISSION:AddGoalFunction( GoalFunction )
|
function MISSION:AddGoalFunction( GoalFunction )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
self.GoalFunction = GoalFunction
|
self.GoalFunction = GoalFunction
|
||||||
trace.e()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Show the briefing of the MISSION to the CLIENT.
|
--- Show the briefing of the MISSION to the CLIENT.
|
||||||
-- @tparam CLIENT Client to show briefing to.
|
-- @tparam CLIENT Client to show briefing to.
|
||||||
-- @treturn CLIENT
|
-- @treturn CLIENT
|
||||||
function MISSION:ShowBriefing( Client )
|
function MISSION:ShowBriefing( Client )
|
||||||
trace.f(self.ClassName, { Client } )
|
self:T( { Client.ClientName } )
|
||||||
|
|
||||||
if not Client.ClientBriefingShown then
|
if not Client.ClientBriefingShown then
|
||||||
Client.ClientBriefingShown = true
|
Client.ClientBriefingShown = true
|
||||||
Client:Message( '(Press the keys [LEFT ALT]+[B] to view the briefing pages. Browse through the graphical briefing.)\n' ..
|
local Briefing = self.MissionBriefing
|
||||||
self.MissionBriefing, 40, self.Name .. '/MissionBriefing', "Mission Command: Mission Briefing" )
|
|
||||||
if Client.ClientBriefing then
|
if Client.ClientBriefing then
|
||||||
Client:Message( Client.ClientBriefing, 40, self.Name .. '/ClientBriefing', "Mission Command: Mission Briefing" )
|
Briefing = Briefing .. "\n" .. Client.ClientBriefing
|
||||||
end
|
end
|
||||||
|
Briefing = Briefing .. "\n (Press [LEFT ALT]+[B] to view the graphical documentation.)"
|
||||||
|
Client:Message( Briefing, 30, self.Name .. '/MissionBriefing', "Command: Mission Briefing" )
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( "", "", { Client } )
|
|
||||||
return Client
|
return Client
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -277,7 +264,7 @@ end
|
|||||||
-- Mission:AddClient( CLIENT:New( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
-- Mission:AddClient( CLIENT:New( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||||
-- Mission:AddClient( CLIENT:New( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
-- Mission:AddClient( CLIENT:New( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||||
function MISSION:AddClient( Client )
|
function MISSION:AddClient( Client )
|
||||||
trace.f(self.ClassName, { Client } )
|
self:T( { Client } )
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
@ -296,8 +283,7 @@ end
|
|||||||
-- -- Seach for Client "Bomber" within the Mission.
|
-- -- Seach for Client "Bomber" within the Mission.
|
||||||
-- local BomberClient = Mission:FindClient( "Bomber" )
|
-- local BomberClient = Mission:FindClient( "Bomber" )
|
||||||
function MISSION:FindClient( ClientName )
|
function MISSION:FindClient( ClientName )
|
||||||
trace.f(self.ClassName)
|
self:T( { self._Clients[ClientName] } )
|
||||||
trace.r( "", "", { self._Clients[ClientName] } )
|
|
||||||
return self._Clients[ClientName]
|
return self._Clients[ClientName]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -328,13 +314,12 @@ end
|
|||||||
-- Mission:AddTask( DeployTask, 2 )
|
-- Mission:AddTask( DeployTask, 2 )
|
||||||
|
|
||||||
function MISSION:AddTask( Task, TaskNumber )
|
function MISSION:AddTask( Task, TaskNumber )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
self._Tasks[TaskNumber] = Task
|
self._Tasks[TaskNumber] = Task
|
||||||
self._Tasks[TaskNumber]:EnableEvents()
|
self._Tasks[TaskNumber]:EnableEvents()
|
||||||
self._Tasks[TaskNumber].ID = TaskNumber
|
self._Tasks[TaskNumber].ID = TaskNumber
|
||||||
|
|
||||||
trace.r( self.ClassName, "" )
|
|
||||||
return Task
|
return Task
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -346,7 +331,7 @@ trace.r( self.ClassName, "" )
|
|||||||
-- Task2 = Mission:GetTask( 2 )
|
-- Task2 = Mission:GetTask( 2 )
|
||||||
|
|
||||||
function MISSION:GetTask( TaskNumber )
|
function MISSION:GetTask( TaskNumber )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
@ -370,51 +355,11 @@ end
|
|||||||
-- Tasks = Mission:GetTasks()
|
-- Tasks = Mission:GetTasks()
|
||||||
-- env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" )
|
-- env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" )
|
||||||
function MISSION:GetTasks()
|
function MISSION:GetTasks()
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
return self._Tasks
|
return self._Tasks
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add Cargo to the mission... Cargo functionality needs to be reworked a bit, so this is still under construction. I need to make a CARGO Class...
|
|
||||||
SpawnCargo = {}
|
|
||||||
function MISSION:AddCargo( CargoName, CargoType, CargoWeight, CargoGroupControlCenter, CargoGroupTemplate, CargoZone )
|
|
||||||
trace.f(self.ClassName, { CargoName, CargoType, CargoWeight, CargoGroupControlCenter, CargoGroupTemplate, CargoZone } )
|
|
||||||
|
|
||||||
local Cargo = {}
|
|
||||||
Cargo.CargoName = CargoName
|
|
||||||
if CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then
|
|
||||||
if not SpawnCargo[CargoGroupTemplate] then
|
|
||||||
SpawnCargo[CargoGroupTemplate] = SPAWN:New( CargoGroupTemplate )
|
|
||||||
end
|
|
||||||
if CargoGroupControlCenter == nil then
|
|
||||||
--- @todo check this
|
|
||||||
Cargo.CargoGroupName = SpawnCargo[CargoGroupTemplate]:InZone( CargoZone ).name
|
|
||||||
else
|
|
||||||
--- @todo check this
|
|
||||||
env.info( "SpawnFromCarrier")
|
|
||||||
Cargo.CargoGroupName = SpawnCargo[CargoGroupTemplate]:FromCarrier( Group.getByName( CargoGroupControlCenter ), CargoZone, nil, true ).name
|
|
||||||
--trigger.action.activateGroup( Group.getByName( Cargo.CargoGroupName ) )
|
|
||||||
--trigger.action.setGroupAIOff( Cargo.CargoGroupName )
|
|
||||||
trace.i( self.ClassName, Cargo.CargoGroupName )
|
|
||||||
|
|
||||||
end
|
|
||||||
else
|
|
||||||
Cargo.CargoGroupName = CargoGroupControlCenter
|
|
||||||
end
|
|
||||||
Cargo.CargoType = CargoType
|
|
||||||
Cargo.CargoWeight = CargoWeight
|
|
||||||
Cargo.CargoGroupControlCenter = CargoGroupControlCenter
|
|
||||||
Cargo.CargoGroupTemplate = CargoGroupTemplate
|
|
||||||
Cargo.CargoZone = CargoZone
|
|
||||||
Cargo.Status = CARGOSTATUS.NONE
|
|
||||||
self._Cargos[CargoName] = Cargo
|
|
||||||
|
|
||||||
trace.r( self.ClassName, "AddCargo", { Cargo.CargoGroupName } )
|
|
||||||
return Cargo.CargoGroupName
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
_TransportExecuteStage: Defines the different stages of Transport unload/load execution. This table is internal and is used to control the validity of Transport load/unload timing.
|
_TransportExecuteStage: Defines the different stages of Transport unload/load execution. This table is internal and is used to control the validity of Transport load/unload timing.
|
||||||
@ -450,6 +395,8 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler")
|
|||||||
|
|
||||||
-- loop through the missions in the TransportTasks
|
-- loop through the missions in the TransportTasks
|
||||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||||
|
|
||||||
|
trace.i( "MISSIONSCHEDULER", MissionName )
|
||||||
|
|
||||||
if not Mission:IsCompleted() then
|
if not Mission:IsCompleted() then
|
||||||
|
|
||||||
@ -457,8 +404,10 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler")
|
|||||||
local ClientsAlive = false
|
local ClientsAlive = false
|
||||||
|
|
||||||
for ClientID, Client in pairs( Mission._Clients ) do
|
for ClientID, Client in pairs( Mission._Clients ) do
|
||||||
|
|
||||||
|
trace.i( "MISSIONSCHEDULER", "Client: " .. Client.ClientName )
|
||||||
|
|
||||||
if Client:ClientGroup() and Client:ClientGroup():getUnits() and Client:ClientGroup():getUnits()[1] and Client:ClientGroup():getUnits()[1]:getLife() > 0.0 then
|
if Client:ClientGroup() then
|
||||||
|
|
||||||
-- There is at least one Client that is alive... So the Mission status is set to Ongoing.
|
-- There is at least one Client that is alive... So the Mission status is set to Ongoing.
|
||||||
ClientsAlive = true
|
ClientsAlive = true
|
||||||
@ -476,13 +425,10 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler")
|
|||||||
Client._Tasks[TaskNumber] = routines.utils.deepCopy( Mission._Tasks[TaskNumber] )
|
Client._Tasks[TaskNumber] = routines.utils.deepCopy( Mission._Tasks[TaskNumber] )
|
||||||
-- Each MissionTask must point to the original Mission.
|
-- Each MissionTask must point to the original Mission.
|
||||||
Client._Tasks[TaskNumber].MissionTask = Mission._Tasks[TaskNumber]
|
Client._Tasks[TaskNumber].MissionTask = Mission._Tasks[TaskNumber]
|
||||||
|
Client._Tasks[TaskNumber].Cargos = Mission._Tasks[TaskNumber].Cargos
|
||||||
|
Client._Tasks[TaskNumber].LandingZones = Mission._Tasks[TaskNumber].LandingZones
|
||||||
end
|
end
|
||||||
Client._Cargos = {}
|
|
||||||
if Client.InitCargoNames then
|
|
||||||
for InitCargoID, InitCargoName in pairs( Client.InitCargoNames ) do
|
|
||||||
Client._Cargos[InitCargoName] = Mission._Cargos[InitCargoName]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Mission:Ongoing()
|
Mission:Ongoing()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -524,6 +470,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler")
|
|||||||
end
|
end
|
||||||
|
|
||||||
if Task:IsDone() then
|
if Task:IsDone() then
|
||||||
|
trace.i( "MISSIONSCHEDULER", "Task " .. Task.Name .. " is Done." )
|
||||||
--env.info( 'Scheduler: Mission '.. Mission.Name .. ' Task ' .. Task.Name .. ' Stage ' .. Task.Stage.Name .. ' done. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
--env.info( 'Scheduler: Mission '.. Mission.Name .. ' Task ' .. Task.Name .. ' Stage ' .. Task.Stage.Name .. ' done. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||||
TaskComplete = true -- when a task is not yet completed, a mission cannot be completed
|
TaskComplete = true -- when a task is not yet completed, a mission cannot be completed
|
||||||
|
|
||||||
@ -539,7 +486,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler")
|
|||||||
if Mission.GoalFunction ~= nil then
|
if Mission.GoalFunction ~= nil then
|
||||||
Mission.GoalFunction( Mission, Client )
|
Mission.GoalFunction( Mission, Client )
|
||||||
end
|
end
|
||||||
_Database:_AddMissionTaskScore( Client:ClientGroup():getUnit(1), Mission.Name, 25 )
|
_Database:_AddMissionTaskScore( Client:GetClientGroupUnit(), Mission.Name, 25 )
|
||||||
|
|
||||||
-- if not Mission:IsCompleted() then
|
-- if not Mission:IsCompleted() then
|
||||||
-- end
|
-- end
|
||||||
@ -580,9 +527,6 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler")
|
|||||||
-- So first sanitize Client._Tasks[TaskNumber].MissionTask, after that, sanitize only the whole _Tasks structure...
|
-- So first sanitize Client._Tasks[TaskNumber].MissionTask, after that, sanitize only the whole _Tasks structure...
|
||||||
--Client._Tasks[TaskNumber].MissionTask = nil
|
--Client._Tasks[TaskNumber].MissionTask = nil
|
||||||
--Client._Tasks = nil
|
--Client._Tasks = nil
|
||||||
|
|
||||||
-- Sanitize the Client._Cargos. Any cargo within the Client will be lost when the client crashes. This is an important statement.
|
|
||||||
Client._Cargos = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -20,61 +20,61 @@ MOVEMENT = {
|
|||||||
-- Movement_US_Platoons = MOVEMENT:New( { 'US Tank Platoon Left', 'US Tank Platoon Middle', 'US Tank Platoon Right', 'US CH-47D Troops' }, 15 )
|
-- Movement_US_Platoons = MOVEMENT:New( { 'US Tank Platoon Left', 'US Tank Platoon Middle', 'US Tank Platoon Right', 'US CH-47D Troops' }, 15 )
|
||||||
|
|
||||||
function MOVEMENT:New( MovePrefixes, MoveMaximum )
|
function MOVEMENT:New( MovePrefixes, MoveMaximum )
|
||||||
trace.f(self.ClassName, { MovePrefixes, MoveMaximum } )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T( { MovePrefixes, MoveMaximum } )
|
||||||
-- Inherits from BASE
|
|
||||||
local Child = BASE:Inherit( self, BASE:New() )
|
|
||||||
|
|
||||||
if type( MovePrefixes ) == 'table' then
|
if type( MovePrefixes ) == 'table' then
|
||||||
Child.MovePrefixes = MovePrefixes
|
self.MovePrefixes = MovePrefixes
|
||||||
else
|
else
|
||||||
Child.MovePrefixes = { MovePrefixes }
|
self.MovePrefixes = { MovePrefixes }
|
||||||
end
|
end
|
||||||
Child.MoveCount = 0 -- The internal counter of the amount of Moveing the has happened since MoveStart.
|
self.MoveCount = 0 -- The internal counter of the amount of Moveing the has happened since MoveStart.
|
||||||
Child.MoveMaximum = MoveMaximum -- Contains the Maximum amount of units that are allowed to move...
|
self.MoveMaximum = MoveMaximum -- Contains the Maximum amount of units that are allowed to move...
|
||||||
Child.AliveUnits = 0 -- Contains the counter how many units are currently alive
|
self.AliveUnits = 0 -- Contains the counter how many units are currently alive
|
||||||
Child.MoveGroups = {} -- Reflects if the Moveing for this MovePrefixes is going to be scheduled or not.
|
self.MoveUnits = {} -- Reflects if the Moving for this MovePrefixes is going to be scheduled or not.
|
||||||
|
|
||||||
Child.AddEvent( Child, world.event.S_EVENT_BIRTH, Child.OnBirth )
|
self.AddEvent( self, world.event.S_EVENT_BIRTH, self.OnBirth )
|
||||||
Child.AddEvent( Child, world.event.S_EVENT_DEAD, Child.OnDeadOrCrash )
|
self.AddEvent( self, world.event.S_EVENT_DEAD, self.OnDeadOrCrash )
|
||||||
Child.AddEvent( Child, world.event.S_EVENT_CRASH, Child.OnDeadOrCrash )
|
self.AddEvent( self, world.event.S_EVENT_CRASH, self.OnDeadOrCrash )
|
||||||
|
|
||||||
Child.EnableEvents( Child )
|
self.EnableEvents( self )
|
||||||
|
|
||||||
Child.ScheduleStart( Child )
|
self.ScheduleStart( self )
|
||||||
|
|
||||||
return Child
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Call this function to start the MOVEMENT scheduling.
|
--- Call this function to start the MOVEMENT scheduling.
|
||||||
function MOVEMENT:ScheduleStart()
|
function MOVEMENT:ScheduleStart()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
self.MoveFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, 120 )
|
self.MoveFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, 120 )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Call this function to stop the MOVEMENT scheduling.
|
--- Call this function to stop the MOVEMENT scheduling.
|
||||||
-- @todo need to implement it ... Forgot.
|
-- @todo need to implement it ... Forgot.
|
||||||
function MOVEMENT:ScheduleStop()
|
function MOVEMENT:ScheduleStop()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Captures the birth events when new Units were spawned.
|
--- Captures the birth events when new Units were spawned.
|
||||||
-- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration.
|
-- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration.
|
||||||
function MOVEMENT:OnBirth( event )
|
function MOVEMENT:OnBirth( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
|
if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
||||||
trace.l(self.ClassName, "OnBirth", "Birth object : " .. event.initiator:getName() )
|
local MovementUnit = event.initiator
|
||||||
local GroupData = Unit.getGroup(event.initiator)
|
local MovementUnitName = MovementUnit:getName()
|
||||||
if GroupData and GroupData:isExist() then
|
self:T( "Birth object : " .. MovementUnitName )
|
||||||
local EventGroupName = GroupData:getName()
|
local MovementGroup = MovementUnit:getGroup()
|
||||||
|
if MovementGroup and MovementGroup:isExist() then
|
||||||
|
local MovementGroupName = MovementGroup:getName()
|
||||||
for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do
|
for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do
|
||||||
if string.find( EventGroupName, MovePrefix, 1, true ) then
|
if string.find( MovementUnitName, MovePrefix, 1, true ) then
|
||||||
self.AliveUnits = self.AliveUnits + 1
|
self.AliveUnits = self.AliveUnits + 1
|
||||||
self.MoveGroups[EventGroupName] = EventGroupName
|
self.MoveUnits[MovementUnitName] = MovementGroupName
|
||||||
trace.l(self.ClassName, "OnBirth", self.AliveUnits )
|
self:T( self.AliveUnits )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -86,16 +86,17 @@ end
|
|||||||
--- Captures the Dead or Crash events when Units crash or are destroyed.
|
--- Captures the Dead or Crash events when Units crash or are destroyed.
|
||||||
-- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration.
|
-- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration.
|
||||||
function MOVEMENT:OnDeadOrCrash( event )
|
function MOVEMENT:OnDeadOrCrash( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then
|
||||||
trace.l( self.ClassName, "OnDeadOrCrash", "Dead object : " .. event.initiator:getName() )
|
local MovementUnit = event.initiator
|
||||||
local EventGroupName = Unit.getGroup(event.initiator):getName()
|
local MovementUnitName = MovementUnit:getName()
|
||||||
|
self:T( "Dead object : " .. MovementUnitName )
|
||||||
for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do
|
for MovePrefixID, MovePrefix in pairs( self.MovePrefixes ) do
|
||||||
if string.find( EventGroupName, MovePrefix, 1, true ) then
|
if string.find( MovementUnitName, MovePrefix, 1, true ) then
|
||||||
self.AliveUnits = self.AliveUnits - 1
|
self.AliveUnits = self.AliveUnits - 1
|
||||||
self.MoveGroups[EventGroupName] = nil
|
self.MoveUnits[MovementUnitName] = nil
|
||||||
trace.l( self.ClassName, "OnDeadOrCrash", self.AliveUnits )
|
self:T( self.AliveUnits )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -103,24 +104,26 @@ end
|
|||||||
|
|
||||||
--- This function is called automatically by the MOVEMENT scheduler. A new function is scheduled when MoveScheduled is true.
|
--- This function is called automatically by the MOVEMENT scheduler. A new function is scheduled when MoveScheduled is true.
|
||||||
function MOVEMENT:_Scheduler()
|
function MOVEMENT:_Scheduler()
|
||||||
trace.l( self.ClassName, '_Scheduler', { self.MovePrefixes, self.MoveMaximum, self.AliveUnits, self.MoveGroups } )
|
self:T( { self.MovePrefixes, self.MoveMaximum, self.AliveUnits, self.MovementGroups } )
|
||||||
|
|
||||||
if self.AliveUnits > 0 then
|
if self.AliveUnits > 0 then
|
||||||
local MoveProbability = ( self.MoveMaximum * 100 ) / self.AliveUnits
|
local MoveProbability = ( self.MoveMaximum * 100 ) / self.AliveUnits
|
||||||
trace.l( self.ClassName, '_Scheduler', 'Move Probability = ' .. MoveProbability )
|
self:T( 'Move Probability = ' .. MoveProbability )
|
||||||
|
|
||||||
for MoveGroupID, MoveGroupName in pairs( self.MoveGroups ) do
|
for MovementUnitName, MovementGroupName in pairs( self.MoveUnits ) do
|
||||||
local MoveGroup = Group.getByName( MoveGroupName )
|
local MovementGroup = Group.getByName( MovementGroupName )
|
||||||
if MoveGroup then
|
if MovementGroup and MovementGroup:isExist() then
|
||||||
local MoveOrStop = math.random( 1, 100 )
|
local MoveOrStop = math.random( 1, 100 )
|
||||||
trace.l( self.ClassName, '_Scheduler', 'MoveOrStop = ' .. MoveOrStop )
|
self:T( 'MoveOrStop = ' .. MoveOrStop )
|
||||||
if MoveOrStop <= MoveProbability then
|
if MoveOrStop <= MoveProbability then
|
||||||
trace.l( self.ClassName, '_Scheduler', 'Group continues moving = ' .. MoveGroupName )
|
self:T( 'Group continues moving = ' .. MovementGroupName )
|
||||||
trigger.action.groupContinueMoving( MoveGroup )
|
trigger.action.groupContinueMoving( MovementGroup )
|
||||||
else
|
else
|
||||||
trace.l( self.ClassName, '_Scheduler', 'Group stops moving = ' .. MoveGroupName )
|
self:T( 'Group stops moving = ' .. MovementGroupName )
|
||||||
trigger.action.groupStopMoving( MoveGroup )
|
trigger.action.groupStopMoving( MovementGroup )
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
self.MoveUnits[MovementUnitName] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
-- @parent TASK
|
-- @parent TASK
|
||||||
|
|
||||||
Include.File("Task")
|
Include.File("Task")
|
||||||
|
Include.File("Cargo")
|
||||||
|
|
||||||
PICKUPTASK = {
|
PICKUPTASK = {
|
||||||
ClassName = "PICKUPTASK",
|
ClassName = "PICKUPTASK",
|
||||||
@ -14,87 +15,103 @@ PICKUPTASK = {
|
|||||||
-- @tparam table{string,...}|string LandingZones Table of Zone names where Cargo is to be loaded.
|
-- @tparam table{string,...}|string LandingZones Table of Zone names where Cargo is to be loaded.
|
||||||
-- @tparam CARGO_TYPE CargoType Type of the Cargo. The type must be of the following Enumeration:..
|
-- @tparam CARGO_TYPE CargoType Type of the Cargo. The type must be of the following Enumeration:..
|
||||||
-- @tparam number OnBoardSide Reflects from which side the cargo Group will be on-boarded on the Carrier.
|
-- @tparam number OnBoardSide Reflects from which side the cargo Group will be on-boarded on the Carrier.
|
||||||
function PICKUPTASK:New( LandingZones, CargoType, OnBoardSide )
|
function PICKUPTASK:New( CargoType, OnBoardSide )
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, TASK:New() )
|
||||||
|
self:T()
|
||||||
|
|
||||||
-- Child holds the inherited instance of the PICKUPTASK Class to the BASE class.
|
-- self holds the inherited instance of the PICKUPTASK Class to the BASE class.
|
||||||
local Child = BASE:Inherit( self, TASK:New() )
|
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
Valid = routines.ValidateZone( LandingZones, "LandingZones", Valid )
|
|
||||||
Valid = routines.ValidateEnumeration( CargoType, "CargoType", CARGO_TYPE, Valid )
|
|
||||||
Valid = routines.ValidateEnumeration( CargoType, "CargoType", CARGO_TYPE, Valid )
|
|
||||||
--Valid = routines.ValidateEnumeration( OnBoardSide, "OnBoardSide", CLIENT.ONBOARDSIDE, Valid )
|
|
||||||
|
|
||||||
if Valid then
|
if Valid then
|
||||||
Child.Name = 'Pickup Cargo'
|
self.Name = 'Pickup Cargo'
|
||||||
Child.TaskBriefing = "Task: Fly to the indicated landing zones and pickup " .. CargoType.TEXT .. ". Your co-pilot will provide you with the directions (required flight angle in degrees) and the distance (in km) to the pickup zone."
|
self.TaskBriefing = "Task: Fly to the indicated landing zones and pickup " .. CargoType .. ". Your co-pilot will provide you with the directions (required flight angle in degrees) and the distance (in km) to the pickup zone."
|
||||||
if type( LandingZones ) == "table" then
|
self.CargoType = CargoType
|
||||||
Child.LandingZones = LandingZones
|
self.GoalVerb = CargoType .. " " .. self.GoalVerb
|
||||||
else
|
self.OnBoardSide = OnBoardSide
|
||||||
Child.LandingZones = { LandingZones }
|
self.IsLandingRequired = false -- required to decide whether the client needs to land or not
|
||||||
end
|
self.IsSlingLoad = false -- Indicates whether the cargo is a sling load cargo
|
||||||
Child.CargoType = CargoType
|
self.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGELOAD:New(), STAGEDONE:New() }
|
||||||
Child.GoalVerb = CargoType.TEXT .. " " .. Child.GoalVerb
|
self.SetStage( self, 1 )
|
||||||
Child.OnBoardSide = OnBoardSide
|
|
||||||
Child.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGELOAD:New(), STAGEDONE:New() }
|
|
||||||
Child.SetStage( Child, 1 )
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return Child
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function PICKUPTASK:FromZone( LandingZone )
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
self.LandingZones.LandingZoneNames[LandingZone.CargoZoneName] = LandingZone.CargoZoneName
|
||||||
|
self.LandingZones.LandingZones[LandingZone.CargoZoneName] = LandingZone
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function PICKUPTASK:InitCargo( InitCargos )
|
||||||
|
self:T( { InitCargos } )
|
||||||
|
|
||||||
|
if type( InitCargos ) == "table" then
|
||||||
|
self.Cargos.InitCargos = InitCargos
|
||||||
|
else
|
||||||
|
self.Cargos.InitCargos = { InitCargos }
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function PICKUPTASK:LoadCargo( LoadCargos )
|
||||||
|
self:T( { LoadCargos } )
|
||||||
|
|
||||||
|
if type( LoadCargos ) == "table" then
|
||||||
|
self.Cargos.LoadCargos = LoadCargos
|
||||||
|
else
|
||||||
|
self.Cargos.LoadCargos = { LoadCargos }
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function PICKUPTASK:AddCargoMenus( Client, Cargos, TransportRadius )
|
function PICKUPTASK:AddCargoMenus( Client, Cargos, TransportRadius )
|
||||||
trace.f(self.ClassName, { Client, Cargos, TransportRadius } )
|
self:T()
|
||||||
|
|
||||||
for CargoID, CargoData in pairs( Cargos ) do
|
for CargoID, Cargo in pairs( Cargos ) do
|
||||||
|
|
||||||
if CargoData.Status ~= CARGOSTATUS.LOADED and CargoData.Status ~= CARGOSTATUS.LOADING then
|
self:T( { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } )
|
||||||
|
|
||||||
if Group.getByName( CargoData.CargoGroupName ) then
|
-- If the Cargo has no status, allow the menu option.
|
||||||
|
if Cargo:IsStatusNone() or ( Cargo:IsStatusLoading() and Client == Cargo:IsLoadingToClient() ) then
|
||||||
|
|
||||||
|
local MenuAdd = false
|
||||||
|
if Cargo:IsNear( Client, self.CurrentCargoZone ) then
|
||||||
|
MenuAdd = true
|
||||||
|
end
|
||||||
|
|
||||||
if Group.getByName( CargoData.CargoGroupName ):getSize() >= 1 then
|
if MenuAdd then
|
||||||
|
if Client._Menus[Cargo.CargoType] == nil then
|
||||||
if Client._Menus[CargoData.CargoType] == nil then
|
Client._Menus[Cargo.CargoType] = {}
|
||||||
Client._Menus[CargoData.CargoType] = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
if not Client._Menus[CargoData.CargoType].PickupMenu then
|
|
||||||
Client._Menus[CargoData.CargoType].PickupMenu = missionCommands.addSubMenuForGroup(
|
|
||||||
Client:ClientGroup():getID(),
|
|
||||||
self.TEXT[1],
|
|
||||||
nil
|
|
||||||
)
|
|
||||||
trace.i( self.ClassName, 'Added PickupMenu' .. self.TEXT[1] )
|
|
||||||
end
|
|
||||||
|
|
||||||
if Client._Menus[CargoData.CargoType].PickupSubMenus == nil then
|
|
||||||
Client._Menus[CargoData.CargoType].PickupSubMenus = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local MenuAdd = false
|
|
||||||
if CargoData.CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then
|
|
||||||
CargoGroup = Group.getByName( CargoData.CargoGroupName )
|
|
||||||
if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientGroup(), TransportRadius ) then
|
|
||||||
MenuAdd = true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
MenuAdd = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if MenuAdd then
|
|
||||||
Client._Menus[CargoData.CargoType].PickupSubMenus[ #Client._Menus[CargoData.CargoType].PickupSubMenus + 1 ] = missionCommands.addCommandForGroup(
|
|
||||||
Client:ClientGroup():getID(),
|
|
||||||
CargoData.CargoName .. " ( " .. CargoData.CargoWeight .. "kg )",
|
|
||||||
Client._Menus[CargoData.CargoType].PickupMenu,
|
|
||||||
self.MenuAction,
|
|
||||||
{ ReferenceTask = self, CargoName = CargoData.CargoName }
|
|
||||||
)
|
|
||||||
trace.i( self.ClassName, 'Added PickupSubMenu' .. CargoData.CargoType.TEXT .. ":" .. CargoData.CargoName .. " ( " .. CargoData.CargoWeight .. "kg )" )
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not Client._Menus[Cargo.CargoType].PickupMenu then
|
||||||
|
Client._Menus[Cargo.CargoType].PickupMenu = missionCommands.addSubMenuForGroup(
|
||||||
|
Client:GetClientGroupID(),
|
||||||
|
self.TEXT[1] .. " " .. Cargo.CargoType,
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
self:T( 'Added PickupMenu: ' .. self.TEXT[1] .. " " .. Cargo.CargoType )
|
||||||
|
end
|
||||||
|
|
||||||
|
if Client._Menus[Cargo.CargoType].PickupSubMenus == nil then
|
||||||
|
Client._Menus[Cargo.CargoType].PickupSubMenus = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
Client._Menus[Cargo.CargoType].PickupSubMenus[ #Client._Menus[Cargo.CargoType].PickupSubMenus + 1 ] = missionCommands.addCommandForGroup(
|
||||||
|
Client:GetClientGroupID(),
|
||||||
|
Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )",
|
||||||
|
Client._Menus[Cargo.CargoType].PickupMenu,
|
||||||
|
self.MenuAction,
|
||||||
|
{ ReferenceTask = self, CargoTask = Cargo }
|
||||||
|
)
|
||||||
|
self:T( 'Added PickupSubMenu' .. Cargo.CargoType .. ":" .. Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -102,103 +119,36 @@ trace.f(self.ClassName, { Client, Cargos, TransportRadius } )
|
|||||||
end
|
end
|
||||||
|
|
||||||
function PICKUPTASK:RemoveCargoMenus( Client )
|
function PICKUPTASK:RemoveCargoMenus( Client )
|
||||||
trace.f(self.ClassName, { Client } )
|
self:T()
|
||||||
|
|
||||||
for MenuID, MenuData in pairs( Client._Menus ) do
|
for MenuID, MenuData in pairs( Client._Menus ) do
|
||||||
for SubMenuID, SubMenuData in pairs( MenuData.PickupSubMenus ) do
|
for SubMenuID, SubMenuData in pairs( MenuData.PickupSubMenus ) do
|
||||||
missionCommands.removeItemForGroup( Client:ClientGroup():getID(), SubMenuData )
|
missionCommands.removeItemForGroup( Client:GetClientGroupID(), SubMenuData )
|
||||||
trace.i( self.ClassName, "Removed PickupSubMenu " )
|
self:T( "Removed PickupSubMenu " )
|
||||||
SubMenuData = nil
|
SubMenuData = nil
|
||||||
end
|
end
|
||||||
if MenuData.PickupMenu then
|
if MenuData.PickupMenu then
|
||||||
missionCommands.removeItemForGroup( Client:ClientGroup():getID(), MenuData.PickupMenu )
|
missionCommands.removeItemForGroup( Client:GetClientGroupID(), MenuData.PickupMenu )
|
||||||
trace.i( self.ClassName, "Removed PickupMenu " )
|
self:T( "Removed PickupMenu " )
|
||||||
MenuData.PickupMenu = nil
|
MenuData.PickupMenu = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for CargoID, Cargo in pairs( CARGOS ) do
|
||||||
|
self:T( { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } )
|
||||||
|
if Cargo:IsStatusLoading() and Client == Cargo:IsLoadingToClient() then
|
||||||
|
Cargo:StatusNone()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function PICKUPTASK:HasFailed( ClientDead )
|
function PICKUPTASK:HasFailed( ClientDead )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
local TaskHasFailed = self.TaskFailed
|
local TaskHasFailed = self.TaskFailed
|
||||||
return TaskHasFailed
|
return TaskHasFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
function PICKUPTASK:OnBoardCargo( ClientGroup, Cargos )
|
|
||||||
trace.f(self.ClassName, { ClientGroup, Cargos } )
|
|
||||||
|
|
||||||
local Valid = true
|
|
||||||
|
|
||||||
Valid = routines.ValidateGroup( ClientGroup, "ClientGroup", Valid )
|
|
||||||
|
|
||||||
if Valid then
|
|
||||||
|
|
||||||
local CarrierPos = ClientGroup:getUnits()[1]:getPoint()
|
|
||||||
local CarrierPosMove = ClientGroup:getUnits()[1]:getPoint()
|
|
||||||
local CarrierPosOnBoard = ClientGroup:getUnits()[1]:getPoint()
|
|
||||||
|
|
||||||
local CargoGroup = Group.getByName( Cargos[ self.CargoName ].CargoGroupName )
|
|
||||||
trigger.action.activateGroup( CargoGroup )
|
|
||||||
trigger.action.setGroupAIOn( CargoGroup )
|
|
||||||
|
|
||||||
local CargoUnits = CargoGroup:getUnits()
|
|
||||||
local CargoPos = CargoUnits[1]:getPoint()
|
|
||||||
|
|
||||||
|
|
||||||
local Points = {}
|
|
||||||
|
|
||||||
trace.i( self.ClassName, 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z )
|
|
||||||
trace.i( self.ClassName, 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z )
|
|
||||||
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CargoPos, "off road", 6 )
|
|
||||||
|
|
||||||
trace.i( self.ClassName, 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y )
|
|
||||||
|
|
||||||
if self.OnBoardSide == nil then
|
|
||||||
self.OnBoardSide = CLIENT.ONBOARDSIDE.NONE
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then
|
|
||||||
trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding LEFT" )
|
|
||||||
CarrierPosMove.z = CarrierPosMove.z - 50
|
|
||||||
CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "diamond", 6 )
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "diamond", 6 )
|
|
||||||
elseif self.OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then
|
|
||||||
trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding RIGHT" )
|
|
||||||
CarrierPosMove.z = CarrierPosMove.z + 50
|
|
||||||
CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "diamond", 6 )
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "diamond", 6 )
|
|
||||||
elseif self.OnBoardSide == CLIENT.ONBOARDSIDE.BACK then
|
|
||||||
trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding BACK" )
|
|
||||||
CarrierPosMove.x = CarrierPosMove.x - 50
|
|
||||||
CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "diamond", 6 )
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "diamond", 6 )
|
|
||||||
elseif self.OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then
|
|
||||||
trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" )
|
|
||||||
CarrierPosMove.x = CarrierPosMove.x + 50
|
|
||||||
CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "diamond", 6 )
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "diamond", 6 )
|
|
||||||
elseif self.OnBoardSide == CLIENT.ONBOARDSIDE.NONE then
|
|
||||||
trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding CENTRAL" )
|
|
||||||
Points[#Points+1] = routines.ground.buildWP( CarrierPos, "diamond", 6 )
|
|
||||||
end
|
|
||||||
trace.i( self.ClassName, "TransportCargoOnBoard: Routing " .. Cargos[ self.CargoName ].CargoGroupName )
|
|
||||||
|
|
||||||
trace.i( self.ClassName, 'Points[2] x = ' .. Points[2].x .. " y = " .. Points[2].y )
|
|
||||||
trace.i( self.ClassName, 'Points[3] x = ' .. Points[3].x .. " y = " .. Points[3].y )
|
|
||||||
|
|
||||||
routines.scheduleFunction(routines.goRoute, {Cargos[ self.CargoName ].CargoGroupName, Points}, timer.getTime() + 8)
|
|
||||||
--routines.goRoute( Cargos[ self.CargoName ].CargoGroupName, Points )
|
|
||||||
end
|
|
||||||
|
|
||||||
return Valid
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
@ -25,6 +25,107 @@ routines.build = 22
|
|||||||
-- Utils- conversion, Lua utils, etc.
|
-- Utils- conversion, Lua utils, etc.
|
||||||
routines.utils = {}
|
routines.utils = {}
|
||||||
|
|
||||||
|
--from http://lua-users.org/wiki/CopyTable
|
||||||
|
routines.utils.deepCopy = function(object)
|
||||||
|
local lookup_table = {}
|
||||||
|
local function _copy(object)
|
||||||
|
if type(object) ~= "table" then
|
||||||
|
return object
|
||||||
|
elseif lookup_table[object] then
|
||||||
|
return lookup_table[object]
|
||||||
|
end
|
||||||
|
local new_table = {}
|
||||||
|
lookup_table[object] = new_table
|
||||||
|
for index, value in pairs(object) do
|
||||||
|
new_table[_copy(index)] = _copy(value)
|
||||||
|
end
|
||||||
|
return setmetatable(new_table, getmetatable(object))
|
||||||
|
end
|
||||||
|
local objectreturn = _copy(object)
|
||||||
|
return objectreturn
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- porting in Slmod's serialize_slmod2
|
||||||
|
routines.utils.oneLineSerialize = function(tbl) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
||||||
|
|
||||||
|
lookup_table = {}
|
||||||
|
|
||||||
|
local function _Serialize( tbl )
|
||||||
|
|
||||||
|
if type(tbl) == 'table' then --function only works for tables!
|
||||||
|
|
||||||
|
if lookup_table[tbl] then
|
||||||
|
return lookup_table[object]
|
||||||
|
end
|
||||||
|
|
||||||
|
local tbl_str = {}
|
||||||
|
|
||||||
|
lookup_table[tbl] = tbl_str
|
||||||
|
|
||||||
|
tbl_str[#tbl_str + 1] = '{'
|
||||||
|
|
||||||
|
for ind,val in pairs(tbl) do -- serialize its fields
|
||||||
|
if type(ind) == "number" then
|
||||||
|
tbl_str[#tbl_str + 1] = '['
|
||||||
|
tbl_str[#tbl_str + 1] = tostring(ind)
|
||||||
|
tbl_str[#tbl_str + 1] = ']='
|
||||||
|
else --must be a string
|
||||||
|
tbl_str[#tbl_str + 1] = '['
|
||||||
|
tbl_str[#tbl_str + 1] = routines.utils.basicSerialize(ind)
|
||||||
|
tbl_str[#tbl_str + 1] = ']='
|
||||||
|
end
|
||||||
|
|
||||||
|
if ((type(val) == 'number') or (type(val) == 'boolean')) then
|
||||||
|
tbl_str[#tbl_str + 1] = tostring(val)
|
||||||
|
tbl_str[#tbl_str + 1] = ','
|
||||||
|
elseif type(val) == 'string' then
|
||||||
|
tbl_str[#tbl_str + 1] = routines.utils.basicSerialize(val)
|
||||||
|
tbl_str[#tbl_str + 1] = ','
|
||||||
|
elseif type(val) == 'nil' then -- won't ever happen, right?
|
||||||
|
tbl_str[#tbl_str + 1] = 'nil,'
|
||||||
|
elseif type(val) == 'table' then
|
||||||
|
if ind == "__index" then
|
||||||
|
tbl_str[#tbl_str + 1] = "__index"
|
||||||
|
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||||
|
else
|
||||||
|
|
||||||
|
tbl_str[#tbl_str + 1] = _Serialize(val)
|
||||||
|
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||||
|
end
|
||||||
|
elseif type(val) == 'function' then
|
||||||
|
tbl_str[#tbl_str + 1] = "function " .. tostring(ind)
|
||||||
|
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
||||||
|
else
|
||||||
|
env.info('unable to serialize value type ' .. routines.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind))
|
||||||
|
env.info( debug.traceback() )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
tbl_str[#tbl_str + 1] = '}'
|
||||||
|
return table.concat(tbl_str)
|
||||||
|
else
|
||||||
|
return tostring(tbl)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local objectreturn = _Serialize(tbl)
|
||||||
|
return objectreturn
|
||||||
|
end
|
||||||
|
|
||||||
|
--porting in Slmod's "safestring" basic serialize
|
||||||
|
routines.utils.basicSerialize = function(s)
|
||||||
|
if s == nil then
|
||||||
|
return "\"\""
|
||||||
|
else
|
||||||
|
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'table') or (type(s) == 'userdata') ) then
|
||||||
|
return tostring(s)
|
||||||
|
elseif type(s) == 'string' then
|
||||||
|
s = string.format('%q', s)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
routines.utils.toDegree = function(angle)
|
routines.utils.toDegree = function(angle)
|
||||||
@ -137,91 +238,6 @@ function routines.utils.get3DDist(point1, point2)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--from http://lua-users.org/wiki/CopyTable
|
|
||||||
routines.utils.deepCopy = function(object)
|
|
||||||
local lookup_table = {}
|
|
||||||
local function _copy(object)
|
|
||||||
if type(object) ~= "table" then
|
|
||||||
return object
|
|
||||||
elseif lookup_table[object] then
|
|
||||||
return lookup_table[object]
|
|
||||||
end
|
|
||||||
local new_table = {}
|
|
||||||
lookup_table[object] = new_table
|
|
||||||
for index, value in pairs(object) do
|
|
||||||
new_table[_copy(index)] = _copy(value)
|
|
||||||
end
|
|
||||||
return setmetatable(new_table, getmetatable(object))
|
|
||||||
end
|
|
||||||
local objectreturn = _copy(object)
|
|
||||||
return objectreturn
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- porting in Slmod's serialize_slmod2
|
|
||||||
routines.utils.oneLineSerialize = function(tbl) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
|
|
||||||
if type(tbl) == 'table' then --function only works for tables!
|
|
||||||
|
|
||||||
local tbl_str = {}
|
|
||||||
|
|
||||||
tbl_str[#tbl_str + 1] = '{'
|
|
||||||
|
|
||||||
for ind,val in pairs(tbl) do -- serialize its fields
|
|
||||||
if type(ind) == "number" then
|
|
||||||
tbl_str[#tbl_str + 1] = '['
|
|
||||||
tbl_str[#tbl_str + 1] = tostring(ind)
|
|
||||||
tbl_str[#tbl_str + 1] = ']='
|
|
||||||
else --must be a string
|
|
||||||
tbl_str[#tbl_str + 1] = '['
|
|
||||||
tbl_str[#tbl_str + 1] = routines.utils.basicSerialize(ind)
|
|
||||||
tbl_str[#tbl_str + 1] = ']='
|
|
||||||
end
|
|
||||||
|
|
||||||
if ((type(val) == 'number') or (type(val) == 'boolean')) then
|
|
||||||
tbl_str[#tbl_str + 1] = tostring(val)
|
|
||||||
tbl_str[#tbl_str + 1] = ','
|
|
||||||
elseif type(val) == 'string' then
|
|
||||||
tbl_str[#tbl_str + 1] = routines.utils.basicSerialize(val)
|
|
||||||
tbl_str[#tbl_str + 1] = ','
|
|
||||||
elseif type(val) == 'nil' then -- won't ever happen, right?
|
|
||||||
tbl_str[#tbl_str + 1] = 'nil,'
|
|
||||||
elseif type(val) == 'table' then
|
|
||||||
if ind == "__index" then
|
|
||||||
tbl_str[#tbl_str + 1] = "__index"
|
|
||||||
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
|
||||||
else
|
|
||||||
tbl_str[#tbl_str + 1] = routines.utils.oneLineSerialize(val)
|
|
||||||
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
|
||||||
end
|
|
||||||
elseif type(val) == 'function' then
|
|
||||||
tbl_str[#tbl_str + 1] = "function " .. tostring(ind)
|
|
||||||
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
|
|
||||||
else
|
|
||||||
env.info('unable to serialize value type ' .. routines.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind))
|
|
||||||
env.info( debug.traceback() )
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
tbl_str[#tbl_str + 1] = '}'
|
|
||||||
return table.concat(tbl_str)
|
|
||||||
else
|
|
||||||
return tostring(tbl)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--porting in Slmod's "safestring" basic serialize
|
|
||||||
routines.utils.basicSerialize = function(s)
|
|
||||||
if s == nil then
|
|
||||||
return "\"\""
|
|
||||||
else
|
|
||||||
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'table') or (type(s) == 'userdata') ) then
|
|
||||||
return tostring(s)
|
|
||||||
elseif type(s) == 'string' then
|
|
||||||
s = string.format('%q', s)
|
|
||||||
return s
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- From http://lua-users.org/wiki/SimpleRound
|
-- From http://lua-users.org/wiki/SimpleRound
|
||||||
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
|
-- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place
|
||||||
@ -280,6 +296,9 @@ routines.vec.rotateVec2 = function(vec2, theta)
|
|||||||
end
|
end
|
||||||
---------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5.
|
-- acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5.
|
||||||
routines.tostringMGRS = function(MGRS, acc)
|
routines.tostringMGRS = function(MGRS, acc)
|
||||||
if acc == 0 then
|
if acc == 0 then
|
||||||
@ -1521,85 +1540,48 @@ trace.r( "", "", { TransportZoneResult } )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function routines.IsUnitInRadius( CargoUnit, ReferenceGroup, Radius )
|
function routines.IsUnitInRadius( CargoUnit, ReferencePosition, Radius )
|
||||||
trace.f()
|
trace.f()
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
-- fill-up some local variables to support further calculations to determine location of units within the zone.
|
-- fill-up some local variables to support further calculations to determine location of units within the zone.
|
||||||
local CargoPos = CargoUnit:getPosition().p
|
local CargoPos = CargoUnit:getPosition().p
|
||||||
local ReferenceGroupPos = ReferenceGroup:getUnits()[1]:getPosition().p
|
local ReferenceP = ReferencePosition.p
|
||||||
|
|
||||||
if (((CargoPos.x - ReferenceGroupPos.x)^2 + (CargoPos.z - ReferenceGroupPos.z)^2)^0.5 <= Radius) then
|
if (((CargoPos.x - ReferenceP.x)^2 + (CargoPos.z - ReferenceP.z)^2)^0.5 <= Radius) then
|
||||||
else
|
else
|
||||||
Valid = false
|
Valid = false
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( "", "", { Valid } )
|
|
||||||
return Valid
|
return Valid
|
||||||
end
|
end
|
||||||
|
|
||||||
function routines.IsPartOfGroupInRadius( CargoGroup, ReferenceGroup, Radius )
|
function routines.IsPartOfGroupInRadius( CargoGroup, ReferencePosition, Radius )
|
||||||
trace.f()
|
trace.f()
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
Valid = routines.ValidateGroup( CargoGroup, "CargoGroup", Valid )
|
Valid = routines.ValidateGroup( CargoGroup, "CargoGroup", Valid )
|
||||||
Valid = routines.ValidateGroup( ReferenceGroup, "ReferenceGroup", Valid )
|
|
||||||
|
|
||||||
-- fill-up some local variables to support further calculations to determine location of units within the zone
|
-- fill-up some local variables to support further calculations to determine location of units within the zone
|
||||||
local CargoUnits = CargoGroup:getUnits()
|
local CargoUnits = CargoGroup:getUnits()
|
||||||
for CargoUnitId, CargoUnit in pairs( CargoUnits ) do
|
for CargoUnitId, CargoUnit in pairs( CargoUnits ) do
|
||||||
local CargoUnitPos = CargoUnit:getPosition().p
|
local CargoUnitPos = CargoUnit:getPosition().p
|
||||||
-- env.info( 'routines.IsPartOfGroupInRadius: CargoUnitPos.x = ' .. CargoUnitPos.x .. ' CargoUnitPos.z = ' .. CargoUnitPos.z )
|
-- env.info( 'routines.IsPartOfGroupInRadius: CargoUnitPos.x = ' .. CargoUnitPos.x .. ' CargoUnitPos.z = ' .. CargoUnitPos.z )
|
||||||
local ReferenceGroupPos = ReferenceGroup:getUnits()[1]:getPosition().p
|
local ReferenceP = ReferencePosition.p
|
||||||
-- env.info( 'routines.IsPartOfGroupInRadius: ReferenceGroupPos.x = ' .. ReferenceGroupPos.x .. ' ReferenceGroupPos.z = ' .. ReferenceGroupPos.z )
|
-- env.info( 'routines.IsPartOfGroupInRadius: ReferenceGroupPos.x = ' .. ReferenceGroupPos.x .. ' ReferenceGroupPos.z = ' .. ReferenceGroupPos.z )
|
||||||
|
|
||||||
if ((( CargoUnitPos.x - ReferenceGroupPos.x)^2 + (CargoUnitPos.z - ReferenceGroupPos.z)^2)^0.5 <= Radius) then
|
if ((( CargoUnitPos.x - ReferenceP.x)^2 + (CargoUnitPos.z - ReferenceP.z)^2)^0.5 <= Radius) then
|
||||||
else
|
else
|
||||||
Valid = false
|
Valid = false
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( "", "", { Valid } )
|
|
||||||
return Valid
|
return Valid
|
||||||
end
|
end
|
||||||
|
|
||||||
function routines.DestroyGroupInRadiusFromGroup( CargoGroup, ReferenceGroup, Radius )
|
|
||||||
trace.f()
|
|
||||||
|
|
||||||
local Valid = true
|
|
||||||
|
|
||||||
Valid = routines.ValidateGroup( CargoGroup, "CargoGroup", Valid )
|
|
||||||
Valid = routines.ValidateGroup( ReferenceGroup, "ReferenceGroup", Valid )
|
|
||||||
|
|
||||||
if Valid then
|
|
||||||
-- fill-up some local variables to support further calculations to determine location of units within the zone
|
|
||||||
local CargoUnits = CargoGroup:getUnits()
|
|
||||||
local AliveCargoUnits = #CargoUnits
|
|
||||||
for CargoUnitId, CargoUnit in pairs( CargoUnits ) do
|
|
||||||
local CargoUnitPos = CargoUnit:getPosition().p
|
|
||||||
-- env.info( 'routines.DestroyGroupInRadiusFromGroup: CargoUnitPos.x = ' .. CargoUnitPos.x .. ' CargoUnitPos.z = ' .. CargoUnitPos.z )
|
|
||||||
local ReferenceGroupPos = ReferenceGroup:getUnits()[1]:getPosition().p
|
|
||||||
-- env.info( 'routines.DestroyGroupInRadiusFromGroup: ReferenceGroupPos.x = ' .. ReferenceGroupPos.x .. ' ReferenceGroupPos.z = ' .. ReferenceGroupPos.z )
|
|
||||||
|
|
||||||
if ((( CargoUnitPos.x - ReferenceGroupPos.x)^2 + (CargoUnitPos.z - ReferenceGroupPos.z)^2)^0.5 <= Radius) then
|
|
||||||
CargoUnit:destroy()
|
|
||||||
AliveCargoUnits = AliveCargoUnits - 1
|
|
||||||
else
|
|
||||||
Valid = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
AliveCargoUnits = -1
|
|
||||||
end
|
|
||||||
|
|
||||||
trace.r( "", "", { AliveCargoUnits } )
|
|
||||||
return AliveCargoUnits
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function routines.ValidateString( Variable, VariableName, Valid )
|
function routines.ValidateString( Variable, VariableName, Valid )
|
||||||
trace.f()
|
trace.f()
|
||||||
@ -1866,6 +1848,23 @@ routines.ground.patrol = function(gpData, pType, form, speed)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function routines.GetUnitHeight( CheckUnit )
|
||||||
|
trace.f( "routines" )
|
||||||
|
|
||||||
|
local UnitPoint = CheckUnit:getPoint()
|
||||||
|
local UnitPosition = { x = UnitPoint.x, y = UnitPoint.z }
|
||||||
|
local UnitHeight = UnitPoint.y
|
||||||
|
|
||||||
|
local LandHeight = land.getHeight( UnitPosition )
|
||||||
|
|
||||||
|
--env.info(( 'CarrierHeight: LandHeight = ' .. LandHeight .. ' CarrierHeight = ' .. CarrierHeight ))
|
||||||
|
|
||||||
|
trace.f( "routines", "Unit Height = " .. UnitHeight - LandHeight )
|
||||||
|
|
||||||
|
return UnitHeight - LandHeight
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Su34Status = { status = {} }
|
Su34Status = { status = {} }
|
||||||
@ -2399,7 +2398,7 @@ trace.f()
|
|||||||
|
|
||||||
--env.info(( 'CarrierHeight: LandHeight = ' .. LandHeight .. ' CarrierHeight = ' .. CarrierHeight ))
|
--env.info(( 'CarrierHeight: LandHeight = ' .. LandHeight .. ' CarrierHeight = ' .. CarrierHeight ))
|
||||||
|
|
||||||
return CarrierHeight - LandHeight
|
return UnitHeight - LandHeight
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -30,51 +30,48 @@ SEAD = {
|
|||||||
-- -- Defends the Russian SA installations from SEAD attacks.
|
-- -- Defends the Russian SA installations from SEAD attacks.
|
||||||
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
|
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
|
||||||
function SEAD:New( SEADGroupPrefixes )
|
function SEAD:New( SEADGroupPrefixes )
|
||||||
trace.f(self.ClassName, SEADGroupPrefixes )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T( SEADGroupPrefixes )
|
||||||
-- Arrange meta tables
|
|
||||||
local Child = BASE:Inherit( self, BASE:New() )
|
|
||||||
if type( SEADGroupPrefixes ) == 'table' then
|
if type( SEADGroupPrefixes ) == 'table' then
|
||||||
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
|
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
|
||||||
Child.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix
|
self.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Child.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes
|
self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes
|
||||||
end
|
end
|
||||||
Child.AddEvent( Child, world.event.S_EVENT_SHOT, Child.EventShot )
|
self.AddEvent( self, world.event.S_EVENT_SHOT, self.EventShot )
|
||||||
Child.EnableEvents( Child )
|
self.EnableEvents( self )
|
||||||
|
|
||||||
return Child
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
|
--- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
|
||||||
-- @see SEAD
|
-- @see SEAD
|
||||||
function SEAD:EventShot( event )
|
function SEAD:EventShot( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired
|
local SEADUnit = event.initiator
|
||||||
local _groupname = _grp:getName() -- return the name of the group
|
local SEADUnitName = SEADUnit:getName()
|
||||||
local _unittable = {event.initiator:getName()} -- return the name of the units in the group
|
local SEADWeapon = event.weapon -- Identify the weapon fired
|
||||||
local _SEADmissile = event.weapon -- Identify the weapon fired
|
local SEADWeaponName = SEADWeapon:getTypeName() -- return weapon type
|
||||||
local _SEADmissileName = _SEADmissile:getTypeName() -- return weapon type
|
--trigger.action.outText( string.format("Alerte, depart missile " ..string.format(SEADWeaponName)), 20) --debug message
|
||||||
--trigger.action.outText( string.format("Alerte, depart missile " ..string.format(_SEADmissileName)), 20) --debug message
|
|
||||||
-- Start of the 2nd loop
|
-- Start of the 2nd loop
|
||||||
trace.i( self.ClassName, "Missile Launched = " .. _SEADmissileName )
|
self:T( "Missile Launched = " .. SEADWeaponName )
|
||||||
if _SEADmissileName == "KH-58" or _SEADmissileName == "KH-25MPU" or _SEADmissileName == "AGM-88" or _SEADmissileName == "KH-31A" or _SEADmissileName == "KH-31P" then -- Check if the missile is a SEAD
|
if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD
|
||||||
local _evade = math.random (1,100) -- random number for chance of evading action
|
local _evade = math.random (1,100) -- random number for chance of evading action
|
||||||
local _targetMim = Weapon.getTarget(_SEADmissile) -- Identify target
|
local _targetMim = Weapon.getTarget(SEADWeapon) -- Identify target
|
||||||
local _targetMimname = Unit.getName(_targetMim)
|
local _targetMimname = Unit.getName(_targetMim)
|
||||||
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(_SEADmissile))
|
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
||||||
local _targetMimgroupName = _targetMimgroup:getName()
|
local _targetMimgroupName = _targetMimgroup:getName()
|
||||||
local _targetMimcont= _targetMimgroup:getController()
|
local _targetMimcont= _targetMimgroup:getController()
|
||||||
local _targetskill = _Database.Units[_targetMimname].Template.skill
|
local _targetskill = _Database.Units[_targetMimname].Template.skill
|
||||||
trace.i( self.ClassName, self.SEADGroupPrefixes )
|
self:T( self.SEADGroupPrefixes )
|
||||||
trace.i( self.ClassName, _targetMimgroupName )
|
self:T( _targetMimgroupName )
|
||||||
local SEADGroupFound = false
|
local SEADGroupFound = false
|
||||||
for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do
|
for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do
|
||||||
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
|
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
|
||||||
SEADGroupFound = true
|
SEADGroupFound = true
|
||||||
trace.i( self.ClassName, 'Group Found' )
|
self:T( 'Group Found' )
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -83,15 +80,15 @@ trace.f( self.ClassName, { event } )
|
|||||||
local Skills = { "Average", "Good", "High", "Excellent" }
|
local Skills = { "Average", "Good", "High", "Excellent" }
|
||||||
_targetskill = Skills[ math.random(1,4) ]
|
_targetskill = Skills[ math.random(1,4) ]
|
||||||
end
|
end
|
||||||
trace.i( self.ClassName, _targetskill ) -- debug message for skill check
|
self:T( _targetskill ) -- debug message for skill check
|
||||||
if self.TargetSkill[_targetskill] then
|
if self.TargetSkill[_targetskill] then
|
||||||
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
||||||
trace.i( self.ClassName, string.format("Evading, target skill " ..string.format(_targetskill)) ) --debug message
|
self:T( string.format("Evading, target skill " ..string.format(_targetskill)) ) --debug message
|
||||||
local _targetMim = Weapon.getTarget(_SEADmissile)
|
local _targetMim = Weapon.getTarget(SEADWeapon)
|
||||||
local _targetMimname = Unit.getName(_targetMim)
|
local _targetMimname = Unit.getName(_targetMim)
|
||||||
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(_SEADmissile))
|
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
||||||
local _targetMimcont= _targetMimgroup:getController()
|
local _targetMimcont= _targetMimgroup:getController()
|
||||||
routines.groupRandomDistSelf(_targetMimgroup,300,'Rank',250,20) -- move randomly
|
routines.groupRandomDistSelf(_targetMimgroup,300,'Diamond',250,20) -- move randomly
|
||||||
local SuppressedGroups1 = {} -- unit suppressed radar off for a random time
|
local SuppressedGroups1 = {} -- unit suppressed radar off for a random time
|
||||||
local function SuppressionEnd1(id)
|
local function SuppressionEnd1(id)
|
||||||
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
||||||
|
|||||||
@ -1,39 +0,0 @@
|
|||||||
--- A SLINGLOADHOOKTASK will orchestrate the sling-load hook activity to slingload a CARGO from a specific landing zone(s).
|
|
||||||
-- @classmod SLINGLOADHOOKTASK
|
|
||||||
|
|
||||||
Include.File("Task")
|
|
||||||
|
|
||||||
SLINGLOADHOOKTASK = {
|
|
||||||
ClassName = "SLINGLOADHOOKTASK",
|
|
||||||
GoalVerb = "Hook and Sling Cargo"
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Creates a new SLINGLOADHOOKTASK.
|
|
||||||
-- @tparam table{string,...}|string LandingZones Table or name of the zone(s) where Cargo is to be loaded.
|
|
||||||
-- @tparam table{string,...)|string CargoPrefixes is the name or prefix of the name of the Cargo objects defined within the DCS ME.
|
|
||||||
-- @treturn SLINGLOADHOOKTASK
|
|
||||||
function SLINGLOADHOOKTASK:New( LandingZones, CargoPrefixes )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, TASK:New() )
|
|
||||||
|
|
||||||
self.Name = 'Hook and Sling Cargo'
|
|
||||||
self.TaskBriefing = "Task: Hook"
|
|
||||||
|
|
||||||
if type( LandingZones ) == "table" then
|
|
||||||
self.LandingZones = LandingZones
|
|
||||||
else
|
|
||||||
self.LandingZones = { LandingZones }
|
|
||||||
end
|
|
||||||
|
|
||||||
if type( CargoPrefixes ) == "table" then
|
|
||||||
self.CargoPrefixes = CargoPrefixes
|
|
||||||
else
|
|
||||||
self.CargoPrefixes = { CargoPrefixes }
|
|
||||||
end
|
|
||||||
|
|
||||||
self.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGE_SLINGLOAD_HOOK:New(), STAGEDONE:New() }
|
|
||||||
self:SetStage( 1 )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
--- A SLINGLOADUNHOOKTASK will orchestrate the sling-load unhook activity to (sling)load a CARGO and deploy it in a specific landing zone(s).
|
|
||||||
-- @classmod SLINGLOADUNHOOKTASK
|
|
||||||
|
|
||||||
Include.File("Task")
|
|
||||||
|
|
||||||
SLINGLOADUNHOOKTASK = {
|
|
||||||
ClassName = "SLINGLOADUNHOOKTASK",
|
|
||||||
GoalVerb = "Sling and UnHook Cargo"
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Creates a new SLINGLOADUNHOOKTASK.
|
|
||||||
-- @tparam table{string,...}|string LandingZones Table or name of the zone(s) where Cargo is to be loaded.
|
|
||||||
-- @tparam table{string,...}|string CargoPrefixes is the name or prefix of the name of the Cargo objects defined within the DCS ME.
|
|
||||||
function SLINGLOADUNHOOKTASK:New( LandingZones, CargoPrefixes )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, TASK:New() )
|
|
||||||
|
|
||||||
self.Name = 'Sling and Unhook Cargo'
|
|
||||||
self.TaskBriefing = "Task: UnHook"
|
|
||||||
|
|
||||||
if type( LandingZones ) == "table" then
|
|
||||||
self.LandingZones = LandingZones
|
|
||||||
else
|
|
||||||
self.LandingZones = { LandingZones }
|
|
||||||
end
|
|
||||||
|
|
||||||
if type( CargoPrefixes ) == "table" then
|
|
||||||
self.CargoPrefixes = CargoPrefixes
|
|
||||||
else
|
|
||||||
self.CargoPrefixes = { CargoPrefixes }
|
|
||||||
end
|
|
||||||
|
|
||||||
self.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGE_SLINGLOAD_UNHOOK:New(), STAGEDONE:New() }
|
|
||||||
self:SetStage( 1 )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
419
Moose/Spawn.lua
419
Moose/Spawn.lua
@ -2,9 +2,13 @@
|
|||||||
-- @classmod SPAWN
|
-- @classmod SPAWN
|
||||||
-- @author Flightcontrol
|
-- @author Flightcontrol
|
||||||
|
|
||||||
|
MOOSE_Version = "0.1.1.1"
|
||||||
|
|
||||||
Include.File( "Routines" )
|
Include.File( "Routines" )
|
||||||
Include.File( "Base" )
|
Include.File( "Base" )
|
||||||
Include.File( "Database" )
|
Include.File( "Database" )
|
||||||
|
Include.File( "Group" )
|
||||||
|
|
||||||
|
|
||||||
SPAWN = {
|
SPAWN = {
|
||||||
ClassName = "SPAWN",
|
ClassName = "SPAWN",
|
||||||
@ -23,10 +27,8 @@ SPAWN = {
|
|||||||
-- -- NATO helicopters engaging in the battle field.
|
-- -- NATO helicopters engaging in the battle field.
|
||||||
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' )
|
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' )
|
||||||
function SPAWN:New( SpawnPrefix )
|
function SPAWN:New( SpawnPrefix )
|
||||||
trace.f(self.ClassName, SpawnPrefix)
|
|
||||||
|
|
||||||
-- Inherits from BASE
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T( SpawnPrefix)
|
||||||
|
|
||||||
local TemplateGroup = Group.getByName( SpawnPrefix )
|
local TemplateGroup = Group.getByName( SpawnPrefix )
|
||||||
if TemplateGroup then
|
if TemplateGroup then
|
||||||
@ -39,6 +41,7 @@ trace.f(self.ClassName, SpawnPrefix)
|
|||||||
self.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts.
|
self.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts.
|
||||||
self.SpawnMaxGroupsAlive = 0 -- The maximum amount of groups that can be alive of SpawnPrefix at the same time.
|
self.SpawnMaxGroupsAlive = 0 -- The maximum amount of groups that can be alive of SpawnPrefix at the same time.
|
||||||
self.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned.
|
self.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned.
|
||||||
|
self.SpawnRandomize = false
|
||||||
else
|
else
|
||||||
error( "SPAWN:New: There is no group declared in the mission editor with SpawnPrefix = '" .. SpawnPrefix .. "'" )
|
error( "SPAWN:New: There is no group declared in the mission editor with SpawnPrefix = '" .. SpawnPrefix .. "'" )
|
||||||
end
|
end
|
||||||
@ -65,11 +68,12 @@ end
|
|||||||
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):RandomizeRoute( 2, 2, 2000 )
|
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):RandomizeRoute( 2, 2, 2000 )
|
||||||
|
|
||||||
function SPAWN:RandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius )
|
function SPAWN:RandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius )
|
||||||
trace.f( self.ClassName, { SpawnStartPoint, SpawnEndPoint, SpawnRadius } )
|
self:T( { SpawnStartPoint, SpawnEndPoint, SpawnRadius } )
|
||||||
|
|
||||||
self.SpawnStartPoint = SpawnStartPoint -- When the spawning occurs, randomize the route points from SpawnStartPoint.
|
self.SpawnStartPoint = SpawnStartPoint -- When the spawning occurs, randomize the route points from SpawnStartPoint.
|
||||||
self.SpawnEndPoint = SpawnEndPoint -- When the spawning occurs, randomize the route points till SpawnEndPoint.
|
self.SpawnEndPoint = SpawnEndPoint -- When the spawning occurs, randomize the route points till SpawnEndPoint.
|
||||||
self.SpawnRadius = SpawnRadius -- The Radius of randomization of the route points from SpawnStartPoint till SpawnEndPoint.
|
self.SpawnRadius = SpawnRadius -- The Radius of randomization of the route points from SpawnStartPoint till SpawnEndPoint.
|
||||||
|
self.SpawnRandomize = true
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -89,7 +93,7 @@ end
|
|||||||
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
|
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
|
||||||
|
|
||||||
function SPAWN:Schedule( SpawnTime, SpawnTimeVariation )
|
function SPAWN:Schedule( SpawnTime, SpawnTimeVariation )
|
||||||
trace.f( self.ClassName, { SpawnTime, SpawnTimeVariation } )
|
self:T( { SpawnTime, SpawnTimeVariation } )
|
||||||
|
|
||||||
self.SpawnCurrentTimer = 0 -- The internal timer counter to trigger a scheduled spawning of SpawnPrefix.
|
self.SpawnCurrentTimer = 0 -- The internal timer counter to trigger a scheduled spawning of SpawnPrefix.
|
||||||
self.SpawnSetTimer = 0 -- The internal timer value when a scheduled spawning of SpawnPrefix occurs.
|
self.SpawnSetTimer = 0 -- The internal timer value when a scheduled spawning of SpawnPrefix occurs.
|
||||||
@ -103,7 +107,7 @@ trace.f( self.ClassName, { SpawnTime, SpawnTimeVariation } )
|
|||||||
self:ScheduleStart()
|
self:ScheduleStart()
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.i( self.ClassName, { self.SpawnLowTimer, self.SpawnHighTimer } )
|
self:T( { self.SpawnLowTimer, self.SpawnHighTimer } )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -111,7 +115,7 @@ end
|
|||||||
--- Will start the SPAWNing timers.
|
--- Will start the SPAWNing timers.
|
||||||
-- This function is called automatically when @{Schedule} is called.
|
-- This function is called automatically when @{Schedule} is called.
|
||||||
function SPAWN:ScheduleStart()
|
function SPAWN:ScheduleStart()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
--local ClientUnit = #AlivePlayerUnits()
|
--local ClientUnit = #AlivePlayerUnits()
|
||||||
|
|
||||||
@ -128,7 +132,7 @@ end
|
|||||||
|
|
||||||
--- Will stop the scheduled SPAWNing activity.
|
--- Will stop the scheduled SPAWNing activity.
|
||||||
function SPAWN:ScheduleStop()
|
function SPAWN:ScheduleStop()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
self.SpawnScheduled = false
|
self.SpawnScheduled = false
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -146,7 +150,7 @@ end
|
|||||||
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Limit( 2, 24 )
|
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Limit( 2, 24 )
|
||||||
|
|
||||||
function SPAWN:Limit( SpawnMaxGroupsAlive, SpawnMaxGroups )
|
function SPAWN:Limit( SpawnMaxGroupsAlive, SpawnMaxGroups )
|
||||||
trace.f( self.ClassName, { SpawnMaxGroupsAlive, SpawnMaxGroups } )
|
self:T( { SpawnMaxGroupsAlive, SpawnMaxGroups } )
|
||||||
|
|
||||||
self.SpawnMaxGroupsAlive = SpawnMaxGroupsAlive -- The maximum amount of groups that can be alive of SpawnPrefix at the same time.
|
self.SpawnMaxGroupsAlive = SpawnMaxGroupsAlive -- The maximum amount of groups that can be alive of SpawnPrefix at the same time.
|
||||||
self.SpawnMaxGroups = SpawnMaxGroups -- The maximum amount of groups that can be spawned.
|
self.SpawnMaxGroups = SpawnMaxGroups -- The maximum amount of groups that can be spawned.
|
||||||
@ -173,7 +177,7 @@ end
|
|||||||
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):Limit( 12, 150 ):Schedule( 200, 0.4 ):RandomizeTemplate( Spawn_US_Platoon ):RandomizeRoute( 3, 3, 2000 )
|
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):Limit( 12, 150 ):Schedule( 200, 0.4 ):RandomizeTemplate( Spawn_US_Platoon ):RandomizeRoute( 3, 3, 2000 )
|
||||||
|
|
||||||
function SPAWN:RandomizeTemplate( SpawnPrefixTable )
|
function SPAWN:RandomizeTemplate( SpawnPrefixTable )
|
||||||
trace.f( self.ClassName, { SpawnPrefix, SpawnPrefixTable } )
|
self:T( { SpawnPrefix, SpawnPrefixTable } )
|
||||||
|
|
||||||
self.SpawnPrefixTable = SpawnPrefixTable
|
self.SpawnPrefixTable = SpawnPrefixTable
|
||||||
|
|
||||||
@ -190,7 +194,7 @@ end
|
|||||||
-- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
|
-- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
|
||||||
|
|
||||||
function SPAWN:Repeat()
|
function SPAWN:Repeat()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
self.SpawnRepeat = true
|
self.SpawnRepeat = true
|
||||||
self.RepeatOnEngineShutDown = false
|
self.RepeatOnEngineShutDown = false
|
||||||
@ -209,7 +213,7 @@ end
|
|||||||
-- @see Repeat
|
-- @see Repeat
|
||||||
|
|
||||||
function SPAWN:RepeatOnLanding()
|
function SPAWN:RepeatOnLanding()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
self:Repeat()
|
self:Repeat()
|
||||||
self.RepeatOnEngineShutDown = false
|
self.RepeatOnEngineShutDown = false
|
||||||
@ -223,7 +227,7 @@ end
|
|||||||
-- @see Repeat
|
-- @see Repeat
|
||||||
|
|
||||||
function SPAWN:RepeatOnEngineShutDown()
|
function SPAWN:RepeatOnEngineShutDown()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
self:Repeat()
|
self:Repeat()
|
||||||
self.RepeatOnEngineShutDown = true
|
self.RepeatOnEngineShutDown = true
|
||||||
@ -232,15 +236,64 @@ trace.f( self.ClassName )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function SPAWN:CleanUp( SpawnCleanUpInterval )
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
self.SpawnCleanUpInterval = SpawnCleanUpInterval
|
||||||
|
self.SpawnCleanUpTimeStamps = {}
|
||||||
|
self.CleanUpFunction = routines.scheduleFunction( self._SpawnCleanUpScheduler, { self }, timer.getTime() + 1, 60 )
|
||||||
|
end
|
||||||
|
|
||||||
|
function SPAWN:_SpawnCleanUpScheduler()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
local SpawnGroup = self:GetFirstAliveGroup()
|
||||||
|
|
||||||
|
while SpawnGroup do
|
||||||
|
|
||||||
|
if SpawnGroup:AllOnGround() and SpawnGroup:GetMaxVelocity() < 1 then
|
||||||
|
if not self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] then
|
||||||
|
self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] = timer.getTime()
|
||||||
|
else
|
||||||
|
if self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] + self.SpawnCleanUpInterval < timer.getTime() then
|
||||||
|
SpawnGroup:Destroy()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
SpawnGroup = self:GetNextAliveGroup()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Will SPAWN a Group whenever you want to do this.
|
--- Will SPAWN a Group whenever you want to do this.
|
||||||
-- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ...
|
-- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ...
|
||||||
-- Uses @{DATABASE} global object defined in MOOSE.
|
-- Uses @{DATABASE} global object defined in MOOSE.
|
||||||
-- @treturn SPAWN
|
-- @treturn SPAWN
|
||||||
function SPAWN:Spawn()
|
function SPAWN:Spawn( SpawnGroupName )
|
||||||
trace.f( self.ClassName )
|
self:T( { self.SpawnPrefix, SpawnGroupName } )
|
||||||
local SpawnTemplate = self:_Prepare( true )
|
local SpawnTemplate = self:_Prepare( SpawnGroupName )
|
||||||
if self.SpawnStartPoint ~= 0 or self.SpawnEndPoint ~= 0 then
|
if self.SpawnRandomize then
|
||||||
|
SpawnTemplate = self:_RandomizeRoute( SpawnTemplate )
|
||||||
|
end
|
||||||
|
_Database:Spawn( SpawnTemplate )
|
||||||
|
if self.SpawnRepeat then
|
||||||
|
_Database:SetStatusGroup( SpawnTemplate.name, "ReSpawn" )
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Will SPAWN a Group with a specified index number whenever you want to do this.
|
||||||
|
-- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ...
|
||||||
|
-- Uses @{DATABASE} global object defined in MOOSE.
|
||||||
|
-- @treturn SPAWN
|
||||||
|
function SPAWN:SpawnWithIndex( SpawnIndex )
|
||||||
|
self:T( { self.SpawnPrefix, SpawnIndex } )
|
||||||
|
local SpawnTemplate = self:_Prepare( self:SpawnGroupName( SpawnIndex ) )
|
||||||
|
if self.SpawnRandomize then
|
||||||
SpawnTemplate = self:_RandomizeRoute( SpawnTemplate )
|
SpawnTemplate = self:_RandomizeRoute( SpawnTemplate )
|
||||||
end
|
end
|
||||||
_Database:Spawn( SpawnTemplate )
|
_Database:Spawn( SpawnTemplate )
|
||||||
@ -257,12 +310,15 @@ end
|
|||||||
-- @treturn SPAWN
|
-- @treturn SPAWN
|
||||||
-- Uses _Database global object defined in MOOSE.
|
-- Uses _Database global object defined in MOOSE.
|
||||||
function SPAWN:ReSpawn( SpawnGroupName )
|
function SPAWN:ReSpawn( SpawnGroupName )
|
||||||
trace.f( self.ClassName, { SpawnGroupName } )
|
self:T( { SpawnGroupName } )
|
||||||
|
|
||||||
local SpawnGroup = Group.getByName( SpawnGroupName )
|
local SpawnGroup = Group.getByName( SpawnGroupName )
|
||||||
SpawnGroup:destroy()
|
if SpawnGroup then
|
||||||
local SpawnTemplate = self:_Prepare( false )
|
SpawnGroup:destroy()
|
||||||
-- Give the Group the original name of the Group.
|
end
|
||||||
SpawnTemplate.name = SpawnGroupName
|
|
||||||
|
local SpawnTemplate = self:_Prepare( SpawnGroupName )
|
||||||
|
|
||||||
-- Give the units of the Group the name following the SPAWN naming convention, so that they don't replace other units within the ME.
|
-- Give the units of the Group the name following the SPAWN naming convention, so that they don't replace other units within the ME.
|
||||||
local SpawnUnits = table.getn( SpawnTemplate.units )
|
local SpawnUnits = table.getn( SpawnTemplate.units )
|
||||||
for u = 1, SpawnUnits do
|
for u = 1, SpawnUnits do
|
||||||
@ -276,13 +332,13 @@ end
|
|||||||
--- Will SPAWN a Group whenever you want to do this, but for AIR Groups only to be applied, and will SPAWN the Group in Uncontrolled mode... This will be similar to the Uncontrolled flag setting in the ME.
|
--- Will SPAWN a Group whenever you want to do this, but for AIR Groups only to be applied, and will SPAWN the Group in Uncontrolled mode... This will be similar to the Uncontrolled flag setting in the ME.
|
||||||
-- @treturn SPAWN
|
-- @treturn SPAWN
|
||||||
function SPAWN:SpawnUncontrolled()
|
function SPAWN:SpawnUncontrolled()
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
self.UnControlled = true
|
self.UnControlled = true
|
||||||
|
|
||||||
local SpawnCountStart = self.SpawnCount + 1
|
local SpawnCountStart = self.SpawnCount + 1
|
||||||
for SpawnCount = SpawnCountStart, self.SpawnMaxGroups do
|
for SpawnCount = SpawnCountStart, self.SpawnMaxGroups do
|
||||||
local SpawnTemplate = self:_Prepare( true )
|
local SpawnTemplate = self:_Prepare( )
|
||||||
SpawnTemplate.uncontrolled = true
|
SpawnTemplate.uncontrolled = true
|
||||||
_Database:Spawn( SpawnTemplate )
|
_Database:Spawn( SpawnTemplate )
|
||||||
end
|
end
|
||||||
@ -293,94 +349,212 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--- Will SPAWN a Group from a Carrier. This function is mostly advisable to be used if you want to simulate SPAWNing from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
|
--- Will SPAWN a Group from a Carrier. This function is mostly advisable to be used if you want to simulate SPAWNing from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
|
||||||
-- @tparam Group CarrierGroup is the Group of the AIR unit or GROUND unit dropping or unloading other units.
|
-- @tparam Group HostUnit is the AIR unit or GROUND unit dropping or unloading the Spawn group.
|
||||||
-- @tparam string TargetZonePrefix is the Prefix of the Zone defined in the ME where the Group should be moving to after drop.
|
-- @tparam string TargetZonePrefix is the Prefix of the Zone defined in the ME where the Group should be moving to after drop.
|
||||||
-- @tparam string NewGroupName (forgot this).
|
-- @tparam string NewGroupName (forgot this).
|
||||||
-- @tparam bool LateActivate (optional) does the SPAWNing with Lateactivation on.
|
-- @tparam bool LateActivate (optional) does the SPAWNing with Lateactivation on.
|
||||||
function SPAWN:FromCarrier( CarrierGroup, TargetZonePrefix, NewGroupName, LateActivate )
|
function SPAWN:FromHost( HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate )
|
||||||
trace.f( self.ClassName, { CarrierGroup, TargetZonePrefix, NewGroupName, LateActivate } )
|
self:T( { HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate } )
|
||||||
|
|
||||||
local SpawnTemplate
|
local SpawnTemplate
|
||||||
|
|
||||||
if CarrierGroup and CarrierGroup:isExist() and CarrierGroup:getUnit(1) then -- and CarrierGroup:getUnit(1):inAir() == false then
|
if HostUnit and HostUnit:isExist() then -- and HostUnit:getUnit(1):inAir() == false then
|
||||||
|
|
||||||
local GroupUnits = CarrierGroup:getUnits()
|
SpawnTemplate = self:_Prepare( NewGroupName )
|
||||||
local GroupUnitCount = table.getn(GroupUnits)
|
|
||||||
trace.i( self.ClassName, "CarrierGroup:getSize() = " .. CarrierGroup:getSize() )
|
|
||||||
trace.i( self.ClassName, 'GroupUnitCount = ' .. GroupUnitCount )
|
|
||||||
|
|
||||||
for UnitId, UnitData in pairs(GroupUnits) do
|
|
||||||
|
|
||||||
UnitDeploy = UnitData
|
if ( self.SpawnMaxGroups == 0 ) or ( self.SpawnCount <= self.SpawnMaxGroups ) then
|
||||||
|
if ( self.SpawnMaxGroupsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
|
||||||
SpawnTemplate = self:_Prepare( true )
|
|
||||||
|
|
||||||
if ( self.SpawnMaxGroups == 0 ) or ( self.SpawnCount <= self.SpawnMaxGroups ) then
|
|
||||||
if ( self.SpawnMaxGroupsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
|
|
||||||
|
|
||||||
if NewGroupName ~= nil then
|
if LateActivate ~= nil then
|
||||||
SpawnTemplate.name = NewGroupName
|
if LateActivate == true then
|
||||||
|
SpawnTemplate.lateActivation = true
|
||||||
|
SpawnTemplate.visible = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if LateActivate ~= nil then
|
|
||||||
if LateActivate == true then
|
|
||||||
SpawnTemplate.lateActivation = true
|
|
||||||
SpawnTemplate.visible = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
SpawnTemplate = self:_RandomizeRoute( SpawnTemplate )
|
|
||||||
|
|
||||||
local TargetZone = trigger.misc.getZone( TargetZonePrefix )
|
|
||||||
local TargetZonePos = {}
|
|
||||||
TargetZonePos.x = TargetZone.point.x + math.random(TargetZone.radius * -1, TargetZone.radius)
|
|
||||||
TargetZonePos.z = TargetZone.point.z + math.random(TargetZone.radius * -1, TargetZone.radius)
|
|
||||||
|
|
||||||
local RouteCount = table.getn( SpawnTemplate.route.points )
|
|
||||||
trace.i( self.ClassName, "RouteCount = " .. RouteCount )
|
|
||||||
|
|
||||||
local UnitDeployPosition = UnitDeploy:getPoint()
|
|
||||||
SpawnTemplate.route.points[1].x = UnitDeployPosition.x - 50
|
|
||||||
SpawnTemplate.route.points[1].y = UnitDeployPosition.z
|
|
||||||
SpawnTemplate.route.points[1].alt = nil
|
|
||||||
SpawnTemplate.route.points[1].alt_type = nil
|
|
||||||
|
|
||||||
if SpawnStartPoint ~= 0 and SpawnEndPoint ~= 0 then
|
|
||||||
SpawnTemplate.route.points[RouteCount].x = TargetZonePos.x
|
|
||||||
SpawnTemplate.route.points[RouteCount].y = TargetZonePos.z
|
|
||||||
else
|
|
||||||
SpawnTemplate.route.points[RouteCount].x = TargetZone.point.x
|
|
||||||
SpawnTemplate.route.points[RouteCount].y = TargetZone.point.z
|
|
||||||
end
|
|
||||||
|
|
||||||
trace.i( self.ClassName, 'SpawnTemplate.route.points['..RouteCount..'].x = ' .. SpawnTemplate.route.points[RouteCount].x .. ', SpawnTemplate.route.points['..RouteCount..'].y = ' .. SpawnTemplate.route.points[RouteCount].y )
|
|
||||||
|
|
||||||
for v = 1, table.getn( SpawnTemplate.units ) do
|
|
||||||
local SpawnPos = routines.getRandPointInCircle( UnitDeployPosition, 40, 10 )
|
|
||||||
SpawnTemplate.units[v].x = SpawnPos.x
|
|
||||||
SpawnTemplate.units[v].y = SpawnPos.y
|
|
||||||
trace.i( self.ClassName, 'SpawnTemplate.units['..v..'].x = ' .. SpawnTemplate.units[v].x .. ', SpawnTemplate.units['..v..'].y = ' .. SpawnTemplate.units[v].y )
|
|
||||||
end
|
|
||||||
|
|
||||||
_Database:Spawn( SpawnTemplate )
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
SpawnTemplate = self:_RandomizeRoute( SpawnTemplate )
|
||||||
|
|
||||||
|
local RouteCount = table.getn( SpawnTemplate.route.points )
|
||||||
|
self:T( "RouteCount = " .. RouteCount )
|
||||||
|
|
||||||
|
local UnitDeployPosition = HostUnit:getPoint()
|
||||||
|
for PointID, Point in pairs( SpawnTemplate.route.points ) do
|
||||||
|
Point.x = UnitDeployPosition.x
|
||||||
|
Point.y = UnitDeployPosition.z
|
||||||
|
Point.alt = nil
|
||||||
|
Point.alt_type = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
for v = 1, table.getn( SpawnTemplate.units ) do
|
||||||
|
local SpawnPos = routines.getRandPointInCircle( UnitDeployPosition, OuterRadius, InnerRadius )
|
||||||
|
SpawnTemplate.units[v].x = SpawnPos.x
|
||||||
|
SpawnTemplate.units[v].y = SpawnPos.y
|
||||||
|
self:T( 'SpawnTemplate.units['..v..'].x = ' .. SpawnTemplate.units[v].x .. ', SpawnTemplate.units['..v..'].y = ' .. SpawnTemplate.units[v].y )
|
||||||
|
end
|
||||||
|
|
||||||
|
_Database:Spawn( SpawnTemplate )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( self.ClassName, "" )
|
return SpawnTemplate
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Will SPAWN a Group from a Carrier. This function is mostly advisable to be used if you want to simulate SPAWNing from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
|
||||||
|
-- @tparam Group CarrierUnit is the AIR unit or GROUND unit dropping or unloading the Spawn group.
|
||||||
|
-- @tparam string TargetZonePrefix is the Prefix of the Zone defined in the ME where the Group should be moving to after drop.
|
||||||
|
-- @tparam string NewGroupName (forgot this).
|
||||||
|
-- @tparam bool LateActivate (optional) does the SPAWNing with Lateactivation on.
|
||||||
|
function SPAWN:FromCarrier( CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate )
|
||||||
|
self:T( { CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate } )
|
||||||
|
|
||||||
|
local SpawnTemplate
|
||||||
|
|
||||||
|
if CarrierUnit and CarrierUnit:isExist() then -- and CarrierUnit:getUnit(1):inAir() == false then
|
||||||
|
|
||||||
|
SpawnTemplate = self:_Prepare( NewGroupName )
|
||||||
|
|
||||||
|
if ( self.SpawnMaxGroups == 0 ) or ( self.SpawnCount <= self.SpawnMaxGroups ) then
|
||||||
|
if ( self.SpawnMaxGroupsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
|
||||||
|
|
||||||
|
if LateActivate ~= nil then
|
||||||
|
if LateActivate == true then
|
||||||
|
SpawnTemplate.lateActivation = true
|
||||||
|
SpawnTemplate.visible = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SpawnTemplate = self:_RandomizeRoute( SpawnTemplate )
|
||||||
|
|
||||||
|
local TargetZone = trigger.misc.getZone( TargetZonePrefix )
|
||||||
|
local TargetZonePos = {}
|
||||||
|
TargetZonePos.x = TargetZone.point.x + math.random(TargetZone.radius / 2 * -1, TargetZone.radius / 2 )
|
||||||
|
TargetZonePos.z = TargetZone.point.z + math.random(TargetZone.radius / 2 * -1, TargetZone.radius / 2 )
|
||||||
|
|
||||||
|
local RouteCount = table.getn( SpawnTemplate.route.points )
|
||||||
|
self:T( "RouteCount = " .. RouteCount )
|
||||||
|
|
||||||
|
local UnitDeployPosition = CarrierUnit:getPosition().p
|
||||||
|
SpawnTemplate.route.points[1].x = UnitDeployPosition.x - 50
|
||||||
|
SpawnTemplate.route.points[1].y = UnitDeployPosition.z
|
||||||
|
SpawnTemplate.route.points[1].alt = nil
|
||||||
|
SpawnTemplate.route.points[1].alt_type = nil
|
||||||
|
|
||||||
|
if self.SpawnRandomize then
|
||||||
|
SpawnTemplate.route.points[RouteCount].x = TargetZonePos.x
|
||||||
|
SpawnTemplate.route.points[RouteCount].y = TargetZonePos.z
|
||||||
|
else
|
||||||
|
SpawnTemplate.route.points[RouteCount].x = TargetZone.point.x
|
||||||
|
SpawnTemplate.route.points[RouteCount].y = TargetZone.point.z
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( 'SpawnTemplate.route.points['..RouteCount..'].x = ' .. SpawnTemplate.route.points[RouteCount].x .. ', SpawnTemplate.route.points['..RouteCount..'].y = ' .. SpawnTemplate.route.points[RouteCount].y )
|
||||||
|
|
||||||
|
for v = 1, table.getn( SpawnTemplate.units ) do
|
||||||
|
local SpawnPos = routines.getRandPointInCircle( UnitDeployPosition, 40, 10 )
|
||||||
|
SpawnTemplate.units[v].x = SpawnPos.x
|
||||||
|
SpawnTemplate.units[v].y = SpawnPos.y
|
||||||
|
self:T( 'SpawnTemplate.units['..v..'].x = ' .. SpawnTemplate.units[v].x .. ', SpawnTemplate.units['..v..'].y = ' .. SpawnTemplate.units[v].y )
|
||||||
|
end
|
||||||
|
|
||||||
|
_Database:Spawn( SpawnTemplate )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return SpawnTemplate
|
return SpawnTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Will return the SpawnGroupName either with with a specific count number or without any count.
|
||||||
|
-- @tparam number SpawnIndex is the number of the Group that is to be SPAWNed.
|
||||||
|
-- @treturn string SpawnGroupName
|
||||||
|
function SPAWN:SpawnGroupName( SpawnIndex )
|
||||||
|
self:T( { self.SpawnPrefix, SpawnIndex } )
|
||||||
|
|
||||||
|
if SpawnIndex then
|
||||||
|
self:T( string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) )
|
||||||
|
return string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex )
|
||||||
|
else
|
||||||
|
self:T( self.SpawnPrefix )
|
||||||
|
return self.SpawnPrefix
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function SPAWN:GetIndexFromGroup( Group )
|
||||||
|
self:T( { self.SpawnPrefix, Group } )
|
||||||
|
|
||||||
|
local IndexString = string.match( Group:GetName(), "#.*$" )
|
||||||
|
local Index = tonumber( IndexString:sub(2) )
|
||||||
|
|
||||||
|
self:T( IndexString, Index )
|
||||||
|
return Index
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function SPAWN:GetLastIndex()
|
||||||
|
|
||||||
|
return self.SpawnCount
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function SPAWN:GetFirstAliveGroup()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
self.SpawnIndex = 1
|
||||||
|
for SpawnIndex = 1, self.SpawnCount do
|
||||||
|
SpawnGroupName = self:SpawnGroupName( SpawnIndex )
|
||||||
|
SpawnGroup = Group.getByName( SpawnGroupName )
|
||||||
|
if SpawnGroup and SpawnGroup:isExist() then
|
||||||
|
self.SpawnIndex = SpawnIndex
|
||||||
|
return GROUP:New( SpawnGroup )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.SpawnIndex = nil
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function SPAWN:GetNextAliveGroup()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
self.SpawnIndex = self.SpawnIndex + 1
|
||||||
|
for SpawnIndex = self.SpawnIndex, self.SpawnCount do
|
||||||
|
SpawnGroupName = self:SpawnGroupName( SpawnIndex )
|
||||||
|
SpawnGroup = Group.getByName( SpawnGroupName )
|
||||||
|
if SpawnGroup and SpawnGroup:isExist() then
|
||||||
|
self.SpawnIndex = SpawnIndex
|
||||||
|
return GROUP:New( SpawnGroup )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.SpawnIndex = nil
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function SPAWN:GetLastAliveGroup()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
local LastGroupName = self:SpawnGroupName( self:GetLastIndex() )
|
||||||
|
|
||||||
|
return GROUP:New( Group.getByName( LastGroupName ) )
|
||||||
|
end
|
||||||
|
|
||||||
--- Will SPAWN a Group within a given ZoneName.
|
--- Will SPAWN a Group within a given ZoneName.
|
||||||
-- @tparam string ZonePrefix is the name of the zone where the Group is to be SPAWNed.
|
-- @tparam string ZonePrefix is the name of the zone where the Group is to be SPAWNed.
|
||||||
-- @treturn SpawnTemplate
|
-- @treturn SpawnTemplate
|
||||||
function SPAWN:InZone( ZonePrefix )
|
function SPAWN:InZone( ZonePrefix, SpawnGroupName )
|
||||||
trace.f("Spawn", ZonePrefix )
|
self:T( ZonePrefix )
|
||||||
|
|
||||||
local SpawnTemplate = self:_Prepare( true )
|
local SpawnTemplate
|
||||||
|
|
||||||
|
if SpawnGroupName then
|
||||||
|
SpawnTemplate = self:_Prepare( SpawnGroupName )
|
||||||
|
else
|
||||||
|
SpawnTemplate = self:_Prepare()
|
||||||
|
end
|
||||||
|
|
||||||
local Zone = trigger.misc.getZone( ZonePrefix )
|
local Zone = trigger.misc.getZone( ZonePrefix )
|
||||||
local ZonePos = {}
|
local ZonePos = {}
|
||||||
@ -443,7 +617,7 @@ end
|
|||||||
--- Gets the Group Template from the ME environment definition.
|
--- Gets the Group Template from the ME environment definition.
|
||||||
-- This method used the @{DATABASE} object, which contains ALL initial and new SPAWNed object in MOOSE.
|
-- This method used the @{DATABASE} object, which contains ALL initial and new SPAWNed object in MOOSE.
|
||||||
function SPAWN:_GetTemplate( SpawnPrefix )
|
function SPAWN:_GetTemplate( SpawnPrefix )
|
||||||
trace.f( self.ClassName, SpawnPrefix )
|
self:T( SpawnPrefix )
|
||||||
|
|
||||||
local SpawnTemplate = nil
|
local SpawnTemplate = nil
|
||||||
|
|
||||||
@ -457,13 +631,13 @@ trace.f( self.ClassName, SpawnPrefix )
|
|||||||
SpawnTemplate.SpawnCategoryID = self:_GetGroupCategoryID( SpawnPrefix )
|
SpawnTemplate.SpawnCategoryID = self:_GetGroupCategoryID( SpawnPrefix )
|
||||||
SpawnTemplate.SpawnCountryID = self:_GetGroupCountryID( SpawnPrefix )
|
SpawnTemplate.SpawnCountryID = self:_GetGroupCountryID( SpawnPrefix )
|
||||||
|
|
||||||
trace.r( self.ClassName, "", { SpawnTemplate } )
|
self:T( { SpawnTemplate } )
|
||||||
return SpawnTemplate
|
return SpawnTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Prepares the new Group Template before Spawning.
|
--- Prepares the new Group Template before Spawning.
|
||||||
function SPAWN:_Prepare( SpawnIncrement )
|
function SPAWN:_Prepare( SpawnGroupName )
|
||||||
trace.f( self.ClassName )
|
self:T()
|
||||||
|
|
||||||
local SpawnCount
|
local SpawnCount
|
||||||
local SpawnUnits
|
local SpawnUnits
|
||||||
@ -476,11 +650,14 @@ trace.f( self.ClassName )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Increase the spawn counter for the group
|
-- Increase the spawn counter for the group
|
||||||
if SpawnIncrement == true then
|
if SpawnGroupName then
|
||||||
|
SpawnTemplate.name = SpawnGroupName
|
||||||
|
else
|
||||||
self.SpawnCount = self.SpawnCount + 1
|
self.SpawnCount = self.SpawnCount + 1
|
||||||
|
SpawnTemplate.name = self:SpawnGroupName( self.SpawnCount )
|
||||||
end
|
end
|
||||||
|
|
||||||
SpawnTemplate.name = string.format( self.SpawnPrefix .. '#%03d', self.SpawnCount )
|
|
||||||
SpawnTemplate.groupId = nil
|
SpawnTemplate.groupId = nil
|
||||||
SpawnTemplate.lateActivation = false
|
SpawnTemplate.lateActivation = false
|
||||||
if SpawnTemplate.SpawnCategoryID == Group.Category.GROUND then
|
if SpawnTemplate.SpawnCategoryID == Group.Category.GROUND then
|
||||||
@ -501,32 +678,32 @@ trace.f( self.ClassName )
|
|||||||
|
|
||||||
SpawnUnits = table.getn( SpawnTemplate.units )
|
SpawnUnits = table.getn( SpawnTemplate.units )
|
||||||
for u = 1, SpawnUnits do
|
for u = 1, SpawnUnits do
|
||||||
SpawnTemplate.units[u].name = string.format( self.SpawnPrefix .. '#%03d-%02d', self.SpawnCount, u )
|
SpawnTemplate.units[u].name = string.format( SpawnTemplate.name .. '-%02d', u )
|
||||||
SpawnTemplate.units[u].unitId = nil
|
SpawnTemplate.units[u].unitId = nil
|
||||||
SpawnTemplate.units[u].x = SpawnTemplate.route.points[1].x
|
SpawnTemplate.units[u].x = SpawnTemplate.route.points[1].x + math.random( -50, 50 )
|
||||||
SpawnTemplate.units[u].y = SpawnTemplate.route.points[1].y
|
SpawnTemplate.units[u].y = SpawnTemplate.route.points[1].y + math.random( -50, 50 )
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( self.ClassName, "", SpawnTemplate.name )
|
self:T( SpawnTemplate.name )
|
||||||
return SpawnTemplate
|
return SpawnTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Will randomize the route of the Group Template.
|
--- Will randomize the route of the Group Template.
|
||||||
function SPAWN:_RandomizeRoute( SpawnTemplate )
|
function SPAWN:_RandomizeRoute( SpawnTemplate )
|
||||||
trace.f( self.ClassName, SpawnTemplate.name )
|
self:T( SpawnTemplate.name )
|
||||||
|
|
||||||
if self.SpawnStartPoint and self.SpawnEndPoint then
|
if self.SpawnRandomize then
|
||||||
local RouteCount = table.getn( SpawnTemplate.route.points )
|
local RouteCount = table.getn( SpawnTemplate.route.points )
|
||||||
for t = self.SpawnStartPoint, RouteCount - self.SpawnEndPoint do
|
for t = self.SpawnStartPoint+1, RouteCount - self.SpawnEndPoint do
|
||||||
SpawnTemplate.route.points[t].x = SpawnTemplate.route.points[t].x + math.random( self.SpawnRadius * -1, self.SpawnRadius )
|
SpawnTemplate.route.points[t].x = SpawnTemplate.route.points[t].x + math.random( self.SpawnRadius * -1, self.SpawnRadius )
|
||||||
SpawnTemplate.route.points[t].y = SpawnTemplate.route.points[t].y + math.random( self.SpawnRadius * -1, self.SpawnRadius )
|
SpawnTemplate.route.points[t].y = SpawnTemplate.route.points[t].y + math.random( self.SpawnRadius * -1, self.SpawnRadius )
|
||||||
SpawnTemplate.route.points[t].alt = nil
|
SpawnTemplate.route.points[t].alt = nil
|
||||||
--SpawnGroup.route.points[t].alt_type = nil
|
--SpawnGroup.route.points[t].alt_type = nil
|
||||||
trace.i( self.ClassName, 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
|
self:T( 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
trace.r( self.ClassName, "", SpawnTemplate.name )
|
self:T( SpawnTemplate.name )
|
||||||
return SpawnTemplate
|
return SpawnTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -536,16 +713,16 @@ end
|
|||||||
--- Obscolete
|
--- Obscolete
|
||||||
-- @todo Need to delete this... _Database does this now ...
|
-- @todo Need to delete this... _Database does this now ...
|
||||||
function SPAWN:OnBirth( event )
|
function SPAWN:OnBirth( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
|
if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
trace.l(self.ClassName, "OnBirth", "Birth object : " .. event.initiator:getName() )
|
self:T( "Birth object : " .. event.initiator:getName() )
|
||||||
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
||||||
if EventPrefix == self.SpawnPrefix .. '#' then
|
if EventPrefix == self.SpawnPrefix .. '#' then
|
||||||
--MessageToAll( "Mission command: unit " .. SpawnPrefix .. " spawned." , 5, EventPrefix .. '/Event')
|
--MessageToAll( "Mission command: unit " .. SpawnPrefix .. " spawned." , 5, EventPrefix .. '/Event')
|
||||||
self.AliveUnits = self.AliveUnits + 1
|
self.AliveUnits = self.AliveUnits + 1
|
||||||
trace.l(self.ClassName, "OnBirth", self.AliveUnits )
|
self:T( self.AliveUnits )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -555,17 +732,17 @@ end
|
|||||||
--- Obscolete
|
--- Obscolete
|
||||||
-- @todo Need to delete this... _Database does this now ...
|
-- @todo Need to delete this... _Database does this now ...
|
||||||
function SPAWN:OnDeadOrCrash( event )
|
function SPAWN:OnDeadOrCrash( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
trace.l( self.ClassName, "OnDeadOrCrash", "Dead object : " .. event.initiator:getName() )
|
self:T( "Dead object : " .. event.initiator:getName() )
|
||||||
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
||||||
if EventPrefix == self.SpawnPrefix .. '#' then
|
if EventPrefix == self.SpawnPrefix .. '#' then
|
||||||
-- local DestroyedUnit = Unit.getByName( EventPrefix )
|
-- local DestroyedUnit = Unit.getByName( EventPrefix )
|
||||||
-- if DestroyedUnit and DestroyedUnit.getLife() <= 1.0 then
|
-- if DestroyedUnit and DestroyedUnit.getLife() <= 1.0 then
|
||||||
--MessageToAll( "Mission command: unit " .. SpawnPrefix .. " crashed." , 5, EventPrefix .. '/Event')
|
--MessageToAll( "Mission command: unit " .. SpawnPrefix .. " crashed." , 5, EventPrefix .. '/Event')
|
||||||
self.AliveUnits = self.AliveUnits - 1
|
self.AliveUnits = self.AliveUnits - 1
|
||||||
trace.l( self.ClassName, "OnDeadOrCrash", self.AliveUnits )
|
self:T( self.AliveUnits )
|
||||||
-- end
|
-- end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -575,17 +752,17 @@ end
|
|||||||
-- This is needed to ensure that Re-SPAWNing is only done for landed AIR Groups.
|
-- This is needed to ensure that Re-SPAWNing is only done for landed AIR Groups.
|
||||||
-- @todo Need to test for AIR Groups only...
|
-- @todo Need to test for AIR Groups only...
|
||||||
function SPAWN:OnLand( event )
|
function SPAWN:OnLand( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
trace.l( self.ClassName, "OnLand", "Landed object : " .. event.initiator:getName() )
|
self:T( "Landed object : " .. event.initiator:getName() )
|
||||||
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
||||||
if EventPrefix == self.SpawnPrefix .. '#' then
|
if EventPrefix == self.SpawnPrefix .. '#' then
|
||||||
self.Landed = true
|
self.Landed = true
|
||||||
trace.l( self.ClassName, "OnLand", "self.Landed = true" )
|
self:T( "self.Landed = true" )
|
||||||
if self.Landed and self.RepeatOnLanding then
|
if self.Landed and self.RepeatOnLanding then
|
||||||
local SpawnGroupName = Unit.getGroup(event.initiator):getName()
|
local SpawnGroupName = Unit.getGroup(event.initiator):getName()
|
||||||
trace.l( self.ClassName, "OnLand", "ReSpawn " .. SpawnGroupName )
|
self:T( "ReSpawn " .. SpawnGroupName )
|
||||||
self:ReSpawn( SpawnGroupName )
|
self:ReSpawn( SpawnGroupName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -596,13 +773,13 @@ end
|
|||||||
-- This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.
|
-- This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.
|
||||||
-- @todo Need to test for AIR Groups only...
|
-- @todo Need to test for AIR Groups only...
|
||||||
function SPAWN:OnTakeOff( event )
|
function SPAWN:OnTakeOff( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
trace.l( self.ClassName, "OnTakeOff", "TakeOff object : " .. event.initiator:getName() )
|
self:T( "TakeOff object : " .. event.initiator:getName() )
|
||||||
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
||||||
if EventPrefix == self.SpawnPrefix .. '#' then
|
if EventPrefix == self.SpawnPrefix .. '#' then
|
||||||
trace.l( self.ClassName, "OnTakeOff", "self.Landed = false" )
|
self:T( "self.Landed = false" )
|
||||||
self.Landed = false
|
self.Landed = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -615,15 +792,15 @@ end
|
|||||||
-- @see OnLand
|
-- @see OnLand
|
||||||
-- @todo Need to test for AIR Groups only...
|
-- @todo Need to test for AIR Groups only...
|
||||||
function SPAWN:OnEngineShutDown( event )
|
function SPAWN:OnEngineShutDown( event )
|
||||||
trace.f( self.ClassName, { event } )
|
self:T( { event } )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
trace.l( self.ClassName, "OnEngineShutDown", "EngineShutDown object : " .. event.initiator:getName() )
|
self:T( "EngineShutDown object : " .. event.initiator:getName() )
|
||||||
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
local EventPrefix = string.match( event.initiator:getName(), ".*#" )
|
||||||
if EventPrefix == self.SpawnPrefix .. '#' then
|
if EventPrefix == self.SpawnPrefix .. '#' then
|
||||||
if self.Landed and self.RepeatOnEngineShutDown then
|
if self.Landed and self.RepeatOnEngineShutDown then
|
||||||
local SpawnGroupName = Unit.getGroup(event.initiator):getName()
|
local SpawnGroupName = Unit.getGroup(event.initiator):getName()
|
||||||
trace.l( self.ClassName, "OnEngineShutDown", "ReSpawn " .. SpawnGroupName )
|
self:T( "ReSpawn " .. SpawnGroupName )
|
||||||
self:ReSpawn( SpawnGroupName )
|
self:ReSpawn( SpawnGroupName )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -636,7 +813,7 @@ end
|
|||||||
--- This function is called automatically by the Spawning scheduler.
|
--- This function is called automatically by the Spawning scheduler.
|
||||||
-- It is the internal worker method SPAWNing new Groups on the defined time intervals.
|
-- It is the internal worker method SPAWNing new Groups on the defined time intervals.
|
||||||
function SPAWN:_Scheduler()
|
function SPAWN:_Scheduler()
|
||||||
trace.l( self.ClassName, '_Scheduler', self.SpawnPrefix )
|
self:T( self.SpawnPrefix )
|
||||||
|
|
||||||
if self.SpawnInit or self.SpawnCurrentTimer == self.SpawnSetTimer then
|
if self.SpawnInit or self.SpawnCurrentTimer == self.SpawnSetTimer then
|
||||||
-- Validate if there are still groups left in the batch...
|
-- Validate if there are still groups left in the batch...
|
||||||
|
|||||||
731
Moose/Stage.lua
731
Moose/Stage.lua
@ -27,13 +27,12 @@ STAGE = {
|
|||||||
|
|
||||||
|
|
||||||
function STAGE:New()
|
function STAGE:New()
|
||||||
trace.f(self.ClassName)
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T()
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGE:Execute( Mission, Client, Task )
|
function STAGE:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
@ -41,13 +40,10 @@ trace.f(self.ClassName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function STAGE:Executing( Mission, Client, Task )
|
function STAGE:Executing( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGE:Validate( Mission, Client, Task )
|
function STAGE:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
local Valid = true
|
local Valid = true
|
||||||
|
|
||||||
return Valid
|
return Valid
|
||||||
@ -56,31 +52,30 @@ end
|
|||||||
|
|
||||||
STAGEBRIEF = {
|
STAGEBRIEF = {
|
||||||
ClassName = "BRIEF",
|
ClassName = "BRIEF",
|
||||||
MSG = { ID = "Brief", TIME = 30 },
|
MSG = { ID = "Brief", TIME = 1 },
|
||||||
Name = "Brief",
|
Name = "Brief",
|
||||||
StageBriefingTime = 0,
|
StageBriefingTime = 0,
|
||||||
StageBriefingDuration = 30
|
StageBriefingDuration = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function STAGEBRIEF:New()
|
function STAGEBRIEF:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEBRIEF:Execute( Mission, Client, Task )
|
function STAGEBRIEF:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
|
||||||
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
Mission:ShowBriefing( Client )
|
Mission:ShowBriefing( Client )
|
||||||
self.StageBriefingTime = timer.getTime()
|
self.StageBriefingTime = timer.getTime()
|
||||||
return Valid
|
return Valid
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEBRIEF:Validate( Mission, Client, Task )
|
function STAGEBRIEF:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
|
||||||
local Valid = STAGE:Validate( Mission, Client, Task )
|
local Valid = STAGE:Validate( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
|
|
||||||
if timer.getTime() - self.StageBriefingTime <= self.StageBriefingDuration then
|
if timer.getTime() - self.StageBriefingTime <= self.StageBriefingDuration then
|
||||||
return 0
|
return 0
|
||||||
@ -94,34 +89,33 @@ end
|
|||||||
|
|
||||||
STAGESTART = {
|
STAGESTART = {
|
||||||
ClassName = "START",
|
ClassName = "START",
|
||||||
MSG = { ID = "Start", TIME = 30 },
|
MSG = { ID = "Start", TIME = 1 },
|
||||||
Name = "Start",
|
Name = "Start",
|
||||||
StageStartTime = 0,
|
StageStartTime = 0,
|
||||||
StageStartDuration = 30
|
StageStartDuration = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
function STAGESTART:New()
|
function STAGESTART:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGESTART:Execute( Mission, Client, Task )
|
function STAGESTART:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
||||||
if Task.TaskBriefing then
|
if Task.TaskBriefing then
|
||||||
Client:Message( Task.TaskBriefing, self.StageStartDuration, Mission.Name .. "/Stage", "Mission Command: Tasking" )
|
Client:Message( Task.TaskBriefing, 30, Mission.Name .. "/Stage", "Mission Command: Tasking" )
|
||||||
else
|
else
|
||||||
Client:Message( 'Task ' .. Task.TaskNumber .. '.', self.StageStartDuration, Mission.Name .. "/Stage", "Mission Command: Tasking" )
|
Client:Message( 'Task ' .. Task.TaskNumber .. '.', 30, Mission.Name .. "/Stage", "Mission Command: Tasking" )
|
||||||
end
|
end
|
||||||
self.StageStartTime = timer.getTime()
|
self.StageStartTime = timer.getTime()
|
||||||
return Valid
|
return Valid
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGESTART:Validate( Mission, Client, Task )
|
function STAGESTART:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
local Valid = STAGE:Validate( Mission, Client, Task )
|
local Valid = STAGE:Validate( Mission, Client, Task )
|
||||||
|
|
||||||
if timer.getTime() - self.StageStartTime <= self.StageStartDuration then
|
if timer.getTime() - self.StageStartTime <= self.StageStartDuration then
|
||||||
@ -135,17 +129,90 @@ trace.f(self.ClassName)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
STAGE_CARGO_LOAD = {
|
||||||
|
ClassName = "STAGE_CARGO_LOAD"
|
||||||
|
}
|
||||||
|
|
||||||
|
function STAGE_CARGO_LOAD:New()
|
||||||
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
|
self:T()
|
||||||
|
self.StageType = 'CLIENT'
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function STAGE_CARGO_LOAD:Execute( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
|
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
||||||
|
|
||||||
|
for LoadCargoID, LoadCargo in pairs( Task.Cargos.LoadCargos ) do
|
||||||
|
LoadCargo:Load( Client )
|
||||||
|
end
|
||||||
|
|
||||||
|
if Mission.MissionReportFlash and Client:IsTransport() then
|
||||||
|
Client:ShowCargo()
|
||||||
|
end
|
||||||
|
|
||||||
|
return Valid
|
||||||
|
end
|
||||||
|
|
||||||
|
function STAGE_CARGO_LOAD:Validate( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
|
local Valid = STAGE:Validate( Mission, Client, Task )
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
STAGE_CARGO_INIT = {
|
||||||
|
ClassName = "STAGE_CARGO_INIT"
|
||||||
|
}
|
||||||
|
|
||||||
|
function STAGE_CARGO_INIT:New()
|
||||||
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
|
self:T()
|
||||||
|
self.StageType = 'CLIENT'
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function STAGE_CARGO_INIT:Execute( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
|
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
||||||
|
|
||||||
|
for InitLandingZoneID, InitLandingZone in pairs( Task.LandingZones.LandingZones ) do
|
||||||
|
self:T( InitLandingZone )
|
||||||
|
InitLandingZone:Spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
self:T( Task.Cargos.InitCargos )
|
||||||
|
for InitCargoID, InitCargoData in pairs( Task.Cargos.InitCargos ) do
|
||||||
|
self:T( { InitCargoData } )
|
||||||
|
InitCargoData:Spawn()
|
||||||
|
end
|
||||||
|
|
||||||
|
return Valid
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function STAGE_CARGO_INIT:Validate( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
|
local Valid = STAGE:Validate( Mission, Client, Task )
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
STAGEROUTE = {
|
STAGEROUTE = {
|
||||||
ClassName = "STAGEROUTE",
|
ClassName = "STAGEROUTE",
|
||||||
MSG = { ID = "Route", TIME = 1 },
|
MSG = { ID = "Route", TIME = 5 },
|
||||||
Frequency = STAGE.FREQUENCY.REPEAT,
|
Frequency = STAGE.FREQUENCY.REPEAT,
|
||||||
Name = "Route"
|
Name = "Route"
|
||||||
}
|
}
|
||||||
|
|
||||||
function STAGEROUTE:New()
|
function STAGEROUTE:New()
|
||||||
trace.f(self.ClassName)
|
|
||||||
-- Arrange meta tables
|
|
||||||
local self = BASE:Inherit( self, STAGE:New() )
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
|
self:T()
|
||||||
self.StageType = 'CLIENT'
|
self.StageType = 'CLIENT'
|
||||||
self.MessageSwitch = true
|
self.MessageSwitch = true
|
||||||
return self
|
return self
|
||||||
@ -153,19 +220,17 @@ end
|
|||||||
|
|
||||||
|
|
||||||
function STAGEROUTE:Execute( Mission, Client, Task )
|
function STAGEROUTE:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
|
||||||
|
|
||||||
if type( Task.LandingZones) == "table" then
|
local RouteMessage = "Fly to "
|
||||||
local RouteMessage = "Fly to "
|
self:T( Task.LandingZones )
|
||||||
for LandingZoneID, LandingZoneName in pairs( Task.LandingZones ) do
|
for LandingZoneID, LandingZoneName in pairs( Task.LandingZones.LandingZoneNames ) do
|
||||||
RouteMessage = RouteMessage .. LandingZoneName .. ' at ' .. routines.getBRStringZone( { zone = LandingZoneName, ref = Client:ClientGroup():getUnit(1):getPoint(), true, true } ) .. ' km. '
|
RouteMessage = RouteMessage .. LandingZoneName .. ' at ' .. routines.getBRStringZone( { zone = LandingZoneName, ref = Client:GetClientGroupUnit():getPoint(), true, true } ) .. ' km. '
|
||||||
end
|
|
||||||
Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageRoute", "Co-Pilot: Route", 10 )
|
|
||||||
else
|
|
||||||
Client:Message( "Fly to " .. Task.LandingZones .. ' at ' .. routines.getBRStringZone( { zone = Task.LandingZones, ref = Client:ClientGroup():getUnit(1):getPoint(), true, true } ) .. ' km. ', self.MSG.TIME, Mission.Name .. "/StageRoute", "Co-Pilot: Route", 1 )
|
|
||||||
end
|
end
|
||||||
if Client:IsTransport() then
|
Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageRoute", "Co-Pilot: Route", 20 )
|
||||||
|
|
||||||
|
if Mission.MissionReportFlash and Client:IsTransport() then
|
||||||
Client:ShowCargo()
|
Client:ShowCargo()
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -173,59 +238,32 @@ trace.f(self.ClassName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function STAGEROUTE:Validate( Mission, Client, Task )
|
function STAGEROUTE:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
local Valid = STAGE:Validate( Mission, Client, Task )
|
local Valid = STAGE:Validate( Mission, Client, Task )
|
||||||
|
|
||||||
|
-- check if the Client is in the landing zone
|
||||||
|
self:T( Task.LandingZones.LandingZoneNames )
|
||||||
|
Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones.LandingZoneNames )
|
||||||
|
|
||||||
|
if Task.CurrentLandingZoneName then
|
||||||
|
|
||||||
-- check if this carrier is in the landing zone
|
Task.CurrentLandingZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName].CargoZone
|
||||||
Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones )
|
Task.CurrentCargoZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName]
|
||||||
if ( Task.CurrentLandingZoneID ) then
|
|
||||||
if not Task.Signalled then
|
if Task.CurrentCargoZone then
|
||||||
|
if not Task.Signalled then
|
||||||
if Task.LandingZoneSignalType then
|
Task.Signalled = Task.CurrentCargoZone:Signal()
|
||||||
env.info( 'TransportSchedule: Task.LandingZoneSignalType = ' .. Task.LandingZoneSignalType.TEXT )
|
|
||||||
if Task.LandingZoneSignalUnitNames then
|
|
||||||
local LandingZoneSignalUnit = Task.LandingZoneSignalUnitNames[Task.CurrentLandingZoneID]
|
|
||||||
trace.i( self.ClassName, 'LandingZoneSignalUnit = ' .. LandingZoneSignalUnit )
|
|
||||||
|
|
||||||
local SignalUnit = Unit.getByName(LandingZoneSignalUnit)
|
|
||||||
if SignalUnit == nil then
|
|
||||||
SignalUnit = StaticObject.getByName( LandingZoneSignalUnit )
|
|
||||||
end
|
|
||||||
if SignalUnit ~= nil then
|
|
||||||
trace.i( self.ClassName, 'Signalling Unit' )
|
|
||||||
local SignalVehiclePos = SignalUnit:getPosition().p
|
|
||||||
SignalVehiclePos.y = SignalVehiclePos.y + Task.LandingZoneSignalHeight
|
|
||||||
if Task.LandingZoneSignalType.ID == Task.SIGNAL.TYPE.SMOKE.ID then
|
|
||||||
trigger.action.smoke( SignalVehiclePos, Task.LandingZoneSignalColor.COLOR )
|
|
||||||
elseif Task.LandingZoneSignalType.ID == Task.SIGNAL.TYPE.FLARE.ID then
|
|
||||||
trigger.action.signalFlare( SignalVehiclePos, Task.LandingZoneSignalColor.COLOR, 0 )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
env.info( 'TransportSchedule: Signaling landing zone ' )
|
|
||||||
|
|
||||||
local LandingZone = trigger.misc.getZone( Task.LandingZones [ Task.CurrentLandingZoneID ] )
|
|
||||||
local CurrentPosition = { x = LandingZone.point.x, y = LandingZone.point.z }
|
|
||||||
LandingZone.point.y = land.getHeight( CurrentPosition ) + 10
|
|
||||||
|
|
||||||
if Task.LandingZoneSignalType.ID == Task.SIGNAL.TYPE.SMOKE.ID then
|
|
||||||
env.info( 'TransportSchedule: Smoking zone x = ' .. LandingZone.point.x .. ' y = ' .. LandingZone.point.y .. ' z = ' .. LandingZone.point.z )
|
|
||||||
trigger.action.smoke( LandingZone.point, Task.LandingZoneSignalColor.COLOR )
|
|
||||||
elseif Task.LandingZoneSignalType.ID == Task.SIGNAL.TYPE.SMOKE.FLARE.ID then
|
|
||||||
env.info( 'TransportSchedule: Flaring zone x = ' .. LandingZone.point.x .. ' y = ' .. LandingZone.point.y .. ' z = ' .. LandingZone.point.z )
|
|
||||||
trigger.action.signalFlare( LandingZone.point, Task.LandingZoneSignalColor.COLOR, 0 )
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.Signalled = true
|
|
||||||
|
return 1
|
||||||
end
|
end
|
||||||
return 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
STAGELANDING = {
|
STAGELANDING = {
|
||||||
ClassName = "STAGELANDING",
|
ClassName = "STAGELANDING",
|
||||||
MSG = { ID = "Landing", TIME = 10 },
|
MSG = { ID = "Landing", TIME = 10 },
|
||||||
@ -234,37 +272,96 @@ STAGELANDING = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGELANDING:New()
|
function STAGELANDING:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGELANDING:Execute( Mission, Client, Task )
|
function STAGELANDING:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
Client:Message( 'We have arrived at ' .. Task.LandingZones[Task.CurrentLandingZoneID] .. '. Land the helicopter to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType.TEXT .. '.',
|
Client:Message( "We have arrived at the landing zone.", self.MSG.TIME, Mission.Name .. "/StageArrived", "Co-Pilot: Arrived", 10 )
|
||||||
self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Landing" )
|
|
||||||
|
Task.HostUnit = Task.CurrentCargoZone:GetHostUnit()
|
||||||
|
|
||||||
|
if Task.HostUnit then
|
||||||
|
|
||||||
|
Task.HostUnitName = Task.HostUnit:getName()
|
||||||
|
Task.HostUnitTypeName = Task.HostUnit:getTypeName()
|
||||||
|
|
||||||
|
local HostMessage = ""
|
||||||
|
Task.CargoNames = ""
|
||||||
|
|
||||||
|
local IsFirst = true
|
||||||
|
|
||||||
|
for CargoID, Cargo in pairs( CARGOS ) do
|
||||||
|
if Cargo.CargoType == Task.CargoType then
|
||||||
|
|
||||||
|
if Cargo:IsLandingRequired() then
|
||||||
|
self:T( "Task for cargo " .. Cargo.CargoType .. " requires landing.")
|
||||||
|
Task.IsLandingRequired = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if Cargo:IsSlingLoad() then
|
||||||
|
self:T( "Task for cargo " .. Cargo.CargoType .. " is a slingload.")
|
||||||
|
Task.IsSlingLoad = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if IsFirst then
|
||||||
|
IsFirst = false
|
||||||
|
Task.CargoNames = Task.CargoNames .. Cargo.CargoName .. "( " .. Cargo.CargoWeight .. " )"
|
||||||
|
else
|
||||||
|
Task.CargoNames = Task.CargoNames .. "; " .. Cargo.CargoName .. "( " .. Cargo.CargoWeight .. " )"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if Task.IsLandingRequired then
|
||||||
|
HostMessage = "Land the helicopter to " .. Task.TEXT[1] .. " " .. Task.CargoNames .. "."
|
||||||
|
else
|
||||||
|
HostMessage = "Use the Radio menu and F6 to find the cargo, then fly or land near the cargo and " .. Task.TEXT[1] .. " " .. Task.CargoNames .. "."
|
||||||
|
end
|
||||||
|
|
||||||
|
Client:Message( HostMessage, self.MSG.TIME, Mission.Name .. "/STAGELANDING.EXEC." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":", 10 )
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGELANDING:Validate( Mission, Client, Task )
|
function STAGELANDING:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then
|
Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones.LandingZoneNames )
|
||||||
else
|
if Task.CurrentLandingZoneName then
|
||||||
Task.Signalled = false
|
|
||||||
Task:RemoveCargoMenus( Client )
|
-- Client is in de landing zone.
|
||||||
return -1
|
self:T( Task.CurrentLandingZoneName )
|
||||||
end
|
|
||||||
|
Task.CurrentLandingZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName].CargoZone
|
||||||
|
Task.CurrentCargoZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName]
|
||||||
|
|
||||||
|
if Task.CurrentCargoZone then
|
||||||
|
if not Task.Signalled then
|
||||||
|
Task.Signalled = Task.CurrentCargoZone:Signal()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if Task.CurrentLandingZone then
|
||||||
|
Task.CurrentLandingZone = nil
|
||||||
|
end
|
||||||
|
if Task.CurrentCargoZone then
|
||||||
|
Task.CurrentCargoZone = nil
|
||||||
|
end
|
||||||
|
Task.Signalled = false
|
||||||
|
Task:RemoveCargoMenus( Client )
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
|
||||||
if not Client:ClientGroup():getUnits()[1]:inAir() then
|
if Task.IsLandingRequired and Client:GetClientGroupUnit():inAir() then
|
||||||
else
|
return 0
|
||||||
return 0
|
end
|
||||||
end
|
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
STAGELANDED = {
|
STAGELANDED = {
|
||||||
@ -275,46 +372,52 @@ STAGELANDED = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGELANDED:New()
|
function STAGELANDED:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGELANDED:Execute( Mission, Client, Task )
|
function STAGELANDED:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
Client:Message( 'We have landed within the landing zone. Use the radio menu (F10) to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType.TEXT .. '.', self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Landed" )
|
|
||||||
if not self.MenusAdded then
|
if Task.IsLandingRequired then
|
||||||
Task:RemoveCargoMenus( Client )
|
Client:Message( 'We have landed within the landing zone. Use the radio menu (F10) to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType .. '.',
|
||||||
Task:AddCargoMenus( Client, Mission._Cargos, 250 )
|
self.MSG.TIME, Mission.Name .. "/STAGELANDED.EXEC." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
if not self.MenusAdded then
|
||||||
|
Task.Cargo = nil
|
||||||
|
Task:RemoveCargoMenus( Client )
|
||||||
|
Task:AddCargoMenus( Client, CARGOS, 250 )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function STAGELANDED:Validate( Mission, Client, Task )
|
function STAGELANDED:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then
|
if not routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then
|
||||||
else
|
self:T( "Client is not anymore in the landing zone, go back to stage Route, and remove cargo menus." )
|
||||||
Task.Signalled = false
|
Task.Signalled = false
|
||||||
Task:RemoveCargoMenus( Client )
|
Task:RemoveCargoMenus( Client )
|
||||||
return -2
|
return -2
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Client:ClientGroup():getUnits()[1]:inAir() then
|
if Task.IsLandingRequired and Client:GetClientGroupUnit():inAir() then
|
||||||
else
|
self:T( "Client went back in the air. Go back to stage Landing." )
|
||||||
Task.Signalled = false
|
Task.Signalled = false
|
||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
|
|
||||||
if Task.ExecuteStage == _TransportExecuteStage.EXECUTING then
|
-- Wait until cargo is selected from the menu.
|
||||||
else
|
if Task.IsLandingRequired then
|
||||||
return 0
|
if not Task.Cargo then
|
||||||
end
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
STAGEUNLOAD = {
|
STAGEUNLOAD = {
|
||||||
@ -324,72 +427,63 @@ STAGEUNLOAD = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGEUNLOAD:New()
|
function STAGEUNLOAD:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEUNLOAD:Execute( Mission, Client, Task )
|
function STAGEUNLOAD:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
Client:Message( 'The ' .. Task.CargoType.TEXT .. ' are being ' .. Task.TEXT[2] .. ' within the landing zone. Wait until the helicopter is ' .. Task.TEXT[3] .. '.',
|
Client:Message( 'The ' .. Task.CargoType .. ' are being ' .. Task.TEXT[2] .. ' within the landing zone. Wait until the helicopter is ' .. Task.TEXT[3] .. '.',
|
||||||
self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Unload" )
|
self.MSG.TIME, Mission.Name .. "/StageUnLoad", "Co-Pilot: Unload" )
|
||||||
Task:RemoveCargoMenus( Client )
|
Task:RemoveCargoMenus( Client )
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEUNLOAD:Executing( Mission, Client, Task )
|
function STAGEUNLOAD:Executing( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
env.info( 'STAGEUNLOAD:Executing() Task.CargoName = ' .. Task.CargoName )
|
env.info( 'STAGEUNLOAD:Executing() Task.Cargo.CargoName = ' .. Task.Cargo.CargoName )
|
||||||
local Cargo = Client:RemoveCargo( Task.CargoName )
|
|
||||||
if Cargo then
|
local TargetZoneName
|
||||||
env.info( 'STAGEUNLOAD:Executing() Cargo.CargoName = ' .. Cargo.CargoName )
|
|
||||||
env.info( 'STAGEUNLOAD:Executing() Cargo.CargoGroupName = ' .. Cargo.CargoGroupName )
|
if Task.TargetZoneName then
|
||||||
env.info( 'STAGEUNLOAD:Executing() Mission._Cargos[Cargo.CargoName].CargoGroupTemplate = ' .. Mission._Cargos[Cargo.CargoName].CargoGroupTemplate )
|
TargetZoneName = Task.TargetZoneName
|
||||||
|
else
|
||||||
if Cargo.CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then
|
TargetZoneName = Task.CurrentLandingZoneName
|
||||||
if Cargo.CargoName then
|
end
|
||||||
if Task.TargetZoneName then
|
|
||||||
SPAWN:New( Mission._Cargos[Cargo.CargoName].CargoGroupTemplate ):FromCarrier ( Client:ClientGroup(),
|
if Task.Cargo:UnLoad( Client, TargetZoneName ) then
|
||||||
Task.TargetZoneName,
|
|
||||||
Mission._Cargos[Cargo.CargoName].CargoGroupName )
|
|
||||||
else
|
|
||||||
SPAWN:New( Mission._Cargos[Cargo.CargoName].CargoGroupTemplate ):FromCarrier ( Client:ClientGroup(),
|
|
||||||
Task.LandingZones[Task.CurrentLandingZoneID],
|
|
||||||
Mission._Cargos[Cargo.CargoName].CargoGroupName )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
|
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
|
||||||
Client:ShowCargo()
|
if Mission.MissionReportFlash then
|
||||||
|
Client:ShowCargo()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEUNLOAD:Validate( Mission, Client, Task )
|
function STAGEUNLOAD:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
env.info( 'STAGEUNLOAD:Validate()' )
|
env.info( 'STAGEUNLOAD:Validate()' )
|
||||||
|
|
||||||
if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then
|
if routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then
|
||||||
else
|
else
|
||||||
Task.ExecuteStage = _TransportExecuteStage.FAILED
|
Task.ExecuteStage = _TransportExecuteStage.FAILED
|
||||||
Task:RemoveCargoMenus( Client )
|
Task:RemoveCargoMenus( Client )
|
||||||
Client:Message( 'The ' .. Task.CargoType.TEXT .. " haven't been successfully " .. Task.TEXT[3] .. ' within the landing zone. Task and mission has failed.',
|
Client:Message( 'The ' .. Task.CargoType .. " haven't been successfully " .. Task.TEXT[3] .. ' within the landing zone. Task and mission has failed.',
|
||||||
_TransportStageMsgTime.DONE, Mission.Name .. "/StageFailure", "Co-Pilot: Unload" )
|
_TransportStageMsgTime.DONE, Mission.Name .. "/StageFailure", "Co-Pilot: Unload" )
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if not Client:ClientGroup():getUnits()[1]:inAir() then
|
if not Client:GetClientGroupUnit():inAir() then
|
||||||
else
|
else
|
||||||
Task.ExecuteStage = _TransportExecuteStage.FAILED
|
Task.ExecuteStage = _TransportExecuteStage.FAILED
|
||||||
Task:RemoveCargoMenus( Client )
|
Task:RemoveCargoMenus( Client )
|
||||||
Client:Message( 'The ' .. Task.CargoType.TEXT .. " haven't been successfully " .. Task.TEXT[3] .. ' within the landing zone. Task and mission has failed.',
|
Client:Message( 'The ' .. Task.CargoType .. " haven't been successfully " .. Task.TEXT[3] .. ' within the landing zone. Task and mission has failed.',
|
||||||
_TransportStageMsgTime.DONE, Mission.Name .. "/StageFailure", "Co-Pilot: Unload" )
|
_TransportStageMsgTime.DONE, Mission.Name .. "/StageFailure", "Co-Pilot: Unload" )
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then
|
if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then
|
||||||
Client:Message( 'The ' .. Task.CargoType.TEXT .. ' have been sucessfully ' .. Task.TEXT[3] .. ' within the landing zone.', _TransportStageMsgTime.DONE, Mission.Name .. "/Stage", "Co-Pilot: Unload" )
|
Client:Message( 'The ' .. Task.CargoType .. ' have been sucessfully ' .. Task.TEXT[3] .. ' within the landing zone.', _TransportStageMsgTime.DONE, Mission.Name .. "/Stage", "Co-Pilot: Unload" )
|
||||||
Mission._Cargos[Task.CargoName].Status = CARGOSTATUS.UNLOADED
|
|
||||||
Task:RemoveCargoMenus( Client )
|
Task:RemoveCargoMenus( Client )
|
||||||
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 ) -- We set the cargo as one more goal completed in the mission.
|
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 ) -- We set the cargo as one more goal completed in the mission.
|
||||||
return 1
|
return 1
|
||||||
@ -405,173 +499,131 @@ STAGELOAD = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGELOAD:New()
|
function STAGELOAD:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGELOAD:Execute( Mission, Client, Task )
|
function STAGELOAD:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
Client:Message( 'The ' .. Task.CargoType.TEXT .. ' are being ' .. Task.TEXT[2] .. ' within the landing zone. Wait until the helicopter is ' .. Task.TEXT[3] .. '.',
|
|
||||||
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/Stage", "Co-Pilot: Load" )
|
if not Task.IsSlingLoad then
|
||||||
|
Client:Message( 'The ' .. Task.CargoType .. ' are being ' .. Task.TEXT[2] .. ' within the landing zone. Wait until the helicopter is ' .. Task.TEXT[3] .. '.',
|
||||||
|
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.EXEC." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
|
||||||
-- Route the cargo to the Carrier
|
-- Route the cargo to the Carrier
|
||||||
if Mission._Cargos[Task.CargoName].CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then
|
Task.Cargo:OnBoard( Client, Task.CurrentCargoZone, Task.OnBoardSide )
|
||||||
Task:OnBoardCargo( Client:ClientGroup(), Mission._Cargos )
|
|
||||||
Task.ExecuteStage = _TransportExecuteStage.EXECUTING
|
Task.ExecuteStage = _TransportExecuteStage.EXECUTING
|
||||||
else
|
else
|
||||||
-- Add the group to the internal cargo;
|
Task.ExecuteStage = _TransportExecuteStage.EXECUTING
|
||||||
Client:AddCargo( Task.CargoName, Mission._Cargos[Task.CargoName].CargoGroupName, Mission._Cargos[Task.CargoName].CargoType, Mission._Cargos[Task.CargoName].CargoWeight, Mission._Cargos[Task.CargoName].CargoGroupTemplate )
|
|
||||||
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGELOAD:Executing( Mission, Client, Task )
|
function STAGELOAD:Executing( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
-- Remove the loaded object from the battle zone.
|
-- If the Cargo is ready to be loaded, load it into the Client.
|
||||||
|
|
||||||
if routines.IsPartOfGroupInRadius( Group.getByName(Mission._Cargos[Task.CargoName].CargoGroupName), Client:ClientGroup(), 75 ) then
|
|
||||||
routines.DestroyGroupInRadiusFromGroup( Group.getByName(Mission._Cargos[Task.CargoName].CargoGroupName), Client:ClientGroup(), 75 )
|
|
||||||
env.info('trying to remove cargo')
|
|
||||||
|
|
||||||
-- Add the group to the internal cargo;
|
|
||||||
Client:AddCargo( Task.CargoName, Mission._Cargos[Task.CargoName].CargoGroupName, Mission._Cargos[Task.CargoName].CargoType, Mission._Cargos[Task.CargoName].CargoWeight, Mission._Cargos[Task.CargoName].CargoGroupTemplate )
|
if not Task.IsSlingLoad then
|
||||||
|
trace.i(self.ClassName, Task.Cargo.CargoName)
|
||||||
-- Message to the pilot that cargo has been loaded.
|
|
||||||
Client:Message( "The cargo " .. Task.CargoName .. " has been loaded in our helicopter.", 20, Mission.Name .. "/Stage", "Co-Pilot: Load" )
|
if Task.Cargo:OnBoarded( Client, Task.CurrentCargoZone ) then
|
||||||
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
|
|
||||||
Client:ShowCargo()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
function STAGELOAD:Validate( Mission, Client, Task )
|
-- Load the Cargo onto the Client
|
||||||
trace.f(self.ClassName)
|
Task.Cargo:Load( Client )
|
||||||
if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then
|
|
||||||
|
-- Message to the pilot that cargo has been loaded.
|
||||||
|
Client:Message( "The cargo " .. Task.Cargo.CargoName .. " has been loaded in our helicopter.",
|
||||||
|
20, Mission.Name .. "/STAGELANDING.LOADING1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
|
||||||
|
|
||||||
|
Client:ShowCargo()
|
||||||
|
end
|
||||||
else
|
else
|
||||||
Task:RemoveCargoMenus( Client )
|
Client:Message( "Hook the " .. Task.CargoNames .. " onto the helicopter " .. Task.TEXT[3] .. " within the landing zone.",
|
||||||
Task.ExecuteStage = _TransportExecuteStage.FAILED
|
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.LOADING.1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":", 10 )
|
||||||
Task.CargoName = nil
|
for CargoID, Cargo in pairs( CARGOS ) do
|
||||||
Client:Message( "The " .. Task.CargoType.TEXT .. " loading has been aborted. You flew outside the pick-up zone while loading. ",
|
self:T( "Cargo.CargoName = " .. Cargo.CargoName )
|
||||||
_TransportStageMsgTime.DONE, Mission.Name .. "/StageSuccess", "Co-Pilot: Load" )
|
|
||||||
return 1
|
if Cargo:IsSlingLoad() then
|
||||||
end
|
local CargoStatic = StaticObject.getByName( Cargo.CargoStaticName )
|
||||||
|
if CargoStatic then
|
||||||
if not Client:ClientGroup():getUnits()[1]:inAir() then
|
trace.i(self.ClassName, "Cargo is found in the DCS simulator.")
|
||||||
else
|
local CargoStaticPosition = CargoStatic:getPosition().p
|
||||||
-- The carrier is back in the air, undo the loading process.
|
trace.i(self.ClassName, "Cargo Position x = " .. CargoStaticPosition.x .. ", y = " .. CargoStaticPosition.y .. ", z = " .. CargoStaticPosition.z )
|
||||||
Task:RemoveCargoMenus( Client )
|
local CargoStaticHeight = routines.GetUnitHeight( CargoStatic )
|
||||||
Task.ExecuteStage = _TransportExecuteStage.NONE
|
if CargoStaticHeight > 5 then
|
||||||
Task.CargoName = nil
|
trace.i(self.ClassName, "Cargo is airborne.")
|
||||||
Client:Message( "The " .. Task.CargoType.TEXT .. " loading has been aborted. Land the helicopter and load the cargo. Don't fly outside the pick-up zone. ",
|
Cargo:StatusLoaded()
|
||||||
_TransportStageMsgTime.DONE, Mission.Name .. "/StageSuccess", "Co-Pilot: Load" )
|
Task.Cargo = Cargo
|
||||||
return -1
|
Client:Message( 'The Cargo has been successfully hooked onto the helicopter and is now being sling loaded. Fly outside the landing zone.',
|
||||||
end
|
self.MSG.TIME, Mission.Name .. "/STAGELANDING.LOADING.2." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
|
||||||
if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then
|
break
|
||||||
Mission._Cargos[Task.CargoName].Status = CARGOSTATUS.LOADED
|
end
|
||||||
Task:RemoveCargoMenus( Client )
|
else
|
||||||
Client:Message( 'Co-Pilot: The ' .. Task.CargoType.TEXT .. ' have been sucessfully ' .. Task.TEXT[3] .. ' within the landing zone.',
|
self:T( "Cargo not found in the DCS simulator." )
|
||||||
_TransportStageMsgTime.DONE, Mission.Name .. "/Stage", "Co-Pilot: Load" )
|
end
|
||||||
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 )
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
STAGE_SLINGLOAD_HOOK = {
|
|
||||||
ClassName = "STAGE_SLINGLOAD_HOOK",
|
|
||||||
MSG = { ID = "SlingLoadHook", TIME = 10 },
|
|
||||||
Name = "SlingLoadHook"
|
|
||||||
}
|
|
||||||
|
|
||||||
function STAGE_SLINGLOAD_HOOK:New()
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
-- Arrange meta tables
|
|
||||||
local self = BASE:Inherit( self, STAGE:New() )
|
|
||||||
self.StageType = 'CLIENT'
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
function STAGE_SLINGLOAD_HOOK:Execute( Mission, Client, Task )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
Client:Message( 'Hook the Cargo onto the helicopter, and fly out the pick-up zone. Due to a bug in DCS world it cannot be chacked (for the moment) ' ..
|
|
||||||
'if the cargo is in our out of the zone and attached to your helicopter...', self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Hook" )
|
|
||||||
end
|
|
||||||
|
|
||||||
function STAGE_SLINGLOAD_HOOK:Validate( Mission, Client, Task )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
|
|
||||||
for CargoID, CargoName in pairs( Task.CargoPrefixes ) do
|
|
||||||
env.info( CargoName )
|
|
||||||
if StaticObject.getByName( CargoName ):inAir() then
|
|
||||||
Task.CargoName = CargoName
|
|
||||||
Task.CargoID = CargoID
|
|
||||||
Client:Message( 'Co-Pilot: The Cargo has been successfully hooked onto the helicopter within the landing zone.', self.MSG.TIME, Mission.Name .. "/StageSuccess" )
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Task.CargoName then
|
|
||||||
if routines.IsStaticInZones( StaticObject.getByName( Task.CargoName ), Task.LandingZones[Task.CurrentLandingZoneID] ) then
|
|
||||||
else
|
|
||||||
Mission._Cargos[Task.CargoName].Status = CARGOSTATUS.LOADED
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return 1
|
|
||||||
end
|
|
||||||
|
|
||||||
STAGE_SLINGLOAD_UNHOOK = {
|
|
||||||
ClassName = "STAGE_SLINGLOAD_UNHOOK",
|
|
||||||
MSG = { ID = "SlingLoadUnHook", TIME = 10 },
|
|
||||||
Name = "SlingLoadUnHook"
|
|
||||||
}
|
|
||||||
|
|
||||||
function STAGE_SLINGLOAD_UNHOOK:New()
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
-- Arrange meta tables
|
|
||||||
local self = BASE:Inherit( self, STAGE:New() )
|
|
||||||
self.StageType = 'CLIENT'
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
function STAGE_SLINGLOAD_UNHOOK:Execute( Mission, Client, Task )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
Client:Message( 'Deploy the Cargo in the Landing Zone and unhook the cargo, and fly out of the drop zone.', self.MSG.TIME, Mission.Name .. "/StageUnhook", "Co-Pilot: Unhook" )
|
|
||||||
end
|
|
||||||
|
|
||||||
function STAGE_SLINGLOAD_UNHOOK:Validate( Mission, Client, Task )
|
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
for CargoID, CargoName in pairs( Task.CargoPrefixes ) do
|
|
||||||
if StaticObject.getByName( CargoName ):inAir() then
|
|
||||||
Task.CargoName = CargoName
|
|
||||||
Task.CargoID = CargoID
|
|
||||||
Client:Message( 'Co-Pilot: Drop the cargo within the landing zone and unhook.', self.MSG.TIME, Mission.Name .. "/Stage" )
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Task.CargoName then
|
|
||||||
if not StaticObject.getByName( Task.CargoName ):inAir() then
|
|
||||||
if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then
|
|
||||||
else
|
|
||||||
Client:Message( 'Co-Pilot: The Cargo is Dropped in the Landing Zone, and You have flown outside of the landing zone.', self.MSG.TIME, Mission.Name .. "/Stage" )
|
|
||||||
return 1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function STAGELOAD:Validate( Mission, Client, Task )
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
self:T( "Task.CurrentLandingZoneName = " .. Task.CurrentLandingZoneName )
|
||||||
|
|
||||||
|
if not Task.IsSlingLoad then
|
||||||
|
if not routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then
|
||||||
|
Task:RemoveCargoMenus( Client )
|
||||||
|
Task.ExecuteStage = _TransportExecuteStage.FAILED
|
||||||
|
Task.CargoName = nil
|
||||||
|
Client:Message( "The " .. Task.CargoType .. " loading has been aborted. You flew outside the pick-up zone while loading. ",
|
||||||
|
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
|
||||||
|
if not Client:GetClientGroupUnit():inAir() then
|
||||||
|
else
|
||||||
|
-- The carrier is back in the air, undo the loading process.
|
||||||
|
Task:RemoveCargoMenus( Client )
|
||||||
|
Task.ExecuteStage = _TransportExecuteStage.NONE
|
||||||
|
Task.CargoName = nil
|
||||||
|
Client:Message( "The " .. Task.CargoType .. " loading has been aborted. Re-start the " .. Task.TEXT[3] .. " process. Don't fly outside the pick-up zone.",
|
||||||
|
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.2." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
|
||||||
|
if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then
|
||||||
|
Task:RemoveCargoMenus( Client )
|
||||||
|
Client:Message( "Good Job. The " .. Task.CargoType .. " has been sucessfully " .. Task.TEXT[3] .. " within the landing zone.",
|
||||||
|
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.3." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 )
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then
|
||||||
|
CargoStatic = StaticObject.getByName( Task.Cargo.CargoStaticName )
|
||||||
|
if CargoStatic and not routines.IsStaticInZones( CargoStatic, Task.CurrentLandingZoneName ) then
|
||||||
|
Client:Message( "Good Job. The " .. Task.CargoType .. " has been sucessfully " .. Task.TEXT[3] .. " and flown outside of the landing zone.",
|
||||||
|
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.4." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" )
|
||||||
|
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.Cargo.CargoName, 1 )
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
STAGEDONE = {
|
STAGEDONE = {
|
||||||
ClassName = "STAGEDONE",
|
ClassName = "STAGEDONE",
|
||||||
MSG = { ID = "Done", TIME = 10 },
|
MSG = { ID = "Done", TIME = 10 },
|
||||||
@ -579,20 +631,19 @@ STAGEDONE = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGEDONE:New()
|
function STAGEDONE:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'AI'
|
||||||
Child.StageType = 'AI'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEDONE:Execute( Mission, Client, Task )
|
function STAGEDONE:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEDONE:Validate( Mission, Client, Task )
|
function STAGEDONE:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
Task:Done()
|
Task:Done()
|
||||||
|
|
||||||
@ -606,24 +657,23 @@ STAGEARRIVE = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGEARRIVE:New()
|
function STAGEARRIVE:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'CLIENT'
|
||||||
Child.StageType = 'CLIENT'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEARRIVE:Execute( Mission, Client, Task )
|
function STAGEARRIVE:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
Client:Message( 'We have arrived at ' .. Task.LandingZones[Task.CurrentLandingZoneID] .. ".", self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Arrived" )
|
Client:Message( 'We have arrived at ' .. Task.CurrentLandingZoneName .. ".", self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Arrived" )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function STAGEARRIVE:Validate( Mission, Client, Task )
|
function STAGEARRIVE:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones )
|
Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones )
|
||||||
if ( Task.CurrentLandingZoneID ) then
|
if ( Task.CurrentLandingZoneID ) then
|
||||||
else
|
else
|
||||||
return -1
|
return -1
|
||||||
@ -641,11 +691,10 @@ STAGEGROUPSDESTROYED = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function STAGEGROUPSDESTROYED:New()
|
function STAGEGROUPSDESTROYED:New()
|
||||||
trace.f(self.ClassName)
|
local self = BASE:Inherit( self, STAGE:New() )
|
||||||
-- Arrange meta tables
|
self:T()
|
||||||
local Child = BASE:Inherit( self, STAGE:New() )
|
self.StageType = 'AI'
|
||||||
Child.StageType = 'AI'
|
return self
|
||||||
return Child
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--function STAGEGROUPSDESTROYED:Execute( Mission, Client, Task )
|
--function STAGEGROUPSDESTROYED:Execute( Mission, Client, Task )
|
||||||
@ -655,7 +704,7 @@ end
|
|||||||
--end
|
--end
|
||||||
|
|
||||||
function STAGEGROUPSDESTROYED:Validate( Mission, Client, Task )
|
function STAGEGROUPSDESTROYED:Validate( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
|
|
||||||
if Task.MissionTask:IsGoalReached() then
|
if Task.MissionTask:IsGoalReached() then
|
||||||
return 1
|
return 1
|
||||||
@ -665,8 +714,8 @@ trace.f(self.ClassName)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function STAGEGROUPSDESTROYED:Execute( Mission, Client, Task )
|
function STAGEGROUPSDESTROYED:Execute( Mission, Client, Task )
|
||||||
trace.f(self.ClassName)
|
self:T()
|
||||||
trace.i( self.ClassName, { Task.ClassName, Task.Destroyed } )
|
self:T( { Task.ClassName, Task.Destroyed } )
|
||||||
--env.info( 'Event Table Task = ' .. tostring(Task) )
|
--env.info( 'Event Table Task = ' .. tostring(Task) )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -9,29 +9,37 @@ Include.File( "Stage" )
|
|||||||
|
|
||||||
TASK = {
|
TASK = {
|
||||||
|
|
||||||
-- Defines the different signal types with a Task.
|
-- Defines the different signal types with a Task.
|
||||||
SIGNAL = {
|
SIGNAL = {
|
||||||
COLOR = {
|
COLOR = {
|
||||||
RED = { ID = 1, COLOR = trigger.smokeColor.Red, TEXT = "A red" },
|
RED = { ID = 1, COLOR = trigger.smokeColor.Red, TEXT = "A red" },
|
||||||
GREEN = { ID = 2, COLOR = trigger.smokeColor.Green, TEXT = "A green" },
|
GREEN = { ID = 2, COLOR = trigger.smokeColor.Green, TEXT = "A green" },
|
||||||
BLUE = { ID = 3, COLOR = trigger.smokeColor.Blue, TEXT = "A blue" },
|
BLUE = { ID = 3, COLOR = trigger.smokeColor.Blue, TEXT = "A blue" },
|
||||||
WHITE = { ID = 4, COLOR = trigger.smokeColor.White, TEXT = "A white" },
|
WHITE = { ID = 4, COLOR = trigger.smokeColor.White, TEXT = "A white" },
|
||||||
ORANGE = { ID = 5, COLOR = trigger.smokeColor.Orange, TEXT = "An orange" }
|
ORANGE = { ID = 5, COLOR = trigger.smokeColor.Orange, TEXT = "An orange" }
|
||||||
},
|
},
|
||||||
TYPE = {
|
TYPE = {
|
||||||
SMOKE = { ID = 1, TEXT = "smoke" },
|
SMOKE = { ID = 1, TEXT = "smoke" },
|
||||||
FLARE = { ID = 2, TEXT = "flare" }
|
FLARE = { ID = 2, TEXT = "flare" }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClassName = "TASK",
|
ClassName = "TASK",
|
||||||
Mission = {}, -- Owning mission of the Task
|
Mission = {}, -- Owning mission of the Task
|
||||||
Name = '',
|
Name = '',
|
||||||
Stages = {},
|
Stages = {},
|
||||||
Stage = {},
|
Stage = {},
|
||||||
ActiveStage = 0,
|
Cargos = {
|
||||||
TaskDone = false,
|
InitCargos = {},
|
||||||
TaskFailed = false,
|
LoadCargos = {}
|
||||||
GoalTasks = {}
|
},
|
||||||
|
LandingZones = {
|
||||||
|
LandingZoneNames = {},
|
||||||
|
LandingZones = {}
|
||||||
|
},
|
||||||
|
ActiveStage = 0,
|
||||||
|
TaskDone = false,
|
||||||
|
TaskFailed = false,
|
||||||
|
GoalTasks = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Instantiates a new TASK Base. Should never be used. Interface Class.
|
--- Instantiates a new TASK Base. Should never be used. Interface Class.
|
||||||
@ -120,7 +128,9 @@ trace.f(self.ClassName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Client:Message( GoalsText, 10, "/TASKPROGRESS" .. self.ClassName, "Mission Command: Task Status", 30 )
|
if Mission.MissionReportFlash or Mission.MissionReportShow then
|
||||||
|
Client:Message( GoalsText, 10, "/TASKPROGRESS" .. self.ClassName, "Mission Command: Task Status", 30 )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets a TASK to status Done.
|
--- Sets a TASK to status Done.
|
||||||
@ -132,7 +142,7 @@ end
|
|||||||
--- Returns if a TASK is done.
|
--- Returns if a TASK is done.
|
||||||
-- @treturn bool
|
-- @treturn bool
|
||||||
function TASK:IsDone()
|
function TASK:IsDone()
|
||||||
trace.f(self.ClassName)
|
trace.i( self.ClassName, self.TaskDone )
|
||||||
return self.TaskDone
|
return self.TaskDone
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -145,7 +155,7 @@ end
|
|||||||
--- Returns if a TASk has failed.
|
--- Returns if a TASk has failed.
|
||||||
-- @return bool
|
-- @return bool
|
||||||
function TASK:IsFailed()
|
function TASK:IsFailed()
|
||||||
trace.f(self.ClassName)
|
trace.i( self.ClassName, self.TaskFailed )
|
||||||
return self.TaskFailed
|
return self.TaskFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -268,7 +278,6 @@ end
|
|||||||
--- Returns if all the Goals of the TASK were achieved.
|
--- Returns if all the Goals of the TASK were achieved.
|
||||||
-- @treturn bool
|
-- @treturn bool
|
||||||
function TASK:IsGoalReached( )
|
function TASK:IsGoalReached( )
|
||||||
trace.f(self.ClassName)
|
|
||||||
|
|
||||||
local GoalReached = true
|
local GoalReached = true
|
||||||
|
|
||||||
@ -287,6 +296,7 @@ trace.f(self.ClassName)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trace.i( self.ClassName, GoalReached )
|
||||||
return GoalReached
|
return GoalReached
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -319,10 +329,9 @@ end
|
|||||||
|
|
||||||
function TASK.MenuAction( Parameter )
|
function TASK.MenuAction( Parameter )
|
||||||
trace.menu("TASK","MenuAction")
|
trace.menu("TASK","MenuAction")
|
||||||
trace.l( "TASK", "MenuAction", { Parameter } )
|
trace.l( "TASK", "MenuAction" )
|
||||||
Parameter.ReferenceTask.ExecuteStage = _TransportExecuteStage.EXECUTING
|
Parameter.ReferenceTask.ExecuteStage = _TransportExecuteStage.EXECUTING
|
||||||
Parameter.ReferenceTask.CargoName = Parameter.CargoName
|
Parameter.ReferenceTask.Cargo = Parameter.CargoTask
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function TASK:StageExecute()
|
function TASK:StageExecute()
|
||||||
|
|||||||
@ -62,6 +62,7 @@ trace.names.FollowPlayers = false
|
|||||||
trace.names.AddPlayerFromUnit = false
|
trace.names.AddPlayerFromUnit = false
|
||||||
trace.names.FromCarrier = false
|
trace.names.FromCarrier = false
|
||||||
trace.names.OnDeadOrCrash = false
|
trace.names.OnDeadOrCrash = false
|
||||||
|
|
||||||
trace.classes.CLEANUP = false
|
trace.classes.CLEANUP = false
|
||||||
trace.cache = {}
|
trace.cache = {}
|
||||||
|
|
||||||
@ -249,8 +250,9 @@ end
|
|||||||
trace.i = function(object, variable)
|
trace.i = function(object, variable)
|
||||||
|
|
||||||
local info = debug.getinfo( 2, "nl" )
|
local info = debug.getinfo( 2, "nl" )
|
||||||
if info.name ~= trace.nametrace then
|
trace.nametrace = info.name
|
||||||
trace.nametrace = info.name
|
if trace.nametrace == nil then
|
||||||
|
trace.nametrace = "function"
|
||||||
end
|
end
|
||||||
if trace.names.all or trace.tracefunction( trace.nametrace ) or trace.classes[ object ] then
|
if trace.names.all or trace.tracefunction( trace.nametrace ) or trace.classes[ object ] then
|
||||||
local objecttrace = ""
|
local objecttrace = ""
|
||||||
|
|||||||
58
Moose/Unit.lua
Normal file
58
Moose/Unit.lua
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
--- UNIT Classes
|
||||||
|
-- @classmod UNIT
|
||||||
|
|
||||||
|
Include.File( "Routines" )
|
||||||
|
Include.File( "Base" )
|
||||||
|
Include.File( "Message" )
|
||||||
|
|
||||||
|
UNITS = {}
|
||||||
|
|
||||||
|
|
||||||
|
UNIT = {
|
||||||
|
ClassName="UNIT",
|
||||||
|
}
|
||||||
|
|
||||||
|
function UNIT:New( _Unit )
|
||||||
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
self:T( _Unit:getName() )
|
||||||
|
|
||||||
|
self._Unit = _Unit
|
||||||
|
self.UnitName = _Unit:getName()
|
||||||
|
self.UnitID = _Unit:getID()
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function UNIT:GetCallSign()
|
||||||
|
self:T( self.UnitName )
|
||||||
|
|
||||||
|
return self._Unit:getCallsign()
|
||||||
|
end
|
||||||
|
|
||||||
|
function UNIT:GetPositionVec3()
|
||||||
|
self:T( self.UnitName )
|
||||||
|
|
||||||
|
local UnitPos = self._Unit:getPosition().p
|
||||||
|
|
||||||
|
self:T( UnitPos )
|
||||||
|
return UnitPos
|
||||||
|
end
|
||||||
|
|
||||||
|
function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
|
||||||
|
self:T( { self.UnitName, AwaitUnit.UnitName, Radius } )
|
||||||
|
|
||||||
|
local UnitPos = self:GetPositionVec3()
|
||||||
|
local AwaitUnitPos = AwaitUnit:GetPositionVec3()
|
||||||
|
|
||||||
|
if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then
|
||||||
|
self:T( "true" )
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
self:T( "false" )
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( "false" )
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
57
Moose/Zone.lua
Normal file
57
Moose/Zone.lua
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
--- ZONE Classes
|
||||||
|
-- @classmod ZONE
|
||||||
|
|
||||||
|
Include.File( "Routines" )
|
||||||
|
Include.File( "Base" )
|
||||||
|
Include.File( "Message" )
|
||||||
|
|
||||||
|
ZONES = {}
|
||||||
|
|
||||||
|
|
||||||
|
ZONE = {
|
||||||
|
ClassName="ZONE",
|
||||||
|
}
|
||||||
|
|
||||||
|
function ZONE:New( ZoneName )
|
||||||
|
trace.f( self.ClassName, ZoneName )
|
||||||
|
|
||||||
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
|
||||||
|
local Zone = trigger.misc.getZone( ZoneName )
|
||||||
|
|
||||||
|
if not Zone then
|
||||||
|
error( "Zone " .. ZoneName .. " does not exist." )
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Zone = Zone
|
||||||
|
self.ZoneName = ZoneName
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function ZONE:GetRandomPoint()
|
||||||
|
trace.f( self.ClassName, self.ZoneName )
|
||||||
|
|
||||||
|
local Point = {}
|
||||||
|
|
||||||
|
local Zone = trigger.misc.getZone( self.ZoneName )
|
||||||
|
|
||||||
|
Point.x = Zone.point.x + math.random( Zone.radius * -1, Zone.radius )
|
||||||
|
Point.y = Zone.point.z + math.random( Zone.radius * -1, Zone.radius )
|
||||||
|
|
||||||
|
trace.i( self.ClassName, { Zone } )
|
||||||
|
trace.i( self.ClassName, { Point } )
|
||||||
|
|
||||||
|
return Point
|
||||||
|
end
|
||||||
|
|
||||||
|
function ZONE:GetRadius()
|
||||||
|
trace.f( self.ClassName, self.ZoneName )
|
||||||
|
|
||||||
|
local Zone = trigger.misc.getZone( self.ZoneName )
|
||||||
|
|
||||||
|
trace.i( self.ClassName, { Zone } )
|
||||||
|
|
||||||
|
return Zone.radius
|
||||||
|
end
|
||||||
126
Test Missions/MOOSE_Pickup_Test.lua
Normal file
126
Test Missions/MOOSE_Pickup_Test.lua
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
Include.File( "Mission" )
|
||||||
|
Include.File( "Client" )
|
||||||
|
Include.File( "DeployTask" )
|
||||||
|
Include.File( "PickupTask" )
|
||||||
|
Include.File( "DestroyGroupsTask" )
|
||||||
|
Include.File( "DestroyRadarsTask" )
|
||||||
|
Include.File( "DestroyUnitTypesTask" )
|
||||||
|
Include.File( "GoHomeTask" )
|
||||||
|
Include.File( "Spawn" )
|
||||||
|
Include.File( "Movement" )
|
||||||
|
Include.File( "Sead" )
|
||||||
|
Include.File( "CleanUp" )
|
||||||
|
|
||||||
|
do
|
||||||
|
local Mission = MISSION:New( 'Pickup', 'Operational', 'Pickup Troops', 'NATO' )
|
||||||
|
|
||||||
|
Mission:AddClient( CLIENT:New( 'DE Pickup Test 1' ):Transport() )
|
||||||
|
Mission:AddClient( CLIENT:New( 'DE Pickup Test 2' ):Transport() )
|
||||||
|
|
||||||
|
local CargoTable = {}
|
||||||
|
|
||||||
|
local EngineerNames = { "Alpha", "Beta", "Gamma", "Delta", "Theta" }
|
||||||
|
|
||||||
|
Cargo_Pickup_Zone_1 = CARGO_ZONE:New( 'Pickup Zone 1', 'DE Communication Center 1' ):BlueSmoke()
|
||||||
|
Cargo_Pickup_Zone_2 = CARGO_ZONE:New( 'Pickup Zone 2', 'DE Communication Center 2' ):RedSmoke()
|
||||||
|
|
||||||
|
for CargoItem = 1, 2 do
|
||||||
|
CargoTable[CargoItem] = CARGO_GROUP:New( 'Engineers', 'Team ' .. EngineerNames[CargoItem], math.random( 70, 100 ) * 3, 'DE Infantry', Cargo_Pickup_Zone_1 )
|
||||||
|
end
|
||||||
|
|
||||||
|
for CargoItem = 3, 5 do
|
||||||
|
CargoTable[CargoItem] = CARGO_GROUP:New( 'Engineers', 'Team ' .. EngineerNames[CargoItem], math.random( 70, 100 ) * 3, 'DE Infantry', Cargo_Pickup_Zone_2 )
|
||||||
|
end
|
||||||
|
|
||||||
|
--Cargo_Package = CARGO_INVISIBLE:New( 'Letter', 0.1, 'DE Secret Agent', 'Pickup Zone Package' )
|
||||||
|
--Cargo_Goods = CARGO_STATIC:New( 'Goods', 20, 'Goods', 'Pickup Zone Goods', 'DE Collection Point' )
|
||||||
|
--Cargo_SlingLoad = CARGO_SLING:New( 'Basket', 40, 'Basket', 'Pickup Zone Sling Load', 'DE Cargo Guard' )
|
||||||
|
|
||||||
|
|
||||||
|
-- Assign the Pickup Task
|
||||||
|
local PickupTask = PICKUPTASK:New( 'Engineers', CLIENT.ONBOARDSIDE.LEFT )
|
||||||
|
PickupTask:FromZone( Cargo_Pickup_Zone_1 )
|
||||||
|
PickupTask:FromZone( Cargo_Pickup_Zone_2 )
|
||||||
|
PickupTask:InitCargo( CargoTable )
|
||||||
|
PickupTask:SetGoalTotal( 3 )
|
||||||
|
Mission:AddTask( PickupTask, 1 )
|
||||||
|
|
||||||
|
|
||||||
|
Cargo_Deploy_Zone_1 = CARGO_ZONE:New( 'Deploy Zone 1', 'DE Communication Center 3' ):RedFlare()
|
||||||
|
Cargo_Deploy_Zone_2 = CARGO_ZONE:New( 'Deploy Zone 2', 'DE Communication Center 4' ):WhiteFlare()
|
||||||
|
|
||||||
|
-- Assign the Pickup Task
|
||||||
|
local DeployTask = DEPLOYTASK:New( 'Engineers' )
|
||||||
|
DeployTask:ToZone( Cargo_Deploy_Zone_1 )
|
||||||
|
DeployTask:ToZone( Cargo_Deploy_Zone_2 )
|
||||||
|
DeployTask:SetGoalTotal( 3 )
|
||||||
|
Mission:AddTask( DeployTask, 2 )
|
||||||
|
|
||||||
|
MISSIONSCHEDULER.AddMission( Mission )
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local Mission = MISSION:New( 'Deliver secret letter', 'Operational', 'Pickup letter to the commander.', 'NATO' )
|
||||||
|
|
||||||
|
Mission:AddClient( CLIENT:New( 'BE Package Test 1' ):Transport() )
|
||||||
|
Mission:AddClient( CLIENT:New( 'BE Package Test 2' ):Transport() )
|
||||||
|
Mission:AddClient( CLIENT:New( 'DE Pickup Test 1' ):Transport() )
|
||||||
|
Mission:AddClient( CLIENT:New( 'DE Pickup Test 2' ):Transport() )
|
||||||
|
|
||||||
|
Package_Pickup_Zone = CARGO_ZONE:New( 'Package Pickup Zone', 'DE Guard' ):GreenSmoke()
|
||||||
|
|
||||||
|
Cargo_Package = CARGO_PACKAGE:New( 'Letter', 'Letter to Command', 0.1, 'DE Guard' )
|
||||||
|
--Cargo_Goods = CARGO_STATIC:New( 'Goods', 20, 'Goods', 'Pickup Zone Goods', 'DE Collection Point' )
|
||||||
|
--Cargo_SlingLoad = CARGO_SLING:New( 'Basket', 40, 'Basket', 'Pickup Zone Sling Load', 'DE Cargo Guard' )
|
||||||
|
|
||||||
|
|
||||||
|
-- Assign the Pickup Task
|
||||||
|
local PickupTask = PICKUPTASK:New( 'Letter', CLIENT.ONBOARDSIDE.FRONT )
|
||||||
|
PickupTask:FromZone( Package_Pickup_Zone )
|
||||||
|
PickupTask:InitCargo( { Cargo_Package } )
|
||||||
|
PickupTask:SetGoalTotal( 1 )
|
||||||
|
Mission:AddTask( PickupTask, 1 )
|
||||||
|
|
||||||
|
|
||||||
|
Package_Deploy_Zone = CARGO_ZONE:New( 'Package Deploy Zone', 'DE Secret Car' ):GreenFlare()
|
||||||
|
|
||||||
|
-- Assign the Pickup Task
|
||||||
|
local DeployTask = DEPLOYTASK:New( 'Letter' )
|
||||||
|
DeployTask:ToZone( Package_Deploy_Zone )
|
||||||
|
DeployTask:SetGoalTotal( 1 )
|
||||||
|
Mission:AddTask( DeployTask, 2 )
|
||||||
|
|
||||||
|
MISSIONSCHEDULER.AddMission( Mission )
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local Mission = MISSION:New( 'Sling load Cargo', 'Operational', 'Sling Load Cargo to Deploy Zone.', 'NATO' )
|
||||||
|
|
||||||
|
Mission:AddClient( CLIENT:New( 'Sling Load Test Client 1' ):Transport() )
|
||||||
|
Mission:AddClient( CLIENT:New( 'Sling Load Test Client 2' ):Transport() )
|
||||||
|
|
||||||
|
Sling_Load_Pickup_Zone = CARGO_ZONE:New( 'Sling Load Pickup Zone', 'Sling Load Guard' ):RedSmoke()
|
||||||
|
|
||||||
|
Cargo_Sling_Load = CARGO_SLINGLOAD:New( 'Sling', 'Food Boxes', 200, 'Sling Load Pickup Zone', 'Sling Load Guard', country.id.USA )
|
||||||
|
--Cargo_Goods = CARGO_STATIC:New( 'Goods', 20, 'Goods', 'Pickup Zone Goods', 'DE Collection Point' )
|
||||||
|
--Cargo_SlingLoad = CARGO_SLING:New( 'Basket', 40, 'Basket', 'Pickup Zone Sling Load', 'DE Cargo Guard' )
|
||||||
|
|
||||||
|
|
||||||
|
-- Assign the Pickup Task
|
||||||
|
local PickupTask = PICKUPTASK:New( 'Sling', CLIENT.ONBOARDSIDE.FRONT )
|
||||||
|
PickupTask:FromZone( Sling_Load_Pickup_Zone )
|
||||||
|
PickupTask:InitCargo( { Cargo_Sling_Load } )
|
||||||
|
PickupTask:SetGoalTotal( 1 )
|
||||||
|
Mission:AddTask( PickupTask, 1 )
|
||||||
|
|
||||||
|
MISSIONSCHEDULER.AddMission( Mission )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- MISSION SCHEDULER STARTUP
|
||||||
|
MISSIONSCHEDULER.Start()
|
||||||
|
MISSIONSCHEDULER.ReportMenu()
|
||||||
|
MISSIONSCHEDULER.ReportMissionsHide()
|
||||||
|
|
||||||
|
env.info( "Test Mission loaded" )
|
||||||
BIN
Test Missions/MOOSE_Pickup_Test.miz
Normal file
BIN
Test Missions/MOOSE_Pickup_Test.miz
Normal file
Binary file not shown.
15
Test Missions/MOOSE_Spawn_Test.lua
Normal file
15
Test Missions/MOOSE_Spawn_Test.lua
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Include.File( "Spawn" )
|
||||||
|
|
||||||
|
SpawnTest = SPAWN:New( 'TEST' ):Schedule( 1, 1, 15, 0.4 ):Repeat()
|
||||||
|
|
||||||
|
SpawnTestPlane = SPAWN:New( 'TESTPLANE' ):Schedule( 1, 1, 15, 0.4 ):RepeatOnLanding()
|
||||||
|
|
||||||
|
SpawnTestShipPlane = SPAWN:New( 'SHIPPLANE' ):Schedule( 1, 1, 15, 0.4 ):RepeatOnLanding()
|
||||||
|
|
||||||
|
SpawnTestShipHeli = SPAWN:New( 'SHIPHELI' ):Schedule( 1, 1, 15, 0.4 ):RepeatOnLanding()
|
||||||
|
|
||||||
|
SpawnCH53E = SPAWN:New( 'VEHICLE' )
|
||||||
|
|
||||||
|
|
||||||
|
SpawnTestHelicopterCleanUp = SPAWN:New( "TEST_HELI_CLEANUP" ):Limit( 3, 100 ):Schedule( 10, 0 ):RandomizeRoute( 1, 1, 1000 ):CleanUp( 180 )
|
||||||
|
SpawnTestVehiclesCleanUp = SPAWN:New( "TEST_AAA_CLEANUP" ):Limit( 3, 100 ):Schedule( 10, 0 ):RandomizeRoute( 1, 1, 1000 )
|
||||||
BIN
Test Missions/MOOSE_Spawn_Test.miz
Normal file
BIN
Test Missions/MOOSE_Spawn_Test.miz
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user