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

Animated Text Support for OT Client 10.98/99 - TFS 1.3

Void_

Banned User
Joined
Jan 7, 2018
Messages
9
Reaction score
12
I discovered that OT Client can support animated text in higher client versions of tibia. To do this its very simple.

Open up compat.lua and find
Lua:
function doSendAnimatedText() debugPrint("Deprecated function.") return true end
and replace it with this
Lua:
function doSendAnimatedText(message, position, color) return Game.sendAnimatedText(message, position, color) end

Open up game.cpp and find this
C++:
void Game::addCreatureHealth(const SpectatorHashSet& spectators, const Creature* target)
{
    for (Creature* spectator : spectators) {
        if (Player* tmpPlayer = spectator->getPlayer()) {
            tmpPlayer->sendCreatureHealth(target);
        }
    }
}
and place this right underneath
C++:
void Game::addAnimatedText(const std::string& message, const Position& pos, TextColor_t color)
{
    SpectatorHashSet spectators;
    map.getSpectators(spectators, pos, true, true);
    addAnimatedText(spectators, message, pos, color);
}


void Game::addAnimatedText(const SpectatorHashSet& spectators, const std::string& message, const Position& pos, TextColor_t color)
{
    for (Creature* spectator : spectators) {
        if (Player* tmpPlayer = spectator->getPlayer()) {
            tmpPlayer->sendAnimatedText(message, pos, color);
        }
    }
}

Open up game.h and find this
C++:
        void addCreatureHealth(const Creature* target);
        static void addCreatureHealth(const SpectatorHashSet& spectators, const Creature* target);
and place this right underneath
C++:
        void addAnimatedText(const std::string& message, const Position& pos, TextColor_t color);
        static void addAnimatedText(const SpectatorHashSet& spectators, const std::string& message, const Position& pos, TextColor_t color);


Open up luascript.cpp and find this
C++:
registerMethod("Game", "reload", LuaScriptInterface::luaGameReload);
and place this right underneath
C++:
registerMethod("Game", "sendAnimatedText", LuaScriptInterface::luaGameSendAnimatedText);

Then find this
C++:
int LuaScriptInterface::luaGameReload(lua_State* L)
{
    // Game.reload(reloadType)
    ReloadTypes_t reloadType = getNumber<ReloadTypes_t>(L, 1);
    if (reloadType == RELOAD_TYPE_GLOBAL) {
        pushBoolean(L, g_luaEnvironment.loadFile("data/global.lua") == 0);
    } else {
        pushBoolean(L, g_game.reload(reloadType));
    }
    lua_gc(g_luaEnvironment.getLuaState(), LUA_GCCOLLECT, 0);
    return 1;
}
and place this right underneath
C++:
int LuaScriptInterface::luaGameSendAnimatedText(lua_State* L)
{
    // Game.sendAnimatedText(message, position, color)
    int parameters = lua_gettop(L);
    if (parameters < 3) {
        pushBoolean(L, false);
        return 1;
    }

    TextColor_t color = getNumber<TextColor_t>(L, 3);
    const Position& position = getPosition(L, 2);
    const std::string& message = getString(L, 1);

    if (!position.x || !position.y) {
        pushBoolean(L, false);
        return 1;
    }

    g_game.addAnimatedText(message, position, color);
    pushBoolean(L, true);
    return 1;
}


Open up luascript.h and find this
C++:
static int luaGameReload(lua_State* L);
and place this right underneath
C++:
static int luaGameSendAnimatedText(lua_State* L);

Next open up player.h and find this
C++:
       void sendCreatureShield(const Creature* creature) {
           if (client) {
               client->sendCreatureShield(creature);
           }
       }
and place this right underneath
C++:
        void sendAnimatedText(const std::string& message, const Position& pos, TextColor_t color) {
            if (client) {
                client->sendAnimatedText(message, pos, color);
            }
        }


Now open up protocolgame.cpp and find this
C++:
void ProtocolGame::sendVIPEntries()
{
    const std::forward_list<VIPEntry>& vipEntries = IOLoginData::getVIPEntries(player->getAccount());

    for (const VIPEntry& entry : vipEntries) {
        VipStatus_t vipStatus = VIPSTATUS_ONLINE;

        Player* vipPlayer = g_game.getPlayerByGUID(entry.guid);

        if (!vipPlayer || vipPlayer->isInGhostMode() || player->isAccessPlayer()) {
            vipStatus = VIPSTATUS_OFFLINE;
        }

        sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus);
    }
}

