• 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!

Lua [SOLVED] Divide each player in storage math.

Hookah

Member
Joined
Jan 20, 2023
Messages
58
Reaction score
9
Hello I'm trying to make this task points system to give each player his task points but if some player with higher storage value "helps" to kill the monster, then the storage for both players is the one that give the last hit. I dont want to put +1 on storages since I want to make it work with "points" some monsters give +3 points

Code:
                                            local pointsToSet = math.min(currentPoints + taskMonster.points, task.pointsToFinish)

                                            attackerPlayer:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, pointsToSet)

                                            attackerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, string.format("%s task: %d/%d", task.name, pointsToSet, task.pointsToFinish))

Function

Lua:
function tryAddTaskPoints(player, monster, isFromParty)
    local currentTasks = getCurrentTasksForPlayer(player)
    if #currentTasks > 0 then
        for i = 1, #currentTasks, 1 do
            local task = currentTasks[i]
            if not isFromParty or isFromParty and task.countPartyMembers then
                for j = 1, #task.monsters, 1 do
                    local taskMonster = task.monsters[j]
                    if taskMonster.name == monster:getName() then
                        local storage = TASK_SYSTEM.CONFIG.startMonsterStorage + task.id
                        local currentPoints = player:getStorageValue(storage)
                for pid, _ in pairs(monster:getDamageMap()) do
                            if currentPoints ~= task.pointsToFinish then
                        local attackerPlayer = Player(pid)
                            if attackerPlayer then
                            if attackerPlayer:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id) then
                                            local pointsToSet = math.min(currentPoints + taskMonster.points, task.pointsToFinish)
                                            attackerPlayer:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, pointsToSet)
                                            attackerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, string.format("%s task: %d/%d", task.name, pointsToSet, task.pointsToFinish))
                            end
                        end
                    end
                end
                        end
                end
            end
        end
    end
end

Thank you for reading
 
Last edited:
I don't understand what your question is / what you want help with.
Can you clarify better?

In the meantime, here is your code tabbed correctly.
Lua:
function tryAddTaskPoints(player, monster, isFromParty)
    local currentTasks = getCurrentTasksForPlayer(player)
    if #currentTasks > 0 then
        for i = 1, #currentTasks, 1 do
            local task = currentTasks[i]
            if not isFromParty or isFromParty and task.countPartyMembers then
                for j = 1, #task.monsters, 1 do
                    local taskMonster = task.monsters[j]
                    if taskMonster.name == monster:getName() then
                        local storage = TASK_SYSTEM.CONFIG.startMonsterStorage + task.id
                        local currentPoints = player:getStorageValue(storage)
                        for pid, _ in pairs(monster:getDamageMap()) do
                            if currentPoints ~= task.pointsToFinish then
                                local attackerPlayer = Player(pid)
                                if attackerPlayer then
                                    if attackerPlayer:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id) then
                                        local pointsToSet = math.min(currentPoints + taskMonster.points, task.pointsToFinish)
                                        attackerPlayer:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, pointsToSet)
                                        attackerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, string.format("%s task: %d/%d", task.name, pointsToSet, task.pointsToFinish))
                                    end
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
 
Thank you for that I guess that was hard to read LOL.
@script: when the script gives the task point it generalize all players, so if I have 5 trolls of 50 and some other guy kill 1 troll (with getDamageMap) with me and he has 40 trolls out of 50, then my storage values goes to 40 same as him
 
Thank you for that I guess that was hard to read LOL.
@script: when the script gives the task point it generalize all players, so if I have 5 trolls of 50 and some other guy kill 1 troll (with getDamageMap) with me and he has 40 trolls out of 50, then my storage values goes to 40 same as him
The problem is here
Lua:
local pointsToSet = math.min(currentPoints + taskMonster.points, task.pointsToFinish)

You are using currentPoints in the calculation (from last hitter), when instead you should be using attackerPlayer storage value of currentPoints.

Solution:
Lua:
local pointsToSet = math.min(attackerPlayer:getStorageValue(storage) + taskMonster.points, task.pointsToFinish)

---------------------------
I believe there is some other issues with the code, that I'd look into.

if not isFromParty or isFromParty and task.countPartyMembers then
I don't believe this is checking what it is intending to check.

if currentPoints ~= task.pointsToFinish then
The location of this check inside of the damageMap.. will cause some players to not be checked, when the person who killed the creature comes around in the loop. (They could potentially go from 49 -> 50 kills, and 'max out' pointsToFinish, for example, and then every player after that in the damage loop would not receive any reward.)

-------
Hope that helps.
 
Should I set
Code:
if currentPoints~= task.pointsToFinish then
above getdamage?

Tested and it works as it should Xikini thank you =]

