• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Creaturescripts task count in party

wizinx

Active Member
Joined
Jul 6, 2010
Messages
202
Solutions
3
Reaction score
46
Location
Chile, Santiago
Hi everyone, I'm editing the code so that the tasks will count in party, but I can't make it 100% functional, since I want to make it count only by damaging the creature.
At the moment it works if they both hit almost the same damage to the creature.

Could you help me?.
Thank you

Lua:
local function getKillers(creature, party)
    local killers = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if (attacker and attacker ~= creature and timeNow - cb.ticks <= inFightTicks) then
            local p = attacker
            if p and p == party then
                killers[#killers +1] = attacker
            end
        end
    end
    return killers
end

function onKill(player, target)
    local monster = config[target:getName():lower()]
    if not monster or target:getMaster() then
        return true
    end
    local killers = getKillers(target, player)
    for k, member in pairs(killers) do
        local storageValue = member:getStorageValue(monster.storage)
        if storageValue >= monster.start then
            if storageValue >= monster.count then
                member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. monster.count .. " " .. monster.plural .. ". Report back to Tusker.")
            else
                member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. monster.count .. "] " .. monster.plural .. ".")
            end
            member:setStorageValue(monster.storage, storageValue + 1)
        end
    end
    return true
end
 
Solution
So now all party participants of everyone who hurt the monster receives storage
lone people also receive storage for hurting to the monster

Update!
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker...
So now all party participants of everyone who hurt the monster receives storage
lone people also receive storage for hurting to the monster

Update!
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker
            end
        end
    end
    return objs
end

local function applyStorages(player, info)
    local storageValue = player:getStorageValue(info.storage)
    if storageValue >= info.start then
        if storageValue >= info.count then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. info.count .. " " .. info.plural .. ". Report back to Tusker.")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. info.count .. "] " .. info.plural .. ".")
        end
        player:setStorageValue(info.storage, storageValue + 1)
    end
end

function onKill(player, creature)
    local info = config[creature:getName():lower()]
    if not info or creature:getMaster() then
        return true
    end

    for _, obj in pairs(getObjs(creature)) do
        if getmetatable(obj) == Party then
            for _, member in pairs({obj:getLeader(), unpack(obj:getMembers())}) do
                applyStorages(member, info)
            end
        else
            applyStorages(obj, info)
        end
    end
    return true
end
 
Last edited:
Solution
The problem with this is multiple people in the party do about the same dmg, the onkill can fire once for each player and if you're doing tasks in a group of 5 for example and that happens, you basically have 25 kills as each trigger will give each party member a point
 
The problem with this is multiple people in the party do about the same dmg, the onkill can fire once for each player and if you're doing tasks in a group of 5 for example and that happens, you basically have 25 kills as each trigger will give each party member a point
This event only runs once when the player kills a creature.

If this does not happen on your server, then you should update your server sources as this behavior is incorrect.
Only one player can be the lastHitKiller

However I think you raised your answer wrong, I think I understand what you mean, I will take a look at the code again and if there is something wrong I will update it
Post automatically merged:

Updated the code, thanks @pink_panther
 
Last edited:
This event only runs once when the player kills a creature.

If this does not happen on your server, then you should update your server sources as this behavior is incorrect.
Only one player can be the lastHitKiller

However I think you raised your answer wrong, I think I understand what you mean, I will take a look at the code again and if there is something wrong I will update it
Post automatically merged:

Updated the code, thanks @pink_panther

Yeah im not sure why, and I guess it shouldn't but the onKill event registered on players for Tasks, etc can sometimes fire more than once per monster.

Theres a lot of threads asking for help with Task pints counting for the party, but running into this same problem.
 
So now all party participants of everyone who hurt the monster receives storage
lone people also receive storage for hurting to the monster

Update!
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker
            end
        end
    end
    return objs
end

local function applyStorages(player, info)
    local storageValue = player:getStorageValue(info.storage)
    if storageValue >= info.start then
        if storageValue >= info.count then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. info.count .. " " .. info.plural .. ". Report back to Tusker.")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. info.count .. "] " .. info.plural .. ".")
        end
        player:setStorageValue(info.storage, storageValue + 1)
    end
end

function onKill(player, creature)
    local info = config[creature:getName():lower()]
    if not info or creature:getMaster() then
        return true
    end

    for _, obj in pairs(getObjs(creature)) do
        if getmetatable(obj) == Party then
            for _, member in pairs({obj:getLeader(), unpack(obj:getMembers())}) do
                applyStorages(member, info)
            end
        else
            applyStorages(obj, info)
        end
    end
    return true
end


Hello, I have problems in the sense that they take advantage of the task, could you make it count only the members in fight? Greetings
 
