Hello everyone,
I am in a project with friends and I am having trouble rooting out a problem in some code. The code is designed to register listeners for construction events, such as EVENT_PLAYER_UNIT_CONSTRUCTION_FINISH, etc. It stores these listeners by unitTypeId then by eventId. I've narrowed it down to when the unitTypeAndEventRegistered function is called, the type for listenersByEvent returns as a table as expected but the type for the inner index (listenersByEvent[whichUnitType]) returns as nil, it is supposed to return a function. I apologize in advance for messy code, I am still relatively new to Lua and programming in general as well as there are things I've done to this code for debugging purposes. This code may change in the future for a more generalized event handler but for now this is what I have as I learn.
I am in a project with friends and I am having trouble rooting out a problem in some code. The code is designed to register listeners for construction events, such as EVENT_PLAYER_UNIT_CONSTRUCTION_FINISH, etc. It stores these listeners by unitTypeId then by eventId. I've narrowed it down to when the unitTypeAndEventRegistered function is called, the type for listenersByEvent returns as a table as expected but the type for the inner index (listenersByEvent[whichUnitType]) returns as nil, it is supposed to return a function. I apologize in advance for messy code, I am still relatively new to Lua and programming in general as well as there are things I've done to this code for debugging purposes. This code may change in the future for a more generalized event handler but for now this is what I have as I learn.
Lua:
do
local constructionEventInfo = {
constructCancel = {
id = EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL,
name = "Construction Cancel",
},
constructFinish = {
id = EVENT_PLAYER_UNIT_CONSTRUCT_FINISH,
name = "Construction Finish",
},
constructStart = {
id = EVENT_PLAYER_UNIT_CONSTRUCT_START,
name = "Construction Start",
},
}
local ConstructionEventListeners = {}
local listenerCount = 0
local function unitTypeAndEventRegistered(whichUnitTypeId, whichEventId)
if listenerCount < 1 then return false end
local listenersByEvent = ConstructionEventListeners[whichUnitTypeId]
if type(listenersByEvent) == "table" and type(listenersByEvent[whichEventId]) == "function" then
return true
end
return false
end
function RegisterConstructionEventListener(whichUnitTypeId, listener, eventId)
if unitTypeAndEventRegistered(whichUnitTypeId, eventId) then
return
end
if ConstructionEventListeners[whichUnitTypeId] == nil then
ConstructionEventListeners[whichUnitTypeId] = {}
end
ConstructionEventListeners[whichUnitTypeId][eventId] = listener
listenerCount = listenerCount + 1
end
local function onConstructionEvent()
local eventId = GetTriggerEventId()
local unit = GetTriggerUnit()
local unitTypeId = GetUnitTypeId(unit)
local eventData = {
constructUnit = unit,
}
if unitTypeAndEventRegistered(unitTypeId, eventId) then
BJDebugMsg("Firing listener for " .. GetUnitName(unit) .. ", id: " .. I2S(unitTypeId))
ConstructionEventListeners[unitTypeId][eventId](eventData)
end
end
function InitializeConstructionTrigger()
local constructEventTrigger = CreateTrigger()
for i = 0, bj_MAX_PLAYERS - 1 do
for _, constructEvent in pairs(constructionEventInfo) do
TriggerRegisterPlayerUnitEvent(constructEventTrigger, Player(i), constructEvent.id, nil)
end
end
TriggerAddAction(constructEventTrigger, onConstructionEvent)
end
end
Lua:
do
local MasonryBuffConfig = {
workshopTypeId = FourCC('sk20'),
masonryBuffId = FourCC('as01'),
--masonryBuffRepairId = FourCC('sa02')
}
local function addMasonryBuffs(whichUnit)
UnitAddAbility(whichUnit, MasonryBuffConfig.masonryBuffId)
--UnitAddAbility(whichUnit, MasonryBuffConfig.masonryBuffRepairId)
end
local function onConstructFinish(eventData)
BJDebugMsg("MasonryBuff construct listener fired for " .. GetUnitName(eventData.constructUnit))
addMasonryBuffs(eventData.constructUnit)
end
function InitializeMasonryBuff()
BJDebugMsg("InitializeMasonryBuff start")
local group = CreateGroup()
GroupEnumUnitsInRect(group, GetPlayableMapRect(), nil)
local unit = FirstOfGroup(group)
while unit ~= nil do
if GetUnitTypeId(unit) == MasonryBuffConfig.workshopTypeId then
BJDebugMsg("Found pre-existing workshop: " .. GetUnitName(unit))
addMasonryBuffs(unit)
end
GroupRemoveUnit(group, unit)
unit = FirstOfGroup(group)
end
DestroyGroup(group)
BJDebugMsg("Registering MasonryBuff construction listener for id:" .. I2S(MasonryBuffConfig.workshopTypeId))
RegisterConstructionEventListener(MasonryBuffConfig.workshopTypeId, onConstructFinish, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH)
end
end