btw do you know why my Available tasks and my Current tasks are always the same? (I should be able to pick only 3 of these)
full code:
TASK_TYPES = {
DRAGON_TASK = 1,
TROLL_TASK = 2,
GOBLIN_TASK = 3,
MINOTAUR_TASK = 4,
WASP_TASK = 5,
WOLF_TASK = 6,
DEMON_TASK = 7
}

function taskAddStorage(player, key, value)
player:setStorageValue(key, math.max(player:getStorageValue(key), 0) + value)
end

function taskSetStorage(player, key, value)
player:setStorageValue(key, value)
end

TASK_SYSTEM = {
CONFIG = {
maximumTasksAtOnce = 3,
startedTasksStorage = 23999,
startTaskStorage = 24000,
startMonsterStorage = 25000,
countPartyMembers = true
},
TASKS = {
[TASK_TYPES.DRAGON_TASK] = {
id = TASK_TYPES.DRAGON_TASK,
name = "Dragons",
maximumRepeat = 100,
countPartyMembers = false,
monsters = {
{name = "Dragon", points = 1},
{name = "Dragon Lord", points = 2},
},
level = {minimum = 1, maximum = 200},
pointsToFinish = 1,
rewards = {
items = {{id = 3043, count = 10}, {id = 2400}},
experience = 100000,
storages = {
{key = 12344, func = taskAddStorage, value = 10, message = "some random storage1"}
}
}
},
[TASK_TYPES.TROLL_TASK] = {
id = TASK_TYPES.TROLL_TASK,
name = "Trolls",
maximumRepeat = 10,
countPartyMembers = true,
monsters = {
{name = "Troll", points = 1},
{name = "Island Troll", points = 1},
{name = "Swamp Troll", points = 1},
},
level = {minimum = 1, maximum = 999},
pointsToFinish = 75,
rewards = {
items = {{id = 3035, count = 25}, {id = 2400}},
experience = 30000,
storages = {
{key = 12345, func = taskAddStorage, value = 10, message = "some random storage1"}
}
}
},
[TASK_TYPES.GOBLIN_TASK] = {
id = TASK_TYPES.GOBLIN_TASK,
name = "Goblins",
maximumRepeat = 10,
countPartyMembers = false,
monsters = {
{name = "Goblin", points = 1},
},
level = {minimum = 1, maximum = 999},
pointsToFinish = 40,
rewards = {
items = {{id = 3035, count = 15}, {id = 2400}},
experience = 20000,
storages = {
{key = 12346, func = taskAddStorage, value = 10, message = "some random storage1"}
}
}
},
[TASK_TYPES.MINOTAUR_TASK] = {
id = TASK_TYPES.MINOTAUR_TASK,
name = "Minotaurs",
maximumRepeat = 10,
countPartyMembers = false,
monsters = {
{name = "Minotaur", points = 1},
{name = "Minotaur Guard", points = 2},
{name = "Minotaur Archer", points = 2},
{name = "Minotaur Mage", points = 3},
},
level = {minimum = 1, maximum = 200},
pointsToFinish = 300,
rewards = {
items = {{id = 3035, count = 100}, {id = 2400}},
experience = 130000,
storages = {
{key = 12347, func = taskAddStorage, value = 10, message = "some random storage1"}
}
}
},
[TASK_TYPES.WASP_TASK] = {
id = TASK_TYPES.WASP_TASK,
name = "Wasps",
maximumRepeat = 5,
countPartyMembers = true,
monsters = {
{name = "Wasp", points = 1},
},
level = {minimum = 1, maximum = 200},
pointsToFinish = 50,
rewards = {
items = {{id = 3035, count = 40}, {id = 2400}},
experience = 20000,
storages = {
{key = 12348, func = taskAddStorage, value = 10, message = "some random storage1"}
}
}
},
[TASK_TYPES.WOLF_TASK] = {
id = TASK_TYPES.WOLF_TASK,
name = "Wolves",
maximumRepeat = 5,
countPartyMembers = false,
monsters = {
{name = "Wolf", points = 1},
},
level = {minimum = 1, maximum = 200},
pointsToFinish = 35,
rewards = {
items = {{id = 3035, count = 20}, {id = 2400}},
experience = 15000,
storages = {
{key = 12349, func = taskAddStorage, value = 10, message = "some random storage1"}
}
}
},
[TASK_TYPES.DEMON_TASK] = {
id = TASK_TYPES.DEMON_TASK,
name = "Demons",
maximumRepeat = 3,
countPartyMembers = false,
monsters = {{name = "Demon", points = 1}},
level = {minimum = 100, maximum = 200},
pointsToFinish = 666,
rewards = {
items = {{id = 2160, count = 100}},
experience = 6666666,
bossFight = {
name = "Demon Boss",
teleport = {x = 1000, y = 1000, z = 7}
},
storages = {
{key = 12345, func = taskSetStorage, value = 1, message = "some random storage2"}
}
}
}
}
}

