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

Solved [tfs 1.0] Experience from killing higher level players

imkingran

Learning everyday.
Premium User
Joined
Jan 15, 2014
Messages
1,317
Solutions
35
Reaction score
434
Hello community,

How can I change this code so that players can gain experience from killing all higher level players without a level range.

So I want to change this to the level player who is being killed.
g_config.getNumber(ConfigManager::EXP_FROM_PLAYERS_LEVEL_RANGE)


This is what it is normally:
Code:
uint64_t Player::getGainedExperience(Creature* attacker) const
{
    if (g_config.getBoolean(ConfigManager::EXPERIENCE_FROM_PLAYERS)) {
        Player* attackerPlayer = attacker->getPlayer();
        if (attackerPlayer && attackerPlayer != this && skillLoss && std::abs((int32_t)(attackerPlayer->getLevel() - level)) <= g_config.getNumber(ConfigManager::EXP_FROM_PLAYERS_LEVEL_RANGE)) {
            return std::max<uint64_t>(0, std::floor(getLostExperience() * getDamageRatio(attacker) * 0.75));
        }
    }
    return 0;
}


This is my attempt to change it:

Code:
uint64_t Player::getGainedExperience(Creature* attacker) const
{
    if (g_config.getBoolean(ConfigManager::EXPERIENCE_FROM_PLAYERS)) {
        Player* attackerPlayer = attacker->getPlayer();
        if (attackerPlayer && attackerPlayer != this && skillLoss && std::abs((int32_t)(attackerPlayer->getLevel() - 0)) <= level) {
            return std::max<uint64_t>(0, std::floor(getLostExperience() * getDamageRatio(attacker) * 0.020));
        }
    }
    return 0;
}

But i'm getting this error:

Code:
1>..\src\player.cpp(3354): warning C4018: '<=' : signed/unsigned mismatch
 
Last edited:
Solution
Why aren't you just using Lua for this?

e.g
Lua:
function onKill(cid, target, lastHit)
    local attackPlayer = Player(target)
    if not attackPlayer then
        return true
    end

    for id, damage in pairs(attackPlayer:getDamageMap()) do
        local player = Player(id)
        if player then
            if attackPlayer:getLevel() >= player:getLevel() then
                local experience = attackPlayer:getExperience()
                local expFormula = ((experience / 100) * 0.75)
                player:addExperience(math.floor(expFormula), true)
            end
        end
    end
end
try this line
Code:
uint64_t Player::getGainedExperience(Creature* attacker) const
{
    if (g_config.getBoolean(ConfigManager::EXPERIENCE_FROM_PLAYERS)) {
        Player* attackerPlayer = attacker->getPlayer();
        if (attackerPlayer && attackerPlayer != this && skillLoss){
            return std::max<uint64_t>(0, std::floor(getLostExperience() * getDamageRatio(attacker) * 0.020));
        }
    }
    return 0;
}
 
try this line
Code:
uint64_t Player::getGainedExperience(Creature* attacker) const
{
    if (g_config.getBoolean(ConfigManager::EXPERIENCE_FROM_PLAYERS)) {
        Player* attackerPlayer = attacker->getPlayer();
        if (attackerPlayer && attackerPlayer != this && skillLoss){
            return std::max<uint64_t>(0, std::floor(getLostExperience() * getDamageRatio(attacker) * 0.020));
        }
    }
    return 0;
}

Thanks, but with this version even Higher level players will gain experience from killing players lower level than them as well.

How can I make it so players will only gain experience if they kill someone who is a higher level than they are?

I know I did not explain it so well in my first post, sorry for that. :(
 
Why aren't you just using Lua for this?

e.g
Lua:
function onKill(cid, target, lastHit)
    local attackPlayer = Player(target)
    if not attackPlayer then
        return true
    end

    for id, damage in pairs(attackPlayer:getDamageMap()) do
        local player = Player(id)
        if player then
            if attackPlayer:getLevel() >= player:getLevel() then
                local experience = attackPlayer:getExperience()
                local expFormula = ((experience / 100) * 0.75)
                player:addExperience(math.floor(expFormula), true)
            end
        end
    end
end
 
Solution
Thanks @Ninja it's working great an much easier to edit.

I'll try to always find a Lua solution first wherever possible from now on. :D
 
Code:
Lua Script Error: [CreatureScript Interface]
data/creaturescripts/scripts/others/pvpexperience.lua:onKill
data/creaturescripts/scripts/others/pvpexperience.lua:3: attempt to index local 'attackPlayer' (a nil value)
stack traceback:
    [C]: in function '__index'
    data/creaturescripts/scripts/others/pvpexperience.lua:3: in function <data/creaturescripts/scripts/others/pvpexperience.lua:1>

Hey @Ninja I keep getting this error when players kill monsters, is there a way to make it check if the (target) is a another player and if not return false?
 
Code:
function onKill(cid, target, lastHit)
    if isPlayer(target) then
        local attackPlayer = Player(target)
        for id, damage in pairs(attackPlayer:getDamageMap()) do
            local player = Player(id)
            if player then
                if attackPlayer:getLevel() >= player:getLevel() then
                    local experience = attackPlayer:getExperience()
                    local expFormula = ((experience / 100) * 0.75)
                    player:addExperience(math.floor(expFormula), true)
                end
            end
        end
    end

Not tested or anything but there is an 'isPlayer(cid)' function to check the target against, there is definitely an error in there im sure but you can see where you could check
 
Last edited:
Not sure how to do it but its going to be something like this:

Code:
function onDeath(creature, corpse, killer, mostDamageKiller, lastHitUnjustified, mostDamageUnjustified)
    if isPlayer(creature) then
        killers = creature:getDamageMap()
            for i, v in ipairs(killers) do
                PLAYER = Player(v)
                    if PLAYER then
                        PLAYER:addExperience(100, true)
                    end
            end
    end
return true
end
 
How to make it work only if it is not in the PVP zone?
@Ninja @imkingran

example +/- :

Code:
 if attackPlayer:getLevel() >= player:getLevel() and ZONE_PVP == false then

xD
 
Last edited by a moderator:
How to make it work only if it is not in the PVP zone?
@Ninja @imkingran

example +/- :

Code:
 if attackPlayer:getLevel() >= player:getLevel() and ZONE_PVP == false then

xD

Code:
attackPlayer:getTile():hasFlag(TILESTATE_PVPZONE)

Will return true or false depending on the situation.
 
Back
Top Bottom