So now all party participants of everyone who hurt the monster receives storage
lone people also receive storage for hurting to the monster

Update!
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker
            end
        end
    end
    return objs
end

local function applyStorages(player, info)
    local storageValue = player:getStorageValue(info.storage)
    if storageValue >= info.start then
        if storageValue >= info.count then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. info.count .. " " .. info.plural .. ". Report back to Tusker.")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. info.count .. "] " .. info.plural .. ".")
        end
        player:setStorageValue(info.storage, storageValue + 1)
    end
end

function onKill(player, creature)
    local info = config[creature:getName():lower()]
    if not info or creature:getMaster() then
        return true
    end

    for _, obj in pairs(getObjs(creature)) do
        if getmetatable(obj) == Party then
            for _, member in pairs({obj:getLeader(), unpack(obj:getMembers())}) do
                applyStorages(member, info)
            end
        else
            applyStorages(obj, info)
        end
    end
    return true
end

1675246831605.png

What is wrong?
 
So now all party participants of everyone who hurt the monster receives storage
lone people also receive storage for hurting to the monster

Update!
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker
            end
        end
    end
    return objs
end

local function applyStorages(player, info)
    local storageValue = player:getStorageValue(info.storage)
    if storageValue >= info.start then
        if storageValue >= info.count then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. info.count .. " " .. info.plural .. ". Report back to Tusker.")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. info.count .. "] " .. info.plural .. ".")
        end
        player:setStorageValue(info.storage, storageValue + 1)
    end
end

function onKill(player, creature)
    local info = config[creature:getName():lower()]
    if not info or creature:getMaster() then
        return true
    end

    for _, obj in pairs(getObjs(creature)) do
        if getmetatable(obj) == Party then
            for _, member in pairs({obj:getLeader(), unpack(obj:getMembers())}) do
                applyStorages(member, info)
            end
        else
            applyStorages(obj, info)
        end
    end
    return true
end

Hello, thank you very much, it helped me, but I have a problem.

can you add that the tasks count only party:isSharedExperienceActive please, I tried to do it but it doesn't work
 
Hello, thank you very much, it helped me, but I have a problem.

can you add that the tasks count only party:isSharedExperienceActive please, I tried to do it but it doesn't work
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party and party:isSharedExperienceActive() then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker
            end
        end
    end
    return objs
end

local function applyStorages(player, info)
    local storageValue = player:getStorageValue(info.storage)
    if storageValue >= info.start then
        if storageValue >= info.count then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. info.count .. " " .. info.plural .. ". Report back to Tusker.")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. info.count .. "] " .. info.plural .. ".")
        end
        player:setStorageValue(info.storage, storageValue + 1)
    end
end

function onKill(player, creature)
    local info = config[creature:getName():lower()]
    if not info or creature:getMaster() then
        return true
    end
    for _, obj in pairs(getObjs(creature)) do
        if getmetatable(obj) == Party then
            for _, member in pairs({obj:getLeader(), unpack(obj:getMembers())}) do
                applyStorages(member, info)
            end
        else
            applyStorages(obj, info)
        end
    end
    return true
end
 
Lua:
local function getObjs(creature)
    local objs = {}
    local timeNow = os.mtime()
    local inFightTicks = configManager.getNumber(configKeys.PZ_LOCKED)
    for uid, cb in pairs(creature:getDamageMap()) do
        local attacker = Player(uid)
        if attacker and timeNow - cb.ticks <= inFightTicks then
            local party = attacker:getParty()
            if party and party:isSharedExperienceActive() then
                local lid = party:getLeader():getId()
                if not objs[lid] then
                    objs[lid] = party
                end
            else
                objs[attacker:getId()] = attacker
            end
        end
    end
    return objs
end

local function applyStorages(player, info)
    local storageValue = player:getStorageValue(info.storage)
    if storageValue >= info.start then
        if storageValue >= info.count then
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have already killed " .. info.count .. " " .. info.plural .. ". Report back to Tusker.")
        else
            player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have killed [" .. storageValue .. "/" .. info.count .. "] " .. info.plural .. ".")
        end
        player:setStorageValue(info.storage, storageValue + 1)
    end
end

function onKill(player, creature)
    local info = config[creature:getName():lower()]
    if not info or creature:getMaster() then
        return true
    end
    for _, obj in pairs(getObjs(creature)) do
        if getmetatable(obj) == Party then
            for _, member in pairs({obj:getLeader(), unpack(obj:getMembers())}) do
                applyStorages(member, info)
            end
        else
            applyStorages(obj, info)
        end
    end
    return true
end
Is it suitable for TFS 0.4?
 
Back
Top