diff --git a/Moose/Base.lua b/Moose/Base.lua index 97fca2da8..c11c786a1 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -52,7 +52,7 @@ function BASE:Inherit( Child, Parent ) setmetatable( Child, Parent ) Child.__index = Child end - --Child.ClassName = Child.ClassName .. '.' .. Child.ClassID + Child.ClassName = Child.ClassName .. '.' .. Child.ClassID trace.i( Child.ClassName, 'Inherited from ' .. Parent.ClassName ) return Child end diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 866c06a5b..8cffe8311 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -1,9 +1,704 @@ ---- CARGO +--- CARGO Classes -- @classmod CARGO ---@todo need to define CARGO Class that is used within a mission... ---- Structures --- @section Structures +Include.File( "Routines" ) +Include.File( "Base" ) +Include.File( "Message" ) + +--- Clients are those Groups defined within the Mission Editor that have the skillset defined as "Client" or "Player". +-- These clients are defined within the Mission Orchestration Framework (MOF) + +trace.names.all = true + +CARGOS = {} + + +CARGO_ZONE = { + ClassName="CARGO_ZONE", + CargoZoneName = '', + CargoHostUnitName = '', + SIGNAL = { + TYPE = { + SMOKE = { ID = 1, TEXT = "smoke" }, + FLARE = { ID = 2, TEXT = "flare" } + }, + COLOR = { + GREEN = { ID = 1, TRIGGERCOLOR = trigger.smokeColor.Green, TEXT = "A green" }, + RED = { ID = 2, TRIGGERCOLOR = trigger.smokeColor.Red, TEXT = "A red" }, + WHITE = { ID = 3, TRIGGERCOLOR = trigger.smokeColor.White, TEXT = "A white" }, + ORANGE = { ID = 4, TRIGGERCOLOR = trigger.smokeColor.Orange, TEXT = "An orange" }, + BLUE = { ID = 5, TRIGGERCOLOR = trigger.smokeColor.Blue, TEXT = "A blue" }, + YELLOW = { ID = 6, TRIGGERCOLOR = trigger.flareColor.Yellow, TEXT = "A yellow" } + } + } +} + +function CARGO_ZONE:New( CargoZoneName, CargoHostGroupName ) +trace.f( self.ClassName, { CargoZoneName, CargoHostGroupName } ) + + local self = BASE:Inherit( self, BASE:New() ) + + self.CargoZoneName = CargoZoneName + self.CargoZone = trigger.misc.getZone( CargoZoneName ) + + if CargoHostGroupName then + self.CargoHostGroupName = CargoHostGroupName + self.CargoHostSpawn = SPAWN:New( CargoHostGroupName ) + end + + return self +end + +function CARGO_ZONE:Spawn() +trace.f( self.ClassName ) + + if self.CargoHostSpawn then + local CargoHostGroup = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) + if CargoHostGroup then + if not CargoHostGroup:isExist() then + self.CargoHostSpawn:ReSpawn( self.CargoHostSpawn:SpawnGroupName() ) + end + else + self.CargoHostSpawn:ReSpawn( self.CargoHostSpawn:SpawnGroupName() ) + end + end + + return self +end + +function CARGO_ZONE:Signal() +trace.f( self.ClassName ) + + local Signalled = false + + if self.SignalType then + + if self.CargoHostGroupName then + + -- A Host has been given, signal the host + local SignalUnit = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) + if SignalUnit == nil then + SignalUnit = StaticObject.getByName( self.CargoHostGroupName ) + else + SignalUnit = SignalUnit:getUnits()[1] + end + + if SignalUnit ~= nil then + + trace.i( self.ClassName, 'Signalling Unit' ) + local SignalVehiclePos = SignalUnit:getPosition().p + SignalVehiclePos.y = SignalVehiclePos.y + 10 + + if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then + + trigger.action.smoke( SignalVehiclePos, self.SignalColor.TRIGGERCOLOR ) + Signalled = true + + elseif self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.FLARE.ID then + + trigger.action.signalFlare( SignalVehiclePos, self.SignalColor.TRIGGERCOLOR , 0 ) + Signalled = false + + end + end + + else + + local CurrentPosition = { x = self.CargoZone.point.x, y = self.CargoZone.point.z } + self.CargoZone.point.y = land.getHeight( CurrentPosition ) + 10 + + if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then + + trigger.action.smoke( self.CargoZone.point, self.SignalColor.TRIGGERCOLOR ) + Signalled = true + + elseif self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.FLARE.ID then + trigger.action.signalFlare( self.CargoZone.point, self.SignalColor.TRIGGERCOLOR, 0 ) + Signalled = false + + end + end + end + + return Signalled + +end + +function CARGO_ZONE:WhiteSmoke() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE + + return self +end + +function CARGO_ZONE:BlueSmoke() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.BLUE + + return self +end + +function CARGO_ZONE:RedSmoke() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED + + return self +end + +function CARGO_ZONE:OrangeSmoke() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.ORANGE + + return self +end + +function CARGO_ZONE:GreenSmoke() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN + + return self +end + + +function CARGO_ZONE:WhiteFlare() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE + + return self +end + +function CARGO_ZONE:RedFlare() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED + + return self +end + +function CARGO_ZONE:GreenFlare() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN + + return self +end + +function CARGO_ZONE:YellowFlare() +trace.f( self.ClassName ) + + self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE + self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.YELLOW + + return self +end + + +function CARGO_ZONE:GetCargoHostGroup() +trace.f( self.ClassName ) + + local CargoHost = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) + if CargoHost and CargoHost:isExist() then + return CargoHost + end + + return nil +end + +function CARGO_ZONE:GetCargoZoneName() +trace.f( self.ClassName ) + + return self.CargoZoneName +end + +CARGO = { + ClassName = "CARGO", + STATUS = { + NONE = 0, + LOADED = 1, + UNLOADED = 2, + LOADING = 3 + } +} + +--- 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... +function CARGO:New( CargoType, CargoName, CargoWeight ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight } ) + + local self = BASE:Inherit( self, BASE:New() ) + + self.CargoType = CargoType + self.CargoName = CargoName + self.CargoWeight = CargoWeight + + self.Status = self:StatusNone() + + return self +end + +function CARGO:Spawn() +trace.f( self.ClassName ) + + return self + +end + +function CARGO:IsNear( Client, LandingZone ) +trace.f( self.ClassName ) + + local Near = true + + return Near + +end + +function CARGO:IsLoadedInClient() + + if self:IsStatusLoaded() then + return self.Client + end + + return nil + +end + +function CARGO:Load( Client ) +trace.f( self.ClassName ) + + Client:AddCargo( self ) + + self.Client = Client + self:StatusLoaded() + + return self +end + +function CARGO:UnLoad( Client, TargetZoneName ) +trace.f( self.ClassName ) + + local Cargo = Client:RemoveCargo( self ) + if Cargo then + env.info( 'STAGEUNLOAD:Executing() Cargo.CargoName = ' .. Cargo.CargoName ) + + Cargo:StatusUnLoaded() + end + + return Cargo +end + +function CARGO:OnBoard( Client, LandingZone ) +trace.f(self.ClassName ) + + local Valid = true + + local ClientUnit = Client:ClientUnit() + + return Valid +end + +function CARGO:OnBoarded( Client, LandingZone ) +trace.f(self.ClassName ) + + local OnBoarded = true + + return OnBoarded +end + +function CARGO:StatusNone() +trace.f(self.ClassName ) + + self.Status = CARGO.STATUS.NONE + + return self +end + +function CARGO:StatusLoaded() +trace.f(self.ClassName ) + + self.Status = CARGO.STATUS.LOADED + + return self +end + +function CARGO:StatusUnLoaded() +trace.f(self.ClassName ) + + self.Status = CARGO.STATUS.UNLOADED + + return self +end + +function CARGO:StatusLoading() +trace.f(self.ClassName ) + + self.Status = CARGO.STATUS.LOADING + + return self +end + +function CARGO:IsStatusNone() +trace.f(self.ClassName ) + + return self.Status == CARGO.STATUS.NONE +end + +function CARGO:IsStatusLoaded() +trace.f(self.ClassName ) + + return self.Status == CARGO.STATUS.LOADED +end + +function CARGO:IsStatusUnLoaded() +trace.f(self.ClassName ) + + return self.Status == CARGO.STATUS.UNLOADED +end + +function CARGO:IsStatusLoading() +trace.f(self.ClassName ) + + return self.Status == CARGO.STATUS.LOADING +end + +CARGO_GROUP = { + ClassName = "CARGO_GROUP" +} + + +function CARGO_GROUP:New( CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone } ) + + -- Arrange meta tables + local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) + + self.CargoSpawn = SPAWN:New( CargoGroupTemplate ) + self.CargoZone = CargoZone + + CARGOS[self.CargoName] = self + + return self + +end + +function CARGO_GROUP:Spawn() +trace.f( self.ClassName ) + + local SpawnCargo = true + + if self.CargoGroupName then + local Client = self.IsLoadedInClient() + if Client and Client:ClientGroup() then + if Client:FindCargo( self.CargoName ) then + SpawnCargo = false + end + end + end + + if SpawnCargo then + if self.CargoZone:GetCargoHostGroup() then + --- ReSpawn the Cargo from the CargoHost + self.CargoGroupName = self.CargoSpawn:FromCarrier( self.CargoZone:GetCargoHostGroup(), self.CargoZone:GetCargoZoneName(), self.CargoName, false ).name + else + --- ReSpawn the Cargo in the CargoZone without a host ... + self.CargoGroupName = self.CargoSpawn:InZone( self.CargoZone:GetCargoZoneName(), self.CargoName ).name + + end + end + trace.i( self.ClassName, { self.CargoGroupName, CARGOS[self.CargoName].CargoGroupName } ) + + return self +end + +function CARGO_GROUP:IsNear( Client, LandingZone ) +trace.f( self.ClassName ) + + local Near = false + + if self.CargoGroupName then + local CargoGroup = Group.getByName( self.CargoGroupName ) + if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 250 ) then + Near = true + end + end + + return Near + +end + +function CARGO_GROUP:OnBoard( Client, LandingZone, OnBoardSide ) +trace.f(self.ClassName ) + + local Valid = true + + local ClientUnit = Client:ClientUnit() + + local CarrierPos = ClientUnit:getPoint() + local CarrierPosMove = ClientUnit:getPoint() + local CarrierPosOnBoard = ClientUnit:getPoint() + + local CargoGroup = Group.getByName( self.CargoGroupName ) + + 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, "Cone", 10 ) + + trace.i( self.ClassName, 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y ) + + if OnBoardSide == nil then + OnBoardSide = CLIENT.ONBOARDSIDE.NONE + end + + if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding LEFT" ) + CarrierPosMove.z = CarrierPosMove.z - 25 + CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding RIGHT" ) + CarrierPosMove.z = CarrierPosMove.z + 25 + CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding BACK" ) + CarrierPosMove.x = CarrierPosMove.x - 25 + CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" ) + CarrierPosMove.x = CarrierPosMove.x + 25 + CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding CENTRAL" ) + Points[#Points+1] = routines.ground.buildWP( CarrierPos, "Cone", 10 ) + + end + trace.i( self.ClassName, "TransportCargoOnBoard: Routing " .. self.CargoGroupName ) + + routines.scheduleFunction( routines.goRoute, { self.CargoGroupName, Points}, timer.getTime() + 4 ) + + return Valid + +end + + +function CARGO_GROUP:OnBoarded( Client, LandingZone ) +trace.f(self.ClassName ) + + local OnBoarded = false + + local CargoGroup = Group.getByName( self.CargoGroupName ) + if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 25 ) then + CargoGroup:destroy() + OnBoarded = true + end + + return OnBoarded +end + +function CARGO_GROUP:UnLoad( Client, TargetZoneName ) +trace.f( self.ClassName ) + + trace.i( self.ClassName, 'self.CargoName = ' .. self.CargoName ) + trace.i( self.ClassName, 'self.CargoGroupName = ' .. self.CargoGroupName ) + + self.CargoSpawn:FromCarrier( Client:ClientGroup(), TargetZoneName, self.CargoGroupName ) + self:StatusUnLoaded() + local Cargo = Client:RemoveCargo( self ) + + + return Cargo +end + + +CARGO_PACKAGE = { + ClassName = "CARGO_PACKAGE" +} + + +function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight } ) + + -- Arrange meta tables + local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) + + CARGOS[self.CargoName] = self + + return self + +end + +function CARGO_PACKAGE:Spawn() +trace.f( self.ClassName ) + + return self +end + +function CARGO_PACKAGE:IsNear( Client, LandingZone ) +trace.f( self.ClassName ) + + local Near = false + + local CargoHostGroup = LandingZone:GetCargoHostGroup() + if routines.IsPartOfGroupInRadius( CargoHostGroup, Client:ClientPosition(), 150 ) then + Near = true + end + + return Near + +end + +function CARGO_PACKAGE:OnBoard( Client, LandingZone, OnBoardSide ) +trace.f(self.ClassName ) + + local Valid = true + + local ClientUnit = Client:ClientUnit() + + local CarrierPos = ClientUnit:getPoint() + local CarrierPosMove = ClientUnit:getPoint() + local CarrierPosOnBoard = ClientUnit:getPoint() + local CarrierPosMoveAway = ClientUnit:getPoint() + + local CargoHostGroup = LandingZone:GetCargoHostGroup() + local CargoHostGroupName = LandingZone:GetCargoHostGroup():getName() + + local CargoHostUnits = CargoHostGroup:getUnits() + local CargoPos = CargoHostUnits[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, "Cone", 10 ) + + trace.i( self.ClassName, 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y ) + + if OnBoardSide == nil then + OnBoardSide = CLIENT.ONBOARDSIDE.NONE + end + + if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding LEFT" ) + CarrierPosMove.z = CarrierPosMove.z - 25 + CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5 + CarrierPosMoveAway.z = CarrierPosMoveAway.z - 20 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding RIGHT" ) + CarrierPosMove.z = CarrierPosMove.z + 25 + CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5 + CarrierPosMoveAway.z = CarrierPosMoveAway.z + 20 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding BACK" ) + CarrierPosMove.x = CarrierPosMove.x - 25 + CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5 + CarrierPosMoveAway.x = CarrierPosMoveAway.x - 20 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" ) + CarrierPosMove.x = CarrierPosMove.x + 25 + CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5 + CarrierPosMoveAway.x = CarrierPosMoveAway.x + 20 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) + + elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then + + trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" ) + CarrierPosMove.x = CarrierPosMove.x + 25 + CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5 + CarrierPosMoveAway.x = CarrierPosMoveAway.x + 20 + Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 ) + Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) + + end + trace.i( self.ClassName, "Routing " .. CargoHostGroupName ) + + routines.scheduleFunction( routines.goRoute, { CargoHostGroupName, Points}, timer.getTime() + 4 ) + + return Valid + +end + + +function CARGO_PACKAGE:OnBoarded( Client, LandingZone ) +trace.f(self.ClassName ) + + local OnBoarded = false + + local CargoHostGroup = LandingZone:GetCargoHostGroup() + if routines.IsPartOfGroupInRadius( CargoHostGroup, Client:ClientPosition(), 25 ) then + --CargoGroup:destroy() + OnBoarded = true + end + + return OnBoarded +end + +function CARGO_PACKAGE:UnLoad( Client, TargetZoneName ) +trace.f( self.ClassName ) + + trace.i( self.ClassName, 'self.CargoName = ' .. self.CargoName ) + --trace.i( self.ClassName, 'self.CargoHostName = ' .. self.CargoHostName ) + + --self.CargoSpawn:FromCarrier( Client:ClientGroup(), TargetZoneName, self.CargoHostName ) + self:StatusUnLoaded() + local Cargo = Client:RemoveCargo( self ) + + return Cargo +end + --[[-- Internal Table to understand the form of the CARGO. @@ -25,9 +720,9 @@ CARGO_TRANSPORT = { UNIT = 1, SLING = 2, STATIC = 3, INVISIBLE = 4 } CARGO_TYPE = { TROOPS = { ID = 1, TEXT = "Troops", TRANSPORT = CARGO_TRANSPORT.UNIT }, GOODS = { ID = 2, TEXT = "Goods", TRANSPORT = CARGO_TRANSPORT.STATIC }, - VEHICLES = { ID = 3, TEXT = "Vehicles", TRANSPORT = CARGO_TRANSPORT.VEHICLES }, + VEHICLES = { ID = 3, TEXT = "Vehicles", TRANSPORT = CARGO_TRANSPORT.STATIC }, INFANTRY = { ID = 4, TEXT = "Infantry", TRANSPORT = CARGO_TRANSPORT.UNIT }, ENGINEERS = { ID = 5, TEXT = "Engineers", TRANSPORT = CARGO_TRANSPORT.UNIT }, - PACKAGE = { ID = 5, TEXT = "Package", TRANSPORT = CARGO_TRANSPORT.INVISIBLE }, - CARGO = { ID = 5, TEXT = "Cargo", TRANSPORT = CARGO_TRANSPORT.STATIC }, + PACKAGE = { ID = 6, TEXT = "Package", TRANSPORT = CARGO_TRANSPORT.INVISIBLE }, + CARGO = { ID = 7, TEXT = "Cargo", TRANSPORT = CARGO_TRANSPORT.STATIC }, } diff --git a/Moose/Client.lua b/Moose/Client.lua index bc19ed666..0563a8685 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -73,7 +73,33 @@ function CLIENT:ClientGroup() trace.i( self.ClassName, self.ClientName .. " : group found!" ) return ClientData else --- trace.x( self.ClassName, self.ClientName .. " : no group found!" ) + return nil + end +end + +--- Returns the Unit of the @{CLIENT}. +-- @treturn Unit +function CLIENT:ClientUnit() +--trace.f(self.ClassName) + local ClientData = Group.getByName( self.ClientName ) + if ClientData and ClientData:isExist() then + trace.i( self.ClassName, self.ClientName .. " : group found!" ) + return ClientData:getUnits()[1] + else + return nil + end +end + + +--- Returns the Position of the @{CLIENT}. +-- @treturn Position +function CLIENT:ClientPosition() +--trace.f(self.ClassName) + local ClientData = Group.getByName( self.ClientName ) + if ClientData and ClientData:isExist() then + trace.i( self.ClassName, self.ClientName .. " : group found!" ) + return ClientData:getUnits()[1]:getPosition() + else return nil end end @@ -115,22 +141,22 @@ end --- ShowCargo shows the @{CARGO} within the CLIENT to the Player. -- The @{CARGO} is shown throught the MESSAGE system of DCS World. function CLIENT:ShowCargo() -trace.f(self.ClassName) +trace.f( self.ClassName ) - local CargoMsg = "" + local CargoMsg = "" - for CargoName, Cargo in pairs( self._Cargos ) do - if CargoMsg ~= "" then - CargoMsg = CargoMsg .. "\n" - end - CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType.TEXT .. " Weight: " .. Cargo.CargoWeight - end + for CargoName, Cargo in pairs( self._Cargos ) do + if CargoMsg ~= "" then + CargoMsg = CargoMsg .. "\n" + end + CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight + end - if CargoMsg == '' then - CargoMsg = "empty" - end + if CargoMsg == '' then + CargoMsg = "empty" + end - self:Message( CargoMsg, 15, self.ClientName .. "/Cargo", "Co-Pilot: Cargo Status", 30 ) + self:Message( CargoMsg, 15, self.ClientName .. "/Cargo", "Co-Pilot: Cargo Status", 30 ) end @@ -155,57 +181,37 @@ trace.f(self.ClassName, { InitCargoNames } ) 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". +-- @tparam string Cargo is the @{CARGO}. -- @treturn CLIENT -function CLIENT:AddCargo( CargoName, CargoGroupName, CargoType, CargoWeight, CargoGroupTemplate ) -trace.f(self.ClassName, { CargoName, CargoGroupName, CargoType, CargoWeight, CargoGroupTemplate } ) +function CLIENT:AddCargo( Cargo ) +trace.f(self.ClassName, { Cargo } ) - 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 + local Valid = true + + if Valid then + self._Cargos[Cargo.CargoName] = Cargo + self:ShowCargo() end - self._Cargos[CargoName] = Cargo - self:ShowCargo() - end - - return self + + return self 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 } ) - +function CLIENT:RemoveCargo( Cargo ) +trace.f(self.ClassName ) 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 + trace.i( "CLIENT", "RemoveCargo: CargoName = " .. Cargo.CargoName ) + local CargoNew = self._Cargos[Cargo.CargoName] + self._Cargos[Cargo.CargoName] = nil end - return Cargo + return CargoNew end diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index 7ba43909c..18e01d141 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -13,7 +13,7 @@ DEPLOYTASK = { --- 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 CARGO_TYPE CargoType Type of the Cargo. -function DEPLOYTASK:New( LandingZones, CargoType ) +function DEPLOYTASK:New( CargoType ) trace.f(self.ClassName) -- Child holds the inherited instance of the DEPLOYTASK Class to the BASE class. @@ -21,26 +21,54 @@ trace.f(self.ClassName) local Valid = true - Valid = routines.ValidateZone( LandingZones, "LandingZones", Valid ) - Valid = routines.ValidateEnumeration( CargoType, "CargoType", CARGO_TYPE, Valid ) - if Valid then Child.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." - if type( LandingZones ) == "table" then - Child.LandingZones = LandingZones - else - Child.LandingZones = { LandingZones } - end + Child.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." 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.GoalVerb = CargoType .. " " .. self.GoalVerb + Child.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGEUNLOAD:New(), STAGEDONE:New() } Child.SetStage( Child, 1 ) end return Child end +function DEPLOYTASK:ToZone( LandingZone ) +trace.f(self.ClassName) + + self.LandingZones.LandingZoneNames[LandingZone.CargoZoneName] = LandingZone.CargoZoneName + self.LandingZones.LandingZones[LandingZone.CargoZoneName] = LandingZone + + return self +end + + +function DEPLOYTASK:InitCargo( InitCargos ) +trace.f( self.ClassName, { InitCargos } ) + + if type( InitCargos ) == "table" then + self.Cargos.InitCargos = InitCargos + else + self.Cargos.InitCargos = { InitCargos } + end + + + return self +end + + +function DEPLOYTASK:LoadCargo( LoadCargos ) +trace.f( self.ClassName, { LoadCargos } ) + + if type( LoadCargos ) == "table" then + self.Cargos.LoadCargos = LoadCargos + else + self.Cargos.LoadCargos = { LoadCargos } + end + + return self +end + --- 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. @@ -60,46 +88,51 @@ trace.f(self.ClassName) end function DEPLOYTASK:AddCargoMenus( Client, Cargos, TransportRadius ) -trace.f(self.ClassName, {Client, Cargos, TransportRadius}) +trace.f( self.ClassName ) - for CargoID, CargoData in pairs( Client._Cargos ) do + for CargoID, Cargo in pairs( Cargos ) do - trace.i( self.ClassName, { CargoData.CargoName } ) - if Client._Menus[CargoData.CargoType] == nil then - Client._Menus[CargoData.CargoType] = {} - end + trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType } ) - if not Client._Menus[CargoData.CargoType].DeployMenu then - Client._Menus[CargoData.CargoType].DeployMenu = missionCommands.addSubMenuForGroup( + if Cargo:IsStatusLoaded() then + + + if Client._Menus[Cargo.CargoType] == nil then + Client._Menus[Cargo.CargoType] = {} + end + + if not Client._Menus[Cargo.CargoType].DeployMenu then + Client._Menus[Cargo.CargoType].DeployMenu = missionCommands.addSubMenuForGroup( + Client:ClientGroup():getID(), + self.TEXT[1], + 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 ].MenuPath = missionCommands.addCommandForGroup( Client:ClientGroup():getID(), - self.TEXT[1], - nil + 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 - - 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 function DEPLOYTASK:RemoveCargoMenus( Client ) -trace.f(self.ClassName, { Client } ) +trace.f(self.ClassName ) for MenuID, MenuData in pairs( Client._Menus ) do if MenuData.DeploySubMenus ~= nil then diff --git a/Moose/Mission.lua b/Moose/Mission.lua index 2ead4c912..a5a5b671a 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -4,7 +4,6 @@ Include.File( "Routines" ) Include.File( "Base" ) -Include.File( "Mission" ) Include.File( "Client" ) Include.File( "Task" ) @@ -30,15 +29,6 @@ MISSION = { _GoalTasks = {} } -CARGOSTATUS = { - NONE = 0, - LOADED = 1, - UNLOADED = 2, - LOADING = 3, - LoadCount= 0, - UnloadCount = 0 -} - function MISSION:Meta() trace.f(self.ClassName) @@ -252,7 +242,7 @@ end -- @tparam CLIENT Client to show briefing to. -- @treturn CLIENT function MISSION:ShowBriefing( Client ) -trace.f(self.ClassName, { Client } ) +trace.f(self.ClassName, { Client.ClientName } ) if not Client.ClientBriefingShown then Client.ClientBriefingShown = true @@ -263,7 +253,6 @@ trace.f(self.ClassName, { Client } ) end end -trace.r( "", "", { Client } ) return Client end @@ -377,45 +366,19 @@ 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 } ) +function MISSION:AddCargo( Cargos ) +trace.f(self.ClassName, { Cargos } ) - local Cargo = {} - Cargo.CargoName = CargoName - if CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then - if not SpawnCargo[CargoGroupTemplate] then - SpawnCargo[CargoGroupTemplate] = SPAWN:New( CargoGroupTemplate ) + if type( Cargos ) == "table" then + for CargoID, Cargo in pairs( Cargos ) do + self._Cargos[Cargo.CargoName] = Cargo 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 + else + self._Cargos[Cargos.CargoName] = Cargos 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. @@ -450,6 +413,8 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") -- loop through the missions in the TransportTasks for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do + + env.info( "Mission: " .. MissionName ) if not Mission:IsCompleted() then @@ -457,6 +422,8 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") local ClientsAlive = false for ClientID, Client in pairs( Mission._Clients ) do + + env.info( "Client: " .. Client.ClientName ) if Client:ClientGroup() and Client:ClientGroup():getUnits() and Client:ClientGroup():getUnits()[1] and Client:ClientGroup():getUnits()[1]:getLife() > 0.0 then @@ -476,13 +443,12 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") Client._Tasks[TaskNumber] = routines.utils.deepCopy( Mission._Tasks[TaskNumber] ) -- Each MissionTask must point to the original Mission. Client._Tasks[TaskNumber].MissionTask = Mission._Tasks[TaskNumber] + Client._Tasks[TaskNumber].Cargos = Mission._Tasks[TaskNumber].Cargos + Client._Tasks[TaskNumber].LandingZones = Mission._Tasks[TaskNumber].LandingZones 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() end diff --git a/Moose/Moose.lua b/Moose/Moose.lua index edacba13a..5dc2b17e8 100644 --- a/Moose/Moose.lua +++ b/Moose/Moose.lua @@ -11,8 +11,8 @@ end Include = {} -Include.MissionPath = script_path() .. "Mission\\" -Include.ProgramPath = "Scripts\\Moose\\Moose\\" +Include.MissionPath = script_path() .. "Mission/" +Include.ProgramPath = "Scripts/Moose/Moose/" env.info( "Include.MissionPath = " .. Include.MissionPath) env.info( "Include.ProgramPath = " .. Include.ProgramPath) @@ -21,17 +21,17 @@ Include.Files = {} Include.File = function( IncludeFile ) if not Include.Files[ IncludeFile ] then Include.Files[IncludeFile] = IncludeFile - local f = base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" ) + local f = assert( base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" ) ) if f == nil then - local f = base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" ) + local f = assert( 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.ProgramPath ) + env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath ) return f() end else - env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath ) + env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath ) return f() end end diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index 401a24f07..a3623580f 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -14,7 +14,7 @@ PICKUPTASK = { -- @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 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) -- Child holds the inherited instance of the PICKUPTASK Class to the BASE class. @@ -22,23 +22,13 @@ trace.f(self.ClassName) 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 Child.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." - if type( LandingZones ) == "table" then - Child.LandingZones = LandingZones - else - Child.LandingZones = { LandingZones } - end + Child.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." Child.CargoType = CargoType - Child.GoalVerb = CargoType.TEXT .. " " .. Child.GoalVerb + Child.GoalVerb = CargoType .. " " .. Child.GoalVerb Child.OnBoardSide = OnBoardSide - Child.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGELOAD:New(), STAGEDONE:New() } + Child.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGELOAD:New(), STAGEDONE:New() } Child.SetStage( Child, 1 ) end @@ -46,55 +36,79 @@ trace.f(self.ClassName) return Child end +function PICKUPTASK:FromZone( LandingZone ) +trace.f(self.ClassName) + + self.LandingZones.LandingZoneNames[LandingZone.CargoZoneName] = LandingZone.CargoZoneName + self.LandingZones.LandingZones[LandingZone.CargoZoneName] = LandingZone + + return self +end + +function PICKUPTASK:InitCargo( InitCargos ) +trace.f( self.ClassName, { InitCargos } ) + + if type( InitCargos ) == "table" then + self.Cargos.InitCargos = InitCargos + else + self.Cargos.InitCargos = { InitCargos } + end + + return self +end + +function PICKUPTASK:LoadCargo( LoadCargos ) +trace.f( self.ClassName, { LoadCargos } ) + + if type( LoadCargos ) == "table" then + self.Cargos.LoadCargos = LoadCargos + else + self.Cargos.LoadCargos = { LoadCargos } + end + + return self +end + function PICKUPTASK:AddCargoMenus( Client, Cargos, TransportRadius ) -trace.f(self.ClassName, { Client, Cargos, TransportRadius } ) +trace.f( self.ClassName ) - 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 + trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType } ) - if Group.getByName( CargoData.CargoGroupName ) then + if not Cargo:IsStatusLoaded() and not Cargo:IsStatusLoading() then + + local MenuAdd = false + if Cargo:IsNear( Client, self.CurrentCargoZone ) then + MenuAdd = true + end - if Group.getByName( CargoData.CargoGroupName ):getSize() >= 1 then - - if Client._Menus[CargoData.CargoType] == nil then - 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 + if MenuAdd then + if Client._Menus[Cargo.CargoType] == nil then + Client._Menus[Cargo.CargoType] = {} end + + if not Client._Menus[Cargo.CargoType].PickupMenu then + Client._Menus[Cargo.CargoType].PickupMenu = missionCommands.addSubMenuForGroup( + Client:ClientGroup():getID(), + self.TEXT[1], + nil + ) + trace.i( self.ClassName, 'Added PickupMenu' .. self.TEXT[1] ) + 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:ClientGroup():getID(), + Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )", + Client._Menus[Cargo.CargoType].PickupMenu, + self.MenuAction, + { ReferenceTask = self, CargoTask = Cargo } + ) + trace.i( self.ClassName, 'Added PickupSubMenu' .. Cargo.CargoType .. ":" .. Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )" ) end end end @@ -102,7 +116,7 @@ trace.f(self.ClassName, { Client, Cargos, TransportRadius } ) end function PICKUPTASK:RemoveCargoMenus( Client ) -trace.f(self.ClassName, { Client } ) +trace.f( self.ClassName ) for MenuID, MenuData in pairs( Client._Menus ) do for SubMenuID, SubMenuData in pairs( MenuData.PickupSubMenus ) do @@ -128,77 +142,3 @@ trace.f(self.ClassName) return TaskHasFailed 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 diff --git a/Moose/Routines.lua b/Moose/Routines.lua index ee1fb2e64..427447b7c 100644 --- a/Moose/Routines.lua +++ b/Moose/Routines.lua @@ -1521,85 +1521,48 @@ trace.r( "", "", { TransportZoneResult } ) end -function routines.IsUnitInRadius( CargoUnit, ReferenceGroup, Radius ) +function routines.IsUnitInRadius( CargoUnit, ReferencePosition, Radius ) trace.f() local Valid = true -- fill-up some local variables to support further calculations to determine location of units within the zone. 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 Valid = false end -trace.r( "", "", { Valid } ) return Valid end -function routines.IsPartOfGroupInRadius( CargoGroup, ReferenceGroup, Radius ) +function routines.IsPartOfGroupInRadius( CargoGroup, ReferencePosition, Radius ) trace.f() local Valid = true 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 local CargoUnits = CargoGroup:getUnits() for CargoUnitId, CargoUnit in pairs( CargoUnits ) do local CargoUnitPos = CargoUnit:getPosition().p -- 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 ) - 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 Valid = false break end end -trace.r( "", "", { Valid } ) return Valid 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 ) trace.f() diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 61acdd908..f728d108e 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -237,9 +237,9 @@ end -- 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:Spawn() +function SPAWN:Spawn( SpawnGroupName ) trace.f( self.ClassName ) - local SpawnTemplate = self:_Prepare( true ) + local SpawnTemplate = self:_Prepare( SpawnGroupName ) if self.SpawnStartPoint ~= 0 or self.SpawnEndPoint ~= 0 then SpawnTemplate = self:_RandomizeRoute( SpawnTemplate ) end @@ -258,11 +258,14 @@ end -- Uses _Database global object defined in MOOSE. function SPAWN:ReSpawn( SpawnGroupName ) trace.f( self.ClassName, { SpawnGroupName } ) + local SpawnGroup = Group.getByName( SpawnGroupName ) - SpawnGroup:destroy() - local SpawnTemplate = self:_Prepare( false ) - -- Give the Group the original name of the Group. - SpawnTemplate.name = SpawnGroupName + if SpawnGroup then + SpawnGroup:destroy() + end + + 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. local SpawnUnits = table.getn( SpawnTemplate.units ) for u = 1, SpawnUnits do @@ -282,7 +285,7 @@ trace.f( self.ClassName ) local SpawnCountStart = self.SpawnCount + 1 for SpawnCount = SpawnCountStart, self.SpawnMaxGroups do - local SpawnTemplate = self:_Prepare( true ) + local SpawnTemplate = self:_Prepare( ) SpawnTemplate.uncontrolled = true _Database:Spawn( SpawnTemplate ) end @@ -313,15 +316,11 @@ trace.f( self.ClassName, { CarrierGroup, TargetZonePrefix, NewGroupName, LateAct UnitDeploy = UnitData - SpawnTemplate = self:_Prepare( true ) + 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 NewGroupName ~= nil then - SpawnTemplate.name = NewGroupName - end - if LateActivate ~= nil then if LateActivate == true then SpawnTemplate.lateActivation = true @@ -374,13 +373,34 @@ trace.f( self.ClassName, { CarrierGroup, TargetZonePrefix, NewGroupName, LateAct return SpawnTemplate end + +--- Will return the SpawnGroupName either with with a specific count number or without any count. +-- @tparam number SpawnNumber is the number of the Group that is to be SPAWNed. +-- @treturn string SpawnGroupName +function SPAWN:SpawnGroupName( SpawnNumber ) +trace.f("Spawn", SpawnNumber ) + + if SpawnNumber then + return string.format( self.SpawnPrefix .. '#%03d', SpawnNumber ) + else + return string.format( self.SpawnPrefix .. '#' ) + end + +end + --- Will SPAWN a Group within a given ZoneName. -- @tparam string ZonePrefix is the name of the zone where the Group is to be SPAWNed. -- @treturn SpawnTemplate -function SPAWN:InZone( ZonePrefix ) +function SPAWN:InZone( ZonePrefix, SpawnGroupName ) trace.f("Spawn", 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 ZonePos = {} @@ -462,7 +482,7 @@ trace.f( self.ClassName, SpawnPrefix ) end --- Prepares the new Group Template before Spawning. -function SPAWN:_Prepare( SpawnIncrement ) +function SPAWN:_Prepare( SpawnGroupName ) trace.f( self.ClassName ) local SpawnCount @@ -476,11 +496,14 @@ trace.f( self.ClassName ) end -- Increase the spawn counter for the group - if SpawnIncrement == true then + if SpawnGroupName then + SpawnTemplate.name = SpawnGroupName + else self.SpawnCount = self.SpawnCount + 1 + SpawnTemplate.name = self:SpawnGroupName( self.SpawnCount ) end - SpawnTemplate.name = string.format( self.SpawnPrefix .. '#%03d', self.SpawnCount ) + SpawnTemplate.groupId = nil SpawnTemplate.lateActivation = false if SpawnTemplate.SpawnCategoryID == Group.Category.GROUND then @@ -501,7 +524,7 @@ trace.f( self.ClassName ) SpawnUnits = table.getn( SpawnTemplate.units ) 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].x = SpawnTemplate.route.points[1].x SpawnTemplate.units[u].y = SpawnTemplate.route.points[1].y diff --git a/Moose/Stage.lua b/Moose/Stage.lua index 9eb6106f9..7e3fe8e7a 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -56,10 +56,10 @@ end STAGEBRIEF = { ClassName = "BRIEF", - MSG = { ID = "Brief", TIME = 30 }, + MSG = { ID = "Brief", TIME = 1 }, Name = "Brief", StageBriefingTime = 0, - StageBriefingDuration = 30 + StageBriefingDuration = 1 } function STAGEBRIEF:New() @@ -94,10 +94,10 @@ end STAGESTART = { ClassName = "START", - MSG = { ID = "Start", TIME = 30 }, + MSG = { ID = "Start", TIME = 1 }, Name = "Start", StageStartTime = 0, - StageStartDuration = 30 + StageStartDuration = 1 } function STAGESTART:New() @@ -135,6 +135,81 @@ trace.f(self.ClassName) end +STAGE_CARGO_LOAD = { + ClassName = "STAGE_CARGO_LOAD" +} + +function STAGE_CARGO_LOAD:New() +trace.f(self.ClassName) + -- Arrange meta tables + local self = BASE:Inherit( self, STAGE:New() ) + self.StageType = 'CLIENT' + return self +end + +function STAGE_CARGO_LOAD:Execute( Mission, Client, Task ) +trace.f(self.ClassName) + local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) + + for LoadCargoID, LoadCargo in pairs( Task.Cargos.LoadCargos ) do + LoadCargo:Load( Client ) + end + + if Client:IsTransport() then + Client:ShowCargo() + end + + return Valid +end + +function STAGE_CARGO_LOAD:Validate( Mission, Client, Task ) +trace.f(self.ClassName) + local Valid = STAGE:Validate( Mission, Client, Task ) + + return 1 +end + + +STAGE_CARGO_INIT = { + ClassName = "STAGE_CARGO_INIT" +} + +function STAGE_CARGO_INIT:New() +trace.f(self.ClassName) + -- Arrange meta tables + local self = BASE:Inherit( self, STAGE:New() ) + self.StageType = 'CLIENT' + return self +end + +function STAGE_CARGO_INIT:Execute( Mission, Client, Task ) +trace.f(self.ClassName) + local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) + + for InitLandingZoneID, InitLandingZone in pairs( Task.LandingZones.LandingZones ) do + trace.i( self.ClassName, InitLandingZone ) + InitLandingZone:Spawn() + end + + + for InitCargoID, InitCargo in pairs( Task.Cargos.InitCargos ) do + trace.i( self.ClassName ) + InitCargo:Spawn() + end + + return Valid +end + + +function STAGE_CARGO_INIT:Validate( Mission, Client, Task ) +trace.f(self.ClassName) + local Valid = STAGE:Validate( Mission, Client, Task ) + + return 1 +end + + + STAGEROUTE = { ClassName = "STAGEROUTE", MSG = { ID = "Route", TIME = 1 }, @@ -156,15 +231,12 @@ function STAGEROUTE:Execute( Mission, Client, Task ) trace.f(self.ClassName) local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) - if type( Task.LandingZones) == "table" then - local RouteMessage = "Fly to " - for LandingZoneID, LandingZoneName in pairs( Task.LandingZones ) do - RouteMessage = RouteMessage .. LandingZoneName .. ' at ' .. routines.getBRStringZone( { zone = LandingZoneName, ref = Client:ClientGroup():getUnit(1):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 ) + local RouteMessage = "Fly to " + 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. ' end + Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageRoute", "Co-Pilot: Route", 10 ) + if Client:IsTransport() then Client:ShowCargo() end @@ -174,56 +246,27 @@ end function STAGEROUTE:Validate( Mission, Client, Task ) trace.f(self.ClassName) - local Valid = STAGE:Validate( Mission, Client, Task ) + local Valid = STAGE:Validate( Mission, Client, Task ) + + -- check if the Client is in the landing zone + trace.i( self.ClassName, Task.LandingZones.LandingZoneNames ) + Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:ClientUnit(), Task.LandingZones.LandingZoneNames ) + + if Task.CurrentLandingZoneName then - -- check if this carrier is in the landing zone - Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones ) - if ( Task.CurrentLandingZoneID ) then - if not Task.Signalled then - - if Task.LandingZoneSignalType then - 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 + 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 - self.Signalled = true + + return 1 end - return 1 - end - - return 0 + return 0 end STAGELANDING = { @@ -244,27 +287,49 @@ end function STAGELANDING:Execute( Mission, Client, Task ) trace.f(self.ClassName) - Client:Message( 'We have arrived at ' .. Task.LandingZones[Task.CurrentLandingZoneID] .. '. Land the helicopter to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType.TEXT .. '.', - self.MSG.TIME, Mission.Name .. "/Stage", "Co-Pilot: Landing" ) + Client:Message( 'We have arrived at ' .. Task.CurrentLandingZoneName .. '. Land the helicopter to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType .. '.', + self.MSG.TIME, Mission.Name .. "/StageLanding", "Co-Pilot: Landing", 10 ) end function STAGELANDING:Validate( Mission, Client, Task ) trace.f(self.ClassName) - if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then - else - Task.Signalled = false - Task:RemoveCargoMenus( Client ) - return -1 - end + if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + -- check if the Client is in the landing zone + trace.i( self.ClassName, Task.LandingZones.LandingZoneNames ) + Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:ClientUnit(), Task.LandingZones.LandingZoneNames ) + + if Task.CurrentLandingZoneName then + + 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 + end + else + Task.Signalled = false + Task:RemoveCargoMenus( Client ) + return -1 + end - if not Client:ClientGroup():getUnits()[1]:inAir() then - else - return 0 - end + if not Client:ClientUnit():inAir() then + else + return 0 + end - return 1 + return 1 end STAGELANDED = { @@ -284,10 +349,10 @@ end function STAGELANDED:Execute( Mission, Client, Task ) trace.f(self.ClassName) - 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" ) + Client:Message( 'We have landed within the landing zone. Use the radio menu (F10) to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType .. '.', self.MSG.TIME, Mission.Name .. "/StageLanded", "Co-Pilot: Landed" ) if not self.MenusAdded then Task:RemoveCargoMenus( Client ) - Task:AddCargoMenus( Client, Mission._Cargos, 250 ) + Task:AddCargoMenus( Client, CARGOS, 250 ) end end @@ -296,14 +361,14 @@ end function STAGELANDED:Validate( Mission, Client, Task ) trace.f(self.ClassName) - if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then + if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then else Task.Signalled = false Task:RemoveCargoMenus( Client ) return -2 end - if not Client:ClientGroup():getUnits()[1]:inAir() then + if not Client:ClientUnit():inAir() then else Task.Signalled = false return -1 @@ -333,33 +398,24 @@ end function STAGEUNLOAD:Execute( Mission, Client, Task ) trace.f(self.ClassName) - Client:Message( 'The ' .. Task.CargoType.TEXT .. ' 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" ) - Task:RemoveCargoMenus( Client ) + 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 .. "/StageUnLoad", "Co-Pilot: Unload" ) + Task:RemoveCargoMenus( Client ) end function STAGEUNLOAD:Executing( Mission, Client, Task ) trace.f(self.ClassName) - env.info( 'STAGEUNLOAD:Executing() Task.CargoName = ' .. Task.CargoName ) - local Cargo = Client:RemoveCargo( Task.CargoName ) - if Cargo then - env.info( 'STAGEUNLOAD:Executing() Cargo.CargoName = ' .. Cargo.CargoName ) - env.info( 'STAGEUNLOAD:Executing() Cargo.CargoGroupName = ' .. Cargo.CargoGroupName ) - env.info( 'STAGEUNLOAD:Executing() Mission._Cargos[Cargo.CargoName].CargoGroupTemplate = ' .. Mission._Cargos[Cargo.CargoName].CargoGroupTemplate ) - - if Cargo.CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then - if Cargo.CargoName then - if Task.TargetZoneName then - SPAWN:New( Mission._Cargos[Cargo.CargoName].CargoGroupTemplate ):FromCarrier ( Client:ClientGroup(), - 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 + env.info( 'STAGEUNLOAD:Executing() Task.Cargo.CargoName = ' .. Task.Cargo.CargoName ) + + local TargetZoneName + + if Task.TargetZoneName then + TargetZoneName = Task.TargetZoneName + else + TargetZoneName = Task.CurrentLandingZoneName + end + + if Task.Cargo:UnLoad( Client, TargetZoneName ) then Task.ExecuteStage = _TransportExecuteStage.SUCCESS Client:ShowCargo() end @@ -369,27 +425,27 @@ function STAGEUNLOAD:Validate( Mission, Client, Task ) trace.f(self.ClassName) env.info( 'STAGEUNLOAD:Validate()' ) - if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then + if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then else Task.ExecuteStage = _TransportExecuteStage.FAILED 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" ) return 1 end - if not Client:ClientGroup():getUnits()[1]:inAir() then + if not Client:ClientUnit():inAir() then else Task.ExecuteStage = _TransportExecuteStage.FAILED 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" ) return 1 end 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" ) - Mission._Cargos[Task.CargoName].Status = CARGOSTATUS.UNLOADED + Client:Message( 'The ' .. Task.CargoType .. ' have been sucessfully ' .. Task.TEXT[3] .. ' within the landing zone.', _TransportStageMsgTime.DONE, Mission.Name .. "/Stage", "Co-Pilot: Unload" ) + Task.Cargo:StatusUnLoaded() Task:RemoveCargoMenus( Client ) Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 ) -- We set the cargo as one more goal completed in the mission. return 1 @@ -414,68 +470,63 @@ end function STAGELOAD:Execute( Mission, Client, Task ) trace.f(self.ClassName) - 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" ) + 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", "Co-Pilot: Load" ) -- Route the cargo to the Carrier - if Mission._Cargos[Task.CargoName].CargoType.TRANSPORT == CARGO_TRANSPORT.UNIT then - Task:OnBoardCargo( Client:ClientGroup(), Mission._Cargos ) - Task.ExecuteStage = _TransportExecuteStage.EXECUTING - else - -- 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 ) - Task.ExecuteStage = _TransportExecuteStage.SUCCESS - end + Task.Cargo:OnBoard( Client, Task.CurrentCargoZone, Task.OnBoardSide ) + Task.ExecuteStage = _TransportExecuteStage.EXECUTING end function STAGELOAD:Executing( Mission, Client, Task ) trace.f(self.ClassName) - -- 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 ) + trace.i(self.ClassName, Task.Cargo) - -- 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" ) - Task.ExecuteStage = _TransportExecuteStage.SUCCESS - Client:ShowCargo() - end + if Task.Cargo:OnBoarded( Client, Task.CurrentCargoZone ) then + + -- Load the Cargo onto the Client + Task.Cargo:Load( Client ) + + -- 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 .. "/StageLoad", "Co-Pilot: Load" ) + Task.ExecuteStage = _TransportExecuteStage.SUCCESS + + Client:ShowCargo() + end end function STAGELOAD:Validate( Mission, Client, Task ) trace.f(self.ClassName) - if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then + if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then else Task:RemoveCargoMenus( Client ) Task.ExecuteStage = _TransportExecuteStage.FAILED Task.CargoName = nil - Client:Message( "The " .. Task.CargoType.TEXT .. " loading has been aborted. You flew outside the pick-up zone while loading. ", + Client:Message( "The " .. Task.CargoType .. " loading has been aborted. You flew outside the pick-up zone while loading. ", _TransportStageMsgTime.DONE, Mission.Name .. "/StageSuccess", "Co-Pilot: Load" ) return 1 end - if not Client:ClientGroup():getUnits()[1]:inAir() then + if not Client:ClientUnit():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.TEXT .. " loading has been aborted. Land the helicopter and load the cargo. Don't fly outside the pick-up zone. ", + Client:Message( "The " .. Task.CargoType .. " loading has been aborted. Land the helicopter and load the cargo. Don't fly outside the pick-up zone. ", _TransportStageMsgTime.DONE, Mission.Name .. "/StageSuccess", "Co-Pilot: Load" ) return -1 end if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then - Mission._Cargos[Task.CargoName].Status = CARGOSTATUS.LOADED + Task.Cargo:StatusLoaded() Task:RemoveCargoMenus( Client ) - Client:Message( 'Co-Pilot: The ' .. Task.CargoType.TEXT .. ' have been sucessfully ' .. Task.TEXT[3] .. ' within the landing zone.', - _TransportStageMsgTime.DONE, Mission.Name .. "/Stage", "Co-Pilot: Load" ) + Client:Message( 'Co-Pilot: The ' .. Task.CargoType .. ' have been sucessfully ' .. Task.TEXT[3] .. ' within the landing zone.', + _TransportStageMsgTime.DONE, Mission.Name .. "/StageLoaded", "Co-Pilot: Load" ) Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 ) return 1 end @@ -518,9 +569,8 @@ trace.f(self.ClassName) end if Task.CargoName then - if routines.IsStaticInZones( StaticObject.getByName( Task.CargoName ), Task.LandingZones[Task.CurrentLandingZoneID] ) then + if routines.IsStaticInZones( StaticObject.getByName( Task.CargoName ), Task.CurrentLandingZoneName ) then else - Mission._Cargos[Task.CargoName].Status = CARGOSTATUS.LOADED return 1 end end @@ -561,7 +611,7 @@ trace.f(self.ClassName) if Task.CargoName then if not StaticObject.getByName( Task.CargoName ):inAir() then - if routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones[Task.CurrentLandingZoneID] ) then + if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) 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 @@ -616,14 +666,14 @@ end function STAGEARRIVE:Execute( Mission, Client, Task ) trace.f(self.ClassName) - 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 function STAGEARRIVE:Validate( Mission, Client, Task ) trace.f(self.ClassName) - Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:ClientGroup():getUnits()[1], Task.LandingZones ) + Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:ClientUnit(), Task.LandingZones ) if ( Task.CurrentLandingZoneID ) then else return -1 diff --git a/Moose/Task.lua b/Moose/Task.lua index 9ab902f20..2d0f753f8 100644 --- a/Moose/Task.lua +++ b/Moose/Task.lua @@ -9,29 +9,37 @@ Include.File( "Stage" ) TASK = { - -- Defines the different signal types with a Task. - SIGNAL = { - COLOR = { - RED = { ID = 1, COLOR = trigger.smokeColor.Red, TEXT = "A red" }, - GREEN = { ID = 2, COLOR = trigger.smokeColor.Green, TEXT = "A green" }, - BLUE = { ID = 3, COLOR = trigger.smokeColor.Blue, TEXT = "A blue" }, - WHITE = { ID = 4, COLOR = trigger.smokeColor.White, TEXT = "A white" }, - ORANGE = { ID = 5, COLOR = trigger.smokeColor.Orange, TEXT = "An orange" } - }, - TYPE = { - SMOKE = { ID = 1, TEXT = "smoke" }, - FLARE = { ID = 2, TEXT = "flare" } - } - }, - ClassName = "TASK", - Mission = {}, -- Owning mission of the Task - Name = '', - Stages = {}, - Stage = {}, - ActiveStage = 0, - TaskDone = false, - TaskFailed = false, - GoalTasks = {} + -- Defines the different signal types with a Task. + SIGNAL = { + COLOR = { + RED = { ID = 1, COLOR = trigger.smokeColor.Red, TEXT = "A red" }, + GREEN = { ID = 2, COLOR = trigger.smokeColor.Green, TEXT = "A green" }, + BLUE = { ID = 3, COLOR = trigger.smokeColor.Blue, TEXT = "A blue" }, + WHITE = { ID = 4, COLOR = trigger.smokeColor.White, TEXT = "A white" }, + ORANGE = { ID = 5, COLOR = trigger.smokeColor.Orange, TEXT = "An orange" } + }, + TYPE = { + SMOKE = { ID = 1, TEXT = "smoke" }, + FLARE = { ID = 2, TEXT = "flare" } + } + }, + ClassName = "TASK", + Mission = {}, -- Owning mission of the Task + Name = '', + Stages = {}, + Stage = {}, + Cargos = { + InitCargos = {}, + LoadCargos = {} + }, + LandingZones = { + LandingZoneNames = {}, + LandingZones = {} + }, + ActiveStage = 0, + TaskDone = false, + TaskFailed = false, + GoalTasks = {} } --- Instantiates a new TASK Base. Should never be used. Interface Class. @@ -319,10 +327,9 @@ end function TASK.MenuAction( Parameter ) trace.menu("TASK","MenuAction") - trace.l( "TASK", "MenuAction", { Parameter } ) + trace.l( "TASK", "MenuAction" ) Parameter.ReferenceTask.ExecuteStage = _TransportExecuteStage.EXECUTING - Parameter.ReferenceTask.CargoName = Parameter.CargoName - + Parameter.ReferenceTask.Cargo = Parameter.CargoTask end function TASK:StageExecute() diff --git a/Moose/Trace.lua b/Moose/Trace.lua index 2d3477242..a6c8b00f6 100644 --- a/Moose/Trace.lua +++ b/Moose/Trace.lua @@ -62,6 +62,7 @@ trace.names.FollowPlayers = false trace.names.AddPlayerFromUnit = false trace.names.FromCarrier = false trace.names.OnDeadOrCrash = false + trace.classes.CLEANUP = false trace.cache = {}