diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 7dbb56451..1d13908b6 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -262,6 +262,95 @@ function PLAYERTASK:New(Type, Target, Repeat, Times, TTSType) end +--- Constructor that automatically determines the task type based on the target. +-- @param #PLAYERTASK self +-- @param Ops.Target#TARGET Target Target for this task +-- @param #boolean Repeat Repeat this task if true (default = false) +-- @param #number Times Repeat on failure this many times if Repeat is true (default = 1) +-- @param #string TTSType TTS friendly task type name +-- @return #PLAYERTASK self +function PLAYERTASK:NewFromTarget(Target, Repeat, Times, TTSType) + return PLAYERTASK:New(self:_GetTaskTypeForTarget(Target), Target, Repeat, Times, TTSType) +end + +--- [Internal] Determines AUFTRAG type based on the target characteristics. +-- @return #AUFTRAG.Type self +function PLAYERTASK:_GetTaskTypeForTarget(Target) + + local group = nil --Wrapper.Group#GROUP + local auftrag = nil + + if Target:IsInstanceOf("GROUP") then + group = Target --Target is already a group. + elseif Target:IsInstanceOf("SET_GROUP") then + group = Target:GetFirst() + elseif Target:IsInstanceOf("UNIT") then + group = Target:GetGroup() + elseif Target:IsInstanceOf("SET_UNIT") then + group = Target:GetFirst():GetGroup() + elseif Target:IsInstanceOf("AIRBASE") then + + auftrag = AUFTRAG.Type.BOMBRUNWAY + + elseif Target:IsInstanceOf("STATIC") + or Target:IsInstanceOf("SET_STATIC") + or Target:IsInstanceOf("SCENERY") + or Target:IsInstanceOf("SET_SCENERY") then + + auftrag = AUFTRAG.Type.BOMBING + + end + + if group then + + local category = group:GetCategory() + local attribute = group:GetAttribute() + + if (category == Group.Category.AIRPLANE or category == Group.Category.HELICOPTER) + and group:InAir() then + + auftrag = AUFTRAG.Type.INTERCEPT + + elseif category == Group.Category.GROUND or category == Group.Category.TRAIN then + + if attribute == GROUP.Attribute.GROUND_SAM + or attribute == GROUP.Attribute.GROUND_EWR then + + auftrag = AUFTRAG.Type.SEAD + + elseif attribute == GROUP.Attribute.GROUND_AAA + or attribute == GROUP.Attribute.GROUND_APC + or attribute == GROUP.Attribute.GROUND_IFV + or attribute == GROUP.Attribute.GROUND_TRUCK + or attribute == GROUP.Attribute.GROUND_TRAIN then + + auftrag = AUFTRAG.Type.BAI + + elseif attribute == GROUP.Attribute.GROUND_INFANTRY + or attribute == GROUP.Attribute.GROUND_ARTILLERY + or attribute == GROUP.Attribute.GROUND_TANK then + + auftrag = AUFTRAG.Type.CAS + + else + + auftrag = AUFTRAG.Type.BAI + + end + + elseif category == Group.Category.SHIP then + + auftrag = AUFTRAG.Type.ANTISHIP + + else + self:T(self.lid .. "ERROR: Unknown Group category!") + end + end + + return auftrag + +end + --- [Internal] Add a PLAYERTASKCONTROLLER for this task -- @param #PLAYERTASK self -- @param Ops.PlayerTask#PLAYERTASKCONTROLLER Controller @@ -378,6 +467,62 @@ function PLAYERTASK:SetMenuName(Text) return self end +--- [USER] Adds task success condition for dead STATIC, SET_STATIC, SCENERY or SET_SCENERY target object. +-- @return #PLAYERTASK self +function PLAYERTASK:AddStaticObjectSuccessCondition() + local task = self + task:AddConditionSuccess( + function(target) + if target == nil then return false end + + local isDead = false + if target:IsInstanceOf("STATIC") + or target:IsInstanceOf("SCENERY") + or target:IsInstanceOf("SET_SCENERY") then + isDead = (not target) or target:GetLife() < 1 or target:GetLife() < 0.2* target:GetLife0() + elseif target:IsInstanceOf("SET_STATIC") then + local deadCount = 0 + target:ForEachStatic(function(static) + if static:GetLife() < 1 or static:GetLife() < 0.2* static:GetLife0() then + deadCount = deadCount + 1 + end + end) + + if deadCount == target:Count() then + isDead = true + end + end + + return isDead + end, task:GetTarget() + ) + return self +end + +--- [USER] Adds task success condition for AUFTRAG.Type.RECON when a client is at a certain LOS distance from the target. +-- @param #number maxDistance Minimum distance from client to target in LOS for success condition. (Default 5 NM) +-- @return #PLAYERTASK self +function PLAYERTASK:AddReconSuccessCondition(minDistance) + local task = self + task:AddConditionSuccess( + function(target) + local targetLocation = target:GetCoordinate() + local minD = minDistance or UTILS.NMToMeters(5) + for _, client in ipairs(task:GetClientObjects()) do + local clientCoord = client:GetCoordinate() + local distance = clientCoord:Get2DDistance(targetLocation) + local isLos = land.isVisible(clientCoord:GetVec3(), targetLocation:GetVec3()) + + if distance < minD and isLos then + return true + end + end + return false + end, task:GetTarget()) + + return self +end + --- [USER] Add a task to be assigned to same clients when task was a success. -- @param #PLAYERTASK self -- @param Ops.PlayerTask#PLAYERTASK Task @@ -1384,7 +1529,10 @@ PLAYERTASKCONTROLLER.Scores = { [AUFTRAG.Type.SEAD] = 100, [AUFTRAG.Type.BOMBING] = 100, [AUFTRAG.Type.BOMBRUNWAY] = 100, - [AUFTRAG.Type.CONQUER] = 100, + [AUFTRAG.Type.CONQUER] = 100, + [AUFTRAG.Type.RECON] = 100, + [AUFTRAG.Type.ESCORT] = 100, + [AUFTRAG.Type.CAP] = 100, } ---