function getCurrentTasksForPlayer(player)
local currentTasks = {}
for i = 1, #TASK_SYSTEM.TASKS, 1 do
local task = TASK_SYSTEM.TASKS
if player:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id) ~= -1 then
table.insert(currentTasks, #currentTasks + 1, task)
end
end
return currentTasks
end

function getAvailableTasksForPlayer(player)
local availableTasks = {}
for i = 1, #TASK_SYSTEM.TASKS, 1 do
local task = TASK_SYSTEM.TASKS
local taskAvailable = true
if task.level then
local playerLevel = player:getLevel()
if task.level.minimum and playerLevel < task.level.minimum then
taskAvailable = false
end
if task.level.maximum and playerLevel > task.level.maximum then
taskAvailable = false
end
end
if taskAvailable then
table.insert(availableTasks, #availableTasks + 1, task)
end
end
return availableTasks
end

function canPlayerStartNewTask(player, task)
return (player:getStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage) < TASK_SYSTEM.CONFIG.maximumTasksAtOnce)
and not isTaskStarted(player, task) and task.maximumRepeat
and (player:getStorageValue(TASK_SYSTEM.CONFIG.startTaskStorage + task.id) < task.maximumRepeat)
end

function startTask(player, task)
player:setStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage, math.max(player:getStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage), 0) + 1)
player:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, 0)
end

function rewardPlayer(player, task)
if player:isPzLocked() then
player:sendTextMessage(MESSAGE_INFO_DESCR, "You cannot claim your reward in fight.")
return false
end

if task.rewards.bossFight then
local teleported = player:teleportTo(task.rewards.bossFight.teleport)
if not teleported then
player:sendTextMessage(MESSAGE_INFO_DESCR, "You couldn't be teleported to the boss fight. Please contact administrator.")
return false
end
end

if task.rewards.items and #task.rewards.items > 0 then
for i = 1, #task.rewards.items, 1 do
local item = task.rewards.items
local count = item.count
if not count or count < 1 then count = 1 end
player:addItem(item.id, count)
end
end

if task.rewards.experience then
player:addExperience(task.rewards.experience)
end

if task.rewards.storages and #task.rewards.storages > 0 then
for i = 1, #task.rewards.storages, 1 do
local storage = task.rewards.storages
storage.func(player, storage.key, storage.value)
end
end

return true
end

function finishTask(player, task)
if not rewardPlayer(player, task) then return end
player:setStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage, math.max(
player:getStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage), 0) - 1)
player:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, -1)
player:setStorageValue(TASK_SYSTEM.CONFIG.startTaskStorage + task.id, math.max(player:getStorageValue(TASK_SYSTEM.CONFIG.startTaskStorage + task.id, 0) + 1))
end

function cancelTask(player, task)
player:setStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage, math.max(
player:getStorageValue(TASK_SYSTEM.CONFIG.startedTasksStorage), 0) - 1)
player:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, -1)
end

function getTaskMessage(player, task)
local message = ""

local pointsMessage = string.format("You need to get %d points to finish this task.", task.pointsToFinish)
message = message .. pointsMessage

if isTaskStarted(player, task) then
local plural = "s"
local points = player:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id)
if points == 1 then plural = "" end
message = message .. string.format("\nYou currenly have %d point%s.", points, plural)
end

local monstersMessage = ""
for i = 1, #task.monsters, 1 do
local taskMonster = task.monsters
local plural = ""
if taskMonster.points > 1 then plural = "s" end
monstersMessage = monstersMessage .. string.format("\n%s gives %d point%s.", taskMonster.name, taskMonster.points, plural)
end
message = message .. monstersMessage

local currentRepeat = math.max(player:getStorageValue(TASK_SYSTEM.CONFIG.startTaskStorage + task.id), 0)
local currentPlural = "s"
if currentRepeat == 1 then currentPlural = "" end

local taskRepetitionMessage = string.format("\nYou can repeat this task indefinitely. Currently you did the task %d time%s", currentRepeat, currentPlural)
if task.maximumRepeat then
local maximumPlural = ""
if task.maximumRepeat > 1 then maximumPlural = "s" end
taskRepetitionMessage = string.format("\nYou can repeat this task %d time%s. Currently you did the task %d time%s",task.maximumRepeat, maximumPlural, currentRepeat, currentPlural)
end
message = message .. taskRepetitionMessage

if task.level then
if task.level.minimum then
message = message .. string.format("\nMinimum level for the task is %d.", task.level.minimum)
end
if task.level.maximum then
message = message .. string.format("\nMaximum level for the task is %d.", task.level.maximum)
end
end