place this right underneath
C++:
void ProtocolGame::sendAnimatedText(const std::string& message, const Position& pos, TextColor_t color)
{
    if (!canSee(pos)) {
        return;
    }

    NetworkMessage msg;
    msg.addByte(0x84);
    msg.addPosition(pos);
    msg.addByte(color);
    msg.addString(message);
    writeToOutputBuffer(msg);
}

Finally open protocolgame.h and find this
C++:
void sendVIPEntries();
and place this right underneath
C++:
void sendAnimatedText(const std::string& message, const Position& pos, TextColor_t color);

Here is a demonstration of this in action

The code used in the video demonstration, this goes in login.lua
Lua:
    local pos = player:getPosition()
    local colors = {5,30,35,95,108,129,143,155,180,198,210,215}
    for i = 1, #colors do
        addEvent(function(x, c)
            Game.sendAnimatedText('this is where i spawned', x, c)
        end, i * 1000, pos, colors[i])
    end
 
This should work in any version or distribution which supports at the very least TFS 1.x code structure but given enough knowledge in C++ anyone can adapt this to their distribution (within reason of course)
 
TFS 1.3 10.98

Followed everything to 100% and client crashes 1 second after joining the world.
 
you need otclient to use this
it will crash in normal client because cipsoft removed ability to use animated text with letters in some client after 9.x
 
Working good on TFS 1.2 too but i change one function:
this
SpectatorHashSet
to
SpectatorVec

on all scripts and working :)
You are best!
 
I discovered that OT Client can support animated text in higher client versions of tibia. To do this its very simple.

Open up compat.lua and find
Lua:
function doSendAnimatedText() debugPrint("Deprecated function.") return true end
and replace it with this
Lua:
function doSendAnimatedText(message, position, color) return Game.sendAnimatedText(message, position, color) end

Open up game.cpp and find this
C++:
void Game::addCreatureHealth(const SpectatorHashSet& spectators, const Creature* target)
{
    for (Creature* spectator : spectators) {
        if (Player* tmpPlayer = spectator->getPlayer()) {
            tmpPlayer->sendCreatureHealth(target);
        }
    }
}
and place this right underneath
C++:
void Game::addAnimatedText(const std::string& message, const Position& pos, TextColor_t color)
{
    SpectatorHashSet spectators;
    map.getSpectators(spectators, pos, true, true);
    addAnimatedText(spectators, message, pos, color);
}


void Game::addAnimatedText(const SpectatorHashSet& spectators, const std::string& message, const Position& pos, TextColor_t color)
{
    for (Creature* spectator : spectators) {
        if (Player* tmpPlayer = spectator->getPlayer()) {
            tmpPlayer->sendAnimatedText(message, pos, color);
        }
    }
}

Open up game.h and find this
C++:
        void addCreatureHealth(const Creature* target);
        static void addCreatureHealth(const SpectatorHashSet& spectators, const Creature* target);
and place this right underneath
C++:
        void addAnimatedText(const std::string& message, const Position& pos, TextColor_t color);
        static void addAnimatedText(const SpectatorHashSet& spectators, const std::string& message, const Position& pos, TextColor_t color);


Open up luascript.cpp and find this
C++:
registerMethod("Game", "reload", LuaScriptInterface::luaGameReload);
and place this right underneath
C++:
registerMethod("Game", "sendAnimatedText", LuaScriptInterface::luaGameSendAnimatedText);

