• 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 [TFS 1.x] Help with getDamageMap and table

E

Evil Puncker

Guest
hello everyone, I'm trying to do a script to give achievement to the player that did the most damage to the creature, and there is a table with creatures, it looks like this:

Lua:
local config = {
    -- [names] {amount, achievement}
    ["Shaburak Demon", "Shaburak Prince"] = {amount = 400, achievement = "Shaburak Nemesis"},
    ["Askarak Prince", "Askarak Demon"] = {amount = 400, achievement = "Askarak Nemesis"},
    ["Slayer of Anmothra"] = {amount = 1, achievement = "Slayer of Anmothra"}
}

function onKill(creature, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end

    local targetName = target:getName():lower()
    if targetName ~= creatureName then
        return true
    end

    for attackerId, damage in pairs(target:getDamageMap()) do
        local tmpPlayer = Player(attackerId)
        if tmpPlayer then
        end

        if config.amount > 1 then
            player:addAchievementProgress(config.achievement, config.amount)
        else
            player:addAchievement(config.achievement)
        end
    end
    return true
end

it is just a draft, I need help with the getDamageMap() to get the most damage one, and help with how to get the values from the table

any help is appreciated
 
Solution
In data/creaturescripts/creaturescripts.xml add new line:
XML:
<event type="kill" name="Achievements" script="achievements.lua"/>


In data/creaturescripts/scripts/ add new file named achievements.lua containing:
Lua:
local config = {
    ['shaburak demon'] = {amount = 400, achievement = 'Shaburak Nemesis'},
    ['shaburak prince'] = {amount = 400, achievement = 'Shaburak Nemesis'},
    ['askarak prince'] = {amount = 400, achievement = 'Askarak Nemesis'},
    ['askarak demon'] = {amount = 400, achievement = 'Askarak Nemesis'},
    ['anmothra'] = {amount = 1, achievement = 'Slayer of Anmothra'},
    ['rat'] = {amount = 10, achievement = 'rat'}
}

function onKill(creature, target)
    local targetMonster = Monster(target)
    local player...
hello everyone, I'm trying to do a script to give achievement to the player that did the most damage to the creature, and there is a table with creatures, it looks like this:

Lua:
local config = {
    -- [names] {amount, achievement}
    ["Shaburak Demon", "Shaburak Prince"] = {amount = 400, achievement = "Shaburak Nemesis"},
    ["Askarak Prince", "Askarak Demon"] = {amount = 400, achievement = "Askarak Nemesis"},
    ["Slayer of Anmothra"] = {amount = 1, achievement = "Slayer of Anmothra"}
}

function onKill(creature, target)
    if not target:isMonster() or target:getMaster() then
        return true
    end

    local targetName = target:getName():lower()
    if targetName ~= creatureName then
        return true
    end

    for attackerId, damage in pairs(target:getDamageMap()) do
        local tmpPlayer = Player(attackerId)
        if tmpPlayer then
        end

        if config.amount > 1 then
            player:addAchievementProgress(config.achievement, config.amount)
        else
            player:addAchievement(config.achievement)
        end
    end
    return true
end

it is just a draft, I need help with the getDamageMap() to get the most damage one, and help with how to get the values from the table

any help is appreciated
Lua:
if targetName ~= creatureName then
where you declare creatureName variable?
Lua:
if config.amount > 1 then
            player:addAchievementProgress(config.achievement, config.amount)
        else
            player:addAchievement(config.achievement)
        end
player variable isn't declared too

You can do:
Lua:
    local higherAttacker = {attackerId = 0, damage = 0}--hold attackerId and damage
    for attackerId, damage in pairs(target:getDamageMap()) do --get damageMap
        if damage > higherAttacker.damage then --if damage delt on for loop is higher than damage on higherAttacker table update higherAttacker info
            higherAttacker.playerId = attackerId
            higherAttacker.damage = damage
        end
    end
    print("Higher Attacker is: "..Creature(higherAttacker.attackerId):getName().." that delt "..higherAttacker.damage.." damage.")
I don't know if is the best way to do, but should work.
Be sure to check if attacker is a player, if player exist and all neededs checks...

Hope helps you.
 
@zxmatzx thanks but it seems to be more complicated than I thought, I'm still stuck with checking target names xD

current script:
Lua:
local config = {
    -- [names] = {amount, achievement}
    [{"shaburak demon", "shaburak prince"}] = {amount = 400, achievement = "Shaburak Nemesis"},
    [{"askarak prince", "askarak demon"}] = {amount = 400, achievement = "Askarak Nemesis"},
    ["anmothra"] = {amount = 1, achievement = "Slayer of Anmothra"},
    ["rat"] = {amount = 10, achievement = "rat"}
}

local creatureevent = CreatureEvent("example")

function creatureevent.onKill(creature, target)
    if not target:isMonster() or target:getMaster() or not creature:isPlayer() then
        return true
    end

    local targetName = target:getName():lower()
    if targetName ~= config then
        print("1")
        return true
    end
    print("2")
    local higherAttacker = {attackerId = 0, damage = 0}--hold attackerId and damage
    for attackerId, damage in pairs(target:getDamageMap()) do --get damageMap
        if damage > higherAttacker.damage then --if damage delt on for loop is higher than damage on higherAttacker table update higherAttacker info
            higherAttacker.playerId = attackerId
            higherAttacker.damage = damage
            if config.amount > 1 then
                Player(attackerId):addAchievementProgress(config.achievement, config.amount)
                print("3")
            else
                Player(attackerId):addAchievement(config.achievement)
                print("4")
            end
        end
    end
    print("Higher Attacker is: "..Creature(higherAttacker.attackerId):getName().." that delt "..higherAttacker.damage.." damage.")
    return true
end

creatureevent:register()
 
Hi,
I think you can't pass a table as index. Try a Monsters name to each index of table config, also this line should be:
Lua:
if not config[targetName] then
after you split the names in index.

When i get home i can fix It to you
Check for typos, written on phone and auto-complete is for another language 🤣
 
In data/creaturescripts/creaturescripts.xml add new line:
XML:
<event type="kill" name="Achievements" script="achievements.lua"/>


In data/creaturescripts/scripts/ add new file named achievements.lua containing:
Lua:
local config = {
    ['shaburak demon'] = {amount = 400, achievement = 'Shaburak Nemesis'},
    ['shaburak prince'] = {amount = 400, achievement = 'Shaburak Nemesis'},
    ['askarak prince'] = {amount = 400, achievement = 'Askarak Nemesis'},
    ['askarak demon'] = {amount = 400, achievement = 'Askarak Nemesis'},
    ['anmothra'] = {amount = 1, achievement = 'Slayer of Anmothra'},
    ['rat'] = {amount = 10, achievement = 'rat'}
}

function onKill(creature, target)
    local targetMonster = Monster(target)
    local player = Player(creature)
    local targetMonsterConfig = config[targetMonster:getName():lower()]
    
    if not targetMonster or targetMonster:getMaster() or not player or not targetMonsterConfig then
        return true
    end
    
    temp = {playerId = 0, damage = 0}
    for currentPlayerId, currentDamage in pairs(targetMonster:getDamageMap()) do
        local attackerPlayer = Player(currentPlayerId)
        if attackerPlayer then
            if temp.damage < currentDamage then
                temp.playerId = currentPlayerId
                temp.damage = currentDamage
            end
        end
    end
    
    if temp.playerId == 0 then
        return true
    end
    
    winnerPlayer = Player(temp.playerId)
    if not winnerPlayer then
        return true
    end
    
    if targetMonsterConfig.amount > 1 then
        winnerPlayer:addAchievementProgress(targetMonsterConfig.achievement, targetMonsterConfig.amount)
    else
        winnerPlayer:addAchievement(targetMonsterConfig.achievement)
    end
end

In data/creaturescripts/scripts/login.lua before
Lua:
return true
end
that ends the file add new line:
Lua:
    player:registerEvent("Achievements")
 
Solution
I believe?

Lua:
Creature::damageMap = {
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
}
 
I believe?

Lua:
Creature::damageMap = {
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
    [attacker:getID()] = { total: damageDone, ticks: timeStampOfLastLandedAttack },
}
🤔 I have no idea what to do with this
 
🤔 I have no idea what to do with this

I believe it's the structure of how a damageMap is made...


Lua:
    for currentPlayerId, currentDamage in pairs(targetMonster:getDamageMap()) do
        local attackerPlayer = Player(currentPlayerId)
        if attackerPlayer then
            if temp.damage < currentDamage then
                temp.playerId = currentPlayerId
                temp.damage = currentDamage
            end
        end
    end

So this is wrong. What's being called "currentDamage" here is not a number, but an object, or table as Lua calls them, with a "total" and a "ticks" property.

currentDamage.total would be what you are actually after I think? Sorry, this seemed like one of those scripts I'd start rewriting then someone would beat me to the punch. 🤔 Guess I was wrong.
 
I believe it's the structure of how a damageMap is made...


Lua:
    for currentPlayerId, currentDamage in pairs(targetMonster:getDamageMap()) do
        local attackerPlayer = Player(currentPlayerId)
        if attackerPlayer then
            if temp.damage < currentDamage then
                temp.playerId = currentPlayerId
                temp.damage = currentDamage
            end
        end
    end

So this is wrong. What's being called "currentDamage" here is not a number, but an object, or table as Lua calls them, with a "total" and a "ticks" property.

currentDamage.total would be what you are actually after I think? Sorry, this seemed like one of those scripts I'd start rewriting then someone would beat me to the punch. 🤔 Guess I was wrong.

03:51 Congratulations! You earned the achievement "Askarak Nemesis".

thank you so much
 
Back
Top