diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index b2c91dba2..4ad7f9e50 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -1124,7 +1124,7 @@ end -- @param #string AirbaseName Name of the airbase. -- @return #number Category. function DATABASE:GetCategoryFromAirbase( AirbaseName ) - return self.AIRBASES[AirbaseName]:GetCategory() + return self.AIRBASES[AirbaseName]:GetAirbaseCategory() end diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index b170501bc..df22111c3 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -388,9 +388,9 @@ end --- Creates a new SPAWN instance to create new groups based on the provided template. This will also register the template for future use. -- @param #SPAWN self -- @param #table SpawnTemplate is the Template of the Group. This must be a valid Group Template structure - see [Hoggit Wiki](https://wiki.hoggitworld.com/view/DCS_func_addGroup)! --- @param #string SpawnTemplatePrefix [Mandatory] is the name of the template and the prefix of the GROUP on spawn. +-- @param #string SpawnTemplatePrefix [Mandatory] is the name of the template and the prefix of the GROUP on spawn. The name in the template **will** be overwritten! -- @param #string SpawnAliasPrefix [Optional] is the prefix that will be given to the GROUP on spawn. --- @param #boolean MooseNaming [Optional] If false, skip the Moose naming additions (like groupname#001-01) - you need to ensure yourself no duplicate group names exist! +-- @param #boolean NoMooseNamingPostfix [Optional] If true, skip the Moose naming additions (like groupname#001-01) - **but** you need to ensure yourself no duplicate group names exist! -- @return #SPAWN self -- @usage -- -- Spawn a P51 Mustang from scratch @@ -491,7 +491,7 @@ end -- ) -- mustang:Spawn() -- -function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix, MooseNaming ) +function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix, NoMooseNamingPostfix ) local self = BASE:Inherit( self, BASE:New() ) self:F( { SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPrefix } ) --if SpawnAliasPrefix == nil or SpawnAliasPrefix == "" then @@ -532,7 +532,10 @@ function SPAWN:NewFromTemplate( SpawnTemplate, SpawnTemplatePrefix, SpawnAliasPr self.SpawnInitModex = nil self.SpawnInitAirbase = nil self.TweakedTemplate = true -- Check if the user is using self made template. - self.MooseNameing = MooseNaming or true + self.MooseNameing = true + if NoMooseNamingPostfix == true then + self.MooseNameing = false + end self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned. else @@ -3158,8 +3161,10 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) -- R2.2 if self.TweakedTemplate ~= nil and self.TweakedTemplate == true then BASE:I( "WARNING: You are using a tweaked template." ) SpawnTemplate = self.SpawnTemplate - if self.MooseNameing then + if self.MooseNameing == true then SpawnTemplate.name = self:SpawnGroupName( SpawnIndex ) + else + SpawnTemplate.name = self:SpawnGroupName() end else SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix ) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index f38fe83c4..12391027c 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -1616,7 +1616,11 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset) if (Offset.dx or Offset.dy) and (Offset.rho or Offset.theta) then error("Cannot use (dx, dy) with (rho, theta)") end + end + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius, true ) ) + + if Offset then self.dy = Offset.dy or 0.0 self.dx = Offset.dx or 0.0 self.rho = Offset.rho or 0.0 @@ -1624,8 +1628,6 @@ function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset) self.relative_to_unit = Offset.relative_to_unit or false end - local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius, true ) ) - self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) self.ZoneUNIT = ZoneUNIT diff --git a/Moose Development/Moose/Functional/RAT.lua b/Moose Development/Moose/Functional/RAT.lua index 081132413..98e295167 100644 --- a/Moose Development/Moose/Functional/RAT.lua +++ b/Moose Development/Moose/Functional/RAT.lua @@ -5832,6 +5832,7 @@ RATMANAGER={ rat={}, name={}, alive={}, + planned={}, min={}, nrat=0, ntot=nil, @@ -5880,6 +5881,7 @@ function RATMANAGER:Add(ratobject,min) self.rat[self.nrat]=ratobject self.alive[self.nrat]=0 + self.planned[self.nrat]=0 self.name[self.nrat]=ratobject.alias self.min[self.nrat]=min or 1 @@ -6020,11 +6022,25 @@ function RATMANAGER:_Manage() for i=1,self.nrat do for j=1,N[i] do time=time+self.dTspawn - SCHEDULER:New(nil, RAT._SpawnWithRoute, {self.rat[i]}, time) + self.planned[i]=self.planned[i]+1 + SCHEDULER:New(nil, RATMANAGER._Spawn, {self, i}, time) end end end +--- Instantly starts the RAT manager and spawns the initial random number RAT groups for each RAT object. +-- @param #RATMANAGER self +-- @param #RATMANAGER RATMANAGER self object. +-- @param #number i Index. +function RATMANAGER:_Spawn(i) + + local rat=self.rat[i] --#RAT + + rat:_SpawnWithRoute() + self.planned[i]=self.planned[i]-1 + +end + --- Counts the number of alive RAT objects. -- @param #RATMANAGER self function RATMANAGER:_Count() @@ -6053,7 +6069,7 @@ function RATMANAGER:_Count() ntotal=ntotal+n -- Debug output. - local text=string.format("Number of alive groups of %s = %d", self.name[i], n) + local text=string.format("Number of alive groups of %s = %d, planned=%d", self.name[i], n, self.planned[i]) self:T(RATMANAGER.id..text) end @@ -6083,9 +6099,10 @@ function RATMANAGER:_RollDice(nrat,ntot,min,alive) local M={} local P={} for i=1,nrat do + local a=alive[i]+self.planned[i] N[#N+1]=0 - M[#M+1]=math.max(alive[i], min[i]) - P[#P+1]=math.max(min[i]-alive[i],0) + M[#M+1]=math.max(a, min[i]) + P[#P+1]=math.max(min[i]-a,0) end -- Min/max group arrays. @@ -6102,7 +6119,7 @@ function RATMANAGER:_RollDice(nrat,ntot,min,alive) -- Number of new groups to be added. local nnew=ntot for i=1,nrat do - nnew=nnew-alive[i] + nnew=nnew-alive[i]-self.planned[i] end for i=1,nrat-1 do @@ -6134,7 +6151,7 @@ function RATMANAGER:_RollDice(nrat,ntot,min,alive) end -- Debug info - self:T3(string.format("RATMANAGER: i=%d, alive=%d, min=%d, mini=%d, maxi=%d, add=%d, sumN=%d, sumP=%d", j, alive[j], min[j], mini[j], maxi[j], N[j],sN, sP)) + self:T3(string.format("RATMANAGER: i=%d, alive=%d, planned=%d, min=%d, mini=%d, maxi=%d, add=%d, sumN=%d, sumP=%d", j, alive[j], self.planned[i], min[j], mini[j], maxi[j], N[j],sN, sP)) end @@ -6149,7 +6166,7 @@ function RATMANAGER:_RollDice(nrat,ntot,min,alive) -- Debug info local text=RATMANAGER.id.."\n" for i=1,nrat do - text=text..string.format("%s: i=%d, alive=%d, min=%d, mini=%d, maxi=%d, add=%d\n", self.name[i], i, alive[i], min[i], mini[i], maxi[i], N[i]) + text=text..string.format("%s: i=%d, alive=%d, planned=%d, min=%d, mini=%d, maxi=%d, add=%d\n", self.name[i], i, alive[i], self.planned[i], min[i], mini[i], maxi[i], N[i]) end text=text..string.format("Total # of groups to add = %d", sum(N, done)) self:T(text) diff --git a/Moose Development/Moose/Functional/Scoring.lua b/Moose Development/Moose/Functional/Scoring.lua index 3dda306a3..950ccd3c0 100644 --- a/Moose Development/Moose/Functional/Scoring.lua +++ b/Moose Development/Moose/Functional/Scoring.lua @@ -715,11 +715,11 @@ function SCORING:AddGoalScorePlayer( PlayerName, GoalTag, Text, Score ) PlayerData.Goals[GoalTag] = PlayerData.Goals[GoalTag] or { Score = 0 } PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score PlayerData.Score = PlayerData.Score + Score - - MESSAGE:NewType( self.DisplayMessagePrefix .. Text, - MESSAGE.Type.Information ) - :ToAll() - + if Text then + MESSAGE:NewType( self.DisplayMessagePrefix .. Text, + MESSAGE.Type.Information ) + :ToAll() + end self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, nil ) end end @@ -738,7 +738,7 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score ) local PlayerName = PlayerUnit:GetPlayerName() - self:F( { PlayerUnit.UnitName, PlayerName, GoalTag, Text, Score } ) + self:T2( { PlayerUnit.UnitName, PlayerName, GoalTag, Text, Score } ) -- PlayerName can be nil, if the Unit with the player crashed or due to another reason. if PlayerName then @@ -747,11 +747,12 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score ) PlayerData.Goals[GoalTag] = PlayerData.Goals[GoalTag] or { Score = 0 } PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score PlayerData.Score = PlayerData.Score + Score - - MESSAGE:NewType( self.DisplayMessagePrefix .. Text, + + if Text then + MESSAGE:NewType( self.DisplayMessagePrefix .. Text, MESSAGE.Type.Information ) :ToAll() - + end self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, PlayerUnit:GetName() ) end end @@ -784,11 +785,12 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score ) PlayerData.Score = self.Players[PlayerName].Score + Score PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score - - MESSAGE:NewType( self.DisplayMessagePrefix .. Mission:GetText() .. " : " .. Text .. " Score: " .. Score, - MESSAGE.Type.Information ) - :ToAll() - + + if Text then + MESSAGE:NewType( self.DisplayMessagePrefix .. Mission:GetText() .. " : " .. Text .. " Score: " .. Score, + MESSAGE.Type.Information ) + :ToAll() + end self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() ) end end @@ -820,9 +822,11 @@ function SCORING:_AddMissionGoalScore( Mission, PlayerName, Text, Score ) PlayerData.Score = self.Players[PlayerName].Score + Score PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score - - MESSAGE:NewType( string.format( "%s%s: %s! Player %s receives %d score!", self.DisplayMessagePrefix, Mission:GetText(), Text, PlayerName, Score ), MESSAGE.Type.Information ):ToAll() - + + if Text then + MESSAGE:NewType( string.format( "%s%s: %s! Player %s receives %d score!", self.DisplayMessagePrefix, Mission:GetText(), Text, PlayerName, Score ), MESSAGE.Type.Information ):ToAll() + end + self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score ) end end @@ -847,11 +851,12 @@ function SCORING:_AddMissionScore( Mission, Text, Score ) PlayerData.Score = PlayerData.Score + Score PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score - - MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in " .. Mission:GetText() .. ". " .. Score .. " mission score!", + + if Text then + MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in " .. Mission:GetText() .. ". " .. Score .. " mission score!", MESSAGE.Type.Information ) :ToAll() - + end self:ScoreCSV( PlayerName, "", "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score ) end end diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 060a6213e..f9ec9e5f5 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -30,7 +30,7 @@ -- @module Ops.CSAR -- @image OPS_CSAR.jpg --- Date: January 2023 +-- Date: May 2023 ------------------------------------------------------------------------- --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM @@ -292,7 +292,7 @@ CSAR.AircraftType["Bronco-OV-10A"] = 2 --- CSAR class version. -- @field #string version -CSAR.version="1.0.17" +CSAR.version="1.0.18" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -316,7 +316,7 @@ function CSAR:New(Coalition, Template, Alias) -- Inherit everything from FSM class. local self=BASE:Inherit(self, FSM:New()) -- #CSAR - BASE:T({Coalition, Prefixes, Alias}) + BASE:T({Coalition, Template, Alias}) --set Coalition if Coalition and type(Coalition)=="string" then @@ -1880,7 +1880,7 @@ function CSAR:_SignalFlare(_unitName) if _SETTINGS:IsImperial() then _distance = string.format("%.1fnm",UTILS.MetersToNM(_closest.distance)) else - _distance = string.format("%.1fkm",_closest.distance) + _distance = string.format("%.1fkm",_closest.distance/1000) end local _msg = string.format("%s - Popping signal flare at your %s o\'clock. Distance %s", self:_GetCustomCallSign(_unitName), _clockDir, _distance) self:_DisplayMessageToSAR(_heli, _msg, self.messageTime, false, true, true) @@ -2175,6 +2175,7 @@ function CSAR:_AddBeaconToGroup(_group, _freq) if _group:IsAlive() then local _radioUnit = _group:GetUnit(1) if _radioUnit then + local name = _radioUnit:GetName() local Frequency = _freq -- Freq in Hertz local name = _radioUnit:GetName() local Sound = "l10n/DEFAULT/"..self.radioSound diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 04e84ee7d..298f7b1dd 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -22,7 +22,7 @@ -- @module Ops.CTLD -- @image OPS_CTLD.jpg --- Last Update Apr 2023 +-- Last Update June 2023 do @@ -1221,7 +1221,7 @@ CTLD.UnitTypes = { --- CTLD class version. -- @field #string version -CTLD.version="1.0.37" +CTLD.version="1.0.39" --- Instantiate a new CTLD. -- @param #CTLD self @@ -1750,6 +1750,8 @@ function CTLD:_EventHandler(EventData) if _coalition ~= self.coalition then return --ignore! end + local unitname = event.IniUnitName or "none" + self.MenusDone[unitname] = nil -- check is Helicopter local _unit = event.IniUnit local _group = event.IniGroup @@ -1770,6 +1772,7 @@ function CTLD:_EventHandler(EventData) local unitname = event.IniUnitName or "none" self.CtldUnits[unitname] = nil self.Loaded_Cargo[unitname] = nil + self.MenusDone[unitname] = nil end return self end @@ -3442,6 +3445,9 @@ function CTLD:_RefreshF10Menus() if _unit:IsHelicopter() or (self:IsHercules(_unit) and self.enableHercules) then --ensure no stupid unit entries here local unitName = _unit:GetName() _UnitList[unitName] = unitName + else + local unitName = _unit:GetName() + _UnitList[unitName] = nil end end -- end isAlive end -- end if _unit @@ -4308,6 +4314,9 @@ end local uspeed = Unit:GetVelocityMPS() local uheight = Unit:GetHeight() local ucoord = Unit:GetCoordinate() + if not ucoord then + return false + end local gheight = ucoord:GetLandHeight() local aheight = uheight - gheight -- height above ground local maxh = self.maximumHoverHeight -- 15 @@ -4334,6 +4343,9 @@ end local uspeed = Unit:GetVelocityMPS() local uheight = Unit:GetHeight() local ucoord = Unit:GetCoordinate() + if not ucoord then + return false + end local gheight = ucoord:GetLandHeight() local aheight = uheight - gheight -- height above ground local minh = self.HercMinAngels-- 1500m @@ -4419,6 +4431,9 @@ end end local uheight = Unit:GetHeight() local ucoord = Unit:GetCoordinate() + if not ucoord then + return false + end local gheight = ucoord:GetLandHeight() local aheight = uheight - gheight -- height above ground if aheight >= minheight then diff --git a/Moose Development/Moose/Ops/Commander.lua b/Moose Development/Moose/Ops/Commander.lua index 16cffed58..16b9d43e1 100644 --- a/Moose Development/Moose/Ops/Commander.lua +++ b/Moose Development/Moose/Ops/Commander.lua @@ -514,7 +514,7 @@ function COMMANDER:AddOpsTransport(Transport) Transport.commander=self - Transport.statusCommander=TRANSPORT.Status.PLANNED + Transport.statusCommander=OPSTRANSPORT.Status.PLANNED table.insert(self.transportqueue, Transport) diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index b5ee9e527..ff0ba343d 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -21,7 +21,7 @@ -- === -- @module Ops.PlayerTask -- @image OPS_PlayerTask.jpg --- @date Last Update December 2022 +-- @date Last Update June 2023 do @@ -58,6 +58,7 @@ do -- @field #table NextTaskFailure -- @field #string FinalState -- @field #string TypeName +-- @field #number PreviousCount -- @extends Core.Fsm#FSM @@ -92,11 +93,12 @@ PLAYERTASK = { NextTaskSuccess = {}, NextTaskFailure = {}, FinalState = "none", + PreviousCount = 0, } --- PLAYERTASK class version. -- @field #string version -PLAYERTASK.version="0.1.14" +PLAYERTASK.version="0.1.17" --- Generic task condition. -- @type PLAYERTASK.Condition @@ -151,6 +153,8 @@ function PLAYERTASK:New(Type, Target, Repeat, Times, TTSType) return self end + self.PreviousCount = self.Target:CountTargets() + self:T(self.lid.."Created.") -- FMS start state is PLANNED. @@ -162,6 +166,7 @@ function PLAYERTASK:New(Type, Target, Repeat, Times, TTSType) self:AddTransition("*", "ClientAdded", "*") -- Client has been added to the task self:AddTransition("*", "ClientRemoved", "*") -- Client has been removed from the task self:AddTransition("*", "Executing", "Executing") -- First client is executing the Task. + self:AddTransition("*", "Progress", "*") -- Task target count reduced - progress self:AddTransition("*", "Done", "Done") -- All clients have reported that Task is done. self:AddTransition("*", "Cancel", "Done") -- Command to cancel the Task. self:AddTransition("*", "Success", "Done") @@ -456,6 +461,9 @@ function PLAYERTASK:AddClient(Client) self.Clients:Push(Client,name) self:__ClientAdded(-2,Client) end + if self.TaskController and self.TaskController.Scoring then + self.TaskController.Scoring:_AddPlayerFromUnit(Client) + end return self end @@ -710,6 +718,16 @@ function PLAYERTASK:onafterStatus(From, Event, To) status = "Success" end + if status ~= "Failed" and status ~= "Success" then + -- Partial Success? + local targetcount = self.Target:CountTargets() + if targetcount < self.PreviousCount then + -- Progress + self:__Progress(-2,targetcount) + self.PreviousCount = targetcount + end + end + if self.verbose then self:I(self.lid.."Target dead: "..tostring(targetdead).." | Clients alive: " .. tostring(clientsalive)) end @@ -723,6 +741,29 @@ function PLAYERTASK:onafterStatus(From, Event, To) end +--- [Internal] On after progress call +-- @param #PLAYERTASK self +-- @param #string From +-- @param #string Event +-- @param #string To +-- @param #number TargetCount +-- @return #PLAYERTASK self +function PLAYERTASK:onafterProgress(From, Event, To, TargetCount) + self:T({From, Event, To}) + if self.TaskController then + if self.TaskController.Scoring then + local clients,count = self:GetClientObjects() + if count > 0 then + for _,_client in pairs(clients) do + self.TaskController.Scoring:AddGoalScore(_client,self.Type,nil,10) + end + end + end + self.TaskController:__TaskProgress(-1,self,TargetCount) + end + return self +end + --- [Internal] On after planned call -- @param #PLAYERTASK self -- @param #string From @@ -835,6 +876,15 @@ function PLAYERTASK:onafterSuccess(From, Event, To) if self.TargetMarker then self.TargetMarker:Remove() end + if self.TaskController.Scoring then + local clients,count = self:GetClientObjects() + if count > 0 then + for _,_client in pairs(clients) do + local auftrag = self:GetSubType() + self.TaskController.Scoring:AddGoalScore(_client,self.Type,nil,self.TaskController.Scores[self.Type]) + end + end + end self.timestamp = timer.getAbsTime() self.FinalState = "Success" self:__Done(-1) @@ -864,6 +914,15 @@ function PLAYERTASK:onafterFailed(From, Event, To) self.FinalState = "Failed" self:__Done(-1) end + if self.TaskController.Scoring then + local clients,count = self:GetClientObjects() + if count > 0 then + for _,_client in pairs(clients) do + local auftrag = self:GetSubType() + self.TaskController.Scoring:AddGoalScore(_client,self.Type,nil,-self.TaskController.Scores[self.Type]) + end + end + end self.timestamp = timer.getAbsTime() return self end @@ -939,6 +998,7 @@ do -- @field #boolean InfoHasLLDDM -- @field #table PlayerMenuTag -- @field #boolean UseTypeNames +-- @field Functional.Scoring#SCORING Scoring -- @extends Core.Fsm#FSM --- @@ -1264,6 +1324,7 @@ PLAYERTASKCONTROLLER = { InfoHasLLDDM = false, InfoHasCoordinate = false, UseTypeNames = false, + Scoring = nil, } --- @@ -1283,6 +1344,22 @@ PLAYERTASKCONTROLLER.Type = { AUFTRAG.Type.PRECISIONBOMBING = "Precision Bombing" AUFTRAG.Type.CTLD = "Combat Transport" AUFTRAG.Type.CSAR = "Combat Rescue" + +--- +-- @type Scores +PLAYERTASKCONTROLLER.Scores = { + [AUFTRAG.Type.PRECISIONBOMBING] = 100, + [AUFTRAG.Type.CTLD] = 100, + [AUFTRAG.Type.CSAR] = 100, + [AUFTRAG.Type.INTERCEPT] = 100, + [AUFTRAG.Type.ANTISHIP] = 100, + [AUFTRAG.Type.CAS] = 100, + [AUFTRAG.Type.BAI] = 100, + [AUFTRAG.Type.SEAD] = 100, + [AUFTRAG.Type.BOMBING] = 100, + [AUFTRAG.Type.PRECISIONBOMBING] = 100, + [AUFTRAG.Type.BOMBRUNWAY] = 100, +} --- -- @type SeadAttributes @@ -1460,7 +1537,7 @@ PLAYERTASKCONTROLLER.Messages = { --- PLAYERTASK class version. -- @field #string version -PLAYERTASKCONTROLLER.version="0.1.58" +PLAYERTASKCONTROLLER.version="0.1.60" --- Create and run a new TASKCONTROLLER instance. -- @param #PLAYERTASKCONTROLLER self @@ -1549,6 +1626,7 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) self:AddTransition("*", "TaskCancelled", "*") self:AddTransition("*", "TaskSuccess", "*") self:AddTransition("*", "TaskFailed", "*") + self:AddTransition("*", "TaskProgress", "*") self:AddTransition("*", "TaskTargetSmoked", "*") self:AddTransition("*", "TaskTargetFlared", "*") self:AddTransition("*", "TaskTargetIlluminated", "*") @@ -1615,6 +1693,15 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) -- @param #string Event Event. -- @param #string To To state. -- @param Ops.PlayerTask#PLAYERTASK Task + + --- On After "TaskProgress" event. Task target count has been reduced. + -- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskProgress + -- @param #PLAYERTASKCONTROLLER self + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + -- @param Ops.PlayerTask#PLAYERTASK Task The current Task. + -- @param #number TargetCount Targets left over --- On After "TaskRepeatOnFailed" event. Task has failed and will be repeated. -- @function [parent=#PLAYERTASKCONTROLLER] OnAfterTaskRepeatOnFailed @@ -1670,6 +1757,23 @@ function PLAYERTASKCONTROLLER:New(Name, Coalition, Type, ClientFilter) end +--- [User] Set or create a SCORING object for this taskcontroller +-- @param #PLAYERTASKCONTROLLER self +-- @param Functional.Scoring#SCORING Scoring (optional) the Scoring object +-- @return #PLAYERTASKCONTROLLER self +function PLAYERTASKCONTROLLER:EnableScoring(Scoring) + self.Scoring = Scoring or SCORING:New(self.Name) + return self +end + +--- [User] Remove the SCORING object from this taskcontroller +-- @param #PLAYERTASKCONTROLLER self +-- @return #PLAYERTASKCONTROLLER self +function PLAYERTASKCONTROLLER:DisableScoring() + self.Scoring = nil + return self +end + --- [Internal] Init localization -- @param #PLAYERTASKCONTROLLER self -- @return #PLAYERTASKCONTROLLER self @@ -3113,7 +3217,7 @@ function PLAYERTASKCONTROLLER:_ActiveTaskInfo(Group, Client, Task) --self:I(self.lid.." | ".. CoordText) end local ThreatLocaleTextTTS = self.gettext:GetEntry("THREATTEXTTTS",self.locale) - local ttstext = string.format(ThreatLocaleTextTTS,self.MenuName or self.Name,ttsplayername,ttstaskname,ThreatLevelText, targets, CoordText) + local ttstext = string.format(ThreatLocaleTextTTS,ttsplayername,self.MenuName or self.Name,ttstaskname,ThreatLevelText, targets, CoordText) -- POINTERTARGETLASINGTTS = ". Pointer over target and lasing." if task.Type == AUFTRAG.Type.PRECISIONBOMBING and self.precisionbombing then if self.LasingDrone.playertask.inreach and self.LasingDrone:IsLasing() then @@ -3303,13 +3407,13 @@ function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu local taskinfomenu = nil if self.taskinfomenu then local menutaskinfo = self.gettext:GetEntry("MENUTASKINFO",self.locale) - local taskinfomenu = MENU_GROUP_DELAYED:New(group,menutaskinfo,topmenu):SetTag(newtag) + local taskinfomenu = MENU_GROUP:New(group,menutaskinfo,topmenu):SetTag(newtag) local ittypes = {} local itaskmenu = {} local tnow = timer.getTime() for _tasktype,_data in pairs(tasktypes) do - ittypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,taskinfomenu):SetTag(newtag) + ittypes[_tasktype] = MENU_GROUP:New(group,_tasktype,taskinfomenu):SetTag(newtag) local tasks = taskpertype[_tasktype] or {} local n = 0 for _,_task in pairs(tasks) do @@ -3335,7 +3439,7 @@ function PLAYERTASKCONTROLLER:_BuildTaskInfoMenu(group,client,playername,topmenu --self:T(self.lid.."Menu text = "..text) end end - local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task):SetTag(newtag) + local taskentry = MENU_GROUP_COMMAND:New(group,text,ittypes[_tasktype],self._ActiveTaskInfo,self,group,client,_task):SetTag(newtag) --taskentry:SetTag(playername) itaskmenu[#itaskmenu+1] = taskentry -- keep max items limit @@ -3409,6 +3513,7 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) -- 2)+3) Join or abort? if joinorabort then self.PlayerMenu[playername]:RemoveSubMenus() + self.PlayerMenu[playername] = MENU_GROUP:New(group,menuname,self.MenuParent) self.PlayerMenu[playername]:SetTag(newtag) topmenu = self.PlayerMenu[playername] elseif (not playerhastask) or enforced then @@ -3420,17 +3525,18 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) --self.PlayerMenu[playername]:RemoveSubMenus() --oldmenu = self.PlayerMenu[playername] --self.PlayerMenu[playername] = nil - self.PlayerMenu[playername]:RemoveSubMenus() - self.PlayerMenu[playername] = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent) - self.PlayerMenu[playername]:SetTag(newtag) - self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() - timedbuild = true + + --self.PlayerMenu[playername]:RemoveSubMenus() + --self.PlayerMenu[playername] = MENU_GROUP:New(group,menuname,self.MenuParent) + --self.PlayerMenu[playername]:SetTag(newtag) + --self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() + --timedbuild = true end topmenu = self.PlayerMenu[playername] end else -- 1) new player# - topmenu = MENU_GROUP_DELAYED:New(group,menuname,self.MenuParent) + topmenu = MENU_GROUP:New(group,menuname,self.MenuParent) self.PlayerMenu[playername] = topmenu self.PlayerMenu[playername]:SetTag(newtag) self.PlayerMenu[playername].PTTimeStamp = timer.getAbsTime() @@ -3450,21 +3556,21 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) local menuflare = self.gettext:GetEntry("MENUFLARE",self.locale) local menuabort = self.gettext:GetEntry("MENUABORT",self.locale) - local active = MENU_GROUP_DELAYED:New(group,menuactive,topmenu):SetTag(newtag) - local info = MENU_GROUP_COMMAND_DELAYED:New(group,menuinfo,active,self._ActiveTaskInfo,self,group,client):SetTag(newtag) - local mark = MENU_GROUP_COMMAND_DELAYED:New(group,menumark,active,self._MarkTask,self,group,client):SetTag(newtag) + local active = MENU_GROUP:New(group,menuactive,topmenu):SetTag(newtag) + local info = MENU_GROUP_COMMAND:New(group,menuinfo,active,self._ActiveTaskInfo,self,group,client):SetTag(newtag) + local mark = MENU_GROUP_COMMAND:New(group,menumark,active,self._MarkTask,self,group,client):SetTag(newtag) if self.Type ~= PLAYERTASKCONTROLLER.Type.A2A then if self.noflaresmokemenu ~= true then -- no smoking/flaring here if A2A or designer has set noflaresmokemenu to true - local smoke = MENU_GROUP_COMMAND_DELAYED:New(group,menusmoke,active,self._SmokeTask,self,group,client):SetTag(newtag) - local flare = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._FlareTask,self,group,client):SetTag(newtag) + local smoke = MENU_GROUP_COMMAND:New(group,menusmoke,active,self._SmokeTask,self,group,client):SetTag(newtag) + local flare = MENU_GROUP_COMMAND:New(group,menuflare,active,self._FlareTask,self,group,client):SetTag(newtag) local IsNight = client:GetCoordinate():IsNight() if IsNight then - local light = MENU_GROUP_COMMAND_DELAYED:New(group,menuflare,active,self._IlluminateTask,self,group,client):SetTag(newtag) + local light = MENU_GROUP_COMMAND:New(group,menuflare,active,self._IlluminateTask,self,group,client):SetTag(newtag) end end end - local abort = MENU_GROUP_COMMAND_DELAYED:New(group,menuabort,active,self._AbortTask,self,group,client):SetTag(newtag) + local abort = MENU_GROUP_COMMAND:New(group,menuabort,active,self._AbortTask,self,group,client):SetTag(newtag) if self.activehasinfomenu and self.taskinfomenu then self:T("Building Active-Info Menus for "..playername) if self.PlayerInfoMenu[playername] then @@ -3484,13 +3590,13 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) self.PlayerJoinMenu[playername]:RemoveSubMenus(nil,oldtag) end - local joinmenu = MENU_GROUP_DELAYED:New(group,menujoin,topmenu):SetTag(newtag) + local joinmenu = MENU_GROUP:New(group,menujoin,topmenu):SetTag(newtag) self.PlayerJoinMenu[playername] = joinmenu local ttypes = {} local taskmenu = {} for _tasktype,_data in pairs(tasktypes) do - ttypes[_tasktype] = MENU_GROUP_DELAYED:New(group,_tasktype,joinmenu):SetTag(newtag) + ttypes[_tasktype] = MENU_GROUP:New(group,_tasktype,joinmenu):SetTag(newtag) local tasks = taskpertype[_tasktype] or {} local n = 0 for _,_task in pairs(tasks) do @@ -3510,7 +3616,7 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) text = string.format("%s (%03d) [%d%s",name,_task.PlayerTaskNr,pilotcount,newtext) end end - local taskentry = MENU_GROUP_COMMAND_DELAYED:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task):SetTag(newtag) + local taskentry = MENU_GROUP_COMMAND:New(group,text,ttypes[_tasktype],self._JoinTask,self,group,client,_task):SetTag(newtag) --taskentry:SetTag(playername) taskmenu[#taskmenu+1] = taskentry n = n + 1 @@ -3527,22 +3633,22 @@ function PLAYERTASKCONTROLLER:_BuildMenus(Client,enforced,fromsuccess) self.PlayerInfoMenu[playername] = self:_BuildTaskInfoMenu(group,client,playername,topmenu,tasktypes,taskpertype,newtag) end end - if self.AllowFlash then + if self.AllowFlash and topmenu ~= nil then local flashtext = self.gettext:GetEntry("FLASHMENU",self.locale) - local flashmenu = MENU_GROUP_COMMAND_DELAYED:New(group,flashtext,topmenu,self._SwitchFlashing,self,group,client):SetTag(newtag) + local flashmenu = MENU_GROUP_COMMAND:New(group,flashtext,topmenu,self._SwitchFlashing,self,group,client):SetTag(newtag) end if self.TaskQueue:Count() == 0 then self:T("No open tasks info") local menunotasks = self.gettext:GetEntry("MENUNOTASKS",self.locale) - local joinmenu = MENU_GROUP_DELAYED:New(group,menunotasks,self.PlayerMenu[playername]):SetTag(newtag) + local joinmenu = MENU_GROUP:New(group,menunotasks,self.PlayerMenu[playername]):SetTag(newtag) rebuilddone = true end --- -- REFRESH MENU --- if rebuilddone then - self.PlayerMenu[playername]:RemoveSubMenus(nil,oldtag) - self.PlayerMenu[playername]:Set() + --self.PlayerMenu[playername]:RemoveSubMenus(nil,oldtag) + --self.PlayerMenu[playername]:Set() self.PlayerMenu[playername]:Refresh() end end @@ -3874,7 +3980,9 @@ function PLAYERTASKCONTROLLER:onafterStatus(From, Event, To) if taskcount ~= self.lasttaskcount then self.lasttaskcount = taskcount - enforcedmenu = true + if taskcount < self.menuitemlimit then + enforcedmenu = true + end end self:_BuildMenus(nil,enforcedmenu) diff --git a/Moose Development/Moose/Wrapper/Airbase.lua b/Moose Development/Moose/Wrapper/Airbase.lua index 07c2acf7e..0930f88ed 100644 --- a/Moose Development/Moose/Wrapper/Airbase.lua +++ b/Moose Development/Moose/Wrapper/Airbase.lua @@ -2295,3 +2295,17 @@ function AIRBASE:CheckOnRunWay(group, radius, despawn) return false end + +--- Get category of airbase. +-- @param #AIRBASE self +-- @return #number Category of airbase from GetDesc().category. +function AIRBASE:GetCategory() + return self.category +end + +--- Get category name of airbase. +-- @param #AIRBASE self +-- @return #string Category of airbase, i.e. Airdrome, Ship, or Helipad +function AIRBASE:GetCategoryName() + return AIRBASE.CategoryName[self.category] +end diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 5eee9236a..e716269a2 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -25,6 +25,7 @@ -- @field #string ClassName Name of the class. -- @field #string UnitName Name of the unit. -- @field #string GroupName Name of the group the unit belongs to. +-- @field #table DCSUnit The DCS Unit object from the API. -- @extends Wrapper.Controllable#CONTROLLABLE --- For each DCS Unit object alive within a running mission, a UNIT wrapper object (instance) will be created within the global _DATABASE object (an instance of @{Core.Database#DATABASE}). @@ -92,6 +93,7 @@ UNIT = { ClassName="UNIT", UnitName=nil, GroupName=nil, + DCSUnit = nil, } @@ -124,6 +126,7 @@ function UNIT:Register( UnitName ) if group then self.GroupName=group:getName() end + self.DCSUnit = unit end -- Set event prio. @@ -175,7 +178,11 @@ function UNIT:GetDCSObject() if DCSUnit then return DCSUnit end - + + if self.DCSUnit then + return self.DCSUnit + end + return nil end