ARTY v0.9.8-buggy

Improved marker assignments.
There is a bug that makes DCS crash when a group is ordered to move and reaches its destination, i.e. arrives.
This commit is contained in:
funkyfranky 2018-06-02 19:13:26 +02:00
parent 0b95930674
commit e9a055219e

View File

@ -459,7 +459,7 @@ ARTY.id="ARTY | "
--- Arty script version.
-- @field #string version
ARTY.version="0.9.8"
ARTY.version="0.9.8-buggy"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -856,17 +856,21 @@ end
function ARTY:RemoveTarget(name)
self:F2(name)
local id=self:_GetTargetIndexByName(name)
if id then
-- Remove target from table.
self:T(ARTY.id..string.format("Group %s: Removing target %s (id=%d).", self.Controllable:GetName(), name, id))
table.remove(self.targets, id)
-- Delete marker belonging to this engagement.
local batteryname,markTargetID, markMoveID=self:_GetMarkIDfromName(name)
if batteryname==self.Controllable:GetName() and markTargetID~=nil then
COORDINATE:RemoveMark(markTargetID)
end
end
self:T(ARTY.id..string.format("Group %s: Number of targets = %d.", self.Controllable:GetName(), #self.targets))
if self.currentTarget then
if self.currentTarget.name==name then
self:T(ARTY.id..string.format("Group %s: Cancelling current target %s.", self.Controllable:GetName(), name))
self:CeaseFire(self.currentTarget)
end
end
end
--- Delete a move from move list.
@ -875,16 +879,17 @@ end
function ARTY:RemoveMove(name)
self:F2(name)
local id=self:_GetMoveIndexByName(name)
if id then
-- Remove move from table.
self:T(ARTY.id..string.format("Group %s: Removing move %s (id=%d).", self.Controllable:GetName(), name, id))
table.remove(self.moves, id)
end
self:T(ARTY.id..string.format("Group %s: Number of moves = %d.", self.Controllable:GetName(), #self.moves))
if self.currentMove then
if self.currentMove.name==name then
self:T(ARTY.id..string.format("Group %s: Cancelling current move %s.", self.Controllable:GetName(), name))
self:Arrived()
end
env.info("FF debug remove move")
-- Delete marker belonging to this relocation move.
--local batteryname,markTargetID,markMoveID=self:_GetMarkIDfromName(name)
--if batteryname==self.Controllable:GetName() and markMoveID~=nil then
--COORDINATE:RemoveMark(markMoveID)
--end
end
end
@ -1110,6 +1115,62 @@ function ARTY:onafterStart(Controllable, From, Event, To)
self:__Status(self.StatusInterval)
end
--- Extract engagement assignments and parameters from mark text.
-- @param #ARTY self
-- @param #string text Marker text.
-- @return #boolean If true, authentification successful.
function ARTY:_MarkerKeyAuthentification(text)
-- Set battery and coalition.
local batteryname=self.Controllable:GetName()
local batterycoalition=self.Controllable:GetCoalition()
-- Get assignment.
local mykey=nil
if self.markkey~=nil then
-- keywords are split by ","
local keywords=self:_split(text, ",")
for _,key in pairs(keywords) do
local s=self:_split(key, " ")
local val=s[2]
if key:lower():find("key") then
mykey=tonumber(val)
self:T(ARTY.id..string.format("Authorisation Key=%s.", val))
end
end
end
-- Check if the authorization key is required and if it is valid.
local _validkey=true
-- Check if group needs authorization.
if self.markkey~=nil then
-- Assume key is incorrect.
_validkey=false
-- If key was found, check if matches.
if mykey~=nil then
_validkey=self.markkey==mykey
end
self:T2(ARTY.id..string.format("%s, authkey=%s == %s=playerkey ==> valid=%s", batteryname, tostring(self.markkey), tostring(mykey), tostring(_validkey)))
-- Send message
local text=""
if mykey==nil then
text=string.format("%s, authorization required but did not receive a key!", batteryname)
elseif _validkey==false then
text=string.format("%s, authorization required but did receive an incorrect key (key=%s)!", batteryname, tostring(mykey))
elseif _validkey==true then
text=string.format("%s, authentification successful!", batteryname)
end
MESSAGE:New(text, 20):ToCoalitionIf(batterycoalition, self.report or self.Debug)
end
return _validkey
end
--- Extract engagement assignments and parameters from mark text.
-- @param #ARTY self
-- @param #string text Marker text to be analyzed.
@ -1123,6 +1184,7 @@ function ARTY:_Markertext(text)
assignment.move=false
assignment.engage=false
assignment.readonly=false
assignment.cancelcurrent=false
assignment.time=nil
assignment.nshells=nil
assignment.prio=nil
@ -1133,7 +1195,7 @@ function ARTY:_Markertext(text)
assignment.onroad=nil
assignment.key=nil
if text:lower():find("arty") then
if text:lower():find("arty") then
if text:lower():find("engage") then
assignment.engage=true
elseif text:lower():find("move") then
@ -1210,19 +1272,18 @@ function ARTY:_Markertext(text)
assignment.speed=tonumber(val)
self:T2(ARTY.id..string.format("Key Speed=%s.", val))
elseif key:lower():find("road") then
elseif key:lower():find("on road") or key:lower():find("onroad") or key:lower():find("use road")then
assignment.onroad=true
self:T2(ARTY.id..string.format("Key Onroad=true."))
elseif key:lower():find("key") then
assignment.key=tonumber(val)
self:T(ARTY.id..string.format("Key Key=%s.", val))
elseif key:lower():find("irrevocable") then
elseif key:lower():find("irrevocable") or key:lower():find("readonly") then
assignment.readonly=true
self:T2(ARTY.id..string.format("Key Readonly=true."))
elseif key:lower():find("cancel current") then
assignment.cancelcurrent=true
self:T2(ARTY.id..string.format("Key Cancel Current=true."))
end
end
@ -1278,6 +1339,58 @@ function ARTY:onEvent(Event)
end
--- Create a name for an engagement initiated by placing a marker.
-- @param #ARTY self
-- @param #number markerid ID of the placed marker.
-- @return #string Name of target engagement.
function ARTY:_MarkTargetName(markerid)
return string.format("BATTERY=%s, Marked Target ID=%d", self.Controllable:GetName(), markerid)
end
--- Create a name for a relocation move initiated by placing a marker.
-- @param #ARTY self
-- @param #number markerid ID of the placed marker.
-- @return #string Name of relocation move.
function ARTY:_MarkMoveName(markerid)
return string.format("BATTERY=%s, Marked Relocation ID=%d", self.Controllable:GetName(), markerid)
end
--- Create a name for a relocation move initiated by placing a marker.
-- @param #ARTY self
-- @param #sting name Name of the assignment.
-- @return #string Name of the ARTY group or nil
-- @return #number ID of the marked target or nil.
-- @return #number ID of the marked relocation move or nil
function ARTY:_GetMarkIDfromName(name)
-- keywords are split by ","
local keywords=self:_split(name, ",")
local battery=nil
local markTID=nil
local markMID=nil
for _,key in pairs(keywords) do
local str=self:_split(key, "=")
local par=str[1]
local val=str[2]
if par:find("BATTERY") then
battery=val
end
if par:find("Marked Target ID") then
markTID=tonumber(val)
end
if par:find("Marked Relocation ID") then
markMID=tonumber(val)
end
end
return battery, markTID, markMID
end
--- Function called when a F10 map mark was removed.
-- @param #ARTY self
-- @param #table Event Event data.
@ -1293,18 +1406,20 @@ function ARTY:_OnEventMarkRemove(Event)
local _canceltarget=false
local _name=""
local _id=nil
if Event.text:find("Marked Relocation") then
_cancelmove=true
_name=string.format("BATTERY %s Marked Relocation ID=%d", batteryname, Event.idx)
_name=self:_MarkMoveName(Event.idx)
_id=self:_GetMoveIndexByName(_name)
elseif Event.text:find("Marked Target") then
_canceltarget=true
_name=string.format("BATTERY %s Marked Target ID=%d", batteryname, Event.idx)
_name=self:_MarkTargetName(Event.idx)
_id=self:_GetTargetIndexByName(_name)
else
return
end
-- Check if there is a task which matches.
if _id==nil then
return
end
@ -1312,48 +1427,25 @@ function ARTY:_OnEventMarkRemove(Event)
-- Check if the coalition is the same or an authorization key has been defined.
if (batterycoalition==Event.coalition and self.markkey==nil) or self.markkey~=nil then
-- Get assignment.
local mykey=nil
if self.markkey~=nil then
-- keywords are split by ","
local keywords=self:_split(Event.text, ",")
for _,key in pairs(keywords) do
local s=self:_split(key, " ")
local val=s[2]
if key:lower():find("key") then
mykey=tonumber(val)
self:T(ARTY.id..string.format("Key Key=%s.", val))
end
end
end
-- Check if the authorization key is required and if it is valid.
local _validkey=true
if self.markkey~=nil then
_validkey=false
if mykey~=nil then
_validkey=self.markkey==mykey
end
self:T2(ARTY.id..string.format("%s, authkey=%s == %s=playerkey ==> valid=%s", batteryname, tostring(self.markkey), tostring(mykey), tostring(_validkey)))
local text=""
if mykey==nil then
text=string.format("%s, authorization required but did not receive a key!", batteryname)
elseif _validkey==false then
text=string.format("%s, authorization required but did receive an incorrect key (key=%s)!", batteryname, tostring(mykey))
elseif _validkey==true then
text=string.format("%s, authentification successful!", batteryname)
end
MESSAGE:New(text, 20):ToCoalitionIf(batterycoalition, self.report or self.Debug)
end
-- Authentify key
local _validkey=self:_MarkerKeyAuthentification(Event.text)
-- Check if we have the right coalition.
if _validkey then
-- This should be the unique name of the target or move.
if _cancelmove then
self:RemoveMove(_name)
if self.currentMove and self.currentMove.name==_name then
self:Arrived()
else
self:RemoveMove(_name)
end
elseif _canceltarget then
self:RemoveTarget(_name)
if self.currentTarget and self.currentTarget.name==_name then
self:CeaseFire(self.currentTarget)
else
self:RemoveTarget(_name)
end
end
end
@ -1397,24 +1489,19 @@ function ARTY:_OnEventMarkChange(Event)
if not (_assign.engage or _assign.move) or (not _assigned) then
return
end
-- Check if the authorization key is required and if it is valid.
local _validkey=true
if self.markkey~=nil then
_validkey=false
if _assign.key~=nil then
_validkey=self.markkey==_assign.key
local _validkey=self:_MarkerKeyAuthentification(Event.text)
-- Cancel current target.
if _validkey and _assign.cancelcurrent then
if _assign.move and self.currentMove then
self:Arrived()
end
self:T2(ARTY.id..string.format("%s, authkey=%s == %s=playerkey ==> valid=%s", batteryname, tostring(self.markkey), tostring(_assign.key), tostring(_validkey)))
local text=""
if _assign.key==nil then
text=string.format("%s, authorization required but did not receive a key!", batteryname)
elseif _validkey==false then
text=string.format("%s, authorization required but did receive an incorrect key (key=%s)!", batteryname, tostring(_assign.key))
elseif _validkey==true then
text=string.format("%s, authentification successful!", batteryname)
if _assign.engage and self.currentTarget then
self:CeaseFire(self.currentTarget)
end
MESSAGE:New(text, 20):ToCoalitionIf(batterycoalition, self.report or self.Debug)
return
end
-- We are meant.
@ -1430,17 +1517,18 @@ function ARTY:_OnEventMarkChange(Event)
-- Also I don't know who can see the mark which was created.
_coord:RemoveMark(Event.idx)
-- Anticipate marker ID.
-- WARNING: Make sure, no marks are set until the COORDINATE:MarkToCoalition() is called or the target/move name will be wrong and target cannot be removed by deleting its marker.
local _id=UTILS._MarkID+1
if _assign.move then
-- Create a new name. This determins the string we search when deleting a move!
local _name=string.format("BATTERY %s Marked Relocation ID=%d", batteryname, _id)
self:E(ARTY.id.._name)
local _name=self:_MarkMoveName(_id)
local text=string.format("%s, received new relocation assignment.", batteryname)
text=text..string.format("\nCoordinates %s",_coord:ToStringLLDMS())
MESSAGE:New(text, 20):ToCoalitionIf(batterycoalition, self.report or self.Debug)
MESSAGE:New(text, 10):ToCoalitionIf(batterycoalition, self.report or self.Debug)
-- Assign a relocation of the arty group.
local _movename=self:AssignMoveCoord(_coord, _assign.time, _assign.speed, _assign.onroad, _assign.cancel,_name, true)
@ -1451,11 +1539,7 @@ function ARTY:_OnEventMarkChange(Event)
-- Create new target name.
local clock=tostring(self:_SecondsToClock(_move.time))
local _road="Off Road"
if _move.onroad==true then
_road="On Road"
end
local _markertext=_movename..string.format(", Time %s, Speed %d km/h, %s.", clock, _move.speed, _road)
local _markertext=_movename..string.format(", Time=%s, Speed=%d km/h, Use Roads=%s.", clock, _move.speed, tostring(_move.onroad))
-- Create a new mark. This will trigger the mark added event.
local _randomcoord=_coord:GetRandomCoordinateInRadius(100)
@ -1465,8 +1549,7 @@ function ARTY:_OnEventMarkChange(Event)
else
-- Create a new name.
local _name=string.format("BATTERY %s Marked Target ID=%d", batteryname, _id)
self:E(ARTY.id.._name)
local _name=self:_MarkTargetName(_id)
local text=string.format("%s, received new target assignment.", batteryname)
text=text..string.format("\nCoordinates %s",_coord:ToStringLLDMS())
@ -1476,6 +1559,9 @@ function ARTY:_OnEventMarkChange(Event)
if _assign.prio then
text=text..string.format("\nPrio %d",_assign.prio)
end
if _assign.prio then
text=text..string.format("\nRadius %d m",_assign.radius)
end
if _assign.nshells then
text=text..string.format("\nShots %d",_assign.nshells)
end
@ -1485,7 +1571,7 @@ function ARTY:_OnEventMarkChange(Event)
if _assign.weapontype then
text=text..string.format("\nWeapon %s",self:_WeaponTypeName(_assign.weapontype))
end
MESSAGE:New(text, 20):ToCoalitionIf(batterycoalition, self.report or self.Debug)
MESSAGE:New(text, 10):ToCoalitionIf(batterycoalition, self.report or self.Debug)
-- Assign a new firing engagement.
-- Note, we set unique=true so this target gets only added once.
@ -1498,7 +1584,7 @@ function ARTY:_OnEventMarkChange(Event)
-- Create new target name.
local clock=tostring(self:_SecondsToClock(_target.time))
local weapon=self:_WeaponTypeName(_target.weapontype)
local _markertext=_targetname..string.format(", Priority %d, Radius=%d m, Shots %d, Engagements=%d, Weapon %s, Time %s", _target.prio, _target.radius, _target.nshells, _target.maxengage, weapon, clock)
local _markertext=_targetname..string.format(", Priority=%d, Radius=%d m, Shots=%d, Engagements=%d, Weapon=%s, Time=%s", _target.prio, _target.radius, _target.nshells, _target.maxengage, weapon, clock)
-- Create a new mark. This will trigger the mark added event.
local _randomcoord=_coord:GetRandomCoordinateInRadius(250)
@ -1547,6 +1633,11 @@ function ARTY:_StatusReport()
for i=1,#self.targets do
text=text..string.format("- %s\n", self:_TargetInfo(self.targets[i]))
end
if self.currentMove then
text=text..string.format("Current Move = %s\n", tostring(self.currentMove.name))
else
text=text..string.format("Current Move = %s\n", "none")
end
text=text..string.format("Moves:\n")
for i=1,#self.moves do
text=text..string.format("- %s\n", self:_MoveInfo(self.moves[i]))
@ -1669,18 +1760,6 @@ function ARTY:_NuclearBlast(_coord)
end
--- Eventhandler for shot event.
-- @param #ARTY self
-- @param Core.Event#EVENTDATA EventData
function ARTY:_OnMarkAdded(EventData)
self:F(EventData)
if EventData.MarkCoordinate then
local coord=EventData.MarkCoordinate --Core.Point#COORDINATE
coord:SmokeGreen()
end
end
--- Eventhandler for shot event.
-- @param #ARTY self
-- @param Core.Event#EVENTDATA EventData
@ -2453,8 +2532,8 @@ function ARTY:onafterArrived(Controllable, From, Event, To)
-- Remove executed move from queue.
if self.currentMove then
self:RemoveMove(self.currentMove.name)
self.currentMove=nil
--self:RemoveMove(self.currentMove.name)
--self.currentMove=nil
end
end