local killTask = CreatureEvent("TaskKill")
local taskSendQueue = {}
local taskSendScheduled = {}
local function queueTaskUpdate(player, taskData)
local pid = player:getId()
taskSendQueue[pid] = taskSendQueue[pid] or {}
table.insert(taskSendQueue[pid], taskData)
if taskSendScheduled[pid] then
return
end
taskSendScheduled[pid] = true
addEvent(function()
local p = Player(pid)
if not p then
taskSendQueue[pid] = nil
taskSendScheduled[pid] = nil
return
end
for _, data in ipairs(taskSendQueue[pid] or {}) do
print("[Task System] Sending payload via ExtendedOpcode 125:", serializeTaskTable(data))
p:sendExtendedOpcode(125, serializeTaskTable(data))
end
taskSendQueue[pid] = nil
taskSendScheduled[pid] = nil
end, 50)
end
function killTask.onKill(creature, target)
local player = creature:getPlayer()
if not player or not target or not target:isMonster() then
return true
end
local targetName = target:getName():lower()
print("[Task System] onKill triggered! target:", targetName)
if not TASKS then
print("[Task System] ERROR: 'TASKS' global table is not defined!")
return true
end
for taskId, task in pairs(TASKS) do
local match = false
local multiplier = 1
if type(task.monster) == "string" then
match = (targetName == task.monster:lower())
elseif type(task.monster) == "table" then
for _, m in ipairs(task.monster) do
if targetName == tostring(m.name):lower() then
multiplier = tonumber(m.points) or 1
match = true
break
end
end
end
if match then
local key = task.storage or (10000 + taskId)
local current = math.max(0, player:getStorageValue(key))
print(string.format("[Task System] Match logic! current: %d, required: %d, multiplier: %d", current, task.amount, multiplier))
if current < task.amount then
local newProgress = math.min(current + multiplier, task.amount)
player:setStorageValue(key, newProgress)
local rewards = {}
for _, reward in ipairs(task.reward or {}) do
local item = ItemType(reward.itemId)
if item and item:getId() ~= 0 then
table.insert(rewards, { itemId = item:getId(), count = reward.count })
else
print(string.format("[Task] Invalid reward itemId %s in task '%s'", tostring(reward.itemId), tostring(task.name)))
end
end
local monsters = {}
if type(task.monster) == "table" then
for _, m in ipairs(task.monster) do
table.insert(monsters, { name = m.name, lookType = m.lookType, points = m.points })
end
else
table.insert(monsters, { name = task.monster, lookType = task.lookType, points = 1 })
end
queueTaskUpdate(player, {
progress = newProgress,
total = task.amount,
name = task.name,
rewards = rewards,
lookType = task.lookType,
monster = monsters
})
if newProgress >= task.amount then
for _, reward in ipairs(task.reward or {}) do
player:addItem(reward.itemId, reward.count)
end
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You completed the task: " .. task.name .. "!")
end
end
end
end
return true
end
killTask:register()