From 7e098b050e9efc6694ec1bc3e3d167eed28a0e14 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Thu, 28 Jan 2016 16:48:22 +0100 Subject: [PATCH 01/51] Work in progress. Reworking complete CARGO logic... Partly working now ... --- Moose/Base.lua | 2 +- Moose/Cargo.lua | 709 ++++++++++++++++++++++++++++++++++++++++++- Moose/Client.lua | 104 ++++--- Moose/DeployTask.lua | 115 ++++--- Moose/Mission.lua | 66 +--- Moose/Moose.lua | 12 +- Moose/PickupTask.lua | 204 +++++-------- Moose/Routines.lua | 49 +-- Moose/Spawn.lua | 59 ++-- Moose/Stage.lua | 324 +++++++++++--------- Moose/Task.lua | 59 ++-- Moose/Trace.lua | 1 + 12 files changed, 1194 insertions(+), 510 deletions(-) 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 = {} From 2f7e3ffb7687e96661e056e4dc23a2941a506ce4 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 29 Jan 2016 00:50:19 +0100 Subject: [PATCH 02/51] Further progress, package pickup is now working... --- Moose/Cargo.lua | 76 +++++++++++++++++++++++++++++++++++++++--------- Moose/Client.lua | 6 ++-- Moose/Stage.lua | 2 +- 3 files changed, 67 insertions(+), 17 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 8cffe8311..53912c207 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -231,7 +231,8 @@ CARGO = { LOADED = 1, UNLOADED = 2, LOADING = 3 - } + }, + CargoCarrierGroupName = nil } --- 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... @@ -549,12 +550,14 @@ CARGO_PACKAGE = { } -function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight ) -trace.f( self.ClassName, { CargoType, CargoName, CargoWeight } ) +function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, InitClientGroupName ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, InitClientGroupName } ) -- Arrange meta tables local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) + self.InitClientGroupName = InitClientGroupName .. '#' -- to fix + CARGOS[self.CargoName] = self return self @@ -564,6 +567,32 @@ end function CARGO_PACKAGE:Spawn() trace.f( self.ClassName ) + -- this needs to be checked thoroughly + + + local SpawnCargo = true + + if self.Client and self.Client:ClientGroup() then + trace.i( self.ClassName, 'There is a Client ' .. self.Client.ClientName ) + if self.Client:FindCargo( self.CargoName ) then + if self.Client:ClientUnit():getPlayerName() then -- this needs to be checked thoroughly + trace.i( self.ClassName, 'ok, Client is of player ' .. self.Client:ClientUnit():getPlayerName() .. ' and contains the Cargo, do nothing' ) + SpawnCargo = false + end + end + else + if self.InitClientGroupName then + local ClientGroup = Group.getByName( self.InitClientGroupName ) + if ClientGroup and ClientGroup:isExist() then + self.Client = CLIENT:New( self.InitClientGroupName, '' ) + end + end + end + + if SpawnCargo then + self.Client:AddCargo( self ) -- Adding cargo to the AI client + end + return self end @@ -571,10 +600,20 @@ 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 + + trace.i( self.ClassName, self.Client.ClientName ) + if self.Client and self.Client:ClientGroup():getName() then + trace.i( self.ClassName, 'Client Exists.' ) + trace.i( self.ClassName, 'self.Client:ClientGroup():getName() = ' .. self.Client:ClientGroup():getName() ) + + -- Find the cargo in the client + local Cargo = self.Client:FindCargo( self.CargoName ) + if Cargo == self then + trace.i( self.ClassName, 'Cargo is loaded in Client.' ) + if routines.IsPartOfGroupInRadius( self.Client:ClientGroup(), Client:ClientPosition(), 150 ) then + Near = true + end + end end return Near @@ -593,8 +632,8 @@ trace.f(self.ClassName ) local CarrierPosOnBoard = ClientUnit:getPoint() local CarrierPosMoveAway = ClientUnit:getPoint() - local CargoHostGroup = LandingZone:GetCargoHostGroup() - local CargoHostGroupName = LandingZone:GetCargoHostGroup():getName() + local CargoHostGroup = self.Client:ClientGroup() + local CargoHostGroupName = self.Client:ClientGroup():getName() local CargoHostUnits = CargoHostGroup:getUnits() local CargoPos = CargoHostUnits[1]:getPoint() @@ -677,10 +716,21 @@ trace.f(self.ClassName ) local OnBoarded = false - local CargoHostGroup = LandingZone:GetCargoHostGroup() - if routines.IsPartOfGroupInRadius( CargoHostGroup, Client:ClientPosition(), 25 ) then - --CargoGroup:destroy() - OnBoarded = true + if self.Client and self.Client:ClientGroup() then + if routines.IsPartOfGroupInRadius( self.Client:ClientGroup(), Client:ClientPosition(), 25 ) then + + -- Switch Cargo from self.Client to Client ... + Client:AddCargo( self ) + self.Client:RemoveCargo( self ) + trace.i( self.ClassName, 'Cargo switched from ' .. self.Client:ClientGroup():getName() .. ' to ' .. Client:ClientGroup():getName() ) + trace.i( self.ClassName, 'Cargo is ' .. self.CargoName ) -- Should not be null + + -- ok, so the Cargo has a new Client, thus, change the Owning Client of the Cargo. + self.Client = Client + + -- All done, onboarded the Cargo to the new Client. + OnBoarded = true + end end return OnBoarded diff --git a/Moose/Client.lua b/Moose/Client.lua index 0563a8685..eb6131080 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -45,7 +45,7 @@ CLIENT = { -- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) function CLIENT:New( ClientName, ClientBriefing ) -trace.f(self.ClassName) +trace.f( self.ClassName, { ClientName, ClientBriefing } ) -- Arrange meta tables local self = BASE:Inherit( self, BASE:New() ) @@ -184,7 +184,7 @@ end -- @tparam string Cargo is the @{CARGO}. -- @treturn CLIENT function CLIENT:AddCargo( Cargo ) -trace.f(self.ClassName, { Cargo } ) +trace.f(self.ClassName, { Cargo.CargoName } ) local Valid = true @@ -201,7 +201,7 @@ end -- @tparam string CargoName is the name of the @{CARGO}. -- @treturn Cargo function CLIENT:RemoveCargo( Cargo ) -trace.f(self.ClassName ) +trace.f(self.ClassName, { Cargo.CargoName } ) local Valid = true diff --git a/Moose/Stage.lua b/Moose/Stage.lua index 7e3fe8e7a..9b6516a13 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -483,7 +483,7 @@ trace.f(self.ClassName) -- If the Cargo is ready to be loaded, load it into the Client. - trace.i(self.ClassName, Task.Cargo) + trace.i(self.ClassName, Task.Cargo.CargoName) if Task.Cargo:OnBoarded( Client, Task.CurrentCargoZone ) then From 6019a2a170a2d60ad8970964d65be6c03272d2c4 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sun, 14 Feb 2016 12:03:17 +0100 Subject: [PATCH 03/51] Got now back a good version working with CARGO now as a separate object. - Sling load working but dealing with the DCS bugs. - Normal CARGO pickup and deployment is working now, but needs to be further optimized... --- Moose/Cargo.lua | 292 ++++++++++++++++++++++++++++++++++-------- Moose/Client.lua | 4 +- Moose/Message.lua | 36 ++++++ Moose/Mission.lua | 8 +- Moose/PickupTask.lua | 7 +- Moose/Routines.lua | 192 +++++++++++++++------------- Moose/Spawn.lua | 12 +- Moose/Stage.lua | 294 +++++++++++++++++++++++++++++-------------- Moose/Task.lua | 4 +- 9 files changed, 600 insertions(+), 249 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 53912c207..d7ed635f3 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -33,39 +33,85 @@ CARGO_ZONE = { } } -function CARGO_ZONE:New( CargoZoneName, CargoHostGroupName ) -trace.f( self.ClassName, { CargoZoneName, CargoHostGroupName } ) +function CARGO_ZONE:New( CargoZoneName, CargoHostName ) +trace.f( self.ClassName, { CargoZoneName, CargoHostName } ) 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 ) + if CargoHostName then + self.CargoHostName = CargoHostName + self.CargoHostSpawn = SPAWN:New( CargoHostName ) end return self end function CARGO_ZONE:Spawn() -trace.f( self.ClassName ) +trace.f( self.ClassName, CargoHostSpawn ) 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() ) + self.CargoHostSpawn:ReSpawn() end else - self.CargoHostSpawn:ReSpawn( self.CargoHostSpawn:SpawnGroupName() ) + self.CargoHostSpawn:ReSpawn() end end return self end +function CARGO_ZONE:GetHostUnit() + + if self.CargoHostName then + + -- A Host has been given, signal the host + local CargoHostGroup = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) + local CargoHostUnit + if CargoHostGroup == nil then + CargoHostUnit = StaticObject.getByName( self.CargoHostName ) + else + CargoHostUnit = CargoHostGroup:getUnits()[1] + end + + return CargoHostUnit + end + + return nil +end + +function CARGO_ZONE:ReportCargosToClient( Client, CargoType ) +trace.f( self.ClassName ) + + local SignalUnit = self:GetHostUnit() + + if SignalUnit then + + local SignalUnitTypeName = SignalUnit:getTypeName() + + local HostMessage = "" + + local IsCargo = false + for CargoID, Cargo in pairs( Cargos ) do + if Cargo.CargoType == Task.CargoType then + HostMessage = HostMessage .. "\n - " .. Cargo.CargoName + IsCargo = true + end + end + + if not IsCargo then + HostMessage = HostMessage .. "No Cargo Available." + end + + Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageHosts." .. SignalUnitTypeName, SignalUnitTypeName .. ": Reporting Cargo", 10 ) + end +end + function CARGO_ZONE:Signal() trace.f( self.ClassName ) @@ -73,21 +119,17 @@ trace.f( self.ClassName ) if self.SignalType then - if self.CargoHostGroupName then + if self.CargoHostName 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 + local SignalUnit = self:GetHostUnit() + + if SignalUnit then trace.i( self.ClassName, 'Signalling Unit' ) local SignalVehiclePos = SignalUnit:getPosition().p - SignalVehiclePos.y = SignalVehiclePos.y + 10 + SignalVehiclePos.y = SignalVehiclePos.y + 2 if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then @@ -105,7 +147,7 @@ trace.f( self.ClassName ) else local CurrentPosition = { x = self.CargoZone.point.x, y = self.CargoZone.point.z } - self.CargoZone.point.y = land.getHeight( CurrentPosition ) + 10 + self.CargoZone.point.y = land.getHeight( CurrentPosition ) + 2 if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then @@ -210,9 +252,9 @@ end function CARGO_ZONE:GetCargoHostGroup() trace.f( self.ClassName ) - local CargoHost = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) - if CargoHost and CargoHost:isExist() then - return CargoHost + local CargoHostGroup = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) + if CargoHostGroup and CargoHostGroup:isExist() then + return CargoHostGroup end return nil @@ -318,6 +360,17 @@ trace.f(self.ClassName ) return OnBoarded end +function CARGO:IsLandingRequired() +trace.f( self.ClassName ) + return true +end + +function CARGO:IsSlingLoad() +trace.f( self.ClassName ) + return false +end + + function CARGO:StatusNone() trace.f(self.ClassName ) @@ -541,7 +594,7 @@ trace.f( self.ClassName ) local Cargo = Client:RemoveCargo( self ) - return Cargo + return self end @@ -550,13 +603,15 @@ CARGO_PACKAGE = { } -function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, InitClientGroupName ) -trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, InitClientGroupName } ) +function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoHostName ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoHostName } ) -- Arrange meta tables local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) - self.InitClientGroupName = InitClientGroupName .. '#' -- to fix + self.CargoHostName = CargoHostName + + self.CargoHostSpawn = SPAWN:New( self.CargoHostName ) CARGOS[self.CargoName] = self @@ -572,6 +627,8 @@ trace.f( self.ClassName ) local SpawnCargo = true + trace.i( self.ClassName, self.CargoHostName ) + if self.Client and self.Client:ClientGroup() then trace.i( self.ClassName, 'There is a Client ' .. self.Client.ClientName ) if self.Client:FindCargo( self.CargoName ) then @@ -581,10 +638,14 @@ trace.f( self.ClassName ) end end else - if self.InitClientGroupName then - local ClientGroup = Group.getByName( self.InitClientGroupName ) - if ClientGroup and ClientGroup:isExist() then - self.Client = CLIENT:New( self.InitClientGroupName, '' ) + if self.CargoHostName then + local CargoHostGroup = Group.getByName( self.CargoHostName ) + if not CargoHostGroup then + self.CargoHostSpawn:ReSpawn() + end + local CargoHostGroup = Group.getByName( self.CargoHostName ) + if CargoHostGroup and CargoHostGroup:isExist() then + self.Client = CLIENT:New( self.CargoHostGroup, '' ) end end end @@ -601,8 +662,8 @@ trace.f( self.ClassName ) local Near = false - trace.i( self.ClassName, self.Client.ClientName ) if self.Client and self.Client:ClientGroup():getName() then + trace.i( self.ClassName, self.Client.ClientName ) trace.i( self.ClassName, 'Client Exists.' ) trace.i( self.ClassName, 'self.Client:ClientGroup():getName() = ' .. self.Client:ClientGroup():getName() ) @@ -633,7 +694,7 @@ trace.f(self.ClassName ) local CarrierPosMoveAway = ClientUnit:getPoint() local CargoHostGroup = self.Client:ClientGroup() - local CargoHostGroupName = self.Client:ClientGroup():getName() + local CargoHostName = self.Client:ClientGroup():getName() local CargoHostUnits = CargoHostGroup:getUnits() local CargoPos = CargoHostUnits[1]:getPoint() @@ -702,9 +763,9 @@ trace.f(self.ClassName ) Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) end - trace.i( self.ClassName, "Routing " .. CargoHostGroupName ) + trace.i( self.ClassName, "Routing " .. CargoHostName ) - routines.scheduleFunction( routines.goRoute, { CargoHostGroupName, Points}, timer.getTime() + 4 ) + routines.scheduleFunction( routines.goRoute, { CargoHostName, Points}, timer.getTime() + 4 ) return Valid @@ -750,29 +811,154 @@ trace.f( self.ClassName ) end +CARGO_SLINGLOAD = { + ClassName = "CARGO_SLINGLOAD" +} + + +function CARGO_SLINGLOAD:New( CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID } ) + + -- Arrange meta tables + local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) + + self.CargoHostName = CargoHostName + + -- Cargo will be initialized around the CargoZone position. + self.CargoZone = CargoZone + + self.CargoCount = 0 + self.CargoStaticName = string.format( "%s#%03d", self.CargoName, self.CargoCount ) + + -- The country ID needs to be correctly set. + self.CargoCountryID = CargoCountryID + + CARGOS[self.CargoName] = self + + return self + +end + +function CARGO_SLINGLOAD:IsLandingRequired() +trace.f( self.ClassName ) + return false +end + +function CARGO_SLINGLOAD:IsSlingLoad() +trace.f( self.ClassName ) + return true +end + + +function CARGO_SLINGLOAD:Spawn() +trace.f( self.ClassName ) + + local Zone = trigger.misc.getZone( self.CargoZone ) + + local ZonePos = {} + ZonePos.x = Zone.point.x + math.random( Zone.radius / 2 * -1, Zone.radius / 2 ) + ZonePos.y = Zone.point.z + math.random( Zone.radius / 2 * -1, Zone.radius / 2 ) + + trace.i( self.ClassName, "Cargo Location = " .. ZonePos.x .. ", " .. ZonePos.y ) + + --[[ + -- This does not work in 1.5.2. + CargoStatic = StaticObject.getByName( self.CargoName ) + if CargoStatic then + CargoStatic:destroy() + end + --]] + + CargoStatic = StaticObject.getByName( self.CargoStaticName ) + + if CargoStatic and CargoStatic:isExist() then + CargoStatic:destroy() + end + + -- I need to make every time a new cargo due to bugs in 1.5.2. + + self.CargoCount = self.CargoCount + 1 + self.CargoStaticName = string.format( "%s#%03d", self.CargoName, self.CargoCount ) + + local CargoTemplate = { + ["category"] = "Cargo", + ["shape_name"] = "ab-212_cargo", + ["type"] = "Cargo1", + ["x"] = ZonePos.x, + ["y"] = ZonePos.y, + ["mass"] = self.CargoWeight, + ["name"] = self.CargoStaticName, + ["canCargo"] = true, + ["heading"] = 0, + } + + coalition.addStaticObject( self.CargoCountryID, CargoTemplate ) + +-- end + + return self +end + +function CARGO_SLINGLOAD:IsInLandingZone( Client, LandingZone ) +trace.f( self.ClassName ) + + local Near = false + + local CargoStaticUnit = StaticObject.getByName( self.CargoName ) + if CargoStaticUnit then + if routines.IsStaticInZones( CargoStaticUnit, LandingZone ) then + Near = true + end + end + + return Near + +end + + + +function CARGO_SLINGLOAD:OnBoard( Client, LandingZone, OnBoardSide ) +trace.f(self.ClassName ) + + local Valid = true + + + return Valid + +end + + +function CARGO_SLINGLOAD:OnBoarded( Client, LandingZone ) +trace.f(self.ClassName ) + + local OnBoarded = false + + local CargoStaticUnit = StaticObject.getByName( self.CargoName ) + if CargoStaticUnit then + if not routines.IsStaticInZones( CargoStaticUnit, LandingZone ) then + Onboarded = true + end + end + + return OnBoarded +end + +function CARGO_SLINGLOAD:UnLoad( Client, TargetZoneName ) +trace.f( self.ClassName ) + + trace.i( self.ClassName, 'self.CargoName = ' .. self.CargoName ) + trace.i( self.ClassName, 'self.CargoGroupName = ' .. self.CargoGroupName ) + + self:StatusUnLoaded() + local Cargo = Client:RemoveCargo( self ) + + + return Cargo +end + --[[-- Internal Table to understand the form of the CARGO. @table CARGO_TRANSPORT --]] CARGO_TRANSPORT = { UNIT = 1, SLING = 2, STATIC = 3, INVISIBLE = 4 } ---[[-- - CARGO_TYPE Defines the different types of transports, which has an impact on the menu commands shown in F10. - @table CARGO_TYPE - @field TROOPS - @field GOODS - @field VEHICLES - @field INFANTRY - @field ENGINEERS - @field PACKAGE - @field CARGO ---]] -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.STATIC }, - INFANTRY = { ID = 4, TEXT = "Infantry", TRANSPORT = CARGO_TRANSPORT.UNIT }, - ENGINEERS = { ID = 5, TEXT = "Engineers", TRANSPORT = CARGO_TRANSPORT.UNIT }, - 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 eb6131080..f667d43e5 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -207,11 +207,11 @@ trace.f(self.ClassName, { Cargo.CargoName } ) if Valid then trace.i( "CLIENT", "RemoveCargo: CargoName = " .. Cargo.CargoName ) - local CargoNew = self._Cargos[Cargo.CargoName] + --local CargoNew = self._Cargos[Cargo.CargoName] self._Cargos[Cargo.CargoName] = nil end - return CargoNew + return Cargo end diff --git a/Moose/Message.lua b/Moose/Message.lua index f10c54fdd..44c128c69 100644 --- a/Moose/Message.lua +++ b/Moose/Message.lua @@ -84,6 +84,42 @@ trace.f(self.ClassName ) return self 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. -- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}. -- @treturn MESSAGE diff --git a/Moose/Mission.lua b/Moose/Mission.lua index a5a5b671a..fcb0d8683 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -102,7 +102,7 @@ end function MISSION:Ongoing() trace.f(self.ClassName) self.MissionStatus = "ONGOING" - self:StatusToClients() + --self:StatusToClients() end --- Returns if a Mission is pending. @@ -136,7 +136,7 @@ end --- Send the status of the MISSION to all Clients. function MISSION:StatusToClients() trace.f(self.ClassName) - if timer.getTime() >= self.MissionReportTrigger then + if self.MissionReportFlash then 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") end @@ -414,7 +414,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") -- loop through the missions in the TransportTasks for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do - env.info( "Mission: " .. MissionName ) + trace.i( "MISSIONSCHEDULER", MissionName ) if not Mission:IsCompleted() then @@ -423,7 +423,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") for ClientID, Client in pairs( Mission._Clients ) do - env.info( "Client: " .. Client.ClientName ) + 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 diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index a3623580f..2b4e1b3ee 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -28,9 +28,10 @@ trace.f(self.ClassName) Child.CargoType = CargoType Child.GoalVerb = CargoType .. " " .. Child.GoalVerb Child.OnBoardSide = OnBoardSide + Child.IsLandingRequired = false -- required to decide whether the client needs to land or not + Child.IsSlingLoad = false -- Indicates whether the cargo is a sling load cargo 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 return Child @@ -91,10 +92,10 @@ trace.f( self.ClassName ) if not Client._Menus[Cargo.CargoType].PickupMenu then Client._Menus[Cargo.CargoType].PickupMenu = missionCommands.addSubMenuForGroup( Client:ClientGroup():getID(), - self.TEXT[1], + self.TEXT[1] .. " " .. Cargo.CargoType, nil ) - trace.i( self.ClassName, 'Added PickupMenu' .. self.TEXT[1] ) + trace.i( self.ClassName, 'Added PickupMenu: ' .. self.TEXT[1] .. " " .. Cargo.CargoType ) end if Client._Menus[Cargo.CargoType].PickupSubMenus == nil then diff --git a/Moose/Routines.lua b/Moose/Routines.lua index 427447b7c..a40a8c9df 100644 --- a/Moose/Routines.lua +++ b/Moose/Routines.lua @@ -25,6 +25,91 @@ routines.build = 22 -- Utils- conversion, Lua utils, etc. 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 + 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 routines.utils.toDegree = function(angle) @@ -137,91 +222,6 @@ function routines.utils.get3DDist(point1, point2) 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 -- use negative idp for rounding ahead of decimal place, positive for rounding after decimal place @@ -280,6 +280,9 @@ routines.vec.rotateVec2 = function(vec2, theta) end --------------------------------------------------------------------------------------------------------------------------- + + + -- acc- the accuracy of each easting/northing. 0, 1, 2, 3, 4, or 5. routines.tostringMGRS = function(MGRS, acc) if acc == 0 then @@ -1829,6 +1832,23 @@ routines.ground.patrol = function(gpData, pType, form, speed) return 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 = {} } @@ -2362,7 +2382,7 @@ trace.f() --env.info(( 'CarrierHeight: LandHeight = ' .. LandHeight .. ' CarrierHeight = ' .. CarrierHeight )) - return CarrierHeight - LandHeight + return UnitHeight - LandHeight end diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index f728d108e..e6d06bd53 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -332,8 +332,8 @@ trace.f( self.ClassName, { CarrierGroup, TargetZonePrefix, NewGroupName, LateAct 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) + 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 ) trace.i( self.ClassName, "RouteCount = " .. RouteCount ) @@ -379,11 +379,13 @@ end -- @treturn string SpawnGroupName function SPAWN:SpawnGroupName( SpawnNumber ) trace.f("Spawn", SpawnNumber ) - + if SpawnNumber then - return string.format( self.SpawnPrefix .. '#%03d', SpawnNumber ) + trace.i( self.ClassName, string.format( '%s#%03d', self.SpawnPrefix, SpawnNumber ) ) + return string.format( '%s#%03d', self.SpawnPrefix, SpawnNumber ) else - return string.format( self.SpawnPrefix .. '#' ) + trace.i( self.ClassName, self.SpawnPrefix ) + return self.SpawnPrefix end end diff --git a/Moose/Stage.lua b/Moose/Stage.lua index 9b6516a13..7dfc90f99 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -112,9 +112,9 @@ function STAGESTART:Execute( Mission, Client, Task ) trace.f(self.ClassName) local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) if Task.TaskBriefing then - Client:Message( Task.TaskBriefing, self.StageStartDuration, Mission.Name .. "/Stage", "Mission Command: Tasking" ) + Client:Message( Task.TaskBriefing, 15, Mission.Name .. "/Stage", "Mission Command: Tasking" ) else - Client:Message( 'Task ' .. Task.TaskNumber .. '.', self.StageStartDuration, Mission.Name .. "/Stage", "Mission Command: Tasking" ) + Client:Message( 'Task ' .. Task.TaskNumber .. '.', 15, Mission.Name .. "/Stage", "Mission Command: Tasking" ) end self.StageStartTime = timer.getTime() return Valid @@ -155,7 +155,7 @@ trace.f(self.ClassName) LoadCargo:Load( Client ) end - if Client:IsTransport() then + if Mission.MissionReportFlash and Client:IsTransport() then Client:ShowCargo() end @@ -212,7 +212,7 @@ end STAGEROUTE = { ClassName = "STAGEROUTE", - MSG = { ID = "Route", TIME = 1 }, + MSG = { ID = "Route", TIME = 5 }, Frequency = STAGE.FREQUENCY.REPEAT, Name = "Route" } @@ -235,9 +235,9 @@ trace.f(self.ClassName) 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 ) + Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageRoute", "Co-Pilot: Route", 20 ) - if Client:IsTransport() then + if Mission.MissionReportFlash and Client:IsTransport() then Client:ShowCargo() end @@ -269,6 +269,8 @@ trace.f(self.ClassName) return 0 end + + STAGELANDING = { ClassName = "STAGELANDING", MSG = { ID = "Landing", TIME = 10 }, @@ -287,45 +289,83 @@ end function STAGELANDING:Execute( Mission, Client, Task ) trace.f(self.ClassName) - 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 ) - + Client:Message( "We have arrived at the landing zone.", self.MSG.TIME, Mission.Name .. "/StageArrived", "Co-Pilot: Arrived", 10 ) + + 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 + trace.i( self.ClassName, "Task for cargo " .. Cargo.CargoType .. " requires landing.") + Task.IsLandingRequired = true + end + + if Cargo:IsSlingLoad() then + trace.i( self.ClassName, "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 function STAGELANDING:Validate( Mission, Client, Task ) trace.f(self.ClassName) - 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 ) + Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:ClientUnit(), Task.LandingZones.LandingZoneNames ) + if Task.CurrentLandingZoneName then + + -- Client is in de landing zone. + trace.i( self.ClassName, Task.CurrentLandingZoneName ) - if Task.CurrentLandingZoneName then + Task.CurrentLandingZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName].CargoZone + Task.CurrentCargoZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName] - 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 + 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:ClientUnit():inAir() then - else + if Task.IsLandingRequired and Client:ClientUnit():inAir() then return 0 end @@ -349,10 +389,15 @@ 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 .. '.', self.MSG.TIME, Mission.Name .. "/StageLanded", "Co-Pilot: Landed" ) - if not self.MenusAdded then - Task:RemoveCargoMenus( Client ) - Task:AddCargoMenus( Client, CARGOS, 250 ) + + if Task.IsLandingRequired then + 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.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 @@ -361,25 +406,27 @@ end function STAGELANDED:Validate( Mission, Client, Task ) trace.f(self.ClassName) - if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then - else - Task.Signalled = false - Task:RemoveCargoMenus( Client ) - return -2 - end + if not routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + trace.i( self.ClassName, "Client is not anymore in the landing zone, go back to stage Route, and remove cargo menus." ) + Task.Signalled = false + Task:RemoveCargoMenus( Client ) + return -2 + end - if not Client:ClientUnit():inAir() then - else - Task.Signalled = false - return -1 - end + if Task.IsLandingRequired and Client:ClientUnit():inAir() then + trace.i( self.ClassName, "Client went back in the air. Go back to stage Landing." ) + Task.Signalled = false + return -1 + end - if Task.ExecuteStage == _TransportExecuteStage.EXECUTING then - else - return 0 - end + -- Wait until cargo is selected from the menu. + if Task.IsLandingRequired then + if not Task.Cargo then + return 0 + end + end - return 1 + return 1 end STAGEUNLOAD = { @@ -417,7 +464,9 @@ trace.f(self.ClassName) if Task.Cargo:UnLoad( Client, TargetZoneName ) then Task.ExecuteStage = _TransportExecuteStage.SUCCESS - Client:ShowCargo() + if Mission.MissionReportFlash then + Client:ShowCargo() + end end end @@ -470,67 +519,122 @@ end function STAGELOAD:Execute( Mission, Client, Task ) trace.f(self.ClassName) - 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" ) + + 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 - Task.Cargo:OnBoard( Client, Task.CurrentCargoZone, Task.OnBoardSide ) - Task.ExecuteStage = _TransportExecuteStage.EXECUTING + -- Route the cargo to the Carrier + Task.Cargo:OnBoard( Client, Task.CurrentCargoZone, Task.OnBoardSide ) + Task.ExecuteStage = _TransportExecuteStage.EXECUTING + else + Task.ExecuteStage = _TransportExecuteStage.EXECUTING + end end function STAGELOAD:Executing( Mission, Client, Task ) trace.f(self.ClassName) - -- If the Cargo is ready to be loaded, load it into the Client. - - trace.i(self.ClassName, Task.Cargo.CargoName) - - if Task.Cargo:OnBoarded( Client, Task.CurrentCargoZone ) then + -- If the Cargo is ready to be loaded, load it into the Client. - -- 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() + if not Task.IsSlingLoad then + trace.i(self.ClassName, Task.Cargo.CargoName) + + 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 .. "/STAGELANDING.LOADING1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" ) + Task.ExecuteStage = _TransportExecuteStage.SUCCESS + + if Mission.MissionReportFlash then + Client:ShowCargo() + end + end + else + Client:Message( "Hook the " .. Task.CargoNames .. " onto the helicopter " .. Task.TEXT[3] .. " within the landing zone.", + _TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.LOADING.1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":", 10 ) + for CargoID, Cargo in pairs( CARGOS ) do + trace.i( self.ClassName, "Cargo.CargoName = " .. Cargo.CargoName ) + + if Cargo:IsSlingLoad() then + local CargoStatic = StaticObject.getByName( Cargo.CargoStaticName ) + if CargoStatic then + trace.i(self.ClassName, "Cargo is found in the DCS simulator.") + local CargoStaticPosition = CargoStatic:getPosition().p + trace.i(self.ClassName, "Cargo Position x = " .. CargoStaticPosition.x .. ", y = " .. CargoStaticPosition.y .. ", z = " .. CargoStaticPosition.z ) + local CargoStaticHeight = routines.GetUnitHeight( CargoStatic ) + if CargoStaticHeight > 5 then + trace.i(self.ClassName, "Cargo is airborne.") + Cargo:StatusLoaded() + Task.Cargo = Cargo + Client:Message( 'The Cargo has been successfully hooked onto the helicopter and is now being sling loaded. Fly outside the landing zone.', + self.MSG.TIME, Mission.Name .. "/STAGELANDING.LOADING.2." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" ) + Task.ExecuteStage = _TransportExecuteStage.SUCCESS + break + end + else + trace.i( self.ClassName, "Cargo not found in the DCS simulator." ) + end + end + end end end function STAGELOAD:Validate( Mission, Client, Task ) trace.f(self.ClassName) - if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + + trace.i( self.ClassName, "Task.CurrentLandingZoneName = " .. Task.CurrentLandingZoneName ) + + if not Task.IsSlingLoad then + if not routines.IsUnitInZones( Client:ClientUnit(), 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: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 .. " 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.Cargo:StatusLoaded() + 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 - 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. ", - _TransportStageMsgTime.DONE, Mission.Name .. "/StageSuccess", "Co-Pilot: Load" ) - return 1 - end - - 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 .. " 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 - Task.Cargo:StatusLoaded() - Task:RemoveCargoMenus( Client ) - 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 + 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 diff --git a/Moose/Task.lua b/Moose/Task.lua index 2d0f753f8..1dce0aab6 100644 --- a/Moose/Task.lua +++ b/Moose/Task.lua @@ -128,7 +128,9 @@ trace.f(self.ClassName) 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 --- Sets a TASK to status Done. From 4a52422fe14ab1a7297191cf62f184f61465c1d5 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Wed, 17 Feb 2016 14:58:27 +0100 Subject: [PATCH 04/51] Added GROUP, ZONE classes to handle Tasks and Zones GROUP will be a class abstraction for the DCS Group class, incorporating the Controller for tasks. ZONE will be a class abstraction for a trigger zone. Each of these classes will have properties to further emulate tasks, and execute all kind of actions on the object. --- Moose/Group.lua | 85 ++++++++++++++++++++++++++++++++++++++++++++ Moose/PickupTask.lua | 1 + Moose/Spawn.lua | 33 ++++++++++++----- Moose/Zone.lua | 57 +++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 Moose/Group.lua create mode 100644 Moose/Zone.lua diff --git a/Moose/Group.lua b/Moose/Group.lua new file mode 100644 index 000000000..bc4cef98e --- /dev/null +++ b/Moose/Group.lua @@ -0,0 +1,85 @@ +--- GROUP Classes +-- @classmod GROUP + +Include.File( "Routines" ) +Include.File( "Base" ) +Include.File( "Message" ) + +GROUPS = {} + + +GROUP = { + ClassName="GROUP", + } + +function GROUP:New( _Group ) +trace.f( self.ClassName, _Group:getName() ) + + local self = BASE:Inherit( self, BASE:New() ) + + self._Group = _Group + self.GroupName = _Group:getName() + self.GroupID = _Group:getID() + + return self +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 diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index 2b4e1b3ee..ac7ce188a 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -3,6 +3,7 @@ -- @parent TASK Include.File("Task") +Include.File("Cargo") PICKUPTASK = { ClassName = "PICKUPTASK", diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index e6d06bd53..48df6e921 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -5,6 +5,8 @@ Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Database" ) +Include.File( "Group" ) + SPAWN = { ClassName = "SPAWN", @@ -375,14 +377,14 @@ 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. +-- @tparam number SpawnIndex is the number of the Group that is to be SPAWNed. -- @treturn string SpawnGroupName -function SPAWN:SpawnGroupName( SpawnNumber ) -trace.f("Spawn", SpawnNumber ) +function SPAWN:SpawnGroupName( SpawnIndex ) +trace.f("Spawn", SpawnIndex ) - if SpawnNumber then - trace.i( self.ClassName, string.format( '%s#%03d', self.SpawnPrefix, SpawnNumber ) ) - return string.format( '%s#%03d', self.SpawnPrefix, SpawnNumber ) + if SpawnIndex then + trace.i( self.ClassName, string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) ) + return string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) else trace.i( self.ClassName, self.SpawnPrefix ) return self.SpawnPrefix @@ -390,6 +392,21 @@ trace.f("Spawn", SpawnNumber ) end +function SPAWN:GetLastIndex() + + return self.SpawnCount +end + + +function SPAWN:GetLastGroup() +trace.f( self.ClassName ) + + local LastGroupName = self:SpawnGroupName( self:GetLastIndex() ) + + return GROUP:New( Group.getByName( LastGroupName ) ) +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 @@ -528,8 +545,8 @@ trace.f( self.ClassName ) for u = 1, SpawnUnits do 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 + SpawnTemplate.units[u].x = SpawnTemplate.route.points[1].x + math.random( -50, 50 ) + SpawnTemplate.units[u].y = SpawnTemplate.route.points[1].y + math.random( -50, 50 ) end trace.r( self.ClassName, "", SpawnTemplate.name ) diff --git a/Moose/Zone.lua b/Moose/Zone.lua new file mode 100644 index 000000000..a4f5fe113 --- /dev/null +++ b/Moose/Zone.lua @@ -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 From c81e7c2488c9fc2ad65c7aa17e71e7781cd84f5c Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Thu, 18 Feb 2016 15:32:29 +0100 Subject: [PATCH 05/51] Try to get the DCS bug in 1.5.3 resolved with :isExist for a Client Group Client groups connected remotely to a server, are not generating any birth events on the server. The server therefore thinks that the Group does not exist ... This bug is present since 1.5. Currently building a logic to go "around" that problem using other functions (the coalition:getPlayerUnits() is key for resolvement) --- Moose/Client.lua | 41 +++++++++++++++++++++++++++++++++++------ Moose/Database.lua | 1 + 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Moose/Client.lua b/Moose/Client.lua index f667d43e5..e4bd7933c 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -65,16 +65,45 @@ trace.f(self.ClassName) end --- 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 function CLIENT:ClientGroup() --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 - else - return nil +-- local ClientData = Group.getByName( self.ClientName ) +-- if ClientData and ClientData:isExist() then +-- trace.i( self.ClassName, self.ClientName .. " : group found!" ) +-- return ClientData +-- else +-- return nil +-- end + + local ClientGroup = Group.getByName( self.ClientName ) + + if ClientGroup then + + local ClientUnits = ClientGroup:getUnits() + + if ClientGroup:isExist() then + trace.i( self.ClassName, self.ClientName .. " : group found!" ) + return ClientGroup + else + -- Now we need to resolve the bugs in DCS 1.5 ... + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + trace.i( self.ClassName, CoalitionData ) + for UnitId, UnitData in pairs( CoalitionData ) do + trace.i( self.ClassName, UnitData ) + if UnitData and UnitData:isExist() then + if UnitData:getID() == ClientUnits[1]:getID() then + trace.i( self.ClassName, self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) + return self.ClientGroup + end + end + end + end + end end + return nil end --- Returns the Unit of the @{CLIENT}. diff --git a/Moose/Database.lua b/Moose/Database.lua index 986896a78..99ceb9f36 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -13,6 +13,7 @@ DATABASE = { NavPoints = {}, Statics = {}, Players = {}, + ActivePlayers = {}, ClientsByName = {}, ClientsByID = {}, } From 61d51fe9a58db3b54697a6765249f8cdcce6520f Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 14:35:59 +0100 Subject: [PATCH 06/51] Added a layer to resolve the Client Bug problems in 1.5 --- Moose/Base.lua | 31 ++++++++++++- Moose/Client.lua | 104 ++++++++++++++++++++++++++++++++------------ Moose/ClientBug.lua | 50 +++++++++++++++++++++ Moose/Database.lua | 2 + Moose/Message.lua | 6 +-- Moose/Mission.lua | 2 +- Moose/Moose.lua | 2 + 7 files changed, 165 insertions(+), 32 deletions(-) create mode 100644 Moose/ClientBug.lua diff --git a/Moose/Base.lua b/Moose/Base.lua index c11c786a1..59edff66e 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -104,6 +104,7 @@ trace.f( self.ClassName ) return self end + BaseEventCodes = { "S_EVENT_SHOT", "S_EVENT_HIT", @@ -129,7 +130,35 @@ BaseEventCodes = { "S_EVENT_SHOOTING_START", "S_EVENT_SHOOTING_END", "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:onEvent(event) --trace.f(self.ClassName, event ) diff --git a/Moose/Client.lua b/Moose/Client.lua index e4bd7933c..c9a7dcfb4 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -68,8 +68,9 @@ end -- This function is modified to deal with a couple of bugs in DCS 1.5.3 -- @treturn Group function CLIENT:ClientGroup() ---trace.f(self.ClassName) --- local ClientData = Group.getByName( self.ClientName ) +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 @@ -77,35 +78,84 @@ function CLIENT:ClientGroup() -- return nil -- end - local ClientGroup = Group.getByName( self.ClientName ) - - if ClientGroup then - - local ClientUnits = ClientGroup:getUnits() - - if ClientGroup:isExist() then - trace.i( self.ClassName, self.ClientName .. " : group found!" ) - return ClientGroup - else - -- Now we need to resolve the bugs in DCS 1.5 ... - local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - trace.i( self.ClassName, CoalitionData ) - for UnitId, UnitData in pairs( CoalitionData ) do - trace.i( self.ClassName, UnitData ) - if UnitData and UnitData:isExist() then - if UnitData:getID() == ClientUnits[1]:getID() then - trace.i( self.ClassName, self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) - return self.ClientGroup + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + trace.i( self.ClassName, CoalitionData ) + for UnitId, UnitData in pairs( CoalitionData ) do + trace.i( self.ClassName, UnitData ) + if UnitData and UnitData:isExist() then + + local ClientGroup = Group.getByName( self.ClientName ) + if ClientGroup then + trace.i( self.ClassName, "ClientGroup = " .. self.ClientName ) + if ClientGroup:isExist() and ClientGroup:getID() == UnitData:getGroup():getID() then + trace.i( self.ClassName, "Normal logic" ) + trace.i( self.ClassName, self.ClientName .. " : group found!" ) + return ClientGroup + 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) + trace.i( self.ClassName, "Bug 1.5 logic" ) + local ClientUnits = _Database.Groups[self.ClientName].Units + trace.i( self.ClassName, { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } ) + for ClientUnitID, ClientUnitData in pairs( ClientUnits ) do + trace.i( self.ClassName, { 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 + trace.i( self.ClassName, 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 + + self.ClientGroupID = nil + self.ClientGroupUnit = nil + return nil end + +function CLIENT:GetClientGroupID() +trace.f(self.ClassName) + + ClientGroup = self:ClientGroup() + + if ClientGroup then + if ClientGroup:isExist() then + return ClientGroup:getID() + else + return self.ClientGroupID + end + end + + return nil +end + +function CLIENT:GetClientGroupUnit() +trace.f(self.ClassName) + + ClientGroup = self:ClientGroup() + + if ClientGroup then + if ClientGroup:isExist() then + return ClientGroup:getUnits()[1] + else + return self.ClientGroupUnit + end + end + + return nil +end + + --- Returns the Unit of the @{CLIENT}. -- @treturn Unit function CLIENT:ClientUnit() @@ -260,10 +310,10 @@ function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, M trace.f( self.ClassName, { Message, MessageDuration, MessageId, MessageCategory, MessageInterval } ) if not self.MenuMessages then - if self:ClientGroup() and self:ClientGroup():getID() then - self.MenuMessages = MENU_SUB_GROUP:New( self:ClientGroup():getID(), 'Messages' ) - self.MenuRouteMessageOn = MENU_COMMAND_GROUP:New( self:ClientGroup():getID(), '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 } ) + if self:GetClientGroupID() then + self.MenuMessages = MENU_SUB_GROUP:New( self:GetClientGroupID(), 'Messages' ) + self.MenuRouteMessageOn = MENU_COMMAND_GROUP:New( self:GetClientGroupID(), 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } ) + self.MenuRouteMessageOff = MENU_COMMAND_GROUP:New( self:GetClientGroupID(),'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } ) end end @@ -283,7 +333,7 @@ trace.f( self.ClassName, { Message, MessageDuration, MessageId, MessageCategory, end MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) 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 MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) self.Messages[MessageId].MessageTime = timer.getTime() diff --git a/Moose/ClientBug.lua b/Moose/ClientBug.lua new file mode 100644 index 000000000..12fc34df5 --- /dev/null +++ b/Moose/ClientBug.lua @@ -0,0 +1,50 @@ +--- Bug Client Activation Multiplayer Classes +-- @classmod CLIENTBUG + +Include.File( "Routines" ) +Include.File( "Base" ) + + +CLIENTBUG = { + ClassName = "CLIENTBUG", +} + +function CLIENTBUG:New( ) +trace.f( self.ClassName ) + + -- Arrange meta tables + local self = BASE:Inherit( self, BASE:New() ) + + self.ActiveClients = {} + + self.ClientBugWorkaround = routines.scheduleFunction( self._ClientBugWorkaround, { self }, timer.getTime() + 1, 0.1 ) + + return self +end + +function CLIENTBUG:_ClientBugWorkaround() + + -- Get the units of the players + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + trace.i( self.ClassName, CoalitionData ) + + for UnitId, UnitData in pairs( CoalitionData ) do + trace.i( self.ClassName, UnitData ) + + if UnitData and UnitData:isExist() then + + local UnitSkill = _Database.Units[UnitData:getName()].Template.skill + trace.i( self.ClassName, "UnitSkill = " .. UnitSkill ) + + if UnitSkill == "Client" then + + -- Generate birth event + self:CreateEventBirth( 0, UnitData, UnitData:getName(), 0, 0 ) + end + end + end + end + +end diff --git a/Moose/Database.lua b/Moose/Database.lua index 99ceb9f36..4ec727564 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -176,6 +176,8 @@ function DATABASE:_RegisterGroup( GroupTemplate ) self.Groups[GroupTemplateName].Template = GroupTemplate self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units + self.Groups[GroupTemplateName].Units = GroupTemplate.units + trace.i( self.ClassName, { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) for unit_num, UnitTemplate in pairs(GroupTemplate.units) do diff --git a/Moose/Message.lua b/Moose/Message.lua index 44c128c69..6ca4b906a 100644 --- a/Moose/Message.lua +++ b/Moose/Message.lua @@ -74,11 +74,11 @@ end function MESSAGE:ToClient( Client ) 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 ) - 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 return self diff --git a/Moose/Mission.lua b/Moose/Mission.lua index fcb0d8683..2ff9c8485 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -425,7 +425,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") 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. ClientsAlive = true diff --git a/Moose/Moose.lua b/Moose/Moose.lua index 5dc2b17e8..4c27ec554 100644 --- a/Moose/Moose.lua +++ b/Moose/Moose.lua @@ -21,8 +21,10 @@ Include.Files = {} Include.File = function( IncludeFile ) if not Include.Files[ IncludeFile ] then Include.Files[IncludeFile] = IncludeFile + env.info( "Include:" .. IncludeFile .. " from " .. Include.ProgramPath ) local f = assert( base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" ) ) if f == nil then + env.info( "Include:" .. IncludeFile .. " from " .. Include.MissionPath ) local f = assert( base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" ) ) if f == nil then error ("Could not load MOOSE file " .. IncludeFile .. ".lua" ) From 357dd87c03544bd767615f258e64ecaf61299bcb Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 14:59:22 +0100 Subject: [PATCH 07/51] Couple of fixes for Client bug in 1.5 --- Moose/Mission.lua | 10 +++++----- Moose/Stage.lua | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Moose/Mission.lua b/Moose/Mission.lua index 2ff9c8485..1d65c5e0c 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -175,12 +175,12 @@ trace.f(self.ClassName) local AlivePlayers = '' for ClientID, Client in pairs( self._Clients ) do if Client:ClientGroup() then - if Client:ClientGroup():getUnit(1) then - if Client:ClientGroup():getUnit(1):getLife() > 0.0 then + if Client:ClientGroupUnit() then + if Client:ClientGroupUnit():getLife() > 0.0 then if AlivePlayers == '' then - AlivePlayers = ' Players: ' .. Client:ClientGroup():getUnit(1):getPlayerName() + AlivePlayers = ' Players: ' .. Client:ClientGroupUnit():getPlayerName() else - AlivePlayers = AlivePlayers .. ' / ' .. Client:ClientGroup():getUnit(1):getPlayerName() + AlivePlayers = AlivePlayers .. ' / ' .. Client:ClientGroupUnit():getPlayerName() end end end @@ -505,7 +505,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") if Mission.GoalFunction ~= nil then Mission.GoalFunction( Mission, Client ) end - _Database:_AddMissionTaskScore( Client:ClientGroup():getUnit(1), Mission.Name, 25 ) + _Database:_AddMissionTaskScore( Client:ClientGroupUnit(), Mission.Name, 25 ) -- if not Mission:IsCompleted() then -- end diff --git a/Moose/Stage.lua b/Moose/Stage.lua index 7dfc90f99..c607a6642 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -233,7 +233,7 @@ trace.f(self.ClassName) 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. ' + RouteMessage = RouteMessage .. LandingZoneName .. ' at ' .. routines.getBRStringZone( { zone = LandingZoneName, ref = Client:ClientGroupUnit():getPoint(), true, true } ) .. ' km. ' end Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageRoute", "Co-Pilot: Route", 20 ) From fd0d012ff5b027fb038a5426fd59caa0ee1945cc Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 15:12:23 +0100 Subject: [PATCH 08/51] Bug fix 1.5 --- Moose/Cargo.lua | 10 +++++----- Moose/Client.lua | 16 ++-------------- Moose/Mission.lua | 10 +++++----- Moose/Stage.lua | 24 ++++++++++++------------ 4 files changed, 24 insertions(+), 36 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index d7ed635f3..7ea80ac71 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -347,7 +347,7 @@ trace.f(self.ClassName ) local Valid = true - local ClientUnit = Client:ClientUnit() + local ClientUnit = Client:GetClientGroupUnit() return Valid end @@ -497,7 +497,7 @@ trace.f(self.ClassName ) local Valid = true - local ClientUnit = Client:ClientUnit() + local ClientUnit = Client:GetClientGroupUnit() local CarrierPos = ClientUnit:getPoint() local CarrierPosMove = ClientUnit:getPoint() @@ -632,8 +632,8 @@ trace.f( self.ClassName ) if self.Client and self.Client:ClientGroup() then trace.i( self.ClassName, 'There is a Client ' .. self.Client.ClientName ) if self.Client:FindCargo( self.CargoName ) then - if self.Client:ClientUnit():getPlayerName() then -- this needs to be checked thoroughly - trace.i( self.ClassName, 'ok, Client is of player ' .. self.Client:ClientUnit():getPlayerName() .. ' and contains the Cargo, do nothing' ) + if self.Client:GetClientGroupUnit():getPlayerName() then -- this needs to be checked thoroughly + trace.i( self.ClassName, 'ok, Client is of player ' .. self.Client:GetClientGroupUnit():getPlayerName() .. ' and contains the Cargo, do nothing' ) SpawnCargo = false end end @@ -686,7 +686,7 @@ trace.f(self.ClassName ) local Valid = true - local ClientUnit = Client:ClientUnit() + local ClientUnit = Client:GetClientGroupUnit() local CarrierPos = ClientUnit:getPoint() local CarrierPosMove = ClientUnit:getPoint() diff --git a/Moose/Client.lua b/Moose/Client.lua index c9a7dcfb4..888dea13f 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -139,6 +139,8 @@ trace.f(self.ClassName) return nil end +--- Returns the Unit of the @{CLIENT}. +-- @treturn Unit function CLIENT:GetClientGroupUnit() trace.f(self.ClassName) @@ -156,20 +158,6 @@ trace.f(self.ClassName) 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() diff --git a/Moose/Mission.lua b/Moose/Mission.lua index 1d65c5e0c..eae5f2fa2 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -175,12 +175,12 @@ trace.f(self.ClassName) local AlivePlayers = '' for ClientID, Client in pairs( self._Clients ) do if Client:ClientGroup() then - if Client:ClientGroupUnit() then - if Client:ClientGroupUnit():getLife() > 0.0 then + if Client:GetClientGroupUnit() then + if Client:GetClientGroupUnit():getLife() > 0.0 then if AlivePlayers == '' then - AlivePlayers = ' Players: ' .. Client:ClientGroupUnit():getPlayerName() + AlivePlayers = ' Players: ' .. Client:GetClientGroupUnit():getPlayerName() else - AlivePlayers = AlivePlayers .. ' / ' .. Client:ClientGroupUnit():getPlayerName() + AlivePlayers = AlivePlayers .. ' / ' .. Client:GetClientGroupUnit():getPlayerName() end end end @@ -505,7 +505,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") if Mission.GoalFunction ~= nil then Mission.GoalFunction( Mission, Client ) end - _Database:_AddMissionTaskScore( Client:ClientGroupUnit(), Mission.Name, 25 ) + _Database:_AddMissionTaskScore( Client:GetClientGroupUnit(), Mission.Name, 25 ) -- if not Mission:IsCompleted() then -- end diff --git a/Moose/Stage.lua b/Moose/Stage.lua index c607a6642..12c77046a 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -233,7 +233,7 @@ trace.f(self.ClassName) local RouteMessage = "Fly to " for LandingZoneID, LandingZoneName in pairs( Task.LandingZones.LandingZoneNames ) do - RouteMessage = RouteMessage .. LandingZoneName .. ' at ' .. routines.getBRStringZone( { zone = LandingZoneName, ref = Client:ClientGroupUnit():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", 20 ) @@ -250,7 +250,7 @@ trace.f(self.ClassName) -- 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 ) + Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones.LandingZoneNames ) if Task.CurrentLandingZoneName then @@ -339,7 +339,7 @@ end function STAGELANDING:Validate( Mission, Client, Task ) trace.f(self.ClassName) - Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:ClientUnit(), Task.LandingZones.LandingZoneNames ) + Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones.LandingZoneNames ) if Task.CurrentLandingZoneName then -- Client is in de landing zone. @@ -365,7 +365,7 @@ trace.f(self.ClassName) return -1 end - if Task.IsLandingRequired and Client:ClientUnit():inAir() then + if Task.IsLandingRequired and Client:GetClientGroupUnit():inAir() then return 0 end @@ -406,14 +406,14 @@ end function STAGELANDED:Validate( Mission, Client, Task ) trace.f(self.ClassName) - if not routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + if not routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then trace.i( self.ClassName, "Client is not anymore in the landing zone, go back to stage Route, and remove cargo menus." ) Task.Signalled = false Task:RemoveCargoMenus( Client ) return -2 end - if Task.IsLandingRequired and Client:ClientUnit():inAir() then + if Task.IsLandingRequired and Client:GetClientGroupUnit():inAir() then trace.i( self.ClassName, "Client went back in the air. Go back to stage Landing." ) Task.Signalled = false return -1 @@ -474,7 +474,7 @@ function STAGEUNLOAD:Validate( Mission, Client, Task ) trace.f(self.ClassName) env.info( 'STAGEUNLOAD:Validate()' ) - if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + if routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then else Task.ExecuteStage = _TransportExecuteStage.FAILED Task:RemoveCargoMenus( Client ) @@ -483,7 +483,7 @@ trace.f(self.ClassName) return 1 end - if not Client:ClientUnit():inAir() then + if not Client:GetClientGroupUnit():inAir() then else Task.ExecuteStage = _TransportExecuteStage.FAILED Task:RemoveCargoMenus( Client ) @@ -592,7 +592,7 @@ trace.f(self.ClassName) trace.i( self.ClassName, "Task.CurrentLandingZoneName = " .. Task.CurrentLandingZoneName ) if not Task.IsSlingLoad then - if not routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + if not routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then Task:RemoveCargoMenus( Client ) Task.ExecuteStage = _TransportExecuteStage.FAILED Task.CargoName = nil @@ -601,7 +601,7 @@ trace.f(self.ClassName) return -1 end - if not Client:ClientUnit():inAir() then + if not Client:GetClientGroupUnit():inAir() then else -- The carrier is back in the air, undo the loading process. Task:RemoveCargoMenus( Client ) @@ -715,7 +715,7 @@ trace.f(self.ClassName) if Task.CargoName then if not StaticObject.getByName( Task.CargoName ):inAir() then - if routines.IsUnitInZones( Client:ClientUnit(), Task.CurrentLandingZoneName ) then + if routines.IsUnitInZones( Client:GetClientGroupUnit(), 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 @@ -777,7 +777,7 @@ trace.f(self.ClassName) function STAGEARRIVE:Validate( Mission, Client, Task ) trace.f(self.ClassName) - Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:ClientUnit(), Task.LandingZones ) + Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones ) if ( Task.CurrentLandingZoneID ) then else return -1 From 7861ae753d5c56b6fa76eddf05a2bf25188b1fbf Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 15:24:07 +0100 Subject: [PATCH 09/51] Small bug fix with cargo --- Moose/Cargo.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 7ea80ac71..681830b77 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -453,7 +453,7 @@ trace.f( self.ClassName ) local SpawnCargo = true if self.CargoGroupName then - local Client = self.IsLoadedInClient() + local Client = self:IsLoadedInClient() if Client and Client:ClientGroup() then if Client:FindCargo( self.CargoName ) then SpawnCargo = false From e3b1d79693c83039037fc73c514d0ddab7438e85 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 15:40:22 +0100 Subject: [PATCH 10/51] Bug 1.5 , fixed cargo menu problems ... --- Moose/DeployTask.lua | 8 ++++---- Moose/PickupTask.lua | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index 18e01d141..94df70d25 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -103,7 +103,7 @@ trace.f( self.ClassName ) if not Client._Menus[Cargo.CargoType].DeployMenu then Client._Menus[Cargo.CargoType].DeployMenu = missionCommands.addSubMenuForGroup( - Client:ClientGroup():getID(), + Client:GetClientGroupID(), self.TEXT[1], nil ) @@ -119,7 +119,7 @@ trace.f( self.ClassName ) end Client._Menus[Cargo.CargoType].DeploySubMenus[ #Client._Menus[Cargo.CargoType].DeploySubMenus + 1 ].MenuPath = missionCommands.addCommandForGroup( - Client:ClientGroup():getID(), + Client:GetClientGroupID(), Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )", Client._Menus[Cargo.CargoType].DeployMenu, self.MenuAction, @@ -137,13 +137,13 @@ trace.f(self.ClassName ) for MenuID, MenuData in pairs( Client._Menus ) do if MenuData.DeploySubMenus ~= nil then for SubMenuID, SubMenuData in pairs( MenuData.DeploySubMenus ) do - missionCommands.removeItemForGroup( Client:ClientGroup():getID(), SubMenuData ) + missionCommands.removeItemForGroup( Client:GetClientGroupID(), SubMenuData ) trace.i( self.ClassName, "Removed DeploySubMenu " ) SubMenuData = nil end end if MenuData.DeployMenu then - missionCommands.removeItemForGroup( Client:ClientGroup():getID(), MenuData.DeployMenu ) + missionCommands.removeItemForGroup( Client:GetClientGroupID(), MenuData.DeployMenu ) trace.i( self.ClassName, "Removed DeployMenu " ) MenuData.DeployMenu = nil end diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index ac7ce188a..a1cf96d47 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -92,7 +92,7 @@ trace.f( self.ClassName ) if not Client._Menus[Cargo.CargoType].PickupMenu then Client._Menus[Cargo.CargoType].PickupMenu = missionCommands.addSubMenuForGroup( - Client:ClientGroup():getID(), + Client:GetClientGroupID(), self.TEXT[1] .. " " .. Cargo.CargoType, nil ) @@ -104,7 +104,7 @@ trace.f( self.ClassName ) end Client._Menus[Cargo.CargoType].PickupSubMenus[ #Client._Menus[Cargo.CargoType].PickupSubMenus + 1 ] = missionCommands.addCommandForGroup( - Client:ClientGroup():getID(), + Client:GetClientGroupID(), Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )", Client._Menus[Cargo.CargoType].PickupMenu, self.MenuAction, @@ -122,12 +122,12 @@ trace.f( self.ClassName ) for MenuID, MenuData in pairs( Client._Menus ) 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 " ) SubMenuData = nil end if MenuData.PickupMenu then - missionCommands.removeItemForGroup( Client:ClientGroup():getID(), MenuData.PickupMenu ) + missionCommands.removeItemForGroup( Client:GetClientGroupID(), MenuData.PickupMenu ) trace.i( self.ClassName, "Removed PickupMenu " ) MenuData.PickupMenu = nil end From 9ddaeb0bbbf8edf90f2973d800b860f8edfb4eb3 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 15:59:17 +0100 Subject: [PATCH 11/51] Bug fix for 1.5 Client bug --- Moose/Client.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Moose/Client.lua b/Moose/Client.lua index 888dea13f..e77dc1fe3 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -162,13 +162,16 @@ end -- @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 + + ClientGroupUnit = self:ClientGroupUnit() + + if ClientGroupUnit then + if ClientGroupUnit:isExist() then + return ClientGroupUnit:getPosition() + end end + + return nil end --- Transport defines that the Client is a Transport. From d197e87fb5728a385e6b9f5b6e4dba05827bc97c Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 16:07:47 +0100 Subject: [PATCH 12/51] stupid syntax error --- Moose/Client.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Client.lua b/Moose/Client.lua index e77dc1fe3..07784f238 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -163,7 +163,7 @@ end function CLIENT:ClientPosition() --trace.f(self.ClassName) - ClientGroupUnit = self:ClientGroupUnit() + ClientGroupUnit = self:GetClientGroupUnit() if ClientGroupUnit then if ClientGroupUnit:isExist() then From b8148a7950b3c74f5579a1512e8fe660bffcddef Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 19:00:40 +0100 Subject: [PATCH 13/51] Converted SPAWN:FromCarrier function SPAWN:FromCarrier now spawns from a Unit instead of a Group. It was confusing from the beginning anyway :-) --- Moose/Cargo.lua | 14 +++---- Moose/Spawn.lua | 103 +++++++++++++++++++++--------------------------- 2 files changed, 53 insertions(+), 64 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 681830b77..32656f4e3 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -249,12 +249,12 @@ trace.f( self.ClassName ) end -function CARGO_ZONE:GetCargoHostGroup() +function CARGO_ZONE:GetCargoHostUnit() trace.f( self.ClassName ) - local CargoHostGroup = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) - if CargoHostGroup and CargoHostGroup:isExist() then - return CargoHostGroup + local CargoHostUnit = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ):getUnit(1) + if CargoHostUnit and CargoHostUnit:isExist() then + return CargoHostUnit end return nil @@ -462,9 +462,9 @@ trace.f( self.ClassName ) end if SpawnCargo then - if self.CargoZone:GetCargoHostGroup() then + if self.CargoZone:GetCargoHostUnit() then --- ReSpawn the Cargo from the CargoHost - self.CargoGroupName = self.CargoSpawn:FromCarrier( self.CargoZone:GetCargoHostGroup(), self.CargoZone:GetCargoZoneName(), self.CargoName, false ).name + self.CargoGroupName = self.CargoSpawn:FromCarrier( self.CargoZone:GetCargoHostUnit(), 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 @@ -589,7 +589,7 @@ 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.CargoSpawn:FromCarrier( Client:GetClientGroupUnit(), TargetZoneName, self.CargoGroupName ) self:StatusUnLoaded() local Cargo = Client:RemoveCargo( self ) diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 48df6e921..14d5cb43b 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -298,76 +298,65 @@ 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 CarrierGroup is the Group of the AIR unit or GROUND unit dropping or unloading other units. +-- @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( CarrierGroup, TargetZonePrefix, NewGroupName, LateActivate ) -trace.f( self.ClassName, { CarrierGroup, TargetZonePrefix, NewGroupName, LateActivate } ) +function SPAWN:FromCarrier( CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate ) +trace.f( self.ClassName, { CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate } ) local SpawnTemplate - if CarrierGroup and CarrierGroup:isExist() and CarrierGroup:getUnit(1) then -- and CarrierGroup:getUnit(1):inAir() == false then + if CarrierUnit and CarrierUnit:isExist() then -- and CarrierUnit:getUnit(1):inAir() == false then - local GroupUnits = CarrierGroup:getUnits() - 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 + SpawnTemplate = self:_Prepare( NewGroupName ) - UnitDeploy = UnitData - - 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 ( 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 + if LateActivate ~= nil then + if LateActivate == true then + SpawnTemplate.lateActivation = true + SpawnTemplate.visible = true 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 ) - 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 + + 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 ) + trace.i( self.ClassName, "RouteCount = " .. RouteCount ) + + local UnitDeployPosition = CarrierUnit: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 - end trace.r( self.ClassName, "" ) From 84b79b0a75d7c97c0fc4804234a435e5855d6bec Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 19:56:11 +0100 Subject: [PATCH 14/51] Removed Group usage from _AddPlayerFromUnit Due to bug 1.5 in DCS world --- Moose/Database.lua | 79 +++++++++++++++++++++------------------------- Moose/Group.lua | 1 + 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index 4ec727564..a33026674 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -305,50 +305,43 @@ trace.f( self.ClassName, UnitData ) if UnitData:isExist() then local UnitName = UnitData:getName() - local GroupData = UnitData:getGroup() + local PlayerName = UnitData:getPlayerName() - if GroupData and GroupData:isExist() then - local GroupName = GroupData:getName() - local PlayerName = UnitData:getPlayerName() + trace.i(self.ClassName, "Player : " .. PlayerName .. " Unit : " .. UnitName ) - 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] = {} - self.Players[PlayerName].Hit = {} - self.Players[PlayerName].Kill = {} - self.Players[PlayerName].Mission = {} - - -- for CategoryID, CategoryName in pairs( DATABASECategory ) do - -- self.Players[PlayerName].Hit[CategoryID] = {} - -- self.Players[PlayerName].Kill[CategoryID] = {} - -- end - self.Players[PlayerName].HitPlayers = {} - self.Players[PlayerName].HitUnits = {} - 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() + 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] = {} + self.Players[PlayerName].Hit = {} + self.Players[PlayerName].Kill = {} + self.Players[PlayerName].Mission = {} + + -- for CategoryID, CategoryName in pairs( DATABASECategory ) do + -- self.Players[PlayerName].Hit[CategoryID] = {} + -- self.Players[PlayerName].Kill[CategoryID] = {} + -- end + self.Players[PlayerName].HitPlayers = {} + self.Players[PlayerName].HitUnits = {} + self.Players[PlayerName].Penalty = 0 + self.Players[PlayerName].PenaltyCoalition = 0 end + + if not self.Players[PlayerName].UnitCoalition then + self.Players[PlayerName].UnitCoalition = Unit: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].UnitCoalition = Unit:getCoalition() + self.Players[PlayerName].UnitCategory = Unit:getCategory() + self.Players[PlayerName].UnitType = UnitData:getTypeName() end end @@ -427,8 +420,8 @@ trace.f( self.ClassName, { event } ) InitGroupName = Unit.getGroup(event.initiator):getName() InitPlayerName = event.initiator:getPlayerName() - InitCoalition = Unit.getGroup(event.initiator):getCoalition() - InitCategory = Unit.getGroup(event.initiator):getCategory() + InitCoalition = Unit:getCoalition() + InitCategory = Unit:getCategory() InitType = event.initiator:getTypeName() InitUnitCoalition = DATABASECoalition[InitCoalition] diff --git a/Moose/Group.lua b/Moose/Group.lua index bc4cef98e..9fa5977af 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -78,6 +78,7 @@ trace.f( self.ClassName, { self.GroupName, Point, Radius } ) return self end + function GROUP:_GetController() return self._Group:getController() From 78efd51c2c1a755edf04d00669fbc3de2254e63b Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 20:12:11 +0100 Subject: [PATCH 15/51] Fixed error while modifying _AddPlayerFromUnit Had syntax error --- Moose/Database.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index a33026674..da4c15293 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -326,16 +326,16 @@ trace.f( self.ClassName, UnitData ) end if not self.Players[PlayerName].UnitCoalition then - self.Players[PlayerName].UnitCoalition = Unit:getCoalition() + self.Players[PlayerName].UnitCoalition = UnitData:getCoalition() else - if self.Players[PlayerName].UnitCoalition ~= Unit.getGroup(UnitData):getCoalition() then + if self.Players[PlayerName].UnitCoalition ~= 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() ) + UnitName, DATABASECategory[UnitData:getCoalition()], DATABASECategory[UnitData:getCategory()], UnitData:getTypeName() ) end end self.Players[PlayerName].UnitName = UnitName From 0c657f00d8a014d7cf40e5910619d5a676c8576d Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 20:21:07 +0100 Subject: [PATCH 16/51] bugfix --- Moose/Database.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index da4c15293..a84d926b8 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -339,8 +339,8 @@ trace.f( self.ClassName, UnitData ) end end self.Players[PlayerName].UnitName = UnitName - self.Players[PlayerName].UnitCoalition = Unit:getCoalition() - self.Players[PlayerName].UnitCategory = Unit:getCategory() + self.Players[PlayerName].UnitCoalition = UnitData:getCoalition() + self.Players[PlayerName].UnitCategory = UnitData:getCategory() self.Players[PlayerName].UnitType = UnitData:getTypeName() end From e550af88013f0c4a70889ab598b39a682344e090 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 19 Feb 2016 20:28:45 +0100 Subject: [PATCH 17/51] bugfix --- Moose/Database.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index a84d926b8..69a427759 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -644,11 +644,11 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play if PlayerUnit then if not PlayerUnitCategory then - PlayerUnitCategory = DATABASECategory[Unit.getGroup(PlayerUnit):getCategory()] + PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] end if not PlayerUnitCoalition then - PlayerUnitCoalition = DATABASECoalition[Unit.getGroup(PlayerUnit):getCoalition()] + PlayerUnitCoalition = DATABASECoalition[PlayerUnit:getCoalition()] end if not PlayerUnitType then From 9591f02a10e9ae9e173da1737e3a847f56b4ff2c Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sat, 20 Feb 2016 07:59:47 +0100 Subject: [PATCH 18/51] Bug fixes --- Moose/Cargo.lua | 2 +- Moose/Database.lua | 24 +++++++++++++++----- Moose/DeployTask.lua | 18 ++++++++++----- Moose/Mission.lua | 1 + Moose/Spawn.lua | 52 ++++++++++++++++++++++++++++++++++++++++++++ Moose/Task.lua | 6 ++--- Moose/Trace.lua | 5 +++-- 7 files changed, 91 insertions(+), 17 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 32656f4e3..57702749a 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -464,7 +464,7 @@ trace.f( self.ClassName ) if SpawnCargo then if self.CargoZone:GetCargoHostUnit() then --- ReSpawn the Cargo from the CargoHost - self.CargoGroupName = self.CargoSpawn:FromCarrier( self.CargoZone:GetCargoHostUnit(), self.CargoZone:GetCargoZoneName(), self.CargoName, false ).name + self.CargoGroupName = self.CargoSpawn:FromHost( self.CargoZone:GetCargoHostUnit(), 60, 30, 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 diff --git a/Moose/Database.lua b/Moose/Database.lua index 69a427759..e650ad31c 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -335,7 +335,7 @@ trace.f( self.ClassName, UnitData ) "(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[UnitData:getCoalition()], DATABASECategory[UnitData:getCategory()], UnitData:getTypeName() ) + UnitName, DATABASECoalition[UnitData:getCoalition()], DATABASECategory[UnitData:getCategory()], UnitData:getTypeName() ) end end self.Players[PlayerName].UnitName = UnitName @@ -357,6 +357,9 @@ trace.f( self.ClassName, { PlayerUnit, MissionName, Score } ) self.Players[PlayerName].Mission[MissionName].ScoreTask = 0 self.Players[PlayerName].Mission[MissionName].ScoreMission = 0 end + + trace.i( self.ClassName, PlayerName ) + trace.i( self.ClassName, self.Players[PlayerName].Mission[MissionName] ) self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score @@ -496,12 +499,16 @@ end function DATABASE:ReportScoreAll() +env.info( "Hello World " ) + local ScoreMessage = "" local PlayerMessage = "" + + trace.i( self.ClassName, "Score Report" ) for PlayerName, PlayerData in pairs( self.Players ) do if PlayerData then -- This should normally not happen, but i'll test it anyway. - trace.i( self.ClassName, "Score" ) + trace.i( self.ClassName, "Score Player: " .. PlayerName ) -- Some variables local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] @@ -517,18 +524,22 @@ function DATABASE:ReportScoreAll() local ScoreMessageHits = "" for CategoryID, CategoryName in pairs( DATABASECategory ) do + trace.i( self.ClassName, CategoryName ) if PlayerData.Hit[CategoryID] then local Score = 0 local ScoreHit = 0 local Penalty = 0 local PenaltyHit = 0 + trace.i( self.ClassName, "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 - ScoreMessageHits = ScoreMessageHits .. string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) + local ScoreMessageHit = string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) + trace.i( self.ClassName, ScoreMessageHit ) + ScoreMessageHits = ScoreMessageHits .. ScoreMessageHit PlayerScore = PlayerScore + Score PlayerPenalty = PlayerPenalty + Penalty else @@ -541,6 +552,7 @@ function DATABASE:ReportScoreAll() local ScoreMessageKills = "" for CategoryID, CategoryName in pairs( DATABASECategory ) do + trace.i( self.ClassName, "Kill scores exist for player " .. PlayerName ) if PlayerData.Kill[CategoryID] then local Score = 0 local ScoreKill = 0 @@ -553,8 +565,10 @@ function DATABASE:ReportScoreAll() Penalty = Penalty + UnitData.Penalty PenaltyKill = PenaltyKill + UnitData.PenaltyKill end - - ScoreMessageKills = ScoreMessageKills .. string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) + + local ScoreMessageKill = string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) + trace.i( self.ClassName, ScoreMessageKill ) + ScoreMessageKills = ScoreMessageKills .. ScoreMessageKill PlayerScore = PlayerScore + Score PlayerPenalty = PlayerPenalty + Penalty diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index 94df70d25..29d9f5214 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -90,20 +90,23 @@ end function DEPLOYTASK:AddCargoMenus( Client, Cargos, TransportRadius ) trace.f( self.ClassName ) + local ClientGroupID = Client:GetClientGroupID() + + trace.i( self.ClassName, ClientGroupID ) + for CargoID, Cargo in pairs( Cargos ) do - trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType } ) + trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo.CargoWeight } ) 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:GetClientGroupID(), + ClientGroupID, self.TEXT[1], nil ) @@ -119,7 +122,7 @@ trace.f( self.ClassName ) end Client._Menus[Cargo.CargoType].DeploySubMenus[ #Client._Menus[Cargo.CargoType].DeploySubMenus + 1 ].MenuPath = missionCommands.addCommandForGroup( - Client:GetClientGroupID(), + ClientGroupID, Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )", Client._Menus[Cargo.CargoType].DeployMenu, self.MenuAction, @@ -134,16 +137,19 @@ end function DEPLOYTASK:RemoveCargoMenus( Client ) trace.f(self.ClassName ) + local ClientGroupID = Client:GetClientGroupID() + trace.i( self.ClassName, ClientGroupID ) + for MenuID, MenuData in pairs( Client._Menus ) do if MenuData.DeploySubMenus ~= nil then for SubMenuID, SubMenuData in pairs( MenuData.DeploySubMenus ) do - missionCommands.removeItemForGroup( Client:GetClientGroupID(), SubMenuData ) + missionCommands.removeItemForGroup( ClientGroupID, SubMenuData ) trace.i( self.ClassName, "Removed DeploySubMenu " ) SubMenuData = nil end end if MenuData.DeployMenu then - missionCommands.removeItemForGroup( Client:GetClientGroupID(), MenuData.DeployMenu ) + missionCommands.removeItemForGroup( ClientGroupID, MenuData.DeployMenu ) trace.i( self.ClassName, "Removed DeployMenu " ) MenuData.DeployMenu = nil end diff --git a/Moose/Mission.lua b/Moose/Mission.lua index eae5f2fa2..62a9f277e 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -490,6 +490,7 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") end 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" ) ) TaskComplete = true -- when a task is not yet completed, a mission cannot be completed diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 14d5cb43b..ad3d95140 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -297,6 +297,58 @@ trace.f( self.ClassName ) 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 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 NewGroupName (forgot this). +-- @tparam bool LateActivate (optional) does the SPAWNing with Lateactivation on. +function SPAWN:FromHost( HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate ) +trace.f( self.ClassName, { HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate } ) + + local SpawnTemplate + + if HostUnit and HostUnit:isExist() then -- and HostUnit: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 RouteCount = table.getn( SpawnTemplate.route.points ) + trace.i( self.ClassName, "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 + 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 + end + + 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. diff --git a/Moose/Task.lua b/Moose/Task.lua index 1dce0aab6..d34ffeed1 100644 --- a/Moose/Task.lua +++ b/Moose/Task.lua @@ -142,7 +142,7 @@ end --- Returns if a TASK is done. -- @treturn bool function TASK:IsDone() -trace.f(self.ClassName) + trace.i( self.ClassName, self.TaskDone ) return self.TaskDone end @@ -155,7 +155,7 @@ end --- Returns if a TASk has failed. -- @return bool function TASK:IsFailed() -trace.f(self.ClassName) + trace.i( self.ClassName, self.TaskFailed ) return self.TaskFailed end @@ -278,7 +278,6 @@ end --- Returns if all the Goals of the TASK were achieved. -- @treturn bool function TASK:IsGoalReached( ) -trace.f(self.ClassName) local GoalReached = true @@ -297,6 +296,7 @@ trace.f(self.ClassName) end end + trace.i( self.ClassName, GoalReached ) return GoalReached end diff --git a/Moose/Trace.lua b/Moose/Trace.lua index a6c8b00f6..876afb947 100644 --- a/Moose/Trace.lua +++ b/Moose/Trace.lua @@ -250,8 +250,9 @@ end trace.i = function(object, variable) 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 if trace.names.all or trace.tracefunction( trace.nametrace ) or trace.classes[ object ] then local objecttrace = "" From 14a48901dcb093be3dea69823a2c67cadc6f985e Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sat, 20 Feb 2016 08:06:27 +0100 Subject: [PATCH 19/51] Bugfix deploymenu --- Moose/DeployTask.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index 29d9f5214..49cbe54c2 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -121,7 +121,7 @@ trace.f( self.ClassName ) trace.i( self.ClassName, 'deploymenu is nil' ) end - Client._Menus[Cargo.CargoType].DeploySubMenus[ #Client._Menus[Cargo.CargoType].DeploySubMenus + 1 ].MenuPath = missionCommands.addCommandForGroup( + Client._Menus[Cargo.CargoType].DeploySubMenus[ #Client._Menus[Cargo.CargoType].DeploySubMenus + 1 ] = missionCommands.addCommandForGroup( ClientGroupID, Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )", Client._Menus[Cargo.CargoType].DeployMenu, From 17118e57840d747b032deb78af0cac41aab716e3 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sat, 20 Feb 2016 09:36:16 +0100 Subject: [PATCH 20/51] Bugfix on hit event --- Moose/Database.lua | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index e650ad31c..0f1fbe106 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -393,6 +393,7 @@ end function DATABASE:OnHit( event ) trace.f( self.ClassName, { event } ) + local InitUnit = nil local InitUnitName = nil local InitGroupName = nil local InitPlayerName = nil @@ -404,6 +405,7 @@ trace.f( self.ClassName, { event } ) local InitUnitCategory = nil local InitUnitType = nil + local TargetUnit = nil local TargetUnitName = nil local TargetGroupName = nil local TargetPlayerName = nil @@ -418,14 +420,16 @@ trace.f( self.ClassName, { event } ) if event.initiator and event.initiator:getName() then if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then + + InitUnit = event.initiator - InitUnitName = event.initiator:getName() - InitGroupName = Unit.getGroup(event.initiator):getName() - InitPlayerName = event.initiator:getPlayerName() + InitUnitName = InitUnit:getName() + InitGroupName = Unit.getGroup(InitUnit):getName() + InitPlayerName = InitUnit:getPlayerName() - InitCoalition = Unit:getCoalition() - InitCategory = Unit:getCategory() - InitType = event.initiator:getTypeName() + InitCoalition = InitUnit:getCoalition() + InitCategory = InitUnit:getCategory() + InitType = InitUnit:getTypeName() InitUnitCoalition = DATABASECoalition[InitCoalition] InitUnitCategory = DATABASECategory[InitCategory] @@ -436,14 +440,16 @@ trace.f( self.ClassName, { event } ) if event.target and Object.getCategory(event.target) == Object.Category.UNIT then + + TargetUnit = event.target - TargetUnitName = event.target:getName() - TargetGroupName = Unit.getGroup(event.target):getName() - TargetPlayerName = event.target:getPlayerName() + TargetUnitName = TargetUnit:getName() + TargetGroupName = Unit.getGroup(TargetUnit):getName() + TargetPlayerName = TargetUnit:getPlayerName() - TargetCoalition = Unit.getGroup(event.target):getCoalition() - TargetCategory = Unit.getGroup(event.target):getCategory() - TargetType = event.target:getTypeName() + TargetCoalition = TargetUnit:getCoalition() + TargetCategory = TargetUnit:getCategory() + TargetType = TargetUnit:getTypeName() TargetUnitCoalition = DATABASECoalition[TargetCoalition] TargetUnitCategory = DATABASECategory[TargetCategory] @@ -453,10 +459,10 @@ trace.f( self.ClassName, { event } ) end 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 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 end From 904e5d2d208a350372a0a7e61248625a6e2631d1 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sat, 20 Feb 2016 10:05:22 +0100 Subject: [PATCH 21/51] remove trace --- Moose/Cargo.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 57702749a..558df5b8d 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -8,8 +8,6 @@ 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 = {} From 0fb88e2bab194ba42e15f0cf622211baa42e5d42 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sat, 20 Feb 2016 14:10:10 +0100 Subject: [PATCH 22/51] Trying with getposition, getpoint returns nil --- Moose/Spawn.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index ad3d95140..5b9157f99 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -383,7 +383,7 @@ trace.f( self.ClassName, { CarrierUnit, TargetZonePrefix, NewGroupName, LateActi local RouteCount = table.getn( SpawnTemplate.route.points ) trace.i( self.ClassName, "RouteCount = " .. RouteCount ) - local UnitDeployPosition = CarrierUnit:getPoint() + 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 From ecf80e52098596e6c9766e79e97fa84a65a64f6b Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sun, 21 Feb 2016 19:34:48 +0100 Subject: [PATCH 23/51] Changes of loading and cleanup. Added dynamic and static loading strategies for MOOSE of a mission file. --- .../Moose_Load_Dynamic.lua | 25 ++- Loaders/Moose_Load_Embedded.lua | 23 +++ Loaders/Moose_Test.lua | 159 ++++++++++++++++++ Moose/Base.lua | 21 ++- Moose/ClientBug.lua | 50 ------ Moose/Mission.lua | 58 +++---- Moose/SlingLoadHookTask.lua | 39 ----- Moose/SlingLoadUnHookTask.lua | 38 ----- Moose/Spawn.lua | 2 + 9 files changed, 243 insertions(+), 172 deletions(-) rename Moose/Moose.lua => Loaders/Moose_Load_Dynamic.lua (90%) create mode 100644 Loaders/Moose_Load_Embedded.lua create mode 100644 Loaders/Moose_Test.lua delete mode 100644 Moose/ClientBug.lua delete mode 100644 Moose/SlingLoadHookTask.lua delete mode 100644 Moose/SlingLoadUnHookTask.lua diff --git a/Moose/Moose.lua b/Loaders/Moose_Load_Dynamic.lua similarity index 90% rename from Moose/Moose.lua rename to Loaders/Moose_Load_Dynamic.lua index 4c27ec554..e12d51570 100644 --- a/Moose/Moose.lua +++ b/Loaders/Moose_Load_Dynamic.lua @@ -1,22 +1,13 @@ local base = _G - 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.MissionPath = script_path() .. "Mission/" -Include.ProgramPath = "Scripts/Moose/Moose/" - -env.info( "Include.MissionPath = " .. Include.MissionPath) -env.info( "Include.ProgramPath = " .. Include.ProgramPath) -Include.Files = {} +Include.Path = function() + local str = debug.getinfo(2, "S").source + return str:match("(.*/)"):sub(1,-2):gsub("\\","/") +end Include.File = function( IncludeFile ) if not Include.Files[ IncludeFile ] then @@ -39,6 +30,14 @@ Include.File = function( IncludeFile ) 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" ) env.info("Loaded MOOSE Include Engine") \ No newline at end of file diff --git a/Loaders/Moose_Load_Embedded.lua b/Loaders/Moose_Load_Embedded.lua new file mode 100644 index 000000000..4314a929d --- /dev/null +++ b/Loaders/Moose_Load_Embedded.lua @@ -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") \ No newline at end of file diff --git a/Loaders/Moose_Test.lua b/Loaders/Moose_Test.lua new file mode 100644 index 000000000..fc6979ea9 --- /dev/null +++ b/Loaders/Moose_Test.lua @@ -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") \ No newline at end of file diff --git a/Moose/Base.lua b/Moose/Base.lua index 59edff66e..dc4029ff0 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -7,9 +7,9 @@ Include.File( "Routines" ) BASE = { ClassName = "BASE", + TraceOn = false, ClassID = 0, Events = {} - } --- The base constructor. This is the top top class of all classed defined within the MOOSE. @@ -188,3 +188,22 @@ function BASE:onEvent(event) end +-- Trace section + + +function BASE:T( Arguments ) + + if BASE.TraceOn 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.%s\(%s\)" , Line, "T", self.ClassName, Function .. routines.utils.oneLineSerialize( Arguments ) ) ) + end +end diff --git a/Moose/ClientBug.lua b/Moose/ClientBug.lua deleted file mode 100644 index 12fc34df5..000000000 --- a/Moose/ClientBug.lua +++ /dev/null @@ -1,50 +0,0 @@ ---- Bug Client Activation Multiplayer Classes --- @classmod CLIENTBUG - -Include.File( "Routines" ) -Include.File( "Base" ) - - -CLIENTBUG = { - ClassName = "CLIENTBUG", -} - -function CLIENTBUG:New( ) -trace.f( self.ClassName ) - - -- Arrange meta tables - local self = BASE:Inherit( self, BASE:New() ) - - self.ActiveClients = {} - - self.ClientBugWorkaround = routines.scheduleFunction( self._ClientBugWorkaround, { self }, timer.getTime() + 1, 0.1 ) - - return self -end - -function CLIENTBUG:_ClientBugWorkaround() - - -- Get the units of the players - local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } - - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - trace.i( self.ClassName, CoalitionData ) - - for UnitId, UnitData in pairs( CoalitionData ) do - trace.i( self.ClassName, UnitData ) - - if UnitData and UnitData:isExist() then - - local UnitSkill = _Database.Units[UnitData:getName()].Template.skill - trace.i( self.ClassName, "UnitSkill = " .. UnitSkill ) - - if UnitSkill == "Client" then - - -- Generate birth event - self:CreateEventBirth( 0, UnitData, UnitData:getName(), 0, 0 ) - end - end - end - end - -end diff --git a/Moose/Mission.lua b/Moose/Mission.lua index 62a9f277e..fdd78404f 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -31,12 +31,11 @@ MISSION = { function MISSION:Meta() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, BASE:New() ) -trace.r( self.ClassName, "", { Child } ) - return Child + local self = BASE:Inherit( self, BASE:New() ) + self:T() + + return self end --- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc. @@ -56,8 +55,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( '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 ) -trace.f(self.ClassName, { MissionName, MissionPriority, MissionBriefing, MissionCoalition } ) + self = MISSION:Meta() + self:T({ MissionName, MissionPriority, MissionBriefing, MissionCoalition }) local Valid = true @@ -73,20 +73,19 @@ trace.f(self.ClassName, { MissionName, MissionPriority, MissionBriefing, Mission self.MissionCoalition = MissionCoalition end -trace.r( self.ClassName, "" ) return self end --- Returns if a Mission has completed. -- @treturn bool function MISSION:IsCompleted() -trace.f(self.ClassName) + self:T() return self.MissionStatus == "ACCOMPLISHED" end --- Set a Mission to completed. function MISSION:Completed() -trace.f(self.ClassName) + self:T() self.MissionStatus = "ACCOMPLISHED" self:StatusToClients() end @@ -94,13 +93,13 @@ end --- Returns if a Mission is ongoing. -- treturn bool function MISSION:IsOngoing() -trace.f(self.ClassName) + self:T() return self.MissionStatus == "ONGOING" end --- Set a Mission to ongoing. function MISSION:Ongoing() -trace.f(self.ClassName) + self:T() self.MissionStatus = "ONGOING" --self:StatusToClients() end @@ -108,13 +107,13 @@ end --- Returns if a Mission is pending. -- treturn bool function MISSION:IsPending() -trace.f(self.ClassName) + self:T() return self.MissionStatus == "PENDING" end --- Set a Mission to pending. function MISSION:Pending() -trace.f(self.ClassName) + self:T() self.MissionStatus = "PENDING" self:StatusToClients() end @@ -122,31 +121,31 @@ end --- Returns if a Mission has failed. -- treturn bool function MISSION:IsFailed() -trace.f(self.ClassName) + self:T() return self.MissionStatus == "FAILED" end --- Set a Mission to failed. function MISSION:Failed() -trace.f(self.ClassName) + self:T() self.MissionStatus = "FAILED" self:StatusToClients() end --- Send the status of the MISSION to all Clients. function MISSION:StatusToClients() -trace.f(self.ClassName) + self:T() if self.MissionReportFlash then 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") end end -trace.e() end --- Handles the reporting. After certain time intervals, a MISSION report MESSAGE will be shown to All Players. function MISSION:ReportTrigger() -trace.f(self.ClassName) + self:T() + if self.MissionReportShow == true then self.MissionReportShow = false trace.r( "MISSION", "1", { true } ) @@ -171,7 +170,8 @@ end --- Report the status of all MISSIONs to all active Clients. function MISSION:ReportToAll() -trace.f(self.ClassName) + self:T() + local AlivePlayers = '' for ClientID, Client in pairs( self._Clients ) do if Client:ClientGroup() then @@ -192,7 +192,6 @@ trace.f(self.ClassName) TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n" 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() -trace.e() end @@ -233,16 +232,15 @@ 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' ) -- Mission:AddGoalFunction( DeployPatriotTroopsGoal ) function MISSION:AddGoalFunction( GoalFunction ) -trace.f(self.ClassName) + self:T() self.GoalFunction = GoalFunction -trace.e() end --- Show the briefing of the MISSION to the CLIENT. -- @tparam CLIENT Client to show briefing to. -- @treturn CLIENT function MISSION:ShowBriefing( Client ) -trace.f(self.ClassName, { Client.ClientName } ) + self:T( { Client.ClientName } ) if not Client.ClientBriefingShown then Client.ClientBriefingShown = true @@ -266,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*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 ) -trace.f(self.ClassName, { Client } ) + self:T( { Client } ) local Valid = true @@ -285,8 +283,7 @@ end -- -- Seach for Client "Bomber" within the Mission. -- local BomberClient = Mission:FindClient( "Bomber" ) function MISSION:FindClient( ClientName ) -trace.f(self.ClassName) -trace.r( "", "", { self._Clients[ClientName] } ) + self:T( { self._Clients[ClientName] } ) return self._Clients[ClientName] end @@ -317,13 +314,12 @@ end -- Mission:AddTask( DeployTask, 2 ) function MISSION:AddTask( Task, TaskNumber ) -trace.f(self.ClassName) + self:T() self._Tasks[TaskNumber] = Task self._Tasks[TaskNumber]:EnableEvents() self._Tasks[TaskNumber].ID = TaskNumber -trace.r( self.ClassName, "" ) return Task end @@ -335,7 +331,7 @@ trace.r( self.ClassName, "" ) -- Task2 = Mission:GetTask( 2 ) function MISSION:GetTask( TaskNumber ) -trace.f(self.ClassName) + self:T() local Valid = true @@ -359,7 +355,7 @@ end -- Tasks = Mission:GetTasks() -- env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" ) function MISSION:GetTasks() -trace.f(self.ClassName) + self:T() return self._Tasks end @@ -367,7 +363,7 @@ 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( Cargos ) -trace.f(self.ClassName, { Cargos } ) + self:T( { Cargos } ) if type( Cargos ) == "table" then for CargoID, Cargo in pairs( Cargos ) do diff --git a/Moose/SlingLoadHookTask.lua b/Moose/SlingLoadHookTask.lua deleted file mode 100644 index 3248d4f95..000000000 --- a/Moose/SlingLoadHookTask.lua +++ /dev/null @@ -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 diff --git a/Moose/SlingLoadUnHookTask.lua b/Moose/SlingLoadUnHookTask.lua deleted file mode 100644 index 6ac3bd131..000000000 --- a/Moose/SlingLoadUnHookTask.lua +++ /dev/null @@ -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 diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 5b9157f99..0fdd5d521 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -2,6 +2,8 @@ -- @classmod SPAWN -- @author Flightcontrol +MOOSE_Version = "0.1.1.1" + Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Database" ) From a3acab92887e064127527bd985a827fdaf5593a2 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sun, 21 Feb 2016 19:42:42 +0100 Subject: [PATCH 24/51] Resolved bug with DeployTask cargo menu. Cargo main menu should contain the type of the cargo, or DCS world gets confused... (menus are hashed on the same apparently). --- Moose/DeployTask.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index 49cbe54c2..0cc5dd2eb 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -107,7 +107,7 @@ trace.f( self.ClassName ) if not Client._Menus[Cargo.CargoType].DeployMenu then Client._Menus[Cargo.CargoType].DeployMenu = missionCommands.addSubMenuForGroup( ClientGroupID, - self.TEXT[1], + self.TEXT[1] .. " " .. Cargo.CargoType, nil ) trace.i( self.ClassName, 'Added DeployMenu ' .. self.TEXT[1] ) From aadd529093236d0af5538cb16ecc7e11e072951a Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sun, 21 Feb 2016 22:30:24 +0100 Subject: [PATCH 25/51] Optimized Cargo Logic --- Moose/Cargo.lua | 207 +++++++++++++++++++++---------------------- Moose/Client.lua | 75 +--------------- Moose/Mission.lua | 20 ----- Moose/PickupTask.lua | 4 +- Moose/Stage.lua | 6 +- 5 files changed, 109 insertions(+), 203 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 558df5b8d..bf0409be8 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -272,7 +272,7 @@ CARGO = { UNLOADED = 2, LOADING = 3 }, - CargoCarrierGroupName = nil + CargoClient = nil } --- 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... @@ -285,7 +285,7 @@ trace.f( self.ClassName, { CargoType, CargoName, CargoWeight } ) self.CargoName = CargoName self.CargoWeight = CargoWeight - self.Status = self:StatusNone() + self:StatusNone() return self end @@ -308,36 +308,21 @@ end function CARGO:IsLoadedInClient() - if self:IsStatusLoaded() then - return self.Client + if self:IsStatusLoaded() or self:IsStatusLoading() then + return self.CargoClient 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 + self:StatusUnLoaded() - return Cargo + return self end function CARGO:OnBoard( Client, LandingZone ) @@ -345,6 +330,7 @@ trace.f(self.ClassName ) local Valid = true + self.CargoClient = Client local ClientUnit = Client:GetClientGroupUnit() return Valid @@ -358,6 +344,14 @@ trace.f(self.ClassName ) return OnBoarded end +function CARGO:Load( Client ) +trace.f( self.ClassName ) + + self:StatusLoaded( Client ) + + return self +end + function CARGO:IsLandingRequired() trace.f( self.ClassName ) return true @@ -372,15 +366,26 @@ end function CARGO:StatusNone() trace.f(self.ClassName ) - self.Status = CARGO.STATUS.NONE + self.CargoClient = nil + self.CargoStatus = CARGO.STATUS.NONE return self end -function CARGO:StatusLoaded() +function CARGO:StatusLoading( Client ) trace.f(self.ClassName ) - self.Status = CARGO.STATUS.LOADED + self.CargoClient = Client + self.CargoStatus = CARGO.STATUS.LOADING + + return self +end + +function CARGO:StatusLoaded( Client ) +trace.f(self.ClassName ) + + self.CargoClient = Client + self.CargoStatus = CARGO.STATUS.LOADED return self end @@ -388,43 +393,38 @@ end function CARGO:StatusUnLoaded() trace.f(self.ClassName ) - self.Status = CARGO.STATUS.UNLOADED + self.CargoClient = nil + self.CargoStatus = 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 + return self.CargoStatus == CARGO.STATUS.NONE end function CARGO:IsStatusLoading() trace.f(self.ClassName ) - return self.Status == CARGO.STATUS.LOADING + return self.CargoStatus == CARGO.STATUS.LOADING end +function CARGO:IsStatusLoaded() +trace.f(self.ClassName ) + + return self.CargoStatus == CARGO.STATUS.LOADED +end + +function CARGO:IsStatusUnLoaded() +trace.f(self.ClassName ) + + return self.CargoStatus == CARGO.STATUS.UNLOADED +end + + CARGO_GROUP = { ClassName = "CARGO_GROUP" } @@ -450,13 +450,19 @@ trace.f( self.ClassName ) local SpawnCargo = true - if self.CargoGroupName then + if self:IsStatusNone() then + + elseif self:IsStatusLoaded() or self:IsStatusLoading() then + local Client = self:IsLoadedInClient() if Client and Client:ClientGroup() then - if Client:FindCargo( self.CargoName ) then - SpawnCargo = false - end + SpawnCargo = false end + + elseif self:IsStatusUnLoaded() then + + SpawnCargo = false + end if SpawnCargo then @@ -466,9 +472,10 @@ trace.f( self.ClassName ) else --- ReSpawn the Cargo in the CargoZone without a host ... self.CargoGroupName = self.CargoSpawn:InZone( self.CargoZone:GetCargoZoneName(), self.CargoName ).name - end + self:StatusNone() end + trace.i( self.ClassName, { self.CargoGroupName, CARGOS[self.CargoName].CargoGroupName } ) return self @@ -561,6 +568,8 @@ trace.f(self.ClassName ) trace.i( self.ClassName, "TransportCargoOnBoard: Routing " .. self.CargoGroupName ) routines.scheduleFunction( routines.goRoute, { self.CargoGroupName, Points}, timer.getTime() + 4 ) + + self:StatusLoading( Client ) return Valid @@ -575,6 +584,7 @@ trace.f(self.ClassName ) local CargoGroup = Group.getByName( self.CargoGroupName ) if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 25 ) then CargoGroup:destroy() + self:StatusLoaded( Client ) OnBoarded = true end @@ -588,9 +598,8 @@ trace.f( self.ClassName ) trace.i( self.ClassName, 'self.CargoGroupName = ' .. self.CargoGroupName ) self.CargoSpawn:FromCarrier( Client:GetClientGroupUnit(), TargetZoneName, self.CargoGroupName ) - self:StatusUnLoaded() - local Cargo = Client:RemoveCargo( self ) + self:StatusUnLoaded() return self end @@ -601,15 +610,18 @@ CARGO_PACKAGE = { } -function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoHostName ) -trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoHostName } ) +function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoClientInitGroupName ) +trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoClientInitGroupName } ) -- Arrange meta tables local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) - self.CargoHostName = CargoHostName + self.CargoClientInitGroupName = CargoClientInitGroupName - self.CargoHostSpawn = SPAWN:New( self.CargoHostName ) + self.CargoClient = CLIENT:New( self.CargoClientInitGroupName ) + self:StatusLoaded( self.CargoClient ) + + self.CargoClientInitGroupSpawn = SPAWN:New( self.CargoClientInitGroupName ) CARGOS[self.CargoName] = self @@ -622,36 +634,36 @@ trace.f( self.ClassName ) -- this needs to be checked thoroughly - local SpawnCargo = true - trace.i( self.ClassName, self.CargoHostName ) + trace.i( self.ClassName, self.CargoClientInitGroupName ) + + if self:IsStatusNone() then - if self.Client and self.Client:ClientGroup() then - trace.i( self.ClassName, 'There is a Client ' .. self.Client.ClientName ) - if self.Client:FindCargo( self.CargoName ) then - if self.Client:GetClientGroupUnit():getPlayerName() then -- this needs to be checked thoroughly - trace.i( self.ClassName, 'ok, Client is of player ' .. self.Client:GetClientGroupUnit():getPlayerName() .. ' and contains the Cargo, do nothing' ) - SpawnCargo = false - end + elseif self:IsStatusLoading() or self:IsStatusLoaded() then + + local Client = self:IsLoadedInClient() + if Client and Client:ClientGroup() then + SpawnCargo = false end + + elseif self:IsStatusUnLoaded() then + + SpawnCargo = false + else - if self.CargoHostName then - local CargoHostGroup = Group.getByName( self.CargoHostName ) - if not CargoHostGroup then - self.CargoHostSpawn:ReSpawn() - end - local CargoHostGroup = Group.getByName( self.CargoHostName ) - if CargoHostGroup and CargoHostGroup:isExist() then - self.Client = CLIENT:New( self.CargoHostGroup, '' ) - end - end - end - - if SpawnCargo then - self.Client:AddCargo( self ) -- Adding cargo to the AI client + end + if SpawnCargo then + self:StatusNone() + end + + local CargoClientInitGroup = Group.getByName( self.CargoClientInitGroupName ) + if CargoClientInitGroup then + self.CargoClientInitGroupSpawn:Spawn( self.CargoClientInitGroupName ) + end + return self end @@ -660,18 +672,12 @@ trace.f( self.ClassName ) local Near = false - if self.Client and self.Client:ClientGroup():getName() then - trace.i( self.ClassName, self.Client.ClientName ) + if self.CargoClient and self.CargoClient:ClientGroup() then + trace.i( self.ClassName, self.CargoClient.ClientName ) trace.i( self.ClassName, 'Client Exists.' ) - trace.i( self.ClassName, 'self.Client:ClientGroup():getName() = ' .. self.Client:ClientGroup():getName() ) - -- Find the cargo in the client - local Cargo = self.Client:FindCargo( self.CargoName ) - if Cargo == self then - trace.i( self.ClassName, 'Cargo is loaded in Client.' ) - if routines.IsPartOfGroupInRadius( self.Client:ClientGroup(), Client:ClientPosition(), 150 ) then - Near = true - end + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupUnit(), Client:ClientPosition(), 150 ) then + Near = true end end @@ -691,8 +697,8 @@ trace.f(self.ClassName ) local CarrierPosOnBoard = ClientUnit:getPoint() local CarrierPosMoveAway = ClientUnit:getPoint() - local CargoHostGroup = self.Client:ClientGroup() - local CargoHostName = self.Client:ClientGroup():getName() + local CargoHostGroup = self.CargoClient:ClientGroup() + local CargoHostName = self.CargoClient:ClientGroup():getName() local CargoHostUnits = CargoHostGroup:getUnits() local CargoPos = CargoHostUnits[1]:getPoint() @@ -775,17 +781,11 @@ trace.f(self.ClassName ) local OnBoarded = false - if self.Client and self.Client:ClientGroup() then - if routines.IsPartOfGroupInRadius( self.Client:ClientGroup(), Client:ClientPosition(), 25 ) then + if self.CargoClient and self.CargoClient:ClientGroup() then + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupUnit(), CargoClient:ClientPosition(), 25 ) then - -- Switch Cargo from self.Client to Client ... - Client:AddCargo( self ) - self.Client:RemoveCargo( self ) - trace.i( self.ClassName, 'Cargo switched from ' .. self.Client:ClientGroup():getName() .. ' to ' .. Client:ClientGroup():getName() ) - trace.i( self.ClassName, 'Cargo is ' .. self.CargoName ) -- Should not be null - - -- ok, so the Cargo has a new Client, thus, change the Owning Client of the Cargo. - self.Client = Client + -- Switch Cargo from self.CargoClient to Client ... Each cargo can have only one client. So assigning the new client for the cargo is enough. + self:StatusLoaded( Client ) -- All done, onboarded the Cargo to the new Client. OnBoarded = true @@ -803,7 +803,6 @@ trace.f( self.ClassName ) --self.CargoSpawn:FromCarrier( Client:ClientGroup(), TargetZoneName, self.CargoHostName ) self:StatusUnLoaded() - local Cargo = Client:RemoveCargo( self ) return Cargo end @@ -948,8 +947,6 @@ trace.f( self.ClassName ) trace.i( self.ClassName, 'self.CargoGroupName = ' .. self.CargoGroupName ) self:StatusUnLoaded() - local Cargo = Client:RemoveCargo( self ) - return Cargo end diff --git a/Moose/Client.lua b/Moose/Client.lua index 07784f238..03169e32e 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -23,7 +23,6 @@ CLIENT = { ClientTransport = false, ClientBriefingShown = false, _Menus = {}, - _Cargos = {}, _Tasks = {}, Messages = { } @@ -61,7 +60,6 @@ end function CLIENT:Reset( ClientName ) trace.f(self.ClassName) self._Menus = {} - self._Cargos = {} end --- ClientGroup returns the Group of a Client. @@ -199,15 +197,6 @@ trace.f(self.ClassName) return self.ClientTransport 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. -- The @{CARGO} is shown throught the MESSAGE system of DCS World. function CLIENT:ShowCargo() @@ -215,14 +204,13 @@ trace.f( self.ClassName ) local CargoMsg = "" - for CargoName, Cargo in pairs( self._Cargos ) do - if CargoMsg ~= "" then - CargoMsg = CargoMsg .. "\n" + for CargoName, Cargo in pairs( CARGOS ) do + if self == Cargo:IsLoadedInClient() then + CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight .. "\n" end - CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight end - if CargoMsg == '' then + if CargoMsg == "" then CargoMsg = "empty" end @@ -230,61 +218,6 @@ trace.f( self.ClassName ) 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 - - return self - -end - ---- AddCargo allows to add @{CARGO} on the CLIENT. --- @tparam string Cargo is the @{CARGO}. --- @treturn CLIENT -function CLIENT:AddCargo( Cargo ) -trace.f(self.ClassName, { Cargo.CargoName } ) - - local Valid = true - - if Valid then - self._Cargos[Cargo.CargoName] = Cargo - self:ShowCargo() - end - - return self - -end - ---- RemoveCargo removes @{CARGO} from the CLIENT. --- @tparam string CargoName is the name of the @{CARGO}. --- @treturn Cargo -function CLIENT:RemoveCargo( Cargo ) -trace.f(self.ClassName, { Cargo.CargoName } ) - - local Valid = true - - if Valid then - trace.i( "CLIENT", "RemoveCargo: CargoName = " .. Cargo.CargoName ) - --local CargoNew = self._Cargos[Cargo.CargoName] - self._Cargos[Cargo.CargoName] = nil - end - - return Cargo - -end - --- SwitchMessages is a local function called by the DCS World Menu system to switch off messages. function CLIENT.SwitchMessages( PrmTable ) PrmTable[1].MessageSwitch = PrmTable[2] diff --git a/Moose/Mission.lua b/Moose/Mission.lua index fdd78404f..13d0ca400 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -15,7 +15,6 @@ MISSION = { _Clients = {}, _Tasks = {}, _ActiveTasks = {}, - _Cargos = {}, GoalFunction = nil, MissionReportTrigger = 0, MissionProgressTrigger = 0, @@ -360,20 +359,6 @@ function MISSION:GetTasks() return self._Tasks 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( Cargos ) - self:T( { Cargos } ) - - if type( Cargos ) == "table" then - for CargoID, Cargo in pairs( Cargos ) do - self._Cargos[Cargo.CargoName] = Cargo - end - else - self._Cargos[Cargos.CargoName] = Cargos - end -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. @@ -443,8 +428,6 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") Client._Tasks[TaskNumber].LandingZones = Mission._Tasks[TaskNumber].LandingZones end - Client._Cargos = {} - Mission:Ongoing() end @@ -543,9 +526,6 @@ trace.scheduled("MISSIONSCHEDULER","Scheduler") -- So first sanitize Client._Tasks[TaskNumber].MissionTask, after that, sanitize only the whole _Tasks structure... --Client._Tasks[TaskNumber].MissionTask = 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 diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index a1cf96d47..bad1ea879 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -76,9 +76,9 @@ trace.f( self.ClassName ) for CargoID, Cargo in pairs( Cargos ) do - trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType } ) + trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } ) - if not Cargo:IsStatusLoaded() and not Cargo:IsStatusLoading() then + if Cargo:IsStatusNone() then local MenuAdd = false if Cargo:IsNear( Client, self.CurrentCargoZone ) then diff --git a/Moose/Stage.lua b/Moose/Stage.lua index 12c77046a..a9e8377aa 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -494,7 +494,6 @@ trace.f(self.ClassName) if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then 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 @@ -551,9 +550,7 @@ trace.f(self.ClassName) 20, Mission.Name .. "/STAGELANDING.LOADING1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":" ) Task.ExecuteStage = _TransportExecuteStage.SUCCESS - if Mission.MissionReportFlash then - Client:ShowCargo() - end + Client:ShowCargo() end else Client:Message( "Hook the " .. Task.CargoNames .. " onto the helicopter " .. Task.TEXT[3] .. " within the landing zone.", @@ -613,7 +610,6 @@ trace.f(self.ClassName) end if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then - Task.Cargo:StatusLoaded() 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 .. ")" .. ":" ) From c22492f0519d6bbc74e29d19825b291cef78bcdc Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sun, 21 Feb 2016 23:29:44 +0100 Subject: [PATCH 26/51] Optimized Cargo logic --- Moose/Cargo.lua | 6 ++++-- Moose/Client.lua | 21 +++++++++++++++++---- Moose/DeployTask.lua | 2 +- Moose/PickupTask.lua | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index bf0409be8..185efc096 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -307,6 +307,7 @@ trace.f( self.ClassName ) end function CARGO:IsLoadedInClient() +trace.f( self.ClassName ) if self:IsStatusLoaded() or self:IsStatusLoading() then return self.CargoClient @@ -656,7 +657,8 @@ trace.f( self.ClassName ) end if SpawnCargo then - self:StatusNone() + self.CargoClient = CLIENT:New( self.CargoClientInitGroupName ) + self:StatusLoaded( self.CargoClient ) end local CargoClientInitGroup = Group.getByName( self.CargoClientInitGroupName ) @@ -782,7 +784,7 @@ trace.f(self.ClassName ) local OnBoarded = false if self.CargoClient and self.CargoClient:ClientGroup() then - if routines.IsUnitInRadius( self.CargoClient:GetClientGroupUnit(), CargoClient:ClientPosition(), 25 ) then + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupUnit(), self.CargoClient:ClientPosition(), 10 ) then -- Switch Cargo from self.CargoClient to Client ... Each cargo can have only one client. So assigning the new client for the cargo is enough. self:StatusLoaded( Client ) diff --git a/Moose/Client.lua b/Moose/Client.lua index 03169e32e..ed8994a53 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -86,10 +86,12 @@ trace.f(self.ClassName) local ClientGroup = Group.getByName( self.ClientName ) if ClientGroup then trace.i( self.ClassName, "ClientGroup = " .. self.ClientName ) - if ClientGroup:isExist() and ClientGroup:getID() == UnitData:getGroup():getID() then - trace.i( self.ClassName, "Normal logic" ) - trace.i( self.ClassName, self.ClientName .. " : group found!" ) - return ClientGroup + if ClientGroup:isExist() then + if ClientGroup:getID() == UnitData:getGroup():getID() then + trace.i( self.ClassName, "Normal logic" ) + trace.i( self.ClassName, 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) @@ -113,6 +115,17 @@ trace.f(self.ClassName) end end end + + -- For non player clients + local ClientGroup = Group.getByName( self.ClientName ) + if ClientGroup then + trace.i( self.ClassName, "ClientGroup = " .. self.ClientName ) + if ClientGroup:isExist() then + trace.i( self.ClassName, "Normal logic" ) + trace.i( self.ClassName, self.ClientName .. " : group found!" ) + return ClientGroup + end + end self.ClientGroupID = nil self.ClientGroupUnit = nil diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index 0cc5dd2eb..e27e29898 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -98,7 +98,7 @@ trace.f( self.ClassName ) trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo.CargoWeight } ) - if Cargo:IsStatusLoaded() then + if Cargo:IsStatusLoaded() and Client == Cargo:IsLoadedInClient() then if Client._Menus[Cargo.CargoType] == nil then Client._Menus[Cargo.CargoType] = {} diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index bad1ea879..52479fa42 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -78,7 +78,7 @@ trace.f( self.ClassName ) trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } ) - if Cargo:IsStatusNone() then + if Cargo:IsStatusNone() or ( Cargo:IsStatusLoaded() and Client ~= Cargo:IsLoadedInClient() ) then local MenuAdd = false if Cargo:IsNear( Client, self.CurrentCargoZone ) then From 9c2741e758ed13d6d36ee2c38979d5e454d47ef4 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Mon, 22 Feb 2016 11:22:30 +0100 Subject: [PATCH 27/51] SlingLoad cargo should never appear in the CARGO menu. It has its own mechanisms. --- Moose/Cargo.lua | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 185efc096..d302f8f98 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -898,6 +898,15 @@ trace.f( self.ClassName ) return self end +function CARGO_SLINGLOAD:IsNear( Client, LandingZone ) +trace.f( self.ClassName ) + + local Near = false + + return Near +end + + function CARGO_SLINGLOAD:IsInLandingZone( Client, LandingZone ) trace.f( self.ClassName ) @@ -911,7 +920,6 @@ trace.f( self.ClassName ) end return Near - end @@ -923,7 +931,6 @@ trace.f(self.ClassName ) return Valid - end From 6955d4584073fb93369fd20cb652ce6d88b3c4e1 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Thu, 25 Feb 2016 14:52:16 +0100 Subject: [PATCH 28/51] Lots of fixes for cargo + optimization of Stage Messages --- Moose/Base.lua | 15 +- Moose/Cargo.lua | 258 +++++++++++++------------- Moose/Client.lua | 70 ++++--- Moose/DeployTask.lua | 33 ++-- Moose/Group.lua | 68 +++++++ Moose/Mission.lua | 7 +- Moose/PickupTask.lua | 48 ++--- Moose/Routines.lua | 90 +++++---- Moose/Spawn.lua | 69 ++++++- Moose/Stage.lua | 271 +++++++++------------------- Test Missions/MOOSE_Pickup_Test.lua | 126 +++++++++++++ Test Missions/MOOSE_Pickup_Test.miz | Bin 0 -> 27262 bytes Test Missions/MOOSE_Spawn_Test.lua | 15 ++ Test Missions/MOOSE_Spawn_Test.miz | Bin 0 -> 19439 bytes 14 files changed, 640 insertions(+), 430 deletions(-) create mode 100644 Test Missions/MOOSE_Pickup_Test.lua create mode 100644 Test Missions/MOOSE_Pickup_Test.miz create mode 100644 Test Missions/MOOSE_Spawn_Test.lua create mode 100644 Test Missions/MOOSE_Spawn_Test.miz diff --git a/Moose/Base.lua b/Moose/Base.lua index dc4029ff0..77724a7a1 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -156,9 +156,20 @@ trace.f( self.ClassName, { EventTime, Initiator, IniUnitName, place, subplace } subplace = subplace } - world.onEvent( Event ) + 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) --trace.f(self.ClassName, event ) @@ -204,6 +215,6 @@ function BASE:T( Arguments ) local Line = DebugInfo.currentline - env.info( string.format( "%6d/%1s:%20s.%s\(%s\)" , Line, "T", self.ClassName, Function .. routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d/%1s:%20s.%s\(%s\)" , Line, "T", self.ClassName, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end end diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index d302f8f98..d113e70b1 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -31,24 +31,25 @@ CARGO_ZONE = { } } -function CARGO_ZONE:New( CargoZoneName, CargoHostName ) -trace.f( self.ClassName, { CargoZoneName, CargoHostName } ) - - local self = BASE:Inherit( self, BASE:New() ) +function CARGO_ZONE:New( CargoZoneName, CargoHostName ) local self = BASE:Inherit( self, BASE:New() ) +self:T( { CargoZoneName, CargoHostName } ) self.CargoZoneName = CargoZoneName self.CargoZone = trigger.misc.getZone( CargoZoneName ) + if CargoHostName then self.CargoHostName = CargoHostName self.CargoHostSpawn = SPAWN:New( CargoHostName ) end + + self:T( self.CargoZone ) return self end function CARGO_ZONE:Spawn() -trace.f( self.ClassName, CargoHostSpawn ) +self:T( CargoHostSpawn ) if self.CargoHostSpawn then local CargoHostGroup = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ) @@ -84,7 +85,7 @@ function CARGO_ZONE:GetHostUnit() end function CARGO_ZONE:ReportCargosToClient( Client, CargoType ) -trace.f( self.ClassName ) +self:T() local SignalUnit = self:GetHostUnit() @@ -95,23 +96,25 @@ trace.f( self.ClassName ) local HostMessage = "" local IsCargo = false - for CargoID, Cargo in pairs( Cargos ) do + for CargoID, Cargo in pairs( CARGOS ) do if Cargo.CargoType == Task.CargoType then - HostMessage = HostMessage .. "\n - " .. Cargo.CargoName - IsCargo = true + if Cargo:IsStatusNone() then + HostMessage = HostMessage .. " - " .. Cargo.CargoName .. " - " .. Cargo.CargoType .. " (" .. Cargo.Weight .. "kg)" .. "\n" + IsCargo = true + end end end if not IsCargo then - HostMessage = HostMessage .. "No Cargo Available." + HostMessage = "No Cargo Available." end - Client:Message( RouteMessage, self.MSG.TIME, Mission.Name .. "/StageHosts." .. SignalUnitTypeName, SignalUnitTypeName .. ": Reporting Cargo", 10 ) + Client:Message( HostMessage, 20, Mission.Name .. "/StageHosts." .. SignalUnitTypeName, SignalUnitTypeName .. ": Reporting Cargo", 10 ) end end function CARGO_ZONE:Signal() -trace.f( self.ClassName ) +self:T() local Signalled = false @@ -125,7 +128,7 @@ trace.f( self.ClassName ) if SignalUnit then - trace.i( self.ClassName, 'Signalling Unit' ) + self:T( 'Signalling Unit' ) local SignalVehiclePos = SignalUnit:getPosition().p SignalVehiclePos.y = SignalVehiclePos.y + 2 @@ -165,7 +168,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:WhiteSmoke() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE @@ -174,7 +177,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:BlueSmoke() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.BLUE @@ -183,7 +186,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:RedSmoke() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED @@ -192,7 +195,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:OrangeSmoke() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.ORANGE @@ -201,7 +204,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:GreenSmoke() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN @@ -211,7 +214,7 @@ end function CARGO_ZONE:WhiteFlare() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE @@ -220,7 +223,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:RedFlare() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED @@ -229,7 +232,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:GreenFlare() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN @@ -238,7 +241,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:YellowFlare() -trace.f( self.ClassName ) +self:T() self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.YELLOW @@ -248,7 +251,7 @@ end function CARGO_ZONE:GetCargoHostUnit() -trace.f( self.ClassName ) +self:T() local CargoHostUnit = Group.getByName( self.CargoHostSpawn:SpawnGroupName() ):getUnit(1) if CargoHostUnit and CargoHostUnit:isExist() then @@ -259,7 +262,7 @@ trace.f( self.ClassName ) end function CARGO_ZONE:GetCargoZoneName() -trace.f( self.ClassName ) +self:T() return self.CargoZoneName end @@ -276,10 +279,9 @@ CARGO = { } --- 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 } ) +function CARGO:New( CargoType, CargoName, CargoWeight ) local self = BASE:Inherit( self, BASE:New() ) +self:T( { CargoType, CargoName, CargoWeight } ) - local self = BASE:Inherit( self, BASE:New() ) self.CargoType = CargoType self.CargoName = CargoName @@ -291,14 +293,14 @@ trace.f( self.ClassName, { CargoType, CargoName, CargoWeight } ) end function CARGO:Spawn() -trace.f( self.ClassName ) +self:T() return self end function CARGO:IsNear( Client, LandingZone ) -trace.f( self.ClassName ) +self:T() local Near = true @@ -307,7 +309,7 @@ trace.f( self.ClassName ) end function CARGO:IsLoadedInClient() -trace.f( self.ClassName ) +self:T() if self:IsStatusLoaded() or self:IsStatusLoading() then return self.CargoClient @@ -319,7 +321,7 @@ end function CARGO:UnLoad( Client, TargetZoneName ) -trace.f( self.ClassName ) +self:T() self:StatusUnLoaded() @@ -327,7 +329,7 @@ trace.f( self.ClassName ) end function CARGO:OnBoard( Client, LandingZone ) -trace.f(self.ClassName ) +self:T() local Valid = true @@ -338,7 +340,7 @@ trace.f(self.ClassName ) end function CARGO:OnBoarded( Client, LandingZone ) -trace.f(self.ClassName ) +self:T() local OnBoarded = true @@ -346,7 +348,7 @@ trace.f(self.ClassName ) end function CARGO:Load( Client ) -trace.f( self.ClassName ) +self:T() self:StatusLoaded( Client ) @@ -354,18 +356,18 @@ trace.f( self.ClassName ) end function CARGO:IsLandingRequired() -trace.f( self.ClassName ) +self:T() return true end function CARGO:IsSlingLoad() -trace.f( self.ClassName ) +self:T() return false end function CARGO:StatusNone() -trace.f(self.ClassName ) +self:T() self.CargoClient = nil self.CargoStatus = CARGO.STATUS.NONE @@ -374,16 +376,17 @@ trace.f(self.ClassName ) end function CARGO:StatusLoading( Client ) -trace.f(self.ClassName ) +self:T() self.CargoClient = Client self.CargoStatus = CARGO.STATUS.LOADING + self:T( "Cargo loaded in Client: " .. CargoClient:GetClientGroupName() ) return self end function CARGO:StatusLoaded( Client ) -trace.f(self.ClassName ) +self:T() self.CargoClient = Client self.CargoStatus = CARGO.STATUS.LOADED @@ -392,7 +395,7 @@ trace.f(self.ClassName ) end function CARGO:StatusUnLoaded() -trace.f(self.ClassName ) +self:T() self.CargoClient = nil self.CargoStatus = CARGO.STATUS.UNLOADED @@ -402,25 +405,25 @@ end function CARGO:IsStatusNone() -trace.f(self.ClassName ) +self:T() return self.CargoStatus == CARGO.STATUS.NONE end function CARGO:IsStatusLoading() -trace.f(self.ClassName ) +self:T() return self.CargoStatus == CARGO.STATUS.LOADING end function CARGO:IsStatusLoaded() -trace.f(self.ClassName ) +self:T() return self.CargoStatus == CARGO.STATUS.LOADED end function CARGO:IsStatusUnLoaded() -trace.f(self.ClassName ) +self:T() return self.CargoStatus == CARGO.STATUS.UNLOADED end @@ -431,12 +434,9 @@ CARGO_GROUP = { } -function CARGO_GROUP:New( CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone ) -trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone } ) +function CARGO_GROUP:New( CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) +self:T( { 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 @@ -447,7 +447,7 @@ trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoGroupTemplate end function CARGO_GROUP:Spawn() -trace.f( self.ClassName ) +self:T() local SpawnCargo = true @@ -477,13 +477,13 @@ trace.f( self.ClassName ) self:StatusNone() end - trace.i( self.ClassName, { self.CargoGroupName, CARGOS[self.CargoName].CargoGroupName } ) + self:T( { self.CargoGroupName, CARGOS[self.CargoName].CargoGroupName } ) return self end function CARGO_GROUP:IsNear( Client, LandingZone ) -trace.f( self.ClassName ) +self:T() local Near = false @@ -498,8 +498,9 @@ trace.f( self.ClassName ) end + function CARGO_GROUP:OnBoard( Client, LandingZone, OnBoardSide ) -trace.f(self.ClassName ) +self:T() local Valid = true @@ -517,12 +518,12 @@ trace.f(self.ClassName ) local Points = {} - trace.i( self.ClassName, 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z ) - trace.i( self.ClassName, 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z ) + self:T( 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z ) + self:T( '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 ) + self:T( 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y ) if OnBoardSide == nil then OnBoardSide = CLIENT.ONBOARDSIDE.NONE @@ -530,7 +531,7 @@ trace.f(self.ClassName ) if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding LEFT" ) + self:T( "TransportCargoOnBoard: Onboarding LEFT" ) CarrierPosMove.z = CarrierPosMove.z - 25 CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5 Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) @@ -538,7 +539,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding RIGHT" ) + self:T( "TransportCargoOnBoard: Onboarding RIGHT" ) CarrierPosMove.z = CarrierPosMove.z + 25 CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5 Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) @@ -546,7 +547,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding BACK" ) + self:T( "TransportCargoOnBoard: Onboarding BACK" ) CarrierPosMove.x = CarrierPosMove.x - 25 CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5 Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) @@ -554,7 +555,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" ) + self:T( "TransportCargoOnBoard: Onboarding FRONT" ) CarrierPosMove.x = CarrierPosMove.x + 25 CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5 Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 ) @@ -562,11 +563,11 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding CENTRAL" ) + self:T( "TransportCargoOnBoard: Onboarding CENTRAL" ) Points[#Points+1] = routines.ground.buildWP( CarrierPos, "Cone", 10 ) end - trace.i( self.ClassName, "TransportCargoOnBoard: Routing " .. self.CargoGroupName ) + self:T( "TransportCargoOnBoard: Routing " .. self.CargoGroupName ) routines.scheduleFunction( routines.goRoute, { self.CargoGroupName, Points}, timer.getTime() + 4 ) @@ -578,7 +579,7 @@ end function CARGO_GROUP:OnBoarded( Client, LandingZone ) -trace.f(self.ClassName ) +self:T() local OnBoarded = false @@ -592,11 +593,12 @@ trace.f(self.ClassName ) 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 ) +function CARGO_GROUP:UnLoad( Client, TargetZoneName ) +self:T() + + self:T( 'self.CargoName = ' .. self.CargoName ) + self:T( 'self.CargoGroupName = ' .. self.CargoGroupName ) self.CargoSpawn:FromCarrier( Client:GetClientGroupUnit(), TargetZoneName, self.CargoGroupName ) @@ -611,18 +613,11 @@ CARGO_PACKAGE = { } -function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoClientInitGroupName ) -trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoClientInitGroupName } ) +function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoClient ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) - -- Arrange meta tables - local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) - - self.CargoClientInitGroupName = CargoClientInitGroupName - - self.CargoClient = CLIENT:New( self.CargoClientInitGroupName ) - self:StatusLoaded( self.CargoClient ) - - self.CargoClientInitGroupSpawn = SPAWN:New( self.CargoClientInitGroupName ) + self:T( { CargoType, CargoName, CargoWeight, CargoClient.ClientName } ) + + self.CargoClient = CargoClient CARGOS[self.CargoName] = self @@ -630,21 +625,28 @@ trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoClientInitGro end + function CARGO_PACKAGE:Spawn() -trace.f( self.ClassName ) +self:T() -- this needs to be checked thoroughly + local CargoClientInitGroup = self.CargoClient:ClientGroup() + if not CargoClientInitGroup then + if not self.CargoClientInitGroupSpawn then + self.CargoClientInitGroupSpawn = SPAWN:New( self.CargoClient:GetClientGroupName() ) + end + self.CargoClientInitGroupSpawn:Spawn( self.CargoClient:GetClientGroupName() ) + end + local SpawnCargo = true - trace.i( self.ClassName, self.CargoClientInitGroupName ) - if self:IsStatusNone() then elseif self:IsStatusLoading() or self:IsStatusLoaded() then - local Client = self:IsLoadedInClient() - if Client and Client:ClientGroup() then + local CargoClientLoaded = self:IsLoadedInClient() + if CargoClientLoaded and CargoClientLoaded:ClientGroup() then SpawnCargo = false end @@ -657,26 +659,21 @@ trace.f( self.ClassName ) end if SpawnCargo then - self.CargoClient = CLIENT:New( self.CargoClientInitGroupName ) self:StatusLoaded( self.CargoClient ) end - - local CargoClientInitGroup = Group.getByName( self.CargoClientInitGroupName ) - if CargoClientInitGroup then - self.CargoClientInitGroupSpawn:Spawn( self.CargoClientInitGroupName ) - end - + return self end + function CARGO_PACKAGE:IsNear( Client, LandingZone ) -trace.f( self.ClassName ) +self:T() local Near = false if self.CargoClient and self.CargoClient:ClientGroup() then - trace.i( self.ClassName, self.CargoClient.ClientName ) - trace.i( self.ClassName, 'Client Exists.' ) + self:T( self.CargoClient.ClientName ) + self:T( 'Client Exists.' ) if routines.IsUnitInRadius( self.CargoClient:GetClientGroupUnit(), Client:ClientPosition(), 150 ) then Near = true @@ -687,8 +684,9 @@ trace.f( self.ClassName ) end + function CARGO_PACKAGE:OnBoard( Client, LandingZone, OnBoardSide ) -trace.f(self.ClassName ) +self:T() local Valid = true @@ -707,12 +705,12 @@ trace.f(self.ClassName ) local Points = {} - trace.i( self.ClassName, 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z ) - trace.i( self.ClassName, 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z ) + self:T( 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z ) + self:T( '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 ) + self:T( 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y ) if OnBoardSide == nil then OnBoardSide = CLIENT.ONBOARDSIDE.NONE @@ -720,7 +718,7 @@ trace.f(self.ClassName ) if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding LEFT" ) + self:T( "TransportCargoOnBoard: Onboarding LEFT" ) CarrierPosMove.z = CarrierPosMove.z - 25 CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5 CarrierPosMoveAway.z = CarrierPosMoveAway.z - 20 @@ -730,7 +728,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding RIGHT" ) + self:T( "TransportCargoOnBoard: Onboarding RIGHT" ) CarrierPosMove.z = CarrierPosMove.z + 25 CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5 CarrierPosMoveAway.z = CarrierPosMoveAway.z + 20 @@ -740,7 +738,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding BACK" ) + self:T( "TransportCargoOnBoard: Onboarding BACK" ) CarrierPosMove.x = CarrierPosMove.x - 25 CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5 CarrierPosMoveAway.x = CarrierPosMoveAway.x - 20 @@ -750,7 +748,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" ) + self:T( "TransportCargoOnBoard: Onboarding FRONT" ) CarrierPosMove.x = CarrierPosMove.x + 25 CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5 CarrierPosMoveAway.x = CarrierPosMoveAway.x + 20 @@ -760,7 +758,7 @@ trace.f(self.ClassName ) elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then - trace.i( self.ClassName, "TransportCargoOnBoard: Onboarding FRONT" ) + self:T( "TransportCargoOnBoard: Onboarding FRONT" ) CarrierPosMove.x = CarrierPosMove.x + 25 CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5 CarrierPosMoveAway.x = CarrierPosMoveAway.x + 20 @@ -769,7 +767,7 @@ trace.f(self.ClassName ) Points[#Points+1] = routines.ground.buildWP( CarrierPosMoveAway, "Cone", 10 ) end - trace.i( self.ClassName, "Routing " .. CargoHostName ) + self:T( "Routing " .. CargoHostName ) routines.scheduleFunction( routines.goRoute, { CargoHostName, Points}, timer.getTime() + 4 ) @@ -779,7 +777,7 @@ end function CARGO_PACKAGE:OnBoarded( Client, LandingZone ) -trace.f(self.ClassName ) +self:T() local OnBoarded = false @@ -797,11 +795,12 @@ trace.f(self.ClassName ) 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 ) +function CARGO_PACKAGE:UnLoad( Client, TargetZoneName ) +self:T() + + self:T( 'self.CargoName = ' .. self.CargoName ) + --self:T( 'self.CargoHostName = ' .. self.CargoHostName ) --self.CargoSpawn:FromCarrier( Client:ClientGroup(), TargetZoneName, self.CargoHostName ) self:StatusUnLoaded() @@ -816,11 +815,10 @@ CARGO_SLINGLOAD = { function CARGO_SLINGLOAD:New( CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID ) -trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID } ) - - -- Arrange meta tables local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) + self:T( { CargoType, CargoName, CargoWeight, CargoZone, CargoHostName, CargoCountryID } ) + self.CargoHostName = CargoHostName -- Cargo will be initialized around the CargoZone position. @@ -838,19 +836,21 @@ trace.f( self.ClassName, { CargoType, CargoName, CargoWeight, CargoZone, CargoHo end + function CARGO_SLINGLOAD:IsLandingRequired() -trace.f( self.ClassName ) +self:T() return false end + function CARGO_SLINGLOAD:IsSlingLoad() -trace.f( self.ClassName ) +self:T() return true end function CARGO_SLINGLOAD:Spawn() -trace.f( self.ClassName ) +self:T() local Zone = trigger.misc.getZone( self.CargoZone ) @@ -858,7 +858,7 @@ trace.f( self.ClassName ) ZonePos.x = Zone.point.x + math.random( Zone.radius / 2 * -1, Zone.radius / 2 ) ZonePos.y = Zone.point.z + math.random( Zone.radius / 2 * -1, Zone.radius / 2 ) - trace.i( self.ClassName, "Cargo Location = " .. ZonePos.x .. ", " .. ZonePos.y ) + self:T( "Cargo Location = " .. ZonePos.x .. ", " .. ZonePos.y ) --[[ -- This does not work in 1.5.2. @@ -898,8 +898,9 @@ trace.f( self.ClassName ) return self end + function CARGO_SLINGLOAD:IsNear( Client, LandingZone ) -trace.f( self.ClassName ) +self:T() local Near = false @@ -908,7 +909,7 @@ end function CARGO_SLINGLOAD:IsInLandingZone( Client, LandingZone ) -trace.f( self.ClassName ) +self:T() local Near = false @@ -923,9 +924,8 @@ trace.f( self.ClassName ) end - function CARGO_SLINGLOAD:OnBoard( Client, LandingZone, OnBoardSide ) -trace.f(self.ClassName ) +self:T() local Valid = true @@ -935,34 +935,28 @@ end function CARGO_SLINGLOAD:OnBoarded( Client, LandingZone ) -trace.f(self.ClassName ) +self:T() local OnBoarded = false local CargoStaticUnit = StaticObject.getByName( self.CargoName ) if CargoStaticUnit then if not routines.IsStaticInZones( CargoStaticUnit, LandingZone ) then - Onboarded = true + OnBoarded = true end end return OnBoarded end -function CARGO_SLINGLOAD:UnLoad( Client, TargetZoneName ) -trace.f( self.ClassName ) - trace.i( self.ClassName, 'self.CargoName = ' .. self.CargoName ) - trace.i( self.ClassName, 'self.CargoGroupName = ' .. self.CargoGroupName ) +function CARGO_SLINGLOAD:UnLoad( Client, TargetZoneName ) +self:T() + + self:T( 'self.CargoName = ' .. self.CargoName ) + self:T( 'self.CargoGroupName = ' .. self.CargoGroupName ) self:StatusUnLoaded() return Cargo end - ---[[-- - Internal Table to understand the form of the CARGO. - @table CARGO_TRANSPORT ---]] -CARGO_TRANSPORT = { UNIT = 1, SLING = 2, STATIC = 3, INVISIBLE = 4 } - diff --git a/Moose/Client.lua b/Moose/Client.lua index ed8994a53..8b152620f 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -44,10 +44,9 @@ CLIENT = { -- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) function CLIENT:New( ClientName, ClientBriefing ) -trace.f( self.ClassName, { ClientName, ClientBriefing } ) - - -- Arrange meta tables local self = BASE:Inherit( self, BASE:New() ) + self:T() + self.ClientName = ClientName self:AddBriefing( ClientBriefing ) self.MessageSwitch = true @@ -58,7 +57,7 @@ end --- 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. function CLIENT:Reset( ClientName ) -trace.f(self.ClassName) +self:T() self._Menus = {} end @@ -66,11 +65,11 @@ end -- This function is modified to deal with a couple of bugs in DCS 1.5.3 -- @treturn Group function CLIENT:ClientGroup() -trace.f(self.ClassName) +self:T() -- local ClientData = Group.getByName( self.ClientName ) -- if ClientData and ClientData:isExist() then --- trace.i( self.ClassName, self.ClientName .. " : group found!" ) +-- self:T( self.ClientName .. " : group found!" ) -- return ClientData -- else -- return nil @@ -78,33 +77,33 @@ trace.f(self.ClassName) local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - trace.i( self.ClassName, CoalitionData ) + self:T( { "CoalitionData:", CoalitionData } ) for UnitId, UnitData in pairs( CoalitionData ) do - trace.i( self.ClassName, UnitData ) + self:T( { "UnitData:", UnitData } ) if UnitData and UnitData:isExist() then local ClientGroup = Group.getByName( self.ClientName ) if ClientGroup then - trace.i( self.ClassName, "ClientGroup = " .. self.ClientName ) + self:T( "ClientGroup = " .. self.ClientName ) if ClientGroup:isExist() then if ClientGroup:getID() == UnitData:getGroup():getID() then - trace.i( self.ClassName, "Normal logic" ) - trace.i( self.ClassName, self.ClientName .. " : group found!" ) + 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) - trace.i( self.ClassName, "Bug 1.5 logic" ) + self:T( "Bug 1.5 logic" ) local ClientUnits = _Database.Groups[self.ClientName].Units - trace.i( self.ClassName, { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } ) + self:T( { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } ) for ClientUnitID, ClientUnitData in pairs( ClientUnits ) do - trace.i( self.ClassName, { tonumber(UnitData:getID()), ClientUnitData.unitId } ) + 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 - trace.i( self.ClassName, self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) + self:T( self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) return ClientGroup end end @@ -119,10 +118,10 @@ trace.f(self.ClassName) -- For non player clients local ClientGroup = Group.getByName( self.ClientName ) if ClientGroup then - trace.i( self.ClassName, "ClientGroup = " .. self.ClientName ) + self:T( "ClientGroup = " .. self.ClientName ) if ClientGroup:isExist() then - trace.i( self.ClassName, "Normal logic" ) - trace.i( self.ClassName, self.ClientName .. " : group found!" ) + self:T( "Normal logic" ) + self:T( self.ClientName .. " : group found!" ) return ClientGroup end end @@ -135,7 +134,7 @@ end function CLIENT:GetClientGroupID() -trace.f(self.ClassName) +self:T() ClientGroup = self:ClientGroup() @@ -150,10 +149,29 @@ trace.f(self.ClassName) 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() -trace.f(self.ClassName) +self:T() ClientGroup = self:ClientGroup() @@ -172,7 +190,7 @@ end --- Returns the Position of the @{CLIENT}. -- @treturn Position function CLIENT:ClientPosition() ---trace.f(self.ClassName) +--self:T() ClientGroupUnit = self:GetClientGroupUnit() @@ -188,7 +206,7 @@ end --- Transport defines that the Client is a Transport. -- @treturn CLIENT function CLIENT:Transport() -trace.f(self.ClassName) +self:T() self.ClientTransport = true return self @@ -198,7 +216,7 @@ end -- @tparam string ClientBriefing is the text defining the Mission briefing. -- @treturn CLIENT function CLIENT:AddBriefing( ClientBriefing ) -trace.f(self.ClassName) +self:T() self.ClientBriefing = ClientBriefing return self end @@ -206,14 +224,14 @@ end --- IsTransport returns if a Client is a transport. -- @treturn bool function CLIENT:IsTransport() -trace.f(self.ClassName) +self:T() return self.ClientTransport 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 ) +self:T() local CargoMsg = "" @@ -244,7 +262,7 @@ end -- @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. 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 self:GetClientGroupID() then diff --git a/Moose/DeployTask.lua b/Moose/DeployTask.lua index e27e29898..612f1f6ad 100644 --- a/Moose/DeployTask.lua +++ b/Moose/DeployTask.lua @@ -14,27 +14,25 @@ DEPLOYTASK = { -- @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( 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 if Valid then - Child.Name = 'Deploy Cargo' - 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 .. " " .. 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 ) + self.Name = 'Deploy Cargo' + 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." + self.CargoType = CargoType + self.GoalVerb = CargoType .. " " .. self.GoalVerb + self.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGEUNLOAD:New(), STAGEDONE:New() } + self.SetStage( self, 1 ) end - return Child + return self end function DEPLOYTASK:ToZone( LandingZone ) -trace.f(self.ClassName) +self:T() self.LandingZones.LandingZoneNames[LandingZone.CargoZoneName] = LandingZone.CargoZoneName self.LandingZones.LandingZones[LandingZone.CargoZoneName] = LandingZone @@ -44,7 +42,7 @@ end function DEPLOYTASK:InitCargo( InitCargos ) -trace.f( self.ClassName, { InitCargos } ) +self:T( { InitCargos } ) if type( InitCargos ) == "table" then self.Cargos.InitCargos = InitCargos @@ -52,13 +50,12 @@ trace.f( self.ClassName, { InitCargos } ) self.Cargos.InitCargos = { InitCargos } end - return self end function DEPLOYTASK:LoadCargo( LoadCargos ) -trace.f( self.ClassName, { LoadCargos } ) +self:T( { LoadCargos } ) if type( LoadCargos ) == "table" then self.Cargos.LoadCargos = LoadCargos @@ -73,7 +70,7 @@ 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. function DEPLOYTASK:SetCargoTargetZoneName( TargetZoneName ) -trace.f(self.ClassName) +self:T() local Valid = true @@ -88,7 +85,7 @@ trace.f(self.ClassName) end function DEPLOYTASK:AddCargoMenus( Client, Cargos, TransportRadius ) -trace.f( self.ClassName ) +self:T() local ClientGroupID = Client:GetClientGroupID() @@ -135,7 +132,7 @@ trace.f( self.ClassName ) end function DEPLOYTASK:RemoveCargoMenus( Client ) -trace.f(self.ClassName ) +self:T() local ClientGroupID = Client:GetClientGroupID() trace.i( self.ClassName, ClientGroupID ) diff --git a/Moose/Group.lua b/Moose/Group.lua index 9fa5977af..3506b79e0 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -24,6 +24,74 @@ trace.f( self.ClassName, _Group:getName() ) 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: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 } ) diff --git a/Moose/Mission.lua b/Moose/Mission.lua index 13d0ca400..3d699212f 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -243,11 +243,12 @@ function MISSION:ShowBriefing( Client ) if not Client.ClientBriefingShown then Client.ClientBriefingShown = true - Client:Message( '(Press the keys [LEFT ALT]+[B] to view the briefing pages. Browse through the graphical briefing.)\n' .. - self.MissionBriefing, 40, self.Name .. '/MissionBriefing', "Mission Command: Mission Briefing" ) + local Briefing = self.MissionBriefing if Client.ClientBriefing then - Client:Message( Client.ClientBriefing, 40, self.Name .. '/ClientBriefing', "Mission Command: Mission Briefing" ) + Briefing = Briefing .. "\n" .. Client.ClientBriefing end + Briefing = Briefing .. "\n (Press [LEFT ALT]+[B] to view the graphical documentation.)" + Client:Message( Briefing, 30, self.Name .. '/MissionBriefing', "Command: Mission Briefing" ) end return Client diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index 52479fa42..92100df64 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -16,30 +16,30 @@ PICKUPTASK = { -- @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( 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. - local Child = BASE:Inherit( self, TASK:New() ) + -- self holds the inherited instance of the PICKUPTASK Class to the BASE class. local Valid = true if Valid then - Child.Name = 'Pickup Cargo' - 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 .. " " .. Child.GoalVerb - Child.OnBoardSide = OnBoardSide - Child.IsLandingRequired = false -- required to decide whether the client needs to land or not - Child.IsSlingLoad = false -- Indicates whether the cargo is a sling load cargo - 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 ) + self.Name = 'Pickup Cargo' + 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." + self.CargoType = CargoType + self.GoalVerb = CargoType .. " " .. self.GoalVerb + self.OnBoardSide = OnBoardSide + self.IsLandingRequired = false -- required to decide whether the client needs to land or not + self.IsSlingLoad = false -- Indicates whether the cargo is a sling load cargo + self.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGELOAD:New(), STAGEDONE:New() } + self.SetStage( self, 1 ) end - return Child + return self end function PICKUPTASK:FromZone( LandingZone ) -trace.f(self.ClassName) +self:T() self.LandingZones.LandingZoneNames[LandingZone.CargoZoneName] = LandingZone.CargoZoneName self.LandingZones.LandingZones[LandingZone.CargoZoneName] = LandingZone @@ -48,7 +48,7 @@ trace.f(self.ClassName) end function PICKUPTASK:InitCargo( InitCargos ) -trace.f( self.ClassName, { InitCargos } ) +self:T( { InitCargos } ) if type( InitCargos ) == "table" then self.Cargos.InitCargos = InitCargos @@ -60,7 +60,7 @@ trace.f( self.ClassName, { InitCargos } ) end function PICKUPTASK:LoadCargo( LoadCargos ) -trace.f( self.ClassName, { LoadCargos } ) +self:T( { LoadCargos } ) if type( LoadCargos ) == "table" then self.Cargos.LoadCargos = LoadCargos @@ -72,11 +72,11 @@ trace.f( self.ClassName, { LoadCargos } ) end function PICKUPTASK:AddCargoMenus( Client, Cargos, TransportRadius ) -trace.f( self.ClassName ) +self:T() for CargoID, Cargo in pairs( Cargos ) do - trace.i( self.ClassName, { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } ) + self:T( { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } ) if Cargo:IsStatusNone() or ( Cargo:IsStatusLoaded() and Client ~= Cargo:IsLoadedInClient() ) then @@ -96,7 +96,7 @@ trace.f( self.ClassName ) self.TEXT[1] .. " " .. Cargo.CargoType, nil ) - trace.i( self.ClassName, 'Added PickupMenu: ' .. self.TEXT[1] .. " " .. Cargo.CargoType ) + self:T( 'Added PickupMenu: ' .. self.TEXT[1] .. " " .. Cargo.CargoType ) end if Client._Menus[Cargo.CargoType].PickupSubMenus == nil then @@ -110,7 +110,7 @@ trace.f( self.ClassName ) self.MenuAction, { ReferenceTask = self, CargoTask = Cargo } ) - trace.i( self.ClassName, 'Added PickupSubMenu' .. Cargo.CargoType .. ":" .. Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )" ) + self:T( 'Added PickupSubMenu' .. Cargo.CargoType .. ":" .. Cargo.CargoName .. " ( " .. Cargo.CargoWeight .. "kg )" ) end end end @@ -118,17 +118,17 @@ trace.f( self.ClassName ) end function PICKUPTASK:RemoveCargoMenus( Client ) -trace.f( self.ClassName ) +self:T() for MenuID, MenuData in pairs( Client._Menus ) do for SubMenuID, SubMenuData in pairs( MenuData.PickupSubMenus ) do missionCommands.removeItemForGroup( Client:GetClientGroupID(), SubMenuData ) - trace.i( self.ClassName, "Removed PickupSubMenu " ) + self:T( "Removed PickupSubMenu " ) SubMenuData = nil end if MenuData.PickupMenu then missionCommands.removeItemForGroup( Client:GetClientGroupID(), MenuData.PickupMenu ) - trace.i( self.ClassName, "Removed PickupMenu " ) + self:T( "Removed PickupMenu " ) MenuData.PickupMenu = nil end end @@ -138,7 +138,7 @@ end function PICKUPTASK:HasFailed( ClientDead ) -trace.f(self.ClassName) +self:T() local TaskHasFailed = self.TaskFailed return TaskHasFailed diff --git a/Moose/Routines.lua b/Moose/Routines.lua index a40a8c9df..bdcc7924f 100644 --- a/Moose/Routines.lua +++ b/Moose/Routines.lua @@ -48,53 +48,69 @@ 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 = {} + lookup_table = {} + + local function _Serialize( tbl ) - 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] = ']=' + if type(tbl) == 'table' then --function only works for tables! + + if lookup_table[tbl] then + return lookup_table[object] 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" + 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 - tbl_str[#tbl_str + 1] = routines.utils.oneLineSerialize(val) - tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it + env.info('unable to serialize value type ' .. routines.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind)) + env.info( debug.traceback() ) 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 - tbl_str[#tbl_str + 1] = '}' - return table.concat(tbl_str) - else - return tostring(tbl) end + + local objectreturn = _Serialize(tbl) + return objectreturn end --porting in Slmod's "safestring" basic serialize diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 0fdd5d521..343d6614b 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -236,6 +236,37 @@ trace.f( self.ClassName ) return self 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. -- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ... @@ -441,7 +472,42 @@ function SPAWN:GetLastIndex() end -function SPAWN:GetLastGroup() + +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() trace.f( self.ClassName ) local LastGroupName = self:SpawnGroupName( self:GetLastIndex() ) @@ -449,7 +515,6 @@ trace.f( self.ClassName ) return GROUP:New( Group.getByName( LastGroupName ) ) 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 diff --git a/Moose/Stage.lua b/Moose/Stage.lua index a9e8377aa..5b79bfd8a 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -27,13 +27,12 @@ STAGE = { function STAGE:New() -trace.f(self.ClassName) local self = BASE:Inherit( self, BASE:New() ) + self:T() return self end function STAGE:Execute( Mission, Client, Task ) -trace.f(self.ClassName) local Valid = true @@ -41,13 +40,10 @@ trace.f(self.ClassName) end function STAGE:Executing( Mission, Client, Task ) -trace.f(self.ClassName) end function STAGE:Validate( Mission, Client, Task ) -trace.f(self.ClassName) - local Valid = true return Valid @@ -63,24 +59,23 @@ STAGEBRIEF = { } function STAGEBRIEF:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGEBRIEF:Execute( Mission, Client, Task ) -trace.f(self.ClassName) local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) + self:T() Mission:ShowBriefing( Client ) self.StageBriefingTime = timer.getTime() return Valid end function STAGEBRIEF:Validate( Mission, Client, Task ) -trace.f(self.ClassName) local Valid = STAGE:Validate( Mission, Client, Task ) + self:T() if timer.getTime() - self.StageBriefingTime <= self.StageBriefingDuration then return 0 @@ -101,27 +96,26 @@ STAGESTART = { } function STAGESTART:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGESTART:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) if Task.TaskBriefing then - Client:Message( Task.TaskBriefing, 15, Mission.Name .. "/Stage", "Mission Command: Tasking" ) + Client:Message( Task.TaskBriefing, 30, Mission.Name .. "/Stage", "Mission Command: Tasking" ) else - Client:Message( 'Task ' .. Task.TaskNumber .. '.', 15, Mission.Name .. "/Stage", "Mission Command: Tasking" ) + Client:Message( 'Task ' .. Task.TaskNumber .. '.', 30, Mission.Name .. "/Stage", "Mission Command: Tasking" ) end self.StageStartTime = timer.getTime() return Valid end function STAGESTART:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = STAGE:Validate( Mission, Client, Task ) if timer.getTime() - self.StageStartTime <= self.StageStartDuration then @@ -140,15 +134,14 @@ STAGE_CARGO_LOAD = { } function STAGE_CARGO_LOAD:New() -trace.f(self.ClassName) - -- Arrange meta tables local self = BASE:Inherit( self, STAGE:New() ) + self:T() self.StageType = 'CLIENT' return self end function STAGE_CARGO_LOAD:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) for LoadCargoID, LoadCargo in pairs( Task.Cargos.LoadCargos ) do @@ -163,7 +156,7 @@ trace.f(self.ClassName) end function STAGE_CARGO_LOAD:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = STAGE:Validate( Mission, Client, Task ) return 1 @@ -175,26 +168,26 @@ STAGE_CARGO_INIT = { } function STAGE_CARGO_INIT:New() -trace.f(self.ClassName) - -- Arrange meta tables local self = BASE:Inherit( self, STAGE:New() ) + self:T() self.StageType = 'CLIENT' return self end function STAGE_CARGO_INIT:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) for InitLandingZoneID, InitLandingZone in pairs( Task.LandingZones.LandingZones ) do - trace.i( self.ClassName, InitLandingZone ) + self:T( InitLandingZone ) InitLandingZone:Spawn() end - - for InitCargoID, InitCargo in pairs( Task.Cargos.InitCargos ) do - trace.i( self.ClassName ) - InitCargo:Spawn() + + self:T( Task.Cargos.InitCargos ) + for InitCargoID, InitCargoData in pairs( Task.Cargos.InitCargos ) do + self:T( { InitCargoData } ) + InitCargoData:Spawn() end return Valid @@ -202,7 +195,7 @@ end function STAGE_CARGO_INIT:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = STAGE:Validate( Mission, Client, Task ) return 1 @@ -218,9 +211,8 @@ STAGEROUTE = { } function STAGEROUTE:New() -trace.f(self.ClassName) - -- Arrange meta tables local self = BASE:Inherit( self, STAGE:New() ) + self:T() self.StageType = 'CLIENT' self.MessageSwitch = true return self @@ -228,10 +220,11 @@ end function STAGEROUTE:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) local RouteMessage = "Fly to " + self:T( Task.LandingZones ) for LandingZoneID, LandingZoneName in pairs( Task.LandingZones.LandingZoneNames ) do RouteMessage = RouteMessage .. LandingZoneName .. ' at ' .. routines.getBRStringZone( { zone = LandingZoneName, ref = Client:GetClientGroupUnit():getPoint(), true, true } ) .. ' km. ' end @@ -245,11 +238,11 @@ trace.f(self.ClassName) end function STAGEROUTE:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() local Valid = STAGE:Validate( Mission, Client, Task ) -- check if the Client is in the landing zone - trace.i( self.ClassName, Task.LandingZones.LandingZoneNames ) + self:T( Task.LandingZones.LandingZoneNames ) Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones.LandingZoneNames ) if Task.CurrentLandingZoneName then @@ -279,15 +272,14 @@ STAGELANDING = { } function STAGELANDING:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGELANDING:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() Client:Message( "We have arrived at the landing zone.", self.MSG.TIME, Mission.Name .. "/StageArrived", "Co-Pilot: Arrived", 10 ) @@ -307,12 +299,12 @@ trace.f(self.ClassName) if Cargo.CargoType == Task.CargoType then if Cargo:IsLandingRequired() then - trace.i( self.ClassName, "Task for cargo " .. Cargo.CargoType .. " requires landing.") + self:T( "Task for cargo " .. Cargo.CargoType .. " requires landing.") Task.IsLandingRequired = true end if Cargo:IsSlingLoad() then - trace.i( self.ClassName, "Task for cargo " .. Cargo.CargoType .. " is a slingload.") + self:T( "Task for cargo " .. Cargo.CargoType .. " is a slingload.") Task.IsSlingLoad = true end @@ -337,13 +329,13 @@ trace.f(self.ClassName) end function STAGELANDING:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones.LandingZoneNames ) if Task.CurrentLandingZoneName then -- Client is in de landing zone. - trace.i( self.ClassName, Task.CurrentLandingZoneName ) + self:T( Task.CurrentLandingZoneName ) Task.CurrentLandingZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName].CargoZone Task.CurrentCargoZone = Task.LandingZones.LandingZones[Task.CurrentLandingZoneName] @@ -380,15 +372,14 @@ STAGELANDED = { } function STAGELANDED:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGELANDED:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() if Task.IsLandingRequired then Client:Message( 'We have landed within the landing zone. Use the radio menu (F10) to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType .. '.', @@ -404,17 +395,17 @@ end function STAGELANDED:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() if not routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then - trace.i( self.ClassName, "Client is not anymore in the landing zone, go back to stage Route, and remove cargo menus." ) + self:T( "Client is not anymore in the landing zone, go back to stage Route, and remove cargo menus." ) Task.Signalled = false Task:RemoveCargoMenus( Client ) return -2 end if Task.IsLandingRequired and Client:GetClientGroupUnit():inAir() then - trace.i( self.ClassName, "Client went back in the air. Go back to stage Landing." ) + self:T( "Client went back in the air. Go back to stage Landing." ) Task.Signalled = false return -1 end @@ -436,22 +427,21 @@ STAGEUNLOAD = { } function STAGEUNLOAD:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGEUNLOAD:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() 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) +self:T() env.info( 'STAGEUNLOAD:Executing() Task.Cargo.CargoName = ' .. Task.Cargo.CargoName ) local TargetZoneName @@ -471,7 +461,7 @@ trace.f(self.ClassName) end function STAGEUNLOAD:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() env.info( 'STAGEUNLOAD:Validate()' ) if routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then @@ -509,15 +499,14 @@ STAGELOAD = { } function STAGELOAD:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGELOAD:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() 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] .. '.', @@ -532,7 +521,7 @@ trace.f(self.ClassName) end function STAGELOAD:Executing( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() -- If the Cargo is ready to be loaded, load it into the Client. @@ -556,7 +545,7 @@ trace.f(self.ClassName) Client:Message( "Hook the " .. Task.CargoNames .. " onto the helicopter " .. Task.TEXT[3] .. " within the landing zone.", _TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.LOADING.1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" .. ":", 10 ) for CargoID, Cargo in pairs( CARGOS ) do - trace.i( self.ClassName, "Cargo.CargoName = " .. Cargo.CargoName ) + self:T( "Cargo.CargoName = " .. Cargo.CargoName ) if Cargo:IsSlingLoad() then local CargoStatic = StaticObject.getByName( Cargo.CargoStaticName ) @@ -575,7 +564,7 @@ trace.f(self.ClassName) break end else - trace.i( self.ClassName, "Cargo not found in the DCS simulator." ) + self:T( "Cargo not found in the DCS simulator." ) end end end @@ -584,9 +573,9 @@ trace.f(self.ClassName) end function STAGELOAD:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() - trace.i( self.ClassName, "Task.CurrentLandingZoneName = " .. Task.CurrentLandingZoneName ) + self:T( "Task.CurrentLandingZoneName = " .. Task.CurrentLandingZoneName ) if not Task.IsSlingLoad then if not routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.CurrentLandingZoneName ) then @@ -634,93 +623,6 @@ trace.f(self.ClassName) 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.CurrentLandingZoneName ) then - else - 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:GetClientGroupUnit(), 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 - end - end - end - - return 1 -end STAGEDONE = { ClassName = "STAGEDONE", @@ -729,20 +631,19 @@ STAGEDONE = { } function STAGEDONE:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'AI' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'AI' + return self end function STAGEDONE:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() end function STAGEDONE:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() Task:Done() @@ -756,22 +657,21 @@ STAGEARRIVE = { } function STAGEARRIVE:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'CLIENT' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'CLIENT' + return self end function STAGEARRIVE:Execute( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() 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) +self:T() Task.CurrentLandingZoneID = routines.IsUnitInZones( Client:GetClientGroupUnit(), Task.LandingZones ) if ( Task.CurrentLandingZoneID ) then @@ -791,11 +691,10 @@ STAGEGROUPSDESTROYED = { } function STAGEGROUPSDESTROYED:New() -trace.f(self.ClassName) - -- Arrange meta tables - local Child = BASE:Inherit( self, STAGE:New() ) - Child.StageType = 'AI' - return Child + local self = BASE:Inherit( self, STAGE:New() ) + self:T() + self.StageType = 'AI' + return self end --function STAGEGROUPSDESTROYED:Execute( Mission, Client, Task ) @@ -805,7 +704,7 @@ end --end function STAGEGROUPSDESTROYED:Validate( Mission, Client, Task ) -trace.f(self.ClassName) +self:T() if Task.MissionTask:IsGoalReached() then return 1 @@ -815,8 +714,8 @@ trace.f(self.ClassName) end function STAGEGROUPSDESTROYED:Execute( Mission, Client, Task ) -trace.f(self.ClassName) - trace.i( self.ClassName, { Task.ClassName, Task.Destroyed } ) +self:T() + self:T( { Task.ClassName, Task.Destroyed } ) --env.info( 'Event Table Task = ' .. tostring(Task) ) end diff --git a/Test Missions/MOOSE_Pickup_Test.lua b/Test Missions/MOOSE_Pickup_Test.lua new file mode 100644 index 000000000..dfe4ff840 --- /dev/null +++ b/Test Missions/MOOSE_Pickup_Test.lua @@ -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" ) diff --git a/Test Missions/MOOSE_Pickup_Test.miz b/Test Missions/MOOSE_Pickup_Test.miz new file mode 100644 index 0000000000000000000000000000000000000000..b200f5ef241f39b6320604682d1cbfd28ff9b002 GIT binary patch literal 27262 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 YD+h#r%_@JKEI)wtzN)5+jQ;%lAGN~Ga{vGU literal 0 HcmV?d00001 diff --git a/Test Missions/MOOSE_Spawn_Test.lua b/Test Missions/MOOSE_Spawn_Test.lua new file mode 100644 index 000000000..e0ef01e5b --- /dev/null +++ b/Test Missions/MOOSE_Spawn_Test.lua @@ -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 ) \ No newline at end of file diff --git a/Test Missions/MOOSE_Spawn_Test.miz b/Test Missions/MOOSE_Spawn_Test.miz new file mode 100644 index 0000000000000000000000000000000000000000..fc2b4022b002b9ec02fe7ccf0c4fd54e38d6ae18 GIT binary patch literal 19439 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 ORl!B@AmFnZd+H#rvL8DHB?RTzS65M zVuPokn?!EN${V-718W0}o76JcCGWNOw>7SS1xj6oB#M4(NA5QcLW6BT&YH%|Kflwv zWTX*}YPhq`cJsj*6}5}qLT!uhnc~V7KG)T(MLc*d{Dg>C?GBaq9rw+6Gn5v-xcjO_ zLQZ}Hu>?>Y;0AT^%060hYE|?E=CEW5m+%)qj+JDy*Kpyh670joKw(PV6!9{F4@HMw z$Nc!yH-L4&aRIV-Pu@|%cp}ne_K&Q={E@hI`=jNxUbc|E2C)PQ^}1!aUbvx00*}L( z=(i?Bzlu*F0U49l61d*}r00yVzE2|LZKW&q$JW`8X4}OSdiNhk-3+N|f(}O_;KY4FCxmRhGHCn`^+pS~6;(%gt zPUBX~hE=9`E|=g@zW!<6TURt=Rjrjjyt&jlXnR+r-HoLq7bLr&QJ|z+FT*eqWwJz? zb$&qKrQV8m2buwz97sHRH5Uq`+MPuIUX%Sy_lT%Q2>?jx0RSY|1VEsZAJW|?0EI*? zWpp4uNHObd?_yzImnx{JImEG-1@b6a!@!y_PrFj~#CTdd=A&4B((hRAb7CB*@(q{8 zzCC<}O1p)5`n&f9M&NS~8oiinWh97( zD86KHyT}!|*}BAm$LDUHiBvC4aztuhyvHIH<`nPzAn6_?$MICOBcvIU6UpL92X#F4 zfwzTDm|_?z8-0(3F`ONmamqDrDB>i)jP_^J$4FJrX0@L=5a9oQ`#bJz zv-}qd%&Q?@MVbq`JLvb9|c6E+$=HM)T+%*)9`k0X->pj{Z9_-M8o= zX#jR;a^P#-be>$H-&% zC;-5ax-M;{jr{$gi literal 0 HcmV?d00001 From c7d3e44a57d327269cb960a05683ff0c3a593e64 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 26 Feb 2016 10:15:03 +0100 Subject: [PATCH 29/51] Optimization of Cargo Loading behaviour Cargo loading is a bit complex. - Cargo should only respawn if it is not existing, and if it is not loading to another client. - The pickup menu should allow Cargo that was loading (but for some reason it did not load), to retry the loading process, but only when the Client is the Client of the active player. - When the menus are removed, any unit that was loading but not loaded, should become back to status none, but only when the Client is the Client of the active player. - Fixed a couple of errors with the Pickup-menu function. --- Moose/Cargo.lua | 36 +++++++++++++++++++++++++++++++++--- Moose/PickupTask.lua | 12 ++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index d113e70b1..7a3fb6a6d 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -308,10 +308,23 @@ self:T() end + +function CARGO:IsLoadingToClient() +self:T() + + if self:IsStatusLoading() then + return self.CargoClient + end + + return nil + +end + + function CARGO:IsLoadedInClient() self:T() - if self:IsStatusLoaded() or self:IsStatusLoading() then + if self:IsStatusLoaded() then return self.CargoClient end @@ -380,7 +393,7 @@ self:T() self.CargoClient = Client self.CargoStatus = CARGO.STATUS.LOADING - self:T( "Cargo loaded in Client: " .. CargoClient:GetClientGroupName() ) + self:T( "Cargo " .. self.CargoName .. " loading to Client: " .. CargoClient:GetClientGroupName() ) return self end @@ -390,6 +403,7 @@ self:T() self.CargoClient = Client self.CargoStatus = CARGO.STATUS.LOADED + self:T( "Cargo " .. self.CargoName .. " loaded in Client: " .. CargoClient:GetClientGroupName() ) return self end @@ -452,8 +466,24 @@ self:T() local SpawnCargo = true if self:IsStatusNone() then + local CargoGroup = Group.getByName( self.CargoSpawn:SpawnGroupName() ) + if CargoGroup then + SpawnCargo = false + end + + elseif self:IsStatusLoading() then - elseif self:IsStatusLoaded() or self:IsStatusLoading() then + local Client = self:IsLoadingToClient() + if Client and Client:ClientGroup() then + SpawnCargo = false + else + local CargoGroup = Group.getByName( self.CargoSpawn:SpawnGroupName() ) + if CargoGroup then + SpawnCargo = false + end + end + + elseif self:IsStatusLoaded() then local Client = self:IsLoadedInClient() if Client and Client:ClientGroup() then diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index 92100df64..d9423d73d 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -78,7 +78,8 @@ self:T() self:T( { Cargo.ClassName, Cargo.CargoName, Cargo.CargoType, Cargo:IsStatusNone(), Cargo:IsStatusLoaded(), Cargo:IsStatusLoading(), Cargo:IsStatusUnLoaded() } ) - if Cargo:IsStatusNone() or ( Cargo:IsStatusLoaded() and Client ~= Cargo:IsLoadedInClient() ) 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 @@ -132,7 +133,14 @@ self:T() MenuData.PickupMenu = nil 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 From a939220d201ca751e1aa9313aa94c87fb731e5c9 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 26 Feb 2016 19:44:27 +0100 Subject: [PATCH 30/51] Added functions for rescue mission. --- Moose/Base.lua | 2 +- Moose/Client.lua | 14 ++++++++---- Moose/Group.lua | 27 ++++++++++++++++++++-- Moose/Spawn.lua | 26 ++++++++++++++++++---- Moose/Unit.lua | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 11 deletions(-) create mode 100644 Moose/Unit.lua diff --git a/Moose/Base.lua b/Moose/Base.lua index 77724a7a1..520c951e3 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -7,7 +7,7 @@ Include.File( "Routines" ) BASE = { ClassName = "BASE", - TraceOn = false, + TraceOn = true, ClassID = 0, Events = {} } diff --git a/Moose/Client.lua b/Moose/Client.lua index 8b152620f..fc74435b1 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -65,7 +65,7 @@ end -- This function is modified to deal with a couple of bugs in DCS 1.5.3 -- @treturn Group function CLIENT:ClientGroup() -self:T() +--self:T() -- local ClientData = Group.getByName( self.ClientName ) -- if ClientData and ClientData:isExist() then @@ -77,9 +77,9 @@ self:T() 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 } ) + --self:T( { "CoalitionData:", CoalitionData } ) for UnitId, UnitData in pairs( CoalitionData ) do - self:T( { "UnitData:", UnitData } ) + --self:T( { "UnitData:", UnitData } ) if UnitData and UnitData:isExist() then local ClientGroup = Group.getByName( self.ClientName ) @@ -173,7 +173,7 @@ end function CLIENT:GetClientGroupUnit() self:T() - ClientGroup = self:ClientGroup() + local ClientGroup = self:ClientGroup() if ClientGroup then if ClientGroup:isExist() then @@ -186,6 +186,12 @@ self:T() return nil end +function CLIENT:GetUnit() + self:T() + + return UNIT:New( self:GetClientGroupUnit() ) +end + --- Returns the Position of the @{CLIENT}. -- @treturn Position diff --git a/Moose/Group.lua b/Moose/Group.lua index 3506b79e0..48971a3ba 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -4,6 +4,7 @@ Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Message" ) +Include.File( "Unit" ) GROUPS = {} @@ -13,9 +14,8 @@ GROUP = { } function GROUP:New( _Group ) -trace.f( self.ClassName, _Group:getName() ) - local self = BASE:Inherit( self, BASE:New() ) + self:T( _Group:getName() ) self._Group = _Group self.GroupName = _Group:getName() @@ -25,12 +25,25 @@ trace.f( self.ClassName, _Group:getName() ) 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 ) @@ -41,6 +54,13 @@ function GROUP:Destroy() 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() @@ -50,6 +70,7 @@ self:T() return IsAirResult end + function GROUP:AllOnGround() self:T() @@ -106,6 +127,7 @@ trace.f( self.ClassName, { self.GroupName, Point, Duration } ) return self end + function GROUP:Embarking( Point, Duration, EmbarkingGroup ) trace.f( self.ClassName, { self.GroupName, Point, Duration, EmbarkingGroup._Group } ) @@ -130,6 +152,7 @@ trace.f( self.ClassName, { self.GroupName, Point, Duration, EmbarkingGroup._Grou return self end + function GROUP:EmbarkToTransport( Point, Radius ) trace.f( self.ClassName, { self.GroupName, Point, Radius } ) diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 343d6614b..29ae2ea72 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -273,7 +273,7 @@ end -- Uses @{DATABASE} global object defined in MOOSE. -- @treturn SPAWN function SPAWN:Spawn( SpawnGroupName ) -trace.f( self.ClassName ) + self:T( { self.SpawnPrefix, SpawnGroupName } ) local SpawnTemplate = self:_Prepare( SpawnGroupName ) if self.SpawnStartPoint ~= 0 or self.SpawnEndPoint ~= 0 then SpawnTemplate = self:_RandomizeRoute( SpawnTemplate ) @@ -286,6 +286,24 @@ trace.f( self.ClassName ) 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.SpawnStartPoint ~= 0 or self.SpawnEndPoint ~= 0 then + SpawnTemplate = self:_RandomizeRoute( SpawnTemplate ) + end + _Database:Spawn( SpawnTemplate ) + if self.SpawnRepeat then + _Database:SetStatusGroup( SpawnTemplate.name, "ReSpawn" ) + end + return self +end + + --- Will Re-SPAWN a Group based on a given GroupName. The GroupName must be a group that is already alive within the DCSRTE and should have a Group Template defined in the ME (with Late Activation flag on). -- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ... -- @tparam string SpawnGroupName @@ -454,13 +472,13 @@ end -- @tparam number SpawnIndex is the number of the Group that is to be SPAWNed. -- @treturn string SpawnGroupName function SPAWN:SpawnGroupName( SpawnIndex ) -trace.f("Spawn", SpawnIndex ) + self:T( { self.SpawnPrefix, SpawnIndex } ) if SpawnIndex then - trace.i( self.ClassName, string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) ) + self:T( string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) ) return string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) else - trace.i( self.ClassName, self.SpawnPrefix ) + self:T( self.SpawnPrefix ) return self.SpawnPrefix end diff --git a/Moose/Unit.lua b/Moose/Unit.lua new file mode 100644 index 000000000..eb5eb9713 --- /dev/null +++ b/Moose/Unit.lua @@ -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 + From 6c456f20dbbea6787d101c31420040324e81d503 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 26 Feb 2016 20:14:24 +0100 Subject: [PATCH 31/51] Trace Off --- Moose/Base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 520c951e3..77724a7a1 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -7,7 +7,7 @@ Include.File( "Routines" ) BASE = { ClassName = "BASE", - TraceOn = true, + TraceOn = false, ClassID = 0, Events = {} } From 7ccdcb93859819b8b3230aef3abc493cc78282bf Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 26 Feb 2016 23:10:40 +0100 Subject: [PATCH 32/51] Needed to test isExist or nothing was spawned. --- Moose/Cargo.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 7a3fb6a6d..d2eb9e915 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -467,7 +467,7 @@ self:T() if self:IsStatusNone() then local CargoGroup = Group.getByName( self.CargoSpawn:SpawnGroupName() ) - if CargoGroup then + if CargoGroup and CargoGroup:isExist() then SpawnCargo = false end @@ -478,7 +478,7 @@ self:T() SpawnCargo = false else local CargoGroup = Group.getByName( self.CargoSpawn:SpawnGroupName() ) - if CargoGroup then + if CargoGroup and CargoGroup:isExist() then SpawnCargo = false end end From fe49fbb0a6d3d19e6db119cd68de6301ee5e3a4a Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Fri, 26 Feb 2016 23:36:26 +0100 Subject: [PATCH 33/51] bug fix --- Moose/Cargo.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index d2eb9e915..540e3ccb6 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -466,7 +466,7 @@ self:T() local SpawnCargo = true if self:IsStatusNone() then - local CargoGroup = Group.getByName( self.CargoSpawn:SpawnGroupName() ) + local CargoGroup = Group.getByName( self.CargoName ) if CargoGroup and CargoGroup:isExist() then SpawnCargo = false end @@ -477,7 +477,7 @@ self:T() if Client and Client:ClientGroup() then SpawnCargo = false else - local CargoGroup = Group.getByName( self.CargoSpawn:SpawnGroupName() ) + local CargoGroup = Group.getByName( self.CargoName ) if CargoGroup and CargoGroup:isExist() then SpawnCargo = false end From b3a68636f8f8835f4800b0d857bd018140ed5a7c Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sat, 27 Feb 2016 07:49:52 +0100 Subject: [PATCH 34/51] Fixing score problems dealing with 1.5.3 Client bug. --- Moose/Base.lua | 2 +- Moose/Cargo.lua | 2 +- Moose/Database.lua | 74 ++++++++++++++++++++++++++++++++------------ Moose/PickupTask.lua | 2 +- 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 77724a7a1..520c951e3 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -7,7 +7,7 @@ Include.File( "Routines" ) BASE = { ClassName = "BASE", - TraceOn = false, + TraceOn = true, ClassID = 0, Events = {} } diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index 540e3ccb6..d323390b7 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -477,7 +477,7 @@ self:T() if Client and Client:ClientGroup() then SpawnCargo = false else - local CargoGroup = Group.getByName( self.CargoName ) + local CargoGroup = Group.getByName( self.CargoName ) if CargoGroup and CargoGroup:isExist() then SpawnCargo = false end diff --git a/Moose/Database.lua b/Moose/Database.lua index 0f1fbe106..fedc72bc2 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -121,6 +121,7 @@ trace.f(self.ClassName ) return self end + --- 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: -- SpawnCountryID, SpawnCategoryID @@ -141,6 +142,7 @@ trace.f( self.ClassName, SpawnTemplate ) coalition.addGroup( SpawnCountryID, SpawnCategoryID, SpawnTemplate ) end + --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) trace.f( self.ClassName, Status ) @@ -148,6 +150,7 @@ trace.f( self.ClassName, Status ) self.Groups[GroupName].Status = Status end + --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) trace.f( self.ClassName, Status ) @@ -163,6 +166,7 @@ end --- Private -- @section Private + --- Registers new Group Templates within the DATABASE Object. function DATABASE:_RegisterGroup( GroupTemplate ) @@ -197,16 +201,20 @@ function DATABASE:_RegisterGroup( GroupTemplate ) end end + --- Events -- @section Events + --- Track DCSRTE DEAD or CRASH events for the internal scoring. function DATABASE:OnDeadOrCrash( event ) trace.f( self.ClassName, { event } ) - local TargetUnitName = nil - local TargetGroupName = nil - local TargetPlayerName = nil + local TargetUnit = nil + local TargetGroup = nil + local TargetUnitName = "" + local TargetGroupName = "" + local TargetPlayerName = "" local TargetCoalition = nil local TargetCategory = nil local TargetType = nil @@ -215,13 +223,19 @@ trace.f( self.ClassName, { event } ) local TargetUnitType = nil if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then - TargetUnitName = event.initiator:getName() - TargetGroupName = Unit.getGroup(event.initiator):getName() - TargetPlayerName = event.initiator:getPlayerName() + + TargetUnit = event.initiator + TargetGroup = Unit.getGroup( TargetUnit ) + + TargetUnitName = TargetUnit:getName() + if TargetGroup then + TargetGroupName = TargetGroup:getName() + end + TargetPlayerName = TargetUnit:getPlayerName() - TargetCoalition = Unit.getGroup(event.initiator):getCoalition() - TargetCategory = Unit.getGroup(event.initiator):getCategory() - TargetType = event.initiator:getTypeName() + TargetCoalition = TargetUnit:getCoalition() + TargetCategory = TargetUnit:getCategory() + TargetType = TargetUnit:getTypeName() TargetUnitCoalition = DATABASECoalition[TargetCoalition] TargetUnitCategory = DATABASECategory[TargetCategory] @@ -275,9 +289,11 @@ trace.f( self.ClassName, { event } ) end end + --- Scheduled -- @section Scheduled + --- Follows new players entering Clients within the DCSRTE. function DATABASE:_FollowPlayers() trace.scheduled( self.ClassName, "_FollowPlayers" ) @@ -296,9 +312,11 @@ trace.scheduled( self.ClassName, "_FollowPlayers" ) end end + --- Private -- @section Private + --- Add a new player entering a Unit. function DATABASE:_AddPlayerFromUnit( UnitData ) trace.f( self.ClassName, UnitData ) @@ -331,7 +349,7 @@ trace.f( self.ClassName, UnitData ) if self.Players[PlayerName].UnitCoalition ~= 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()] .. + MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. DATABASECoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. DATABASECoalition[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, @@ -346,6 +364,7 @@ trace.f( self.ClassName, UnitData ) end + --- Registers Scores the players completing a Mission Task. function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score ) trace.f( self.ClassName, { PlayerUnit, MissionName, Score } ) @@ -387,16 +406,18 @@ trace.f( self.ClassName, { PlayerUnit, MissionName, Score } ) end end + --- Events -- @section Events + function DATABASE:OnHit( event ) trace.f( self.ClassName, { event } ) local InitUnit = nil - local InitUnitName = nil - local InitGroupName = nil - local InitPlayerName = nil + local InitUnitName = "" + local InitGroupName = "" + local InitPlayerName = "" local InitCoalition = nil local InitCategory = nil @@ -406,9 +427,9 @@ trace.f( self.ClassName, { event } ) local InitUnitType = nil local TargetUnit = nil - local TargetUnitName = nil - local TargetGroupName = nil - local TargetPlayerName = nil + local TargetUnitName = "" + local TargetGroupName = "" + local TargetPlayerName = "" local TargetCoalition = nil local TargetCategory = nil @@ -422,9 +443,12 @@ trace.f( self.ClassName, { event } ) if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then InitUnit = event.initiator + InitGroup = Unit.getGroup( InitUnit ) InitUnitName = InitUnit:getName() - InitGroupName = Unit.getGroup(InitUnit):getName() + if InitGroup then + InitGroupName = InitGroup:getName() + end InitPlayerName = InitUnit:getPlayerName() InitCoalition = InitUnit:getCoalition() @@ -442,9 +466,12 @@ trace.f( self.ClassName, { event } ) if event.target and Object.getCategory(event.target) == Object.Category.UNIT then TargetUnit = event.target + TargetGroup = Unit.getGroup( TargetUnit ) TargetUnitName = TargetUnit:getName() - TargetGroupName = Unit.getGroup(TargetUnit):getName() + if TargetGroup then + TargetGroupName = TargetGroup:getName() + end TargetPlayerName = TargetUnit:getPlayerName() TargetCoalition = TargetUnit:getCoalition() @@ -503,6 +530,7 @@ trace.f( self.ClassName, { event } ) end end + function DATABASE:ReportScoreAll() env.info( "Hello World " ) @@ -615,17 +643,22 @@ env.info( "Hello World " ) end end + function DATABASE:ReportScorePlayer() end + function DATABASE:ScoreMenu() local ReportScore = SUBMENU:New( 'Scoring' ) local ReportAllScores = COMMANDMENU:New( 'Score All Active Players', ReportScore, DATABASE.ReportScoreAll, self ) local ReportPlayerScores = COMMANDMENU:New('Your Current Score', ReportScore, DATABASE.ReportScorePlayer, self ) end + + + -- File Logic for tracking the scores function DATABASE:SecondsToClock(sSeconds) @@ -641,6 +674,7 @@ local nSeconds = sSeconds end end + function DATABASE:ScoreOpen() if lfs then local fdir = lfs.writedir() .. [[Logs\]] .. "Player_Scores_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv" @@ -654,6 +688,7 @@ function DATABASE:ScoreOpen() end end + function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, PlayerUnitName, PlayerUnitCoalition, PlayerUnitCategory, PlayerUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) --write statistic information to file local ScoreTime = self:SecondsToClock(timer.getTime()) @@ -663,7 +698,7 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play local PlayerUnit = Unit.getByName( PlayerUnitName ) if PlayerUnit then - if not PlayerUnitCategory then +☺ if not PlayerUnitCategory then PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] end @@ -711,6 +746,7 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play self.StatFile:write( "\n" ) end end + function LogClose() if lfs then diff --git a/Moose/PickupTask.lua b/Moose/PickupTask.lua index d9423d73d..ad26b7c4d 100644 --- a/Moose/PickupTask.lua +++ b/Moose/PickupTask.lua @@ -134,7 +134,7 @@ self:T() end end - for CargoID, Cargo in pairs( Cargos ) do + 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() From a0c043a4659834a6b3768dc6fb16a0ad03768135 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sat, 27 Feb 2016 07:54:45 +0100 Subject: [PATCH 35/51] typo --- Moose/Database.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index fedc72bc2..4781cc110 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -698,7 +698,7 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play local PlayerUnit = Unit.getByName( PlayerUnitName ) if PlayerUnit then -☺ if not PlayerUnitCategory then + if not PlayerUnitCategory then PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] end From b51b102aa148099478b62f8e924da7b71c65aab6 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sat, 27 Feb 2016 08:02:58 +0100 Subject: [PATCH 36/51] bug fix with group logic --- Moose/Database.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index 4781cc110..2a0ed377a 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -228,7 +228,7 @@ trace.f( self.ClassName, { event } ) TargetGroup = Unit.getGroup( TargetUnit ) TargetUnitName = TargetUnit:getName() - if TargetGroup then + if TargetGroup and TargetGroup:isExist() then TargetGroupName = TargetGroup:getName() end TargetPlayerName = TargetUnit:getPlayerName() @@ -446,7 +446,7 @@ trace.f( self.ClassName, { event } ) InitGroup = Unit.getGroup( InitUnit ) InitUnitName = InitUnit:getName() - if InitGroup then + if InitGroup and InitGroup:isExist() then InitGroupName = InitGroup:getName() end InitPlayerName = InitUnit:getPlayerName() @@ -469,7 +469,7 @@ trace.f( self.ClassName, { event } ) TargetGroup = Unit.getGroup( TargetUnit ) TargetUnitName = TargetUnit:getName() - if TargetGroup then + if TargetGroup and TargetGroup:isExist() then TargetGroupName = TargetGroup:getName() end TargetPlayerName = TargetUnit:getPlayerName() From 4dbe5183229728fed0585dbce8535587f68d5766 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sat, 27 Feb 2016 11:48:31 +0100 Subject: [PATCH 37/51] Made the score system work again! --- Moose/Base.lua | 14 +++-- Moose/Database.lua | 133 +++++++++++++++++++++++++-------------------- 2 files changed, 83 insertions(+), 64 deletions(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 520c951e3..9c4addf0e 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -4,10 +4,14 @@ Include.File( "Routines" ) +_TraceOn = true +_TraceClass = { + DATABASE = true, + } + BASE = { ClassName = "BASE", - TraceOn = true, ClassID = 0, Events = {} } @@ -52,8 +56,8 @@ function BASE:Inherit( Child, Parent ) setmetatable( Child, Parent ) Child.__index = Child end - Child.ClassName = Child.ClassName .. '.' .. Child.ClassID - trace.i( Child.ClassName, 'Inherited from ' .. Parent.ClassName ) + --Child.ClassName = Child.ClassName .. '.' .. Child.ClassID + self:T( 'Inherited from ' .. Parent.ClassName ) return Child end @@ -204,7 +208,7 @@ end function BASE:T( Arguments ) - if BASE.TraceOn then + if _TraceOn and _TraceClass[self.ClassName] then local DebugInfo = debug.getinfo( 2, "nl" ) @@ -215,6 +219,6 @@ function BASE:T( Arguments ) local Line = DebugInfo.currentline - env.info( string.format( "%6d/%1s:%20s.%s\(%s\)" , Line, "T", self.ClassName, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d/%1s:%20s%05d.%s\(%s\)" , Line, "T", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end end diff --git a/Moose/Database.lua b/Moose/Database.lua index 2a0ed377a..da1c6af23 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -28,7 +28,7 @@ DATABASECategory = { [Unit.Category.AIRPLANE] = "Plane", [Unit.Category.HELICOPTER] = "Helicopter", - [Unit.Category.GROUND_UNIT] = "Ground", + [Unit.Category.GROUND_UNIT] = "Vehicle", [Unit.Category.SHIP] = "Ship", [Unit.Category.STRUCTURE] = "Structure", } @@ -40,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. -- DBObject = DATABASE:New() function DATABASE:New() -trace.f(self.ClassName ) -- Inherits from BASE local self = BASE:Inherit( self, BASE:New() ) @@ -127,9 +126,8 @@ end -- SpawnCountryID, SpawnCategoryID -- This method is used by the SPAWN class. 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 SpawnCategoryID = SpawnTemplate.SpawnCategoryID @@ -145,7 +143,7 @@ end --- Set a status to a Group within the Database, this to check crossing events for example. function DATABASE:SetStatusGroup( GroupName, Status ) -trace.f( self.ClassName, Status ) + self:T( Status ) self.Groups[GroupName].Status = Status end @@ -153,7 +151,7 @@ end --- Get a status to a Group within the Database, this to check crossing events for example. function DATABASE:GetStatusGroup( GroupName ) -trace.f( self.ClassName, Status ) + self:T( Status ) if self.Groups[GroupName] then return self.Groups[GroupName].Status @@ -182,7 +180,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units self.Groups[GroupTemplateName].Units = GroupTemplate.units - trace.i( self.ClassName, { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) + self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) for unit_num, UnitTemplate in pairs(GroupTemplate.units) do @@ -197,7 +195,7 @@ function DATABASE:_RegisterGroup( GroupTemplate ) self.ClientsByName[UnitTemplateName] = UnitTemplate self.ClientsByID[UnitTemplate.unitId] = UnitTemplate end - trace.i( self.ClassName, { "Unit", self.Units[UnitTemplateName].UnitName } ) + self:T( { "Unit", self.Units[UnitTemplateName].UnitName } ) end end @@ -208,7 +206,7 @@ end --- Track DCSRTE DEAD or CRASH events for the internal scoring. function DATABASE:OnDeadOrCrash( event ) -trace.f( self.ClassName, { event } ) + self:T( { event } ) local TargetUnit = nil local TargetGroup = nil @@ -226,6 +224,7 @@ trace.f( self.ClassName, { event } ) TargetUnit = event.initiator TargetGroup = Unit.getGroup( TargetUnit ) + TargetUnitDesc = TargetUnit:getDesc() TargetUnitName = TargetUnit:getName() if TargetGroup and TargetGroup:isExist() then @@ -234,25 +233,30 @@ trace.f( self.ClassName, { event } ) TargetPlayerName = TargetUnit:getPlayerName() TargetCoalition = TargetUnit:getCoalition() - TargetCategory = TargetUnit:getCategory() + --TargetCategory = TargetUnit:getCategory() + TargetCategory = TargetUnitDesc.category -- Workaround TargetType = TargetUnit:getTypeName() TargetUnitCoalition = DATABASECoalition[TargetCoalition] TargetUnitCategory = DATABASECategory[TargetCategory] TargetUnitType = TargetType - trace.i( self.ClassName, { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) + self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } ) end for PlayerName, PlayerData in pairs( self.Players ) do 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 - local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] - local InitUnitCategory = DATABASECategory[PlayerData.UnitCategory] - local InitUnitType = PlayerData.UnitType 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? if TargetCategory then @@ -268,17 +272,17 @@ trace.f( self.ClassName, { event } ) PlayerData.Kill[TargetCategory][TargetType].PenaltyKill = 0 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].PenaltyKill = PlayerData.Kill[TargetCategory][TargetType].PenaltyKill + 1 - MESSAGE:New( "Player '" .. PlayerName .. "' killed a target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. - PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Score: " .. PlayerData.Kill[TargetCategory][TargetType].Penalty, - "Game Status: Score", 20, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll() + MESSAGE:New( "Player '" .. PlayerName .. "' killed a friendly " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " .. + PlayerData.Kill[TargetCategory][TargetType].PenaltyKill .. " times. Penalty: -" .. PlayerData.Kill[TargetCategory][TargetType].Penalty, + "Game Status: Penalty", 20, "/PENALTY" .. PlayerName .. "/" .. InitUnitName ):ToAll() self:ScoreAdd( PlayerName, "KILL_PENALTY", 1, -125, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) else PlayerData.Kill[TargetCategory][TargetType].Score = PlayerData.Kill[TargetCategory][TargetType].Score + 10 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, "Game Status: Score", 20, "/SCORE" .. PlayerName .. "/" .. InitUnitName ):ToAll() self:ScoreAdd( PlayerName, "KILL_SCORE", 1, 10, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) @@ -296,7 +300,7 @@ end --- Follows new players entering Clients within the DCSRTE. function DATABASE:_FollowPlayers() -trace.scheduled( self.ClassName, "_FollowPlayers" ) + self:T( "_FollowPlayers" ) local ClientUnit = 0 local CoalitionsData = { AlivePlayersRed = coalition.getPlayers(coalition.side.RED), AlivePlayersBlue = coalition.getPlayers(coalition.side.BLUE) } @@ -305,7 +309,7 @@ trace.scheduled( self.ClassName, "_FollowPlayers" ) local AlivePlayerUnits = {} for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - trace.l( self.ClassName, "_FollowPlayers", CoalitionData ) + self:T( { "_FollowPlayers", CoalitionData } ) for UnitId, UnitData in pairs( CoalitionData ) do self:_AddPlayerFromUnit( UnitData ) end @@ -319,13 +323,17 @@ end --- Add a new player entering a Unit. function DATABASE:_AddPlayerFromUnit( UnitData ) -trace.f( self.ClassName, UnitData ) + self:T( UnitData ) if UnitData:isExist() then local UnitName = UnitData:getName() local PlayerName = UnitData:getPlayerName() + local UnitDesc = UnitData:getDesc() + local UnitCategory = UnitDesc.category + local UnitCoalition = UnitData:getCoalition() + local UnitTypeName = UnitData:getTypeName() - trace.i(self.ClassName, "Player : " .. PlayerName .. " Unit : " .. UnitName ) + self:T( { PlayerName, UnitName, UnitCategory, UnitCoalition, UnitTypeName } ) 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] = {} @@ -344,22 +352,22 @@ trace.f( self.ClassName, UnitData ) end if not self.Players[PlayerName].UnitCoalition then - self.Players[PlayerName].UnitCoalition = UnitData:getCoalition() + self.Players[PlayerName].UnitCoalition = UnitCoalition else - if self.Players[PlayerName].UnitCoalition ~= UnitData:getCoalition() then + 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[UnitData:getCoalition()] .. + 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[UnitData:getCoalition()], DATABASECategory[UnitData:getCategory()], UnitData:getTypeName() ) + UnitName, DATABASECoalition[UnitCoalition], DATABASECategory[UnitCategory], UnitData:getTypeName() ) end end self.Players[PlayerName].UnitName = UnitName - self.Players[PlayerName].UnitCoalition = UnitData:getCoalition() - self.Players[PlayerName].UnitCategory = UnitData:getCategory() - self.Players[PlayerName].UnitType = UnitData:getTypeName() + self.Players[PlayerName].UnitCoalition = UnitCoalition + self.Players[PlayerName].UnitCategory = UnitCategory + self.Players[PlayerName].UnitType = UnitTypeName end end @@ -367,7 +375,7 @@ end --- Registers Scores the players completing a Mission Task. function DATABASE:_AddMissionTaskScore( PlayerUnit, MissionName, Score ) -trace.f( self.ClassName, { PlayerUnit, MissionName, Score } ) + self:T( { PlayerUnit, MissionName, Score } ) local PlayerName = PlayerUnit:getPlayerName() @@ -377,8 +385,8 @@ trace.f( self.ClassName, { PlayerUnit, MissionName, Score } ) self.Players[PlayerName].Mission[MissionName].ScoreMission = 0 end - trace.i( self.ClassName, PlayerName ) - trace.i( self.ClassName, self.Players[PlayerName].Mission[MissionName] ) + self:T( PlayerName ) + self:T( self.Players[PlayerName].Mission[MissionName] ) self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score @@ -392,7 +400,7 @@ end --- Registers Mission Scores for possible multiple players that contributed in the Mission. 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 @@ -412,7 +420,7 @@ end function DATABASE:OnHit( event ) -trace.f( self.ClassName, { event } ) + self:T( { event } ) local InitUnit = nil local InitUnitName = "" @@ -444,6 +452,7 @@ trace.f( self.ClassName, { event } ) InitUnit = event.initiator InitGroup = Unit.getGroup( InitUnit ) + InitUnitDesc = InitUnit:getDesc() InitUnitName = InitUnit:getName() if InitGroup and InitGroup:isExist() then @@ -452,14 +461,16 @@ trace.f( self.ClassName, { event } ) InitPlayerName = InitUnit:getPlayerName() InitCoalition = InitUnit:getCoalition() - InitCategory = InitUnit:getCategory() + --InitCategory = InitUnit:getCategory() + InitCategory = InitUnitDesc.category -- Workaround InitType = InitUnit:getTypeName() InitUnitCoalition = DATABASECoalition[InitCoalition] InitUnitCategory = DATABASECategory[InitCategory] 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 @@ -467,6 +478,7 @@ trace.f( self.ClassName, { event } ) TargetUnit = event.target TargetGroup = Unit.getGroup( TargetUnit ) + TargetUnitDesc = TargetUnit:getDesc() TargetUnitName = TargetUnit:getName() if TargetGroup and TargetGroup:isExist() then @@ -475,14 +487,16 @@ trace.f( self.ClassName, { event } ) TargetPlayerName = TargetUnit:getPlayerName() TargetCoalition = TargetUnit:getCoalition() - TargetCategory = TargetUnit:getCategory() + --TargetCategory = TargetUnit:getCategory() + TargetCategory = TargetUnitDesc.category -- Workaround TargetType = TargetUnit:getTypeName() TargetUnitCoalition = DATABASECoalition[TargetCoalition] TargetUnitCategory = DATABASECategory[TargetCategory] 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 if InitPlayerName ~= nil then -- It is a player that is hitting something @@ -493,7 +507,7 @@ trace.f( self.ClassName, { event } ) self.Players[InitPlayerName].HitPlayers = self.Players[InitPlayerName].HitPlayers + 1 end - trace.i( self.ClassName, "Hitting Something" ) + self:T( "Hitting Something" ) -- What is he hitting? if TargetCategory then if not self.Players[InitPlayerName].Hit[TargetCategory] then @@ -511,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].PenaltyHit = self.Players[InitPlayerName].Hit[TargetCategory][TargetUnitName].PenaltyHit + 1 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() self:ScoreAdd( InitPlayerName, "HIT_PENALTY", 1, -25, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType ) else @@ -538,11 +552,11 @@ env.info( "Hello World " ) local ScoreMessage = "" local PlayerMessage = "" - trace.i( self.ClassName, "Score Report" ) + 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. - trace.i( self.ClassName, "Score Player: " .. PlayerName ) + self:T( "Score Player: " .. PlayerName ) -- Some variables local InitUnitCoalition = DATABASECoalition[PlayerData.UnitCoalition] @@ -558,21 +572,21 @@ env.info( "Hello World " ) local ScoreMessageHits = "" for CategoryID, CategoryName in pairs( DATABASECategory ) do - trace.i( self.ClassName, CategoryName ) + self:T( CategoryName ) if PlayerData.Hit[CategoryID] then local Score = 0 local ScoreHit = 0 local Penalty = 0 local PenaltyHit = 0 - trace.i( self.ClassName, "Hit scores exist for player " .. PlayerName ) + 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 score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreHit, PenaltyHit ) - trace.i( self.ClassName, ScoreMessageHit ) + 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 PlayerPenalty = PlayerPenalty + Penalty @@ -581,12 +595,12 @@ env.info( "Hello World " ) end end if ScoreMessageHits ~= "" then - ScoreMessage = ScoreMessage .. " Hits: " .. ScoreMessageHits .. " " + ScoreMessage = ScoreMessage .. "\n Hits: " .. ScoreMessageHits .. " " end local ScoreMessageKills = "" for CategoryID, CategoryName in pairs( DATABASECategory ) do - trace.i( self.ClassName, "Kill scores exist for player " .. PlayerName ) + self:T( "Kill scores exist for player " .. PlayerName ) if PlayerData.Kill[CategoryID] then local Score = 0 local ScoreKill = 0 @@ -600,8 +614,8 @@ env.info( "Hello World " ) PenaltyKill = PenaltyKill + UnitData.PenaltyKill end - local ScoreMessageKill = string.format( " %s = %d score(%d;-%d) hits(#%d;#-%d)", CategoryName, Score - Penalty, Score, Penalty, ScoreKill, PenaltyKill ) - trace.i( self.ClassName, ScoreMessageKill ) + 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 @@ -611,16 +625,16 @@ env.info( "Hello World " ) end end if ScoreMessageKills ~= "" then - ScoreMessage = ScoreMessage .. " Kills: " .. ScoreMessageKills .. " " + ScoreMessage = ScoreMessage .. "\n Kills: " .. ScoreMessageKills .. " " end local ScoreMessageCoalitionChangePenalties = "" 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 end if ScoreMessageCoalitionChangePenalties ~= "" then - ScoreMessage = ScoreMessage .. " Coalition: " .. ScoreMessageCoalitionChangePenalties .. " " + ScoreMessage = ScoreMessage .. "\n Coalition: " .. ScoreMessageCoalitionChangePenalties .. " " end local ScoreMessageMission = "" @@ -634,13 +648,13 @@ env.info( "Hello World " ) PlayerScore = PlayerScore + ScoreMission + ScoreTask if ScoreMessageMission ~= "" then - ScoreMessage = ScoreMessage .. " Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") " + ScoreMessage = ScoreMessage .. "\n Tasks: " .. ScoreTask .. " Mission: " .. ScoreMission .. " ( " .. ScoreMessageMission .. ") " end - PlayerMessage = string.format( " Player '%s' Score = %d ( %d Score, -%d Penalties ):", PlayerName, PlayerScore - PlayerPenalty, PlayerScore, PlayerPenalty ) - MESSAGE:New( PlayerMessage .. ScoreMessage, "Player Scores", 30, "/SCORE/" .. PlayerName ):ToAll() + 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 @@ -699,7 +713,8 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play if PlayerUnit then if not PlayerUnitCategory then - PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] + --PlayerUnitCategory = DATABASECategory[PlayerUnit:getCategory()] + PlayerUnitCategory = DATABASECategory[PlayerUnit:getDesc().category] end if not PlayerUnitCoalition then From b4602c93bee87924d5e484fd89eaba06744faa37 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sun, 28 Feb 2016 07:50:21 +0100 Subject: [PATCH 38/51] Dealing with Group Client bug in 1.5.3 --- Moose/DestroyBaseTask.lua | 51 ++++++++++++++++++++------------------- Moose/Sead.lua | 51 ++++++++++++++++++--------------------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/Moose/DestroyBaseTask.lua b/Moose/DestroyBaseTask.lua index 997e959a1..4ac7a245a 100644 --- a/Moose/DestroyBaseTask.lua +++ b/Moose/DestroyBaseTask.lua @@ -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}. -- @treturn DESTROYBASETASK function DESTROYBASETASK:New( DestroyGroupType, DestroyUnitType, DestroyGroupPrefixes, DestroyPercentage ) -trace.f(self.ClassName) - - -- Inheritance - local Child = BASE:Inherit( self, TASK:New() ) + local self = BASE:Inherit( self, TASK:New() ) + self:T() - Child.Name = 'Destroy' - Child.Destroyed = 0 - Child.DestroyGroupPrefixes = DestroyGroupPrefixes - Child.DestroyGroupType = DestroyGroupType - Child.DestroyUnitType = DestroyUnitType - Child.TaskBriefing = "Task: Destroy " .. DestroyGroupType .. "." - Child.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEGROUPSDESTROYED:New(), STAGEDONE:New() } - Child.SetStage( Child, 1 ) + self.Name = 'Destroy' + self.Destroyed = 0 + self.DestroyGroupPrefixes = DestroyGroupPrefixes + self.DestroyGroupType = DestroyGroupType + self.DestroyUnitType = DestroyUnitType + self.TaskBriefing = "Task: Destroy " .. DestroyGroupType .. "." + self.Stages = { STAGEBRIEF:New(), STAGESTART:New(), STAGEGROUPSDESTROYED:New(), STAGEDONE:New() } + 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) ) - return Child + return self end --- Handle the S_EVENT_DEAD events to validate the destruction of units for the task monitoring. -- @param event Event structure of DCS world. function DESTROYBASETASK:EventDead( event ) -trace.f( self.ClassName, { 'EventDead', event } ) + self:T( { 'EventDead', event } ) if event.initiator then - local DestroyGroup = Unit.getGroup( event.initiator ) - local DestroyGroupName = DestroyGroup:getName() local DestroyUnit = event.initiator 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 - trace.i( self.ClassName, DestroyGroupName ) - trace.i( self.ClassName, DestroyUnitName ) + self:T( DestroyGroupName ) + self:T( DestroyUnitName ) for DestroyGroupPrefixID, DestroyGroupPrefix in pairs( self.DestroyGroupPrefixes ) do - trace.i( self.ClassName, DestroyGroupPrefix ) + self:T( DestroyGroupPrefix ) 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 ) - trace.i( self.ClassName, UnitsDestroyed ) + self:T( UnitsDestroyed ) end end - trace.i( self.ClassName, { UnitsDestroyed } ) + self:T( { UnitsDestroyed } ) self:IncreaseGoalCount( UnitsDestroyed, self.GoalVerb ) end end @@ -73,7 +74,7 @@ end -- @param DestroyGroup Group structure describing the group to be evaluated. -- @param DestroyUnit Unit structure describing the Unit to be evaluated. function DESTROYBASETASK:ReportGoalProgress( DestroyGroup, DestroyUnit ) -trace.f(self.ClassName) +self:T() return 0 end diff --git a/Moose/Sead.lua b/Moose/Sead.lua index e9b2a31f3..c068491d7 100644 --- a/Moose/Sead.lua +++ b/Moose/Sead.lua @@ -30,51 +30,48 @@ SEAD = { -- -- 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' } ) function SEAD:New( SEADGroupPrefixes ) -trace.f(self.ClassName, SEADGroupPrefixes ) - - -- Arrange meta tables - local Child = BASE:Inherit( self, BASE:New() ) + local self = BASE:Inherit( self, BASE:New() ) + self:T( SEADGroupPrefixes ) if type( SEADGroupPrefixes ) == 'table' then for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do - Child.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix + self.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix end else - Child.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes + self.SEADGroupNames[SEADGroupPrefixes] = SEADGroupPrefixes end - Child.AddEvent( Child, world.event.S_EVENT_SHOT, Child.EventShot ) - Child.EnableEvents( Child ) + self.AddEvent( self, world.event.S_EVENT_SHOT, self.EventShot ) + self.EnableEvents( self ) - return Child + return self 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. -- @see SEAD function SEAD:EventShot( event ) -trace.f( self.ClassName, { event } ) +self:T( { event } ) - local _grp = Unit.getGroup(event.initiator)-- Identify the group that fired - local _groupname = _grp:getName() -- return the name of the group - local _unittable = {event.initiator:getName()} -- return the name of the units in the group - local _SEADmissile = event.weapon -- Identify the weapon fired - local _SEADmissileName = _SEADmissile:getTypeName() -- return weapon type - --trigger.action.outText( string.format("Alerte, depart missile " ..string.format(_SEADmissileName)), 20) --debug message + local SEADUnit = event.initiator + local SEADUnitName = SEADUnit:getName() + local SEADWeapon = event.weapon -- Identify the weapon fired + local SEADWeaponName = SEADWeapon:getTypeName() -- return weapon type + --trigger.action.outText( string.format("Alerte, depart missile " ..string.format(SEADWeaponName)), 20) --debug message -- Start of the 2nd loop - trace.i( self.ClassName, "Missile Launched = " .. _SEADmissileName ) - 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 + self:T( "Missile Launched = " .. SEADWeaponName ) + 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 _targetMim = Weapon.getTarget(_SEADmissile) -- Identify target + local _targetMim = Weapon.getTarget(SEADWeapon) -- Identify target local _targetMimname = Unit.getName(_targetMim) - local _targetMimgroup = Unit.getGroup(Weapon.getTarget(_SEADmissile)) + local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroupName = _targetMimgroup:getName() local _targetMimcont= _targetMimgroup:getController() local _targetskill = _Database.Units[_targetMimname].Template.skill - trace.i( self.ClassName, self.SEADGroupPrefixes ) - trace.i( self.ClassName, _targetMimgroupName ) + self:T( self.SEADGroupPrefixes ) + self:T( _targetMimgroupName ) local SEADGroupFound = false for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then SEADGroupFound = true - trace.i( self.ClassName, 'Group Found' ) + self:T( 'Group Found' ) break end end @@ -83,13 +80,13 @@ trace.f( self.ClassName, { event } ) local Skills = { "Average", "Good", "High", "Excellent" } _targetskill = Skills[ math.random(1,4) ] 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 (_evade > self.TargetSkill[_targetskill].Evade) then - trace.i( self.ClassName, string.format("Evading, target skill " ..string.format(_targetskill)) ) --debug message - local _targetMim = Weapon.getTarget(_SEADmissile) + self:T( string.format("Evading, target skill " ..string.format(_targetskill)) ) --debug message + local _targetMim = Weapon.getTarget(SEADWeapon) local _targetMimname = Unit.getName(_targetMim) - local _targetMimgroup = Unit.getGroup(Weapon.getTarget(_SEADmissile)) + local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimcont= _targetMimgroup:getController() routines.groupRandomDistSelf(_targetMimgroup,300,'Rank',250,20) -- move randomly local SuppressedGroups1 = {} -- unit suppressed radar off for a random time From 6bb392b331cd2940f096620c1a89c98469fa8c43 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sat, 27 Feb 2016 11:52:37 +0100 Subject: [PATCH 39/51] deactivated trace --- Moose/Base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 9c4addf0e..4e8bcca9a 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -4,7 +4,7 @@ Include.File( "Routines" ) -_TraceOn = true +_TraceOn = false _TraceClass = { DATABASE = true, } From d0bdf7b3c05b738e99d10ba10d23772d22803528 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sun, 28 Feb 2016 14:21:14 +0100 Subject: [PATCH 40/51] trace --- Moose/Base.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Moose/Base.lua b/Moose/Base.lua index 4e8bcca9a..9aa8bc867 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -7,6 +7,8 @@ Include.File( "Routines" ) _TraceOn = false _TraceClass = { DATABASE = true, + SEAD = true, + DESTROYBASETASK = true, } BASE = { From 1c9644bee732b474a516d71fa23cbf772e507a66 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sun, 28 Feb 2016 14:28:16 +0100 Subject: [PATCH 41/51] bug fix. forgot self. --- Moose/Cargo.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index d323390b7..3ff9617a8 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -403,7 +403,7 @@ self:T() self.CargoClient = Client self.CargoStatus = CARGO.STATUS.LOADED - self:T( "Cargo " .. self.CargoName .. " loaded in Client: " .. CargoClient:GetClientGroupName() ) + self:T( "Cargo " .. self.CargoName .. " loaded in Client: " .. self.CargoClient:GetClientGroupName() ) return self end From 8b556f1dcec325d7df2b75921a673ebe03445257 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Sun, 28 Feb 2016 15:38:36 +0100 Subject: [PATCH 42/51] trying to fix an error --- Moose/DestroyBaseTask.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/DestroyBaseTask.lua b/Moose/DestroyBaseTask.lua index 4ac7a245a..9e0555a21 100644 --- a/Moose/DestroyBaseTask.lua +++ b/Moose/DestroyBaseTask.lua @@ -45,7 +45,7 @@ end function DESTROYBASETASK:EventDead( event ) self:T( { 'EventDead', event } ) - if event.initiator then + if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then local DestroyUnit = event.initiator local DestroyUnitName = DestroyUnit:getName() local DestroyGroup = Unit.getGroup( DestroyUnit ) From bcd066217b59adb559f898fc1fa9e729504117a1 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Mon, 29 Feb 2016 09:49:14 +0100 Subject: [PATCH 43/51] Fixed bugs --- Moose/Base.lua | 1 + Moose/Movement.lua | 91 ++++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 9aa8bc867..a23455b7d 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -9,6 +9,7 @@ _TraceClass = { DATABASE = true, SEAD = true, DESTROYBASETASK = true, + MOVEMENT = true, } BASE = { diff --git a/Moose/Movement.lua b/Moose/Movement.lua index 69f6d1971..3ef4e4638 100644 --- a/Moose/Movement.lua +++ b/Moose/Movement.lua @@ -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 ) function MOVEMENT:New( MovePrefixes, MoveMaximum ) -trace.f(self.ClassName, { MovePrefixes, MoveMaximum } ) - - -- Inherits from BASE - local Child = BASE:Inherit( self, BASE:New() ) + local self = BASE:Inherit( self, BASE:New() ) + self:T( { MovePrefixes, MoveMaximum } ) if type( MovePrefixes ) == 'table' then - Child.MovePrefixes = MovePrefixes + self.MovePrefixes = MovePrefixes else - Child.MovePrefixes = { MovePrefixes } + self.MovePrefixes = { MovePrefixes } end - Child.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... - Child.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.MoveCount = 0 -- The internal counter of the amount of Moveing the has happened since MoveStart. + self.MoveMaximum = MoveMaximum -- Contains the Maximum amount of units that are allowed to move... + self.AliveUnits = 0 -- Contains the counter how many units are currently alive + 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 ) - Child.AddEvent( Child, world.event.S_EVENT_DEAD, Child.OnDeadOrCrash ) - Child.AddEvent( Child, world.event.S_EVENT_CRASH, Child.OnDeadOrCrash ) + self.AddEvent( self, world.event.S_EVENT_BIRTH, self.OnBirth ) + self.AddEvent( self, world.event.S_EVENT_DEAD, self.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 --- Call this function to start the MOVEMENT scheduling. function MOVEMENT:ScheduleStart() -trace.f( self.ClassName ) +self:T() self.MoveFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, 120 ) end --- Call this function to stop the MOVEMENT scheduling. -- @todo need to implement it ... Forgot. function MOVEMENT:ScheduleStop() -trace.f( self.ClassName ) +self:T() end --- Captures the birth events when new Units were spawned. -- @todo This method should become obsolete. The new @{DATABASE} class will handle the collection administration. 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 event.initiator and event.initiator:getName() then - trace.l(self.ClassName, "OnBirth", "Birth object : " .. event.initiator:getName() ) - local GroupData = Unit.getGroup(event.initiator) - if GroupData and GroupData:isExist() then - local EventGroupName = GroupData:getName() + if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then + local MovementUnit = event.initiator + local MovementUnitName = MovementUnit:getName() + self:T( "Birth object : " .. MovementUnitName ) + local MovementGroup = MovementUnit:getGroup() + if MovementGroup and MovementGroup:isExist() then + local MovementGroupName = MovementGroup:getName() 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.MoveGroups[EventGroupName] = EventGroupName - trace.l(self.ClassName, "OnBirth", self.AliveUnits ) + self.MoveUnits[MovementUnitName] = MovementGroupName + self:T( self.AliveUnits ) end end end @@ -86,16 +86,17 @@ end --- 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. function MOVEMENT:OnDeadOrCrash( event ) -trace.f( self.ClassName, { event } ) +self:T( { event } ) - if event.initiator and event.initiator:getName() then - trace.l( self.ClassName, "OnDeadOrCrash", "Dead object : " .. event.initiator:getName() ) - local EventGroupName = Unit.getGroup(event.initiator):getName() + if event.initiator and Object.getCategory(event.initiator) == Object.Category.UNIT then + local MovementUnit = event.initiator + local MovementUnitName = MovementUnit:getName() + self:T( "Dead object : " .. MovementUnitName ) 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.MoveGroups[EventGroupName] = nil - trace.l( self.ClassName, "OnDeadOrCrash", self.AliveUnits ) + self.MoveUnits[MovementUnitName] = nil + self:T( self.AliveUnits ) 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. 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 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 - local MoveGroup = Group.getByName( MoveGroupName ) - if MoveGroup then + for MovementUnitName, MovementGroupName in pairs( self.MoveUnits ) do + local MovementGroup = Group.getByName( MovementGroupName ) + if MovementGroup and MovementGroup:isExist() then local MoveOrStop = math.random( 1, 100 ) - trace.l( self.ClassName, '_Scheduler', 'MoveOrStop = ' .. MoveOrStop ) + self:T( 'MoveOrStop = ' .. MoveOrStop ) if MoveOrStop <= MoveProbability then - trace.l( self.ClassName, '_Scheduler', 'Group continues moving = ' .. MoveGroupName ) - trigger.action.groupContinueMoving( MoveGroup ) + self:T( 'Group continues moving = ' .. MovementGroupName ) + trigger.action.groupContinueMoving( MovementGroup ) else - trace.l( self.ClassName, '_Scheduler', 'Group stops moving = ' .. MoveGroupName ) - trigger.action.groupStopMoving( MoveGroup ) + self:T( 'Group stops moving = ' .. MovementGroupName ) + trigger.action.groupStopMoving( MovementGroup ) end + else + self.MoveUnits[MovementUnitName] = nil end end end From d458355c582b4aeccfd1e9b1c40db81c7e1e75df Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Mon, 29 Feb 2016 13:44:39 +0100 Subject: [PATCH 44/51] Optimizations and added RU Rescue mission --- Moose/Base.lua | 9 ++-- Moose/Spawn.lua | 109 ++++++++++++++++++++++++++---------------------- 2 files changed, 63 insertions(+), 55 deletions(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index a23455b7d..905db03bf 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -6,10 +6,11 @@ Include.File( "Routines" ) _TraceOn = false _TraceClass = { - DATABASE = true, - SEAD = true, - DESTROYBASETASK = true, - MOVEMENT = true, + --DATABASE = true, + --SEAD = true, + --DESTROYBASETASK = true, + --MOVEMENT = true, + SPAWN = true, } BASE = { diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 29ae2ea72..28454a43f 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -27,10 +27,8 @@ SPAWN = { -- -- NATO helicopters engaging in the battle field. -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ) function SPAWN:New( SpawnPrefix ) -trace.f(self.ClassName, SpawnPrefix) - - -- Inherits from BASE local self = BASE:Inherit( self, BASE:New() ) + self:T( SpawnPrefix) local TemplateGroup = Group.getByName( SpawnPrefix ) if TemplateGroup then @@ -69,7 +67,7 @@ end -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):RandomizeRoute( 2, 2, 2000 ) 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.SpawnEndPoint = SpawnEndPoint -- When the spawning occurs, randomize the route points till SpawnEndPoint. @@ -93,7 +91,7 @@ end -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 ) 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.SpawnSetTimer = 0 -- The internal timer value when a scheduled spawning of SpawnPrefix occurs. @@ -107,7 +105,7 @@ trace.f( self.ClassName, { SpawnTime, SpawnTimeVariation } ) self:ScheduleStart() end - trace.i( self.ClassName, { self.SpawnLowTimer, self.SpawnHighTimer } ) + self:T( { self.SpawnLowTimer, self.SpawnHighTimer } ) return self end @@ -115,7 +113,7 @@ end --- Will start the SPAWNing timers. -- This function is called automatically when @{Schedule} is called. function SPAWN:ScheduleStart() -trace.f( self.ClassName ) +self:T() --local ClientUnit = #AlivePlayerUnits() @@ -132,7 +130,7 @@ end --- Will stop the scheduled SPAWNing activity. function SPAWN:ScheduleStop() -trace.f( self.ClassName ) +self:T() self.SpawnScheduled = false end @@ -150,7 +148,7 @@ end -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Limit( 2, 24 ) 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.SpawnMaxGroups = SpawnMaxGroups -- The maximum amount of groups that can be spawned. @@ -177,7 +175,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 ) function SPAWN:RandomizeTemplate( SpawnPrefixTable ) -trace.f( self.ClassName, { SpawnPrefix, SpawnPrefixTable } ) +self:T( { SpawnPrefix, SpawnPrefixTable } ) self.SpawnPrefixTable = SpawnPrefixTable @@ -194,7 +192,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() function SPAWN:Repeat() -trace.f( self.ClassName ) +self:T() self.SpawnRepeat = true self.RepeatOnEngineShutDown = false @@ -213,7 +211,7 @@ end -- @see Repeat function SPAWN:RepeatOnLanding() -trace.f( self.ClassName ) +self:T() self:Repeat() self.RepeatOnEngineShutDown = false @@ -227,7 +225,7 @@ end -- @see Repeat function SPAWN:RepeatOnEngineShutDown() -trace.f( self.ClassName ) +self:T() self:Repeat() self.RepeatOnEngineShutDown = true @@ -310,7 +308,7 @@ end -- @treturn SPAWN -- Uses _Database global object defined in MOOSE. function SPAWN:ReSpawn( SpawnGroupName ) -trace.f( self.ClassName, { SpawnGroupName } ) +self:T( { SpawnGroupName } ) local SpawnGroup = Group.getByName( SpawnGroupName ) if SpawnGroup then @@ -332,7 +330,7 @@ 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. -- @treturn SPAWN function SPAWN:SpawnUncontrolled() -trace.f( self.ClassName ) +self:T() self.UnControlled = true @@ -354,7 +352,7 @@ end -- @tparam string NewGroupName (forgot this). -- @tparam bool LateActivate (optional) does the SPAWNing with Lateactivation on. function SPAWN:FromHost( HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate ) -trace.f( self.ClassName, { HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate } ) +self:T( { HostUnit, OuterRadius, InnerRadius, NewGroupName, LateActivate } ) local SpawnTemplate @@ -375,7 +373,7 @@ trace.f( self.ClassName, { HostUnit, OuterRadius, InnerRadius, NewGroupName, Lat SpawnTemplate = self:_RandomizeRoute( SpawnTemplate ) local RouteCount = table.getn( SpawnTemplate.route.points ) - trace.i( self.ClassName, "RouteCount = " .. RouteCount ) + self:T( "RouteCount = " .. RouteCount ) local UnitDeployPosition = HostUnit:getPoint() for PointID, Point in pairs( SpawnTemplate.route.points ) do @@ -389,7 +387,7 @@ trace.f( self.ClassName, { HostUnit, OuterRadius, InnerRadius, NewGroupName, Lat local SpawnPos = routines.getRandPointInCircle( UnitDeployPosition, OuterRadius, InnerRadius ) 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 ) + self:T( 'SpawnTemplate.units['..v..'].x = ' .. SpawnTemplate.units[v].x .. ', SpawnTemplate.units['..v..'].y = ' .. SpawnTemplate.units[v].y ) end _Database:Spawn( SpawnTemplate ) @@ -406,7 +404,7 @@ end -- @tparam string NewGroupName (forgot this). -- @tparam bool LateActivate (optional) does the SPAWNing with Lateactivation on. function SPAWN:FromCarrier( CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate ) -trace.f( self.ClassName, { CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate } ) +self:T( { CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate } ) local SpawnTemplate @@ -432,7 +430,7 @@ trace.f( self.ClassName, { CarrierUnit, TargetZonePrefix, NewGroupName, LateActi TargetZonePos.z = TargetZone.point.z + math.random(TargetZone.radius / 2 * -1, TargetZone.radius / 2 ) local RouteCount = table.getn( SpawnTemplate.route.points ) - trace.i( self.ClassName, "RouteCount = " .. RouteCount ) + self:T( "RouteCount = " .. RouteCount ) local UnitDeployPosition = CarrierUnit:getPosition().p SpawnTemplate.route.points[1].x = UnitDeployPosition.x - 50 @@ -448,21 +446,19 @@ trace.f( self.ClassName, { CarrierUnit, TargetZonePrefix, NewGroupName, LateActi 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 ) + 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 - trace.i( self.ClassName, 'SpawnTemplate.units['..v..'].x = ' .. SpawnTemplate.units[v].x .. ', SpawnTemplate.units['..v..'].y = ' .. SpawnTemplate.units[v].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 - - trace.r( self.ClassName, "" ) + end return SpawnTemplate end @@ -484,6 +480,17 @@ function SPAWN:SpawnGroupName( SpawnIndex ) 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 @@ -526,7 +533,7 @@ self:T() end function SPAWN:GetLastAliveGroup() -trace.f( self.ClassName ) +self:T() local LastGroupName = self:SpawnGroupName( self:GetLastIndex() ) @@ -537,7 +544,7 @@ end -- @tparam string ZonePrefix is the name of the zone where the Group is to be SPAWNed. -- @treturn SpawnTemplate function SPAWN:InZone( ZonePrefix, SpawnGroupName ) -trace.f("Spawn", ZonePrefix ) +self:T( ZonePrefix ) local SpawnTemplate @@ -608,7 +615,7 @@ end --- 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. function SPAWN:_GetTemplate( SpawnPrefix ) -trace.f( self.ClassName, SpawnPrefix ) +self:T( SpawnPrefix ) local SpawnTemplate = nil @@ -622,13 +629,13 @@ trace.f( self.ClassName, SpawnPrefix ) SpawnTemplate.SpawnCategoryID = self:_GetGroupCategoryID( SpawnPrefix ) SpawnTemplate.SpawnCountryID = self:_GetGroupCountryID( SpawnPrefix ) - trace.r( self.ClassName, "", { SpawnTemplate } ) + self:T( { SpawnTemplate } ) return SpawnTemplate end --- Prepares the new Group Template before Spawning. function SPAWN:_Prepare( SpawnGroupName ) -trace.f( self.ClassName ) +self:T() local SpawnCount local SpawnUnits @@ -675,13 +682,13 @@ trace.f( self.ClassName ) SpawnTemplate.units[u].y = SpawnTemplate.route.points[1].y + math.random( -50, 50 ) end - trace.r( self.ClassName, "", SpawnTemplate.name ) + self:T( SpawnTemplate.name ) return SpawnTemplate end --- Will randomize the route of the Group Template. function SPAWN:_RandomizeRoute( SpawnTemplate ) -trace.f( self.ClassName, SpawnTemplate.name ) +self:T( SpawnTemplate.name ) if self.SpawnStartPoint and self.SpawnEndPoint then local RouteCount = table.getn( SpawnTemplate.route.points ) @@ -690,11 +697,11 @@ trace.f( self.ClassName, SpawnTemplate.name ) SpawnTemplate.route.points[t].y = SpawnTemplate.route.points[t].y + math.random( self.SpawnRadius * -1, self.SpawnRadius ) SpawnTemplate.route.points[t].alt = 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 - trace.r( self.ClassName, "", SpawnTemplate.name ) + self:T( SpawnTemplate.name ) return SpawnTemplate end @@ -704,16 +711,16 @@ end --- Obscolete -- @todo Need to delete this... _Database does this now ... 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 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(), ".*#" ) if EventPrefix == self.SpawnPrefix .. '#' then --MessageToAll( "Mission command: unit " .. SpawnPrefix .. " spawned." , 5, EventPrefix .. '/Event') self.AliveUnits = self.AliveUnits + 1 - trace.l(self.ClassName, "OnBirth", self.AliveUnits ) + self:T( self.AliveUnits ) end end end @@ -723,17 +730,17 @@ end --- Obscolete -- @todo Need to delete this... _Database does this now ... function SPAWN:OnDeadOrCrash( event ) -trace.f( self.ClassName, { event } ) +self:T( { event } ) 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(), ".*#" ) if EventPrefix == self.SpawnPrefix .. '#' then -- local DestroyedUnit = Unit.getByName( EventPrefix ) -- if DestroyedUnit and DestroyedUnit.getLife() <= 1.0 then --MessageToAll( "Mission command: unit " .. SpawnPrefix .. " crashed." , 5, EventPrefix .. '/Event') self.AliveUnits = self.AliveUnits - 1 - trace.l( self.ClassName, "OnDeadOrCrash", self.AliveUnits ) + self:T( self.AliveUnits ) -- end end end @@ -743,17 +750,17 @@ end -- This is needed to ensure that Re-SPAWNing is only done for landed AIR Groups. -- @todo Need to test for AIR Groups only... function SPAWN:OnLand( event ) -trace.f( self.ClassName, { event } ) +self:T( { event } ) 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(), ".*#" ) if EventPrefix == self.SpawnPrefix .. '#' then self.Landed = true - trace.l( self.ClassName, "OnLand", "self.Landed = true" ) + self:T( "self.Landed = true" ) if self.Landed and self.RepeatOnLanding then local SpawnGroupName = Unit.getGroup(event.initiator):getName() - trace.l( self.ClassName, "OnLand", "ReSpawn " .. SpawnGroupName ) + self:T( "ReSpawn " .. SpawnGroupName ) self:ReSpawn( SpawnGroupName ) end end @@ -764,13 +771,13 @@ end -- This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups. -- @todo Need to test for AIR Groups only... function SPAWN:OnTakeOff( event ) -trace.f( self.ClassName, { event } ) +self:T( { event } ) 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(), ".*#" ) if EventPrefix == self.SpawnPrefix .. '#' then - trace.l( self.ClassName, "OnTakeOff", "self.Landed = false" ) + self:T( "self.Landed = false" ) self.Landed = false end end @@ -783,15 +790,15 @@ end -- @see OnLand -- @todo Need to test for AIR Groups only... function SPAWN:OnEngineShutDown( event ) -trace.f( self.ClassName, { event } ) +self:T( { event } ) 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(), ".*#" ) if EventPrefix == self.SpawnPrefix .. '#' then if self.Landed and self.RepeatOnEngineShutDown then local SpawnGroupName = Unit.getGroup(event.initiator):getName() - trace.l( self.ClassName, "OnEngineShutDown", "ReSpawn " .. SpawnGroupName ) + self:T( "ReSpawn " .. SpawnGroupName ) self:ReSpawn( SpawnGroupName ) end end @@ -804,7 +811,7 @@ end --- This function is called automatically by the Spawning scheduler. -- It is the internal worker method SPAWNing new Groups on the defined time intervals. function SPAWN:_Scheduler() -trace.l( self.ClassName, '_Scheduler', self.SpawnPrefix ) +self:T( self.SpawnPrefix ) if self.SpawnInit or self.SpawnCurrentTimer == self.SpawnSetTimer then -- Validate if there are still groups left in the batch... From d1fac8b8ebbc4026a227af16a2f18d19b3136d7b Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Mon, 29 Feb 2016 14:37:47 +0100 Subject: [PATCH 45/51] Fixed bug with randomization --- Moose/Spawn.lua | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 28454a43f..97ee2b0af 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -41,6 +41,7 @@ function SPAWN:New( SpawnPrefix ) 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.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned. + self.SpawnRandomize = false else error( "SPAWN:New: There is no group declared in the mission editor with SpawnPrefix = '" .. SpawnPrefix .. "'" ) end @@ -72,6 +73,7 @@ self:T( { SpawnStartPoint, SpawnEndPoint, SpawnRadius } ) 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.SpawnRadius = SpawnRadius -- The Radius of randomization of the route points from SpawnStartPoint till SpawnEndPoint. + self.SpawnRandomize = true return self end @@ -273,7 +275,7 @@ end function SPAWN:Spawn( SpawnGroupName ) self:T( { self.SpawnPrefix, SpawnGroupName } ) 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 ) @@ -291,7 +293,7 @@ end function SPAWN:SpawnWithIndex( SpawnIndex ) self:T( { self.SpawnPrefix, SpawnIndex } ) local SpawnTemplate = self:_Prepare( self:SpawnGroupName( SpawnIndex ) ) - if self.SpawnStartPoint ~= 0 or self.SpawnEndPoint ~= 0 then + if self.SpawnRandomize then SpawnTemplate = self:_RandomizeRoute( SpawnTemplate ) end _Database:Spawn( SpawnTemplate ) @@ -438,7 +440,7 @@ self:T( { CarrierUnit, TargetZonePrefix, NewGroupName, LateActivate } ) SpawnTemplate.route.points[1].alt = nil SpawnTemplate.route.points[1].alt_type = nil - if SpawnStartPoint ~= 0 and SpawnEndPoint ~= 0 then + if self.SpawnRandomize then SpawnTemplate.route.points[RouteCount].x = TargetZonePos.x SpawnTemplate.route.points[RouteCount].y = TargetZonePos.z else @@ -690,7 +692,7 @@ end function SPAWN:_RandomizeRoute( SpawnTemplate ) self:T( SpawnTemplate.name ) - if self.SpawnStartPoint and self.SpawnEndPoint then + if self.SpawnRandomize then local RouteCount = table.getn( SpawnTemplate.route.points ) for t = self.SpawnStartPoint, RouteCount - self.SpawnEndPoint do SpawnTemplate.route.points[t].x = SpawnTemplate.route.points[t].x + math.random( self.SpawnRadius * -1, self.SpawnRadius ) From 26fc977adf20d128eac5103b554f2514c8845f69 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Mon, 29 Feb 2016 14:55:44 +0100 Subject: [PATCH 46/51] bugfix --- Moose/Spawn.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 97ee2b0af..3885e0553 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -694,7 +694,7 @@ self:T( SpawnTemplate.name ) if self.SpawnRandomize then 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].y = SpawnTemplate.route.points[t].y + math.random( self.SpawnRadius * -1, self.SpawnRadius ) SpawnTemplate.route.points[t].alt = nil From cc521aa0a9f69df277218a6b2a69bc93c7b0d322 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Mon, 29 Feb 2016 16:08:03 +0100 Subject: [PATCH 47/51] trace --- Moose/Base.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 905db03bf..5377329f8 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -4,13 +4,15 @@ Include.File( "Routines" ) -_TraceOn = false +_TraceOn = true _TraceClass = { --DATABASE = true, --SEAD = true, --DESTROYBASETASK = true, --MOVEMENT = true, SPAWN = true, + GROUP = true, + UNIT = true, } BASE = { From 847eac245e846d0949c312061ab4c67e38274f9b Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Mon, 29 Feb 2016 16:47:56 +0100 Subject: [PATCH 48/51] trace --- Moose/Base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 5377329f8..756703cb1 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -4,7 +4,7 @@ Include.File( "Routines" ) -_TraceOn = true +_TraceOn = false _TraceClass = { --DATABASE = true, --SEAD = true, From 9f46a66cadf0b4a8ef8851dff8607bb2e0832972 Mon Sep 17 00:00:00 2001 From: svenvandevelde Date: Tue, 1 Mar 2016 13:57:34 +0100 Subject: [PATCH 49/51] Updated score view --- Moose/Database.lua | 118 +++++++++++++++++++++++++++++++++++++++++++-- Moose/Sead.lua | 2 +- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index da1c6af23..6ce2b18ec 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -547,6 +547,119 @@ end function DATABASE:ReportScoreAll() +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 + 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 = "" @@ -655,11 +768,6 @@ env.info( "Hello World " ) end end MESSAGE:New( PlayerMessage, "Player Scores", 30, "AllPlayerScores"):ToAll() -end - - -function DATABASE:ReportScorePlayer() - end diff --git a/Moose/Sead.lua b/Moose/Sead.lua index c068491d7..e1891c039 100644 --- a/Moose/Sead.lua +++ b/Moose/Sead.lua @@ -88,7 +88,7 @@ self:T( { event } ) local _targetMimname = Unit.getName(_targetMim) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) 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 function SuppressionEnd1(id) id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN) From 6bbc0c152db49887708a40af96279c482e649eda Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Wed, 2 Mar 2016 06:41:15 +0100 Subject: [PATCH 50/51] Fixed titles on scoring log. and activated trace to try to resolve the getPlayerName() bug in MP. --- Moose/Base.lua | 10 +++++----- Moose/Database.lua | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Moose/Base.lua b/Moose/Base.lua index 756703cb1..dfc1d888a 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -4,15 +4,15 @@ Include.File( "Routines" ) -_TraceOn = false +_TraceOn = true _TraceClass = { - --DATABASE = true, + DATABASE = true, --SEAD = true, --DESTROYBASETASK = true, --MOVEMENT = true, - SPAWN = true, - GROUP = true, - UNIT = true, + --SPAWN = true, + --GROUP = true, + --UNIT = true, } BASE = { diff --git a/Moose/Database.lua b/Moose/Database.lua index 6ce2b18ec..9ac06ec7c 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -804,7 +804,7 @@ function DATABASE:ScoreOpen() if not self.StatFile then error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() ) 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") end From 11c9e3f025fc23ad0259c08644b9b80250e9f5b8 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Wed, 2 Mar 2016 22:15:07 +0100 Subject: [PATCH 51/51] Test if getPlayerName really returns an empty string ... --- Moose/Database.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose/Database.lua b/Moose/Database.lua index 9ac06ec7c..9f41192a4 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -425,7 +425,7 @@ function DATABASE:OnHit( event ) local InitUnit = nil local InitUnitName = "" local InitGroupName = "" - local InitPlayerName = "" + local InitPlayerName = "dummy" local InitCoalition = nil local InitCategory = nil