**CHIEF**
- Fixed bugs of polygon opszones
- Added option to use CAPTUREZONE auftrag for opszones

**OPSZONE**
- Fixed bug when marker off

**ZONE_POLYGON_BASE**
- Added `GetRadius()` function

**LEGION**
- Improved Reinforcement
This commit is contained in:
Frank 2023-01-03 22:09:56 +01:00
parent 58dc353bcd
commit dbaed1e97b
7 changed files with 180 additions and 97 deletions

View File

@ -2084,13 +2084,10 @@ function ZONE_POLYGON_BASE:DrawZone(Coalition, Color, Alpha, FillColor, FillAlph
return self
end
--- Get the smallest circular zone encompassing all points points of the polygon zone.
--- Get the smallest radius encompassing all points of the polygon zone.
-- @param #ZONE_POLYGON_BASE self
-- @param #string ZoneName (Optional) Name of the zone. Default is the name of the polygon zone.
-- @param #boolean DoNotRegisterZone (Optional) If `true`, zone is not registered.
-- @return #ZONE_RADIUS The circular zone.
function ZONE_POLYGON_BASE:GetZoneRadius(ZoneName, DoNotRegisterZone)
-- @return #number Radius of the zone in meters.
function ZONE_POLYGON_BASE:GetRadius()
local center=self:GetVec2()
@ -2106,6 +2103,20 @@ function ZONE_POLYGON_BASE:GetZoneRadius(ZoneName, DoNotRegisterZone)
end
end
return radius
end
--- Get the smallest circular zone encompassing all points of the polygon zone.
-- @param #ZONE_POLYGON_BASE self
-- @param #string ZoneName (Optional) Name of the zone. Default is the name of the polygon zone.
-- @param #boolean DoNotRegisterZone (Optional) If `true`, zone is not registered.
-- @return #ZONE_RADIUS The circular zone.
function ZONE_POLYGON_BASE:GetZoneRadius(ZoneName, DoNotRegisterZone)
local center=self:GetVec2()
local radius=self:GetRadius()
local zone=ZONE_RADIUS:New(ZoneName or self.ZoneName, center, radius, DoNotRegisterZone)

View File

@ -5829,62 +5829,65 @@ function WAREHOUSE:_SpawnAssetRequest(Request)
-- Get stock item.
local asset=cargoassets[i] --#WAREHOUSE.Assetitem
if not asset.spawned then
-- Set asset status to not spawned until we capture its birth event.
asset.spawned=false
asset.iscargo=true
-- Set request ID.
asset.rid=Request.uid
-- Spawn group name.
local _alias=asset.spawngroupname
--Request add asset by id.
Request.assets[asset.uid]=asset
-- Spawn an asset group.
local _group=nil --Wrapper.Group#GROUP
if asset.category==Group.Category.GROUND then
-- Spawn ground troops.
_group=self:_SpawnAssetGroundNaval(_alias, asset, Request, self.spawnzone, Request.lateActivation)
elseif asset.category==Group.Category.AIRPLANE or asset.category==Group.Category.HELICOPTER then
-- Spawn air units.
if Parking[asset.uid] then
_group=self:_SpawnAssetAircraft(_alias, asset, Request, Parking[asset.uid], UnControlled, Request.lateActivation)
else
_group=self:_SpawnAssetAircraft(_alias, asset, Request, nil, UnControlled, Request.lateActivation)
end
elseif asset.category==Group.Category.TRAIN then
-- Spawn train.
if self.rail then
--TODO: Rail should only get one asset because they would spawn on top!
-- Spawn naval assets.
-- Set asset status to not spawned until we capture its birth event.
asset.iscargo=true
-- Set request ID.
asset.rid=Request.uid
-- Spawn group name.
local _alias=asset.spawngroupname
--Request add asset by id.
Request.assets[asset.uid]=asset
-- Spawn an asset group.
local _group=nil --Wrapper.Group#GROUP
if asset.category==Group.Category.GROUND then
-- Spawn ground troops.
_group=self:_SpawnAssetGroundNaval(_alias, asset, Request, self.spawnzone, Request.lateActivation)
elseif asset.category==Group.Category.AIRPLANE or asset.category==Group.Category.HELICOPTER then
-- Spawn air units.
if Parking[asset.uid] then
_group=self:_SpawnAssetAircraft(_alias, asset, Request, Parking[asset.uid], UnControlled, Request.lateActivation)
else
_group=self:_SpawnAssetAircraft(_alias, asset, Request, nil, UnControlled, Request.lateActivation)
end
elseif asset.category==Group.Category.TRAIN then
-- Spawn train.
if self.rail then
--TODO: Rail should only get one asset because they would spawn on top!
-- Spawn naval assets.
_group=self:_SpawnAssetGroundNaval(_alias, asset, Request, self.spawnzone, Request.lateActivation)
end
--self:E(self.lid.."ERROR: Spawning of TRAIN assets not possible yet!")
elseif asset.category==Group.Category.SHIP then
-- Spawn naval assets.
_group=self:_SpawnAssetGroundNaval(_alias, asset, Request, self.portzone, Request.lateActivation)
else
self:E(self.lid.."ERROR: Unknown asset category!")
end
--self:E(self.lid.."ERROR: Spawning of TRAIN assets not possible yet!")
elseif asset.category==Group.Category.SHIP then
-- Spawn naval assets.
_group=self:_SpawnAssetGroundNaval(_alias, asset, Request, self.portzone, Request.lateActivation)
else
self:E(self.lid.."ERROR: Unknown asset category!")
-- Trigger event.
if _group then
self:__AssetSpawned(0.01, _group, asset, Request)
end
end
-- Trigger event.
if _group then
self:__AssetSpawned(0.01, _group, asset, Request)
end
end
end

View File

@ -56,6 +56,8 @@
-- @field #table DCStask DCS task structure.
-- @field #number Ncasualties Number of own casualties during mission.
-- @field #number Nkills Number of (enemy) units killed by assets of this mission.
-- @field #number Ndead Number of assigned groups that are dead.
-- @field #number Nassigned Number of assigned groups.
-- @field #number Nelements Number of elements (units) assigned to mission.
-- @field #number dTevaluate Time interval in seconds before the mission result is evaluated after mission is over.
-- @field #number Tover Mission abs. time stamp, when mission was over.
@ -92,6 +94,7 @@
-- @field #number refuelSystem Refuel type (boom or probe) for TANKER missions.
--
-- @field Wrapper.Group#GROUP escortGroup The group to be escorted.
-- @field #string escortGroupName Name of the escorted group.
-- @field DCS#Vec3 escortVec3 The 3D offset vector from the escorted group to the escort group.
--
-- @field #number facDesignation FAC designation type.
@ -3597,7 +3600,7 @@ function AUFTRAG:IsExecuting(AllGroups)
local N
if self.Nassigned then
N=self.Nassigned-self.Ndead
N=self.Nassigned-self.Ndead
else
N=self:CountOpsGroups()
end
@ -3885,6 +3888,8 @@ function AUFTRAG:onafterStatus(From, Event, To)
-- Number of alive groups attached to this mission.
local Ngroups=self:CountOpsGroups()
local Nassigned=self.Nassigned and self.Nassigned-self.Ndead or 0
-- Check if mission is not OVER yet.
if self:IsNotOver() then
@ -3920,7 +3925,13 @@ function AUFTRAG:onafterStatus(From, Event, To)
self:T(self.lid.."No targets left cancelling mission!")
self:Cancel()
elseif self:IsExecuting() and ((not self.reinforce) or self.reinforce==0) then
elseif self:IsExecuting() and ((not self.reinforce) or (self.reinforce==0 and Nassigned<=0)) then
-- env.info("Mission Done:")
-- env.info(string.format("Nreinforce= %d", self.reinforce or 0))
-- env.info(string.format("Nassigned = %d", self.Nassigned))
-- env.info(string.format("Ndead = %d", self.Ndead))
-- env.info(string.format("Nass-Ndead= %d", Nassigned))
-- Had the case that mission was in state Executing but all assigned groups were dead.
-- TODO: might need to loop over all assigned groups
@ -3980,6 +3991,17 @@ function AUFTRAG:onafterStatus(From, Event, To)
end
self:I(self.lid..text)
end
-- Group info.
if self.verbose>=3 then
-- Data on assigned groups.
local text=string.format("Assets [N=%d,Nassigned=%s, Ndead=%s]:", self.Nassets or 0, self.Nassigned or 0, self.Ndead or 0)
for i,_asset in pairs(self.assets or {}) do
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
text=text..string.format("\n[%d] %s: spawned=%s, requested=%s, reserved=%s", i, asset.spawngroupname, tostring(asset.spawned), tostring(asset.requested), tostring(asset.reserved))
end
self:I(self.lid..text)
end
-- Ready to evaluate mission outcome?
local ready2evaluate=self.Tover and Tnow-self.Tover>=self.dTevaluate or false
@ -4398,11 +4420,9 @@ function AUFTRAG:GetGroupEgressWaypointUID(opsgroup)
end
end
--- Check if all flights are done with their mission (or dead).
--- Check if all groups are done with their mission (or dead).
-- @param #AUFTRAG self
-- @return #boolean If true, all flights are done with the mission.
-- @return #boolean If `true`, all groups are done with the mission.
function AUFTRAG:CheckGroupsDone()
-- Check status of all OPS groups.
@ -4410,7 +4430,7 @@ function AUFTRAG:CheckGroupsDone()
local groupdata=data --#AUFTRAG.GroupData
if groupdata then
if not (groupdata.status==AUFTRAG.GroupStatus.DONE or groupdata.status==AUFTRAG.GroupStatus.CANCELLED) then
-- At least this flight is not DONE or CANCELLED.
-- At least this group is not DONE or CANCELLED.
self:T2(self.lid..string.format("CheckGroupsDone: OPSGROUP %s is not DONE or CANCELLED but in state %s. Mission NOT DONE!", groupdata.opsgroup.groupname, groupdata.status:upper()))
return false
end
@ -4451,12 +4471,12 @@ function AUFTRAG:CheckGroupsDone()
end
-- Check if there is still reinforcement to be expected.
if self:IsExecuting() and self.reinforce and self.reinforce>0 then
if self:IsExecuting() and self.reinforce and (self.reinforce>0 or self.Nassigned-self.Ndead>0) then
self:T2(self.lid..string.format("CheckGroupsDone: Mission is still in state %s [FSM=%s] and reinfoce=%d. Mission NOT DONE!", self.status, self:GetState(), self.reinforce))
return false
end
-- It could be that all flights were destroyed on the way to the mission execution waypoint.
-- It could be that all groups were destroyed on the way to the mission execution waypoint.
-- TODO: would be better to check if everybody is dead by now.
if self:IsStarted() and self:CountOpsGroups()==0 then
self:T(self.lid..string.format("CheckGroupsDone: Mission is STARTED state %s [FSM=%s] but count of alive OPSGROUP is zero. Mission DONE!", self.status, self:GetState()))
@ -4591,6 +4611,7 @@ end
function AUFTRAG:onafterGroupDead(From, Event, To, OpsGroup)
local asset=self:GetAssetByName(OpsGroup.groupname)
if asset then
self:AssetDead(asset)
end
@ -4683,7 +4704,7 @@ function AUFTRAG:onafterCancel(From, Event, To)
-- Debug info.
self:T(self.lid..string.format("LEGION %s will cancel the mission. Will wait for mission DONE before evaluation!", legion.alias))
-- Legion will cancel all flight missions and remove queued request from warehouse queue.
-- Legion will cancel all group's missions and remove queued request from warehouse queue.
legion:MissionCancel(self)
end
@ -4949,7 +4970,7 @@ function AUFTRAG:onafterRepeat(From, Event, To)
end
end
-- No flight data.
-- No group data.
self.groupdata={}
-- Reset casualties and units assigned.
@ -4967,7 +4988,7 @@ function AUFTRAG:onafterRepeat(From, Event, To)
end
--- On after "Stop" event. Remove mission from AIRWING and FLIGHTGROUP mission queues.
--- On after "Stop" event. Remove mission from LEGION and OPSGROUP mission queues.
-- @param #AUFTRAG self
-- @param #string From From state.
-- @param #string Event Event.
@ -5006,7 +5027,7 @@ function AUFTRAG:onafterStop(From, Event, To)
-- No mission assets.
self.assets={}
-- No flight data.
-- No group data.
self.groupdata={}
-- Clear pending scheduler calls.
@ -5811,7 +5832,7 @@ function AUFTRAG:GetDCSMissionTask()
DCStask.id="OpsTransport"
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
DCStask.params=param
@ -5841,7 +5862,7 @@ function AUFTRAG:GetDCSMissionTask()
DCStask.id=AUFTRAG.SpecialTask.FORMATION
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
param.unitname=self:GetTargetName()
param.offsetX=200
@ -5892,7 +5913,7 @@ function AUFTRAG:GetDCSMissionTask()
DCStask.id=AUFTRAG.SpecialTask.BARRAGE
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
param.zone=self:GetObjective()
param.altitude=self.artyAltitude
@ -5916,7 +5937,7 @@ function AUFTRAG:GetDCSMissionTask()
DCStask.id=AUFTRAG.SpecialTask.PATROLZONE
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
param.zone=self:GetObjective()
param.altitude=self.missionAltitude
@ -5936,7 +5957,7 @@ function AUFTRAG:GetDCSMissionTask()
DCStask.id=AUFTRAG.SpecialTask.CAPTUREZONE
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
DCStask.params=param
@ -5952,7 +5973,7 @@ function AUFTRAG:GetDCSMissionTask()
DCStask.id=AUFTRAG.SpecialTask.PATROLZONE
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
-- We create a "fake" DCS task and pass the parameters to the OPSGROUP.
local param={}
param.zone=self:GetObjective()
param.altitude=self.missionAltitude

View File

@ -218,6 +218,7 @@
-- * `AUFTRAG.Type.ARTY`
-- * `AUFTRAG.Type.PATROLZONE`
-- * `AUFTRAG.Type.ONGUARD`
-- * `AUFTRAG.Type.CAPTUREZONE`
-- * `AUFTRAG.Type.RECON`
-- * `AUFTRAG.Type.AMMOSUPPLY`
-- * `AUFTRAG.Type.BOMBING`
@ -330,7 +331,7 @@ CHIEF.Strategy = {
--- CHIEF class version.
-- @field #string version
CHIEF.version="0.5.3"
CHIEF.version="0.6.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -3033,6 +3034,9 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
LEGION.UnRecruitAssets(assets)
return false
end
-- Debug messgage.
self:T2(self.lid..string.format("Recruited %d assets for mission %s", #assets, MissionType))
if MissionType==AUFTRAG.Type.PATROLZONE or MissionType==AUFTRAG.Type.ONGUARD then
@ -3040,10 +3044,7 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
---
-- PATROLZONE or ONGUARD
---
-- Debug messgage.
self:T2(self.lid..string.format("Recruited %d assets for PATROL mission", #assets))
if MissionType==AUFTRAG.Type.PATROLZONE then
mission=AUFTRAG:NewPATROLZONE(TargetZone)
@ -3054,6 +3055,14 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
-- Engage detected targets.
mission:SetEngageDetected(25, {"Ground Units", "Light armed ships", "Helicopters"})
elseif MissionType==AUFTRAG.Type.CAPTUREZONE then
---
-- CAPTUREZONE
---
mission=AUFTRAG:NewCAPTUREZONE(StratZone.opszone, self.coalition)
elseif MissionType==AUFTRAG.Type.CASENHANCED then
---
@ -3089,6 +3098,9 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
end
end
-- Here we need a circular zone.
TargetZone=StratZone.opszone.zoneCircular
-- Leg length.
local Leg = TargetZone:GetRadius() <= 10000 and 5 or UTILS.MetersToNM(TargetZone:GetRadius())
@ -3163,9 +3175,7 @@ function CHIEF:RecruitAssetsForZone(StratZone, Resource)
if mission then
-- Add assets to mission.
for _,asset in pairs(assets) do
mission:AddAsset(asset)
end
mission:_AddAssets(assets)
-- Assign mission to legions.
self:MissionAssign(mission, legions)

View File

@ -158,12 +158,14 @@ function LEGION:New(WarehouseName, LegionName)
-- @function [parent=#LEGION] MissionRequest
-- @param #LEGION self
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Assets (Optional) Assets to add.
--- Triggers the FSM event "MissionRequest" after a delay.
-- @function [parent=#LEGION] __MissionRequest
-- @param #LEGION self
-- @param #number delay Delay in seconds.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Assets (Optional) Assets to add.
--- On after "MissionRequest" event.
-- @function [parent=#LEGION] OnAfterMissionRequest
@ -172,6 +174,7 @@ function LEGION:New(WarehouseName, LegionName)
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Assets (Optional) Assets to add.
--- Triggers the FSM event "MissionCancel" after a delay.
@ -671,13 +674,15 @@ function LEGION:CheckMissionQueue()
if mission:IsExecuting() and mission.reinforce and mission.reinforce>0 then
-- Number of current opsgroups.
local N=mission:CountOpsGroups()
local N=mission.Nassigned-mission.Ndead
if N<mission.NassetsMin then
reinforce=true
end
self:I(self.lid..string.format("Checking Reinforcement N=%d, Nmin=%d ==> Reinforce=%s", N, mission.NassetsMin, tostring(reinforce)))
-- Debug info.
self:T(self.lid..string.format("Checking Reinforcement Nreinf=%d, Nops=%d, Nassigned=%d, Ndead=%d, Nmin=%d ==> Reinforce=%s",
mission.reinforce, N, mission.Nassigned, mission.Ndead, mission.NassetsMin, tostring(reinforce)))
end
-- Firstly, check if mission is due?
@ -689,8 +694,8 @@ function LEGION:CheckMissionQueue()
-- Did we find enough assets?
if recruited then
-- Reserve assets and add to mission.
mission:_AddAssets(assets)
-- Add to mission.
--mission:_AddAssets(assets)
-- Recruit asset for escorting recruited mission assets.
local EscortAvail=self:RecruitAssetsForEscort(mission, assets)
@ -722,7 +727,7 @@ function LEGION:CheckMissionQueue()
if EscortAvail and TransportAvail then
-- Got a mission.
self:MissionRequest(mission)
self:MissionRequest(mission, assets)
-- Reduce number of reinforcements.
if reinforce then
@ -846,6 +851,7 @@ end
-- @param #number nAsset Number of groups requested that match the asset specification.
-- @param #number Prio Priority of the request. Number ranging from 1=high to 100=low.
-- @param #string Assignment A keyword or text that can later be used to identify this request and postprocess the assets.
-- @return Functional.Warehouse#WAREHOUSE.Queueitem The request.
function LEGION:_AddRequest(AssetDescriptor, AssetDescriptorValue, nAsset, Prio, Assignment)
-- Defaults.
@ -889,6 +895,7 @@ function LEGION:_AddRequest(AssetDescriptor, AssetDescriptorValue, nAsset, Prio,
self.alias, self.alias, request.assetdesc, descval, tostring(request.nasset), request.transporttype, tostring(request.ntransport))
self:_DebugMessage(text, 5)
return request
end
@ -898,10 +905,14 @@ end
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Auftrag#AUFTRAG Mission The requested mission.
function LEGION:onafterMissionRequest(From, Event, To, Mission)
-- @param #table Assets (Optional) Assets to add.
function LEGION:onafterMissionRequest(From, Event, To, Mission, Assets)
-- Debug info.
self:T(self.lid..string.format("MissionRequest for mission %s [%s]", Mission:GetName(), Mission:GetType()))
-- Take provided assets or that of the mission.
Assets=Assets or Mission.assets
-- Set mission status from QUEUED to REQUESTED.
Mission:Requested()
@ -917,7 +928,7 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission)
-- Assets to be requested.
local Assetlist={}
for _,_asset in pairs(Mission.assets) do
for _,_asset in pairs(Assets) do
local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem
-- Check that this asset belongs to this Legion warehouse.
@ -929,7 +940,7 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission)
-- Spawned Assets
---
if asset.flightgroup then
if asset.flightgroup and not asset.flightgroup:IsMissionInQueue(Mission) then
-- Add new mission.
asset.flightgroup:AddMission(Mission)
@ -992,11 +1003,13 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission)
end
Mission:AddAsset(asset)
-- Trigger event.
self:__OpsOnMission(2, asset.flightgroup, Mission)
else
self:E(self.lid.."ERROR: OPSGROUP for asset does NOT exist but it seems to be SPAWNED (asset.spawned=true)!")
self:T(self.lid.."ERROR: OPSGROUP for asset does NOT exist but it seems to be SPAWNED (asset.spawned=true)!")
end
else
@ -1040,22 +1053,29 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission)
if Mission.type==AUFTRAG.Type.ALERT5 then
asset.takeoffType=COORDINATE.WaypointType.TakeOffParking
end
Mission:AddAsset(asset)
end
-- Set assignment.
-- TODO: Get/set functions for assignment string.
local assignment=string.format("Mission-%d", Mission.auftragsnummer)
--local request=Mission:_GetRequest(self)
-- Add request to legion warehouse.
--self:AddRequest(self, WAREHOUSE.Descriptor.ASSETLIST, Assetlist, #Assetlist, nil, nil, Mission.prio, assignment)
self:_AddRequest(WAREHOUSE.Descriptor.ASSETLIST, Assetlist, #Assetlist, Mission.prio, assignment)
local request=self:_AddRequest(WAREHOUSE.Descriptor.ASSETLIST, Assetlist, #Assetlist, Mission.prio, assignment)
env.info(string.format("FF Added request=%d for Nasssets=%d", request.uid, #Assetlist))
-- The queueid has been increased in the onafterAddRequest function. So we can simply use it here.
Mission.requestID[self.alias]=self.queueid
--Mission.requestID[self.alias]=self.queueid
Mission:_SetRequestID(self, self.queueid)
-- Get request.
local request=self:GetRequestByID(self.queueid)
--local request=self:GetRequestByID(self.queueid)
-- Debug info.
self:T(self.lid..string.format("Mission %s [%s] got Request ID=%d", Mission:GetName(), Mission:GetType(), self.queueid))

View File

@ -5065,6 +5065,24 @@ function OPSGROUP:GetMissionByID(id)
return nil
end
--- Check if a given mission is already in the queue.
-- @param #OPSGROUP self
-- @param Ops.Auftrag#AUFTRAG Mission the mission to check
-- @return #boolean If `true`, the mission is in the queue.
function OPSGROUP:IsMissionInQueue(Mission)
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.auftragsnummer==Mission.auftragsnummer then
return true
end
end
return false
end
--- Get mission by its task id.
-- @param #OPSGROUP self
-- @param #number taskid The id of the (waypoint) task of the mission.

View File

@ -506,7 +506,7 @@ function OPSZONE:SetMarkZone(Switch, ReadOnly)
self.marker:Remove()
end
self.marker=nil
--self.marker=false
self.markZone=false
end
return self
end