• 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+ Max 255 limit

T

Tibia Demon

Guest
I use OTClientV8 and I want to remove the 255 limit for magic level and skills.
I use TFS 1.3/1.4 with last commits.
I tried changing this in source not sure if its correct or not. protocolgame.cpp

C++:
void ProtocolGame::AddPlayerStats(NetworkMessage &msg)
{
    msg.addByte(0xA0);

    msg.add<uint64_t>(std::min<uint64_t>(player->getHealth(), std::numeric_limits<uint64_t>::max()));
    msg.add<uint64_t>(std::min<uint64_t>(player->getMaxHealth(), std::numeric_limits<uint64_t>::max()));

    msg.add<uint64_t>(player->getFreeCapacity());
    msg.add<uint64_t>(player->getCapacity());

    msg.add<uint64_t>(player->getExperience());

    msg.add<uint64_t>(player->getLevel());
    msg.addByte(player->getLevelPercent());

    msg.add<uint64_t>(100); // base xp gain rate
    msg.add<uint64_t>(0);    // xp voucher
    msg.add<uint64_t>(0);    // low level bonus
    msg.add<uint64_t>(0);    // xp boost
    msg.add<uint64_t>(100); // stamina multiplier (100 = x1.0)

    msg.add<uint64_t>(std::min<uint64_t>(player->getMana(), std::numeric_limits<uint64_t>::max()));
    msg.add<uint64_t>(std::min<uint64_t>(player->getMaxMana(), std::numeric_limits<uint64_t>::max()));

    msg.addByte(std::min<uint64_t>(player->getMagicLevel(), std::numeric_limits<uint64_t>::max()));
    msg.addByte(std::min<uint64_t>(player->getBaseMagicLevel(), std::numeric_limits<uint64_t>::max()));
    msg.addByte(player->getMagicLevelPercent());

    msg.addByte(player->getSoul());

    msg.add<uint64_t>(player->getStaminaMinutes());

    msg.add<uint64_t>(player->getBaseSpeed());

    Condition *condition = player->getCondition(CONDITION_REGENERATION);
    msg.add<uint64_t>(condition ? condition->getTicks() / 1000 : 0x00);

    msg.add<uint64_t>(player->getOfflineTrainingTime() / 60 / 1000);

    msg.add<uint64_t>(0); // xp boost time (seconds)
    msg.addByte(0);          // enables exp boost in the store
}

C++:
void ProtocolGame::AddPlayerSkills(NetworkMessage &msg)
{
    msg.addByte(0xA1);

    for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i)
    {
        msg.add<uint64_t>(std::min<uint64_t>(player->getSkillLevel(i), std::numeric_limits<uint64_t>::max()));
        msg.add<uint64_t>(player->getBaseSkill(i));
        msg.addByte(player->getSkillPercent(i));
    }

    for (uint8_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i)
    {
        msg.add<uint64_t>(std::min<uint64_t>(100, player->varSpecialSkills[i]));
        msg.add<uint64_t>(0);
    }
}
I have also added this to OTClientV8
Lua:
    if(version >= 1035) then
        g_game.enableFeature(GameDoubleSkills)
        g_game.enableFeature(GameBaseSkillU16)
    end
 
Solution
it seems alright,
Lua:
uint16_t
is the proper value. While uint16 max value is 65535 vs you had before uint64 which max value at: 18446744073709551615. If you want to push higher, you need then edit the client aswell.
I might shoot this shot without full info, but adding more than 255 means that otclient needs to handle 16 bits, I do wonder if that works, maybe you could rewrite of how the magic level and skills are recieved to the client.
 
I believe OTClientV8 should be able to handle 16 bits because I have already seen it on many servers without buying its source files.
So I only need to know how to edit it server side. I have tried to do it on the lines I posted UP but I fucked it and now it shows all as 0.
Post automatically merged:

This is the lines I edited
but i reverted my changes and now it looks like forgottenserver without any edits.
Post automatically merged:

I made the skills one by follow this.
but doesn't work for magic level or level or [health-mana] any idea why or what changes I need to do?
 
