TARGET v0.7

- Bug fixes
- Improved FSM function docs
This commit is contained in:
Frank 2024-11-20 11:15:05 +01:00
parent 09e1883488
commit b87930738a

View File

@ -153,13 +153,13 @@ _TARGETID=0
--- TARGET class version.
-- @field #string version
TARGET.version="0.6.0"
TARGET.version="0.7.0"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Had cases where target life was 0 but target was not dead. Need to figure out why!
-- DONE: Had cases where target life was 0 but target was not dead. Need to figure out why! <== This is due to delayed dead event.
-- DONE: Add pseudo functions.
-- DONE: Initial object can be nil.
@ -243,6 +243,36 @@ function TARGET:New(TargetObject)
-- @function [parent=#TARGET] __Status
-- @param #TARGET self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "ObjectDamaged".
-- @function [parent=#TARGET] ObjectDamaged
-- @param #TARGET self
-- @param #TARGET.Object Target Target object.
--- Triggers the FSM event "ObjectDestroyed".
-- @function [parent=#TARGET] ObjectDestroyed
-- @param #TARGET self
-- @param #TARGET.Object Target Target object.
--- Triggers the FSM event "ObjectDead".
-- @function [parent=#TARGET] ObjectDead
-- @param #TARGET self
-- @param #TARGET.Object Target Target object.
--- Triggers the FSM event "Damaged".
-- @function [parent=#TARGET] Damaged
-- @param #TARGET self
--- Triggers the FSM event "Destroyed".
-- @function [parent=#TARGET] Destroyed
-- @param #TARGET self
--- Triggers the FSM event "Dead".
-- @function [parent=#TARGET] Dead
-- @param #TARGET self
--- On After "ObjectDamaged" event. A (sub-) target object has been damaged, e.g. a UNIT of a GROUP, or an object of a SET
-- @function [parent=#TARGET] OnAfterObjectDamaged
@ -267,22 +297,23 @@ function TARGET:New(TargetObject)
-- @param #string Event Event.
-- @param #string To To state.
-- @param #TARGET.Object Target Target object.
--- On After "Damaged" event. The (whole) target object has been damaged.
--- On After "Damaged" event. Any of the target objects has been damaged.
-- @function [parent=#TARGET] OnAfterDamaged
-- @param #TARGET self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- On After "ObjectDestroyed" event. The (whole) target object has been destroyed.
--- On After "Destroyed" event. All target objects have been destroyed.
-- @function [parent=#TARGET] OnAfterDestroyed
-- @param #TARGET self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- On After "ObjectDead" event. The (whole) target object is dead.
--- On After "Dead" event. All target objects are dead.
-- @function [parent=#TARGET] OnAfterDead
-- @param #TARGET self
-- @param #string From From state.
@ -290,7 +321,7 @@ function TARGET:New(TargetObject)
-- @param #string To To state.
-- Start.
self:__Start(-1)
self:__Start(-0.1)
return self
end
@ -527,6 +558,11 @@ function TARGET:IsAlive()
for _,_target in pairs(self.targets) do
local target=_target --Ops.Target#TARGET.Object
if target.Status~=TARGET.ObjectStatus.DEAD then
if self.isDestroyed then
self:E(self.lid..string.format("ERROR: target is DESTROYED but target object status is not DEAD but %s for object %s", target.Status, target.Name))
elseif self:IsDead() then
self:E(self.lid..string.format("ERROR: target is DEAD but target object status is not DEAD but %s for object %s", target.Status, target.Name))
end
return true
end
end
@ -550,6 +586,25 @@ function TARGET:IsDead()
return is
end
--- Check if target object is dead.
-- @param #TARGET self
-- @param #TARGET.Object TargetObject The target object.
-- @return #boolean If true, target is dead.
function TARGET:IsTargetDead(TargetObject)
local isDead=TargetObject.Status==TARGET.ObjectStatus.DEAD
return isDead
end
--- Check if target object is alive.
-- @param #TARGET self
-- @param #TARGET.Object TargetObject The target object.
-- @return #boolean If true, target is dead.
function TARGET:IsTargetAlive(TargetObject)
local isAlive=TargetObject.Status==TARGET.ObjectStatus.ALIVE
return isAlive
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start & Status
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -581,7 +636,8 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function TARGET:onafterStatus(From, Event, To)
self:T({From, Event, To})
--self:T({From, Event, To})
-- FSM state.
local fsmstate=self:GetState()
@ -592,6 +648,7 @@ function TARGET:onafterStatus(From, Event, To)
-- old life
local life=target.Life
-- curr life
target.Life=self:GetTargetLife(target)
@ -603,13 +660,14 @@ function TARGET:onafterStatus(From, Event, To)
self.life0 = self.life0+delta
end
-- Check if life decreased ==> damaged
if target.Life<life then
target.Status = TARGET.ObjectStatus.DAMAGED
self:ObjectDamaged(target)
--target.Status = TARGET.ObjectStatus.DAMAGED
self:ObjectDamaged(target)
damaged=true
end
if life < 1 and (not target.Status == TARGET.ObjectStatus.DEAD) then
if target.Life<1 and target.Status~=TARGET.ObjectStatus.DEAD then
self:E(self.lid..string.format("FF life is zero but no object dead event fired ==> object dead now for target object %s!", tostring(target.Name)))
self:ObjectDead(target)
damaged = true
@ -624,11 +682,12 @@ function TARGET:onafterStatus(From, Event, To)
-- Log output verbose=1.
if self.verbose>=1 then
local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), self.N0, self:GetLife(), self:GetLife0(), self:GetDamage())
local text=string.format("%s: Targets=%d/%d [%d, %d], Life=%.1f/%.1f, Damage=%.1f",
fsmstate, self:CountTargets(), self.N0, self.Ndestroyed, self.Ndead, self:GetLife(), self:GetLife0(), self:GetDamage())
if self:CountTargets() == 0 or self:GetDamage() >= 100 then
text=text.." Dead!"
text=text.." - Dead!"
elseif damaged then
text=text.." Damaged!"
text=text.." - Damaged!"
end
self:I(self.lid..text)
end
@ -639,19 +698,35 @@ function TARGET:onafterStatus(From, Event, To)
for i,_target in pairs(self.targets) do
local target=_target --#TARGET.Object
local damage=(1-target.Life/target.Life0)*100
text=text..string.format("\n[%d] %s %s %s: Life=%.1f/%.1f, Damage=%.1f", i, target.Type, target.Name, target.Status, target.Life, target.Life0, damage)
text=text..string.format("\n[%d] %s %s %s: Life=%.1f/%.1f, Damage=%.1f, N0=%d, Ndestroyed=%d, Ndead=%d",
i, target.Type, target.Name, target.Status, target.Life, target.Life0, damage, target.N0, target.Ndestroyed, target.Ndead)
end
self:I(self.lid..text)
end
if self:CountTargets() == 0 or self:GetDamage() >= 100 then
-- Consitency check if target is still alive but all target objects are dead
if self:IsAlive() and (self:CountTargets()==0 or self:GetDamage()>=100) then
self:Dead()
end
-- Quick sanity check
for i,_target in pairs(self.targets) do
local target=_target --#TARGET.Object
if target.Ndestroyed>target.N0 then
self:E(self.lid..string.format("ERROR: Number of destroyed target objects greater than number of initial target objects: %d>%d!", target.Ndestroyed, target.N0))
end
if target.Ndestroyed>target.N0 then
self:E(self.lid..string.format("ERROR: Number of dead target objects greater than number of initial target objects: %d>%d!", target.Ndead, target.N0))
end
end
-- Update status again in 30 sec.
if self:IsAlive() then
self:__Status(-self.TStatus)
else
self:I(self.lid..string.format("Target is not alive any more ==> no further status updates are carried out"))
end
return self
end
@ -687,6 +762,10 @@ function TARGET:onafterObjectDestroyed(From, Event, To, Target)
-- Increase destroyed counter.
self.Ndestroyed=self.Ndestroyed+1
Target.Ndestroyed=Target.Ndestroyed+1
Target.Life=0
-- Call object dead event.
self:ObjectDead(Target)
@ -707,6 +786,12 @@ function TARGET:onafterObjectDead(From, Event, To, Target)
-- Set target status.
Target.Status=TARGET.ObjectStatus.DEAD
-- Increase dead object counter
Target.Ndead=Target.Ndead+1
-- Set target object life to 0.
Target.Life=0
-- Increase dead counter.
self.Ndead=self.Ndead+1
@ -716,6 +801,7 @@ function TARGET:onafterObjectDead(From, Event, To, Target)
local target=_target --#TARGET.Object
if target.Status==TARGET.ObjectStatus.ALIVE then
dead=false
break -- break the loop because we now we are not dead
end
end
@ -759,7 +845,6 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function TARGET:onafterDestroyed(From, Event, To)
self:T({From, Event, To})
self:T(self.lid..string.format("TARGET destroyed"))
@ -813,23 +898,27 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
-- Check if we could find a target object.
if target then
local Ndead=target.Ndead
local Ndestroyed=target.Ndestroyed
if EventData.id==EVENTS.RemoveUnit then
target.Ndead=target.Ndead+1
Ndead=Ndead+1
else
target.Ndestroyed=target.Ndestroyed+1
target.Ndead=target.Ndead+1
Ndestroyed=Ndestroyed+1
Ndead=Ndead+1
end
if target.Ndead==target.N0 then
if target.Ndestroyed>=target.N0 then
-- Check if ALL objects are dead
if Ndead==target.N0 then
if Ndestroyed>=target.N0 then
-- Debug message.
self:T2(self.lid..string.format("EVENT ID=%d: target %s dead/lost ==> destroyed", EventData.id, tostring(target.Name)))
target.Life = 0
-- Trigger object destroyed event.
-- Trigger object destroyed event. This sets the Life to zero and increases Ndestroyed
self:ObjectDestroyed(target)
else
@ -839,7 +928,7 @@ function TARGET:OnEventUnitDeadOrLost(EventData)
target.Life = 0
-- Trigger object dead event.
-- Trigger object dead event. This sets the Life to zero and increases Ndead counter
self:ObjectDead(target)
end