Then find this
C++:
int LuaScriptInterface::luaGameReload(lua_State* L)
{
    // Game.reload(reloadType)
    ReloadTypes_t reloadType = getNumber<ReloadTypes_t>(L, 1);
    if (reloadType == RELOAD_TYPE_GLOBAL) {
        pushBoolean(L, g_luaEnvironment.loadFile("data/global.lua") == 0);
    } else {
        pushBoolean(L, g_game.reload(reloadType));
    }
    lua_gc(g_luaEnvironment.getLuaState(), LUA_GCCOLLECT, 0);
    return 1;
}
and place this right underneath
C++:
int LuaScriptInterface::luaGameSendAnimatedText(lua_State* L)
{
    // Game.sendAnimatedText(message, position, color)
    int parameters = lua_gettop(L);
    if (parameters < 3) {
        pushBoolean(L, false);
        return 1;
    }

    TextColor_t color = getNumber<TextColor_t>(L, 3);
    const Position& position = getPosition(L, 2);
    const std::string& message = getString(L, 1);

    if (!position.x || !position.y) {
        pushBoolean(L, false);
        return 1;
    }

    g_game.addAnimatedText(message, position, color);
    pushBoolean(L, true);
    return 1;
}


Open up luascript.h and find this
C++:
static int luaGameReload(lua_State* L);
and place this right underneath
C++:
static int luaGameSendAnimatedText(lua_State* L);

Next open up player.h and find this
C++:
       void sendCreatureShield(const Creature* creature) {
           if (client) {
               client->sendCreatureShield(creature);
           }
       }
and place this right underneath
C++:
        void sendAnimatedText(const std::string& message, const Position& pos, TextColor_t color) {
            if (client) {
                client->sendAnimatedText(message, pos, color);
            }
        }


Now open up protocolgame.cpp and find this
C++:
void ProtocolGame::sendVIPEntries()
{
    const std::forward_list<VIPEntry>& vipEntries = IOLoginData::getVIPEntries(player->getAccount());

    for (const VIPEntry& entry : vipEntries) {
        VipStatus_t vipStatus = VIPSTATUS_ONLINE;

        Player* vipPlayer = g_game.getPlayerByGUID(entry.guid);

        if (!vipPlayer || vipPlayer->isInGhostMode() || player->isAccessPlayer()) {
            vipStatus = VIPSTATUS_OFFLINE;
        }

        sendVIP(entry.guid, entry.name, entry.description, entry.icon, entry.notify, vipStatus);
    }
}

place this right underneath
C++:
void ProtocolGame::sendAnimatedText(const std::string& message, const Position& pos, TextColor_t color)
{
    if (!canSee(pos)) {
        return;
    }

    NetworkMessage msg;
    msg.addByte(0x84);
    msg.addPosition(pos);
    msg.addByte(color);
    msg.addString(message);
    writeToOutputBuffer(msg);
}

Finally open protocolgame.h and find this
C++:
void sendVIPEntries();
and place this right underneath
C++:
void sendAnimatedText(const std::string& message, const Position& pos, TextColor_t color);

Here is a demonstration of this in action

The code used in the video demonstration, this goes in login.lua
Lua:
    local pos = player:getPosition()
    local colors = {5,30,35,95,108,129,143,155,180,198,210,215}
    for i = 1, #colors do
        addEvent(function(x, c)
            Game.sendAnimatedText('this is where i spawned', x, c)
        end, i * 1000, pos, colors[i])
    end
Can no stack text?
 
Video offline.


How i add animated text in login.lua? Vídeo offline

i got error with:

local pos = player:getPosition()
local colors = {5,30,35,95,108,129,143,155,180,198,210,215}
for i = 1, #colors do
addEvent(function(x, c)
Game.sendAnimatedText('this is where i spawned', x, c)
end, i * 1000, pos, colors)
end
 
how to use that above tps?

edit:
nvm just solved it
 
Last edited:
Would this work in other protocols ? like 8,6 i mean by the packets sent by the server
Lua:
msg.addByte(0x84);
I tried but was having console errors, any clue about how to use this code in 8.6 protocols?
Code:
attempt to index a number value
stack traceback:
        [C]: at 0x7ff72d1e2950
        [C]: in function 'doSendAnimatedText'
        data/actions/scripts/premium1.lua:8: in function <data/actions/scripts/premium1.lua:5>
 
Last edited:
sendAnimatedText is removed on my repo what can i replace it with?

data.pos:sendAnimatedText("Get your reward!")

data.pos:sendAnimatedText(string.format("Boss Fight\n%s", data.chest.boss.name))
 
how to use in c++??


g_game.sendAnimatedTex(getPosition(), TEXTCOLOR_WHITE_EXP, "Extra melee");
 
Back
Top