Last edited by a moderator:
I made it all like this and it works in game and shows correct values.
C++:
void ProtocolGame::AddPlayerStats(NetworkMessage& msg)
{
    msg.addByte(0xA0);

    msg.add<uint32_t>(std::min<int64_t>(player->getHealth(), std::numeric_limits<uint32_t>::max()));
    msg.add<uint32_t>(std::min<int64_t>(player->getMaxHealth(), std::numeric_limits<uint32_t>::max()));

    msg.add<uint32_t>(player->getFreeCapacity());
    msg.add<uint32_t>(player->getCapacity());

    msg.add<uint64_t>(player->getExperience());

    msg.add<uint32_t>(player->getLevel());
    msg.addByte(player->getLevelPercent());

    msg.add<uint16_t>(100); // base xp gain rate
    msg.add<uint16_t>(0); // xp voucher
    msg.add<uint16_t>(0); // low level bonus
    msg.add<uint16_t>(0); // xp boost
    msg.add<uint16_t>(100); // stamina multiplier (100 = x1.0)

    msg.add<uint32_t>(std::min<int64_t>(player->getMana(), std::numeric_limits<uint32_t>::max()));
    msg.add<uint32_t>(std::min<int64_t>(player->getMaxMana(), std::numeric_limits<uint32_t>::max()));

    msg.add<uint16_t>(std::min<uint64_t>(player->getMagicLevel(), std::numeric_limits<uint16_t>::max()));
    msg.add<uint16_t>(std::min<uint64_t>(player->getBaseMagicLevel(), std::numeric_limits<uint16_t>::max()));
    msg.addByte(player->getMagicLevelPercent());

    msg.addByte(player->getSoul());

    msg.add<uint16_t>(player->getStaminaMinutes());

    msg.add<uint16_t>(player->getBaseSpeed());

    Condition* condition = player->getCondition(CONDITION_REGENERATION);
    msg.add<uint16_t>(condition ? condition->getTicks() / 1000 : 0x00);

    msg.add<uint16_t>(player->getOfflineTrainingTime() / 60 / 1000);

    msg.add<uint16_t>(0); // xp boost time (seconds)
    msg.addByte(0); // enables exp boost in the store
}

void ProtocolGame::AddPlayerSkills(NetworkMessage& msg)
{
    msg.addByte(0xA1);

    for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
        msg.add<uint16_t>(std::min<int64_t>(player->getSkillLevel(i), std::numeric_limits<uint16_t>::max()));
        msg.add<uint16_t>(player->getBaseSkill(i));
        msg.addByte(player->getSkillPercent(i));
    }

    for (uint8_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
        msg.add<uint16_t>(std::min<int32_t>(100, player->varSpecialSkills[i]));
        msg.add<uint16_t>(0);
    }
}
but is it safe or I destroyed something? can someone tell me if its safe programming side?
 
it seems alright,
Lua:
uint16_t
is the proper value. While uint16 max value is 65535 vs you had before uint64 which max value at: 18446744073709551615. If you want to push higher, you need then edit the client aswell.
 
Solution
I think I have mistaken on something.
Monsters corpses aren't falling on ground. They just stand still with 0 hp like nothing happened until I logout or go off screen then return back.
speedtest.PNG
Speed always shows number - number like in this screenshot on level [8] character.
Someone can check my lines and tell me what to change pls.
I only changed this in player.h
it was like this code
C++:
static constexpr int32_t PLAYER_MAX_SPEED = 1500;
static constexpr int32_t PLAYER_MIN_SPEED = 10;
and I change it to this code
C++:
static constexpr int32_t PLAYER_MAX_SPEED = 131070;
static constexpr int32_t PLAYER_MIN_SPEED = 10;

