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

How to add Outfit to OTHire?

The client works with ranges, you‘ll have to edit outfit.cpp and increase the range, also don‘t forget to add the outfit in your sprites file (.spr) respectively to the range you set on the source edit.
 
In game procotolcpp you got method for outfit window. I put comments for better understanding

C++:
void ProtocolGame::sendOutfitWindow()
{
    NetworkMessage_ptr msg = getOutputBuffer();
    if (msg){
        msg->AddByte(0xC8); //code for client to open outfit window
        AddCreatureOutfit(msg, player, player->getDefaultOutfit()); //your current outfit as first showin outfit in window

        switch (player->getSex()) {
        case PLAYERSEX_FEMALE: //for female players
            msg->AddU16(136); //first female outfit
            if (player->isPremium())
                msg->AddU16(142); //last female outfit if player got premium (+3 premium outfits)
            else
                msg->AddU16(139); //last female outfit if players is facc

            break;
        case PLAYERSEX_MALE: //same for males
            msg->AddU16(128);
            if (player->isPremium())
                msg->AddU16(134);
            else
                msg->AddU16(131);

            break;
        case 2:
            msg->AddU16(160); // GM outfit? idk whats on sex=2
            msg->AddU16(160);

            break;
        default: //male facc outfits as default, but should never gets here
            msg->AddU16(128);
            msg->AddU16(134);
        }
    }
}

So for example, male facc players can select one from 128-131 outfits ids (128,129,130,131) and for example PACC player female can select 136-142 ids (136,137,138,139,140,141,142).

Keep in mind that those outfits ranges needs to be continuous in older clients. So you can not set male outfits 128,129,130,131 and 100. It needs to be close each other, because in the end you send the packet with the range between which client will allow player to choose the outfit.


So if you would like to add for example new male outfit you need:

arrange in tibia.dat outfits
where currently:

Male outfits: 128,129,130,131,132,133,134
Female outs: 136,137,138,139,140,141,142

you got two free spaces after male (135,136), lucky you can add 2 more male outfits there (and on 143,144 corresponding female outfits). But if you would want to add more outfits you would need to move all the female outfits further and register it in sources

for example if you want to add 5 new outfits for every sex:

Male outfits: 128,129,130,131,132,133,134,135,136,137,138,139

Female outfits: 140,141,142,143,144,145,146,147,148,149,150,151


In object builder (tibia.dat edit):

Leave normal male outfits 128,129,130,131,132,133,134 and on ids 135,136,137,138,139, you can put your new outfits

then on ids:
140,141,142,143,144,145,146 put female outfits and on 147,148,149,150,151, you can put new female outfits

Then in protocolgame.cpp method:

C++:
void ProtocolGame::sendOutfitWindow()
{
    NetworkMessage_ptr msg = getOutputBuffer();
    if (msg){
        msg->AddByte(0xC8); //code for client to open outfit window
        AddCreatureOutfit(msg, player, player->getDefaultOutfit()); //your current outfit as first showin outfit in window

        switch (player->getSex()) {
        case PLAYERSEX_FEMALE: //for female players
            msg->AddU16(140); //first female outfit
            if (player->isPremium())
                msg->AddU16(151); // New 5 outfits only for pacc
            else
                msg->AddU16(145); // old outfits for facc

            break;
        case PLAYERSEX_MALE: //same for males
            msg->AddU16(128);
            if (player->isPremium())
                msg->AddU16(139); // New 5 outfits only for pacc
            else
                msg->AddU16(134); // old outfits for facc

            break;
        case 2:
            msg->AddU16(160); // GM outfit? idk whats on sex=2
            msg->AddU16(160);

            break;
        default: //male facc outfits as default, but should never gets here
            msg->AddU16(128);
            msg->AddU16(134);
        }
    }
}



I think thats the only method for older clients. It sucks that outfits needs to be declared in ranges, but I haven't found any cooler way to select some weird outfit ids to the outfit window. Theres also possiblity to make unique outfit window function for certain outfit called from lua level, but its still not very handy.
 
@pasiak12 could you provide more information about this outfit window function called from lua level? Is there a way that I can contribute to it? I'm kind of lazy to move all my outfits to a wider range so I'd help out on that one.
 
@pasiak12 So, if i want to add outfit elf (144) and dwarf (160) i will have to add using object builder to set dwarf (135,143) and elf (136,144)? Is not it possible to declare as separate parameters?
 
@pasiak12 So, if i want to add outfit elf (144) and dwarf (160) i will have to add using object builder to set dwarf (135,143) and elf (136,144)? Is not it possible to declare as separate parameters?
No, it's not, 7.72 client works with ranges and as we don't have the sources for it we cannot change the way it gathers and process such information. I'm looking for helping out on developing the new outfit window that can be called from Lua.
 
@pasiak12 could you provide more information about this outfit window function called from lua level? Is there a way that I can contribute to it? I'm kind of lazy to move all my outfits to a wider range so I'd help out on that one.

In protocolgame.cpp just create new method by copying outfitwindow function and modifty it to work with single outfit id given by argument.

Then call it from lua level. Theres my function used on YurOtsX server
Lua:
int LuaScriptInterface::luaPlayerSendOutfitWindowForOne(lua_State* L)
{
    // player:sendOutfitWindowForOne(id)
    Player* player = getUserdata<Player>(L, 1);
    if (player) {

        uint16_t id = getNumber<uint16_t>(L, 2);
        player->sendOutfitWindowForOne(id);
        pushBoolean(L, true);
    }
    else {
        lua_pushnil(L);
    }
    return 1;
}

Remember to register it etc.

Also keep in mind that if you call that lua function with outfit id that doesnt exist, the tibia client will crash, so it needs to used only by admins with knowledge or needs to be added some security things.
 
I solved my problem, thx all for pointing out the right way, new outfits looks great! :)

2qncetf.jpg


2r6jxuh.jpg
 
Last edited:
msg->AddU16(151); // New 5 outfits only for pacc

But if i want to add if people buy on shop only ??? so i dont want all premium account got it i want if people purcharse this outfit they can put it
 
think it would be easier on nekiro downgraded server or nostalrius any ot tfs up to 1.x not imposible but neither easy
 
maybe this
 
sory to bump an old thread, but how do i remove ranged outfit? wan to handle outfit by xml
C++:
const auto& outfits = Outfits::getInstance().getOutfits(player->getSex());
    protocolOutfits.reserve(outfits.size());
    for (const Outfit& outfit : outfits) {
        uint8_t addons;
        if (!player->getOutfitAddons(outfit, addons)) {
            continue;
        }

        protocolOutfits.emplace_back(outfit.name, outfit.lookType, addons);
        if (protocolOutfits.size() == 150) { // Game client doesn't allow more than 50 outfits
            break;
        }
    }

    msg.addByte(protocolOutfits.size());
    for (const ProtocolOutfit& outfit : protocolOutfits) {
        msg.add<uint16_t>(outfit.lookType);
        msg.addString(outfit.name);
    }
have tried adapting this code but i always get errors or if it's compile i get error ingame or can't use outfit window
 
Last edited:
Back
Top