Jump to content

Death event handlers


Go to solution Solved by cfrag,

Recommended Posts

Posted

I swear to Zeus this is killing me.. I have tried setting up an event handler to take certain actions when a unit dies, but is constantly running in to bugs. I have tried DEAD, KILL, UNIT_LOST and BDA with similar issues of initiator and target randomly not having any values (returning nil even though it should be there). In testing it seems BDA is the least likely one to throw errors. My suspicion is that since it is evaluated faster than DEAD and UNIT_LOST, it may get in and grab the values before they are removed from the table in memory..

Below is an example of what I am trying to do at the moment:

local unitReport = {}
local _mrkID = 1000
function unitReport:onEvent(event)
    if (world.event.S_EVENT_BDA == event.id) then
        local _objectSide = event.target:getCoalition()
        local _deadUnitName = event.target:getName()
        local enmyPt = event.initiator:getPoint() --buggy line
        local _enmyType = event.initiator:getTypeName()
        local _enmyWPN = event.weapon:getTypeName()
        if _objectSide == 2 then
            trigger.action.outText(_deadUnitName..' is hit!', 2)
            _spottingChance = math.random(1,10)
            if _spottingChance > 6 then
                trigger.action.markToCoalition(_mrkID,'enemy contact: '.._enmyType,enmyPt,2,false)
                _mrkID = _mrkID + 1
            end
        end
    end
end

and attached is the error I'm getting. I have also experienced similar nil value issues when trying to access the killed unit, as if the program already forgot it was there..

Any help would be hot!

image.png

Posted

So I did a bit more testing. My suspicions about the game dumping the event information too rapidly seems to be correct. Once I put in a condition to check whether the event values were actually populated, the errors seem to have stopped.

Code looks like this now, with added code in bold:

function unitReport:onEvent(event)
    if (world.event.S_EVENT_BDA == event.id) then
        if event.target ~= nil and event.initiator ~= nil then --check if event data is present
            local _objectSide = event.target:getCoalition()
            local _deadUnitName = event.target:getName()
            local _deadUnitCat = event.target:getCategory()
            local _enmyPt = event.initiator:getPoint()
            local _enmyType = event.initiator:getTypeName()
            if _objectSide == 2 and _deadUnitCat == 2 then
                trigger.action.outText(_deadUnitName..' is hit!', 2)
                local _spottingChance = math.random(1,10)
                if _spottingChance > 5 then
                    trigger.action.markToCoalition(_mrkID,'enemy contact: '.._enmyType,_enmyPt,2,false)
                    _mrkID = _mrkID + 1
                end
            end
        end
    elseif (world.event.S_EVENT_CRASH == event.id) then
        if event.initiator ~= nil then --check if event data is present
            local _objectSide = event.initiator:getCoalition()
            local _crashedUnitName = event.initiator:getName()
            local _crashPt = event.initiator:getPoint()
            if _objectSide == 2 then
                trigger.action.outText(_crashedUnitName..' is down!', 2)
                trigger.action.markToCoalition(_mrkID,_crashedUnitName..' crash site',_crashPt,2,false)
                _mrkID = _mrkID + 1
            end
        end    
    end
end

  • Solution
Posted

I agree that it would be prudent to apply some sanity checks at the very beginning of your event processor:

function unitReport:onEvent(event)
    if not event then return end -- wtf? bad call
    if not event.initiator then return end -- no initiator, no interest 

	... (some more test before you dereference them) ...
	if not event.target then return end 

end

That way, your code won't scream at you when it receives something unexpected (for example, when at a event.dead invocation, a formerly unit object got sneakily converted to a static object and now crashes on getCoalition() and similar fun. Yeah, that can now happen when the unit 'cooks off'. Fun with events.)

 

-ch

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...