and I made changes in protocolgame.cpp
it was like this code here
C++:
    msg.add<uint16_t>(std::min<int32_t>(player->getHealth(), std::numeric_limits<uint16_t>::max()));
    msg.add<uint16_t>(std::min<int32_t>(player->getMaxHealth(), std::numeric_limits<uint16_t>::max()));

    msg.add<uint16_t>(player->getLevel());

    msg.add<uint16_t>(std::min<int32_t>(player->getMana(), std::numeric_limits<uint16_t>::max()));
    msg.add<uint16_t>(std::min<int32_t>(player->getMaxMana(), std::numeric_limits<uint16_t>::max()));

    msg.addByte(std::min<uint32_t>(player->getMagicLevel(), std::numeric_limits<uint8_t>::max()));
    msg.addByte(std::min<uint32_t>(player->getBaseMagicLevel(), std::numeric_limits<uint8_t>::max()));

    msg.add<uint16_t>(player->getBaseSpeed() / 2);

    for (uint8_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
        msg.add<uint16_t>(std::min<int32_t>(player->getSkillLevel(i), std::numeric_limits<uint16_t>::max()));
        msg.add<uint16_t>(player->getBaseSkill(i));
        msg.addByte(player->getSkillPercent(i));
and I changed this lines to this code here
C++:
    msg.add<uint32_t>(std::min<int64_t>(player->getHealth(), std::numeric_limits<uint32_t>::max()));
    msg.add<uint32_t>(std::min<int64_t>(player->getMaxHealth(), std::numeric_limits<uint32_t>::max()));

    msg.add<uint32_t>(player->getLevel());

    msg.add<uint32_t>(std::min<int64_t>(player->getMana(), std::numeric_limits<uint32_t>::max()));
    msg.add<uint32_t>(std::min<int64_t>(player->getMaxMana(), std::numeric_limits<uint32_t>::max()));

    msg.add<uint16_t>(std::min<uint64_t>(player->getMagicLevel(), std::numeric_limits<uint16_t>::max()));
    msg.add<uint16_t>(std::min<uint64_t>(player->getBaseMagicLevel(), std::numeric_limits<uint16_t>::max()));

    msg.add<uint16_t>(player->getBaseSpeed());

    for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
        msg.add<uint16_t>(std::min<int64_t>(player->getSkillLevel(i), std::numeric_limits<uint16_t>::max()));
        msg.add<uint16_t>(player->getBaseSkill(i));
        msg.addByte(player->getSkillPercent(i));
Post automatically merged:

I forgot to mention that I add to otclientv8 features this
Lua:
        g_game.enableFeature(GameBaseSkillU16)
        g_game.enableFeature(GameDoubleSoul)
        g_game.enableFeature(GameDoubleLevel)
        g_game.enableFeature(GameDoubleSkills)
        g_game.enableFeature(GameDoubleHealth)
        g_game.enableFeature(GameDoubleMagicLevel)
I read them in here
 
Last edited by a moderator:
You are missing
C++:
    msg.addByte(player->getMagicLevelPercent());

    msg.add<uint16_t>(player->getSoul());

    msg.add<uint16_t>(player->getStaminaMinutes());

Between
C++:
    msg.add<uint16_t>(std::min<uint64_t>(player->getBaseMagicLevel(), std::numeric_limits<uint16_t>::max()));

   // here

    msg.add<uint16_t>(player->getBaseSpeed());
 
I know. Sorry I only posted lines I have edited so I thought this will make it easier to read.
but I have them in my server. This is exactly how I have in my server.
C++:
void ProtocolGame::AddPlayerStats(NetworkMessage& msg)
{
    msg.addByte(0xA0);

    msg.add<uint32_t>(std::min<int64_t>(player->getHealth(), std::numeric_limits<uint32_t>::max()));
    msg.add<uint32_t>(std::min<int64_t>(player->getMaxHealth(), std::numeric_limits<uint32_t>::max()));

    msg.add<uint32_t>(player->getFreeCapacity());
    msg.add<uint32_t>(player->getCapacity());

    msg.add<uint64_t>(player->getExperience());

    msg.add<uint32_t>(player->getLevel());
    msg.addByte(player->getLevelPercent());

    msg.add<uint16_t>(100); // base xp gain rate
    msg.add<uint16_t>(0); // xp voucher
    msg.add<uint16_t>(0); // low level bonus
    msg.add<uint16_t>(0); // xp boost
    msg.add<uint16_t>(100); // stamina multiplier (100 = x1.0)

    msg.add<uint32_t>(std::min<int64_t>(player->getMana(), std::numeric_limits<uint32_t>::max()));
    msg.add<uint32_t>(std::min<int64_t>(player->getMaxMana(), std::numeric_limits<uint32_t>::max()));

    msg.add<uint16_t>(std::min<uint64_t>(player->getMagicLevel(), std::numeric_limits<uint16_t>::max()));
    msg.add<uint16_t>(std::min<uint64_t>(player->getBaseMagicLevel(), std::numeric_limits<uint16_t>::max()));
    msg.addByte(player->getMagicLevelPercent());

    msg.addByte(player->getSoul());

    msg.add<uint16_t>(player->getStaminaMinutes());

    msg.add<uint16_t>(player->getBaseSpeed());

    Condition* condition = player->getCondition(CONDITION_REGENERATION);
    msg.add<uint16_t>(condition ? condition->getTicks() / 1000 : 0x00);

    msg.add<uint16_t>(player->getOfflineTrainingTime() / 60 / 1000);

    msg.add<uint16_t>(0); // xp boost time (seconds)
    msg.addByte(0); // enables exp boost in the store
}

void ProtocolGame::AddPlayerSkills(NetworkMessage& msg)
{
    msg.addByte(0xA1);

    for (uint16_t i = SKILL_FIRST; i <= SKILL_LAST; ++i) {
        msg.add<uint16_t>(std::min<int64_t>(player->getSkillLevel(i), std::numeric_limits<uint16_t>::max()));
        msg.add<uint16_t>(player->getBaseSkill(i));
        msg.addByte(player->getSkillPercent(i));
    }

    for (uint8_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
        msg.add<uint16_t>(std::min<int32_t>(100, player->varSpecialSkills[i]));
        msg.add<uint16_t>(0);
    }
}
and this exactly what I have in client
Lua:
   if(version >= 1035) then
        g_game.enableFeature(GameBaseSkillU16)
        g_game.enableFeature(GameDoubleSoul)
        g_game.enableFeature(GameDoubleLevel)
        g_game.enableFeature(GameDoubleSkills)
        g_game.enableFeature(GameDoubleHealth)
        g_game.enableFeature(GameDoubleMagicLevel)
   end
Post automatically merged:

This screen of how monsters stand and not dying [taking time]
monsterstand.PNG
 
Back
Top