if task.rewards then
local rewardsMessage = "\nRewards:"
if task.rewards.items then
for i = 1, #task.rewards.items, 1 do
local item = task.rewards.items
local itemType = ItemType(item.id)
local usePlural = false
if item.count and item.count > 1 then
usePlural = true
end
if usePlural then
rewardsMessage = rewardsMessage .. string.format("\n%d %s", item.count, itemType:getPluralName())
else
rewardsMessage = rewardsMessage .. string.format("\n%s", itemType:getName())
end
end
end

if task.rewards.experience then
rewardsMessage = rewardsMessage .. string.format("\n%d experience points", task.rewards.experience)
end

if task.rewards.storages then
for i = 1, #task.rewards.storages, 1 do
local storage = task.rewards.storages
if storage.message and storage.message ~= "" then
rewardsMessage = rewardsMessage .. string.format("\n%s", storage.message)
end
end
end

if task.rewards.bossFight then
rewardsMessage = rewardsMessage .. string.format("\nYou will be teleported to fight %s after finishing the task.", task.rewards.bossFight.name)
end
message = message .. rewardsMessage
end
return message
end

function isTaskFinished(player, task)
return (player:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id) == task.pointsToFinish)
end

function isTaskStarted(player, task)
return (player:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id) ~= -1)
end

function showTaskWindowToPlayer(player, task, back)
local window = ModalWindow {
title = string.format('%s', task.name),
message = getTaskMessage(player, task)
}

window:addButton('Back', function(button, choice) back(player) end)
window:setDefaultEscapeButton('Back')

if canPlayerStartNewTask(player, task) then
window:addButton('Start', function(button, choice)
startTask(player, task)
showTaskWindowToPlayer(player, task, back)
end)
end

if isTaskFinished(player, task) then
window:addButton('Finish', function(button, choice)
finishTask(player, task)
end)
end

if isTaskStarted(player, task) then
window:addButton('Cancel', function(button, choice)
cancelTask(player, task)
showTaskWindowToPlayer(player, task, back)
end)
end

window:sendToPlayer(player)
end

function showAllTasksWindow(player)
local window = ModalWindow {
title = 'Tasks',
message = 'Please choose which task you want to see.'
}

local availableTasks = getAvailableTasksForPlayer(player)
if #availableTasks > 0 then
for i = 1, #availableTasks, 1 do
local availableTask = availableTasks
local choice = window:addChoice(availableTask.name)
choice.task = availableTask
end

window:addButton('PickUp Task', function(button, choice)
showTaskWindowToPlayer(player, choice.task, showAllTasksWindow)
end)
window:setDefaultEnterButton('Choose')
end

window:addButton('Close')
window:setDefaultEscapeButton('Close')

window:sendToPlayer(player)
end

function showCurrentTasksWindow(player)
local window = ModalWindow {
title = 'Current tasks',
message = 'Please choose which one of your task you want to review.'
}

local availableTasks = getCurrentTasksForPlayer(player)
if #availableTasks > 0 then
for i = 1, #availableTasks, 1 do
local availableTask = availableTasks
local choice = window:addChoice(availableTask.name)
choice.task = availableTask
end

window:addButton('Choose', function(button, choice)
showTaskWindowToPlayer(player, choice.task, showCurrentTasksWindow)
end)

window:setDefaultEnterButton('Choose')
end

window:addButton('Close')
window:setDefaultEscapeButton('Close')

window:sendToPlayer(player)
end

function tryAddTaskPoints(player, monster, isFromParty)
local currentTasks = getCurrentTasksForPlayer(player)
if #currentTasks > 0 then
for i = 1, #currentTasks, 1 do
local task = currentTasks
if not isFromParty or isFromParty and task.countPartyMembers then
for j = 1, #task.monsters, 1 do
local taskMonster = task.monsters[j]
if taskMonster.name == monster:getName() then
local storage = TASK_SYSTEM.CONFIG.startMonsterStorage + task.id
local currentPoints = player:getStorageValue(storage)
if currentPoints ~= task.pointsToFinish then
for pid, _ in pairs(monster:getDamageMap()) do
local attackerPlayer = Player(pid)
if attackerPlayer then
if attackerPlayer:getStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id) then
local pointsToSet = math.min(attackerPlayer:getStorageValue(storage) + taskMonster.points, task.pointsToFinish)
attackerPlayer:setStorageValue(TASK_SYSTEM.CONFIG.startMonsterStorage + task.id, pointsToSet)
attackerPlayer:sendTextMessage(MESSAGE_INFO_DESCR, string.format("%s task: %d/%d", task.name, pointsToSet, task.pointsToFinish))
end
end
end
end
end
end
end
end
end
end
 
Last edited:
Back
Top