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

C++ - Addon system added TFS 1.X - 772

dropz

Member
Joined
May 4, 2022
Messages
46
Reaction score
24
hello!

dudes, i came here to try get some help in this issue that i facing.

before all this implementation of addon system in TFS 1.2 Nostalrius, i was trying use another way to implement outfits, understanding the point about i didn't will have addon features inside my server... but one of the biggest points that made me implement it was the possibility to handle with the "outfits.xml", also having after that the possibility to add some addons inside the server.

well, after added on all src files the addon features and compiled the source, i got the results... if i didn't change inside game_features on OTCV8 the features of 770 protocol my client returns a lot of errors of packets, after added "g_game.enableFeature(GameNewOutfitProtocol); g_game.enableFeature(GamePlayerAddons)" this errors stopped and the game was running okay, but the point is after this im not able to change my outfits anymore, when i open the Set Outfit panel, no outfits appears there.

im asking myself about if outfits.xml its working properly now, i added there the basic outfits that has on my .spr file of the client, all of them without addons yet just the basic ones of old protocols, but in the game none of them appears, did you guys know something about it?

if necessary i can share with you the codes and whole stuffs to understand how to handle with that.

here's my outfits.xml, but i dont know if the server now is reading the file, maybe can something like this..
XML:
<?xml version="1.0" encoding="UTF-8"?>
<outfits>
    <!-- Female outfits -->
    <outfit type="0" looktype="140" name="Citizen" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="0" looktype="141" name="Hunter" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="0" looktype="142" name="Mage" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="0" looktype="143" name="Knight" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="0" looktype="144" name="Noblewoman" premium="yes" unlocked="yes" enabled="yes" />

    <!-- Male outfits -->
    <outfit type="1" looktype="128" name="Citizen" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="1" looktype="129" name="Hunter" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="1" looktype="130" name="Mage" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="1" looktype="131" name="Knight" premium="no" unlocked="yes" enabled="yes" />
    <outfit type="1" looktype="132" name="Nobleman" premium="yes" unlocked="yes" enabled="yes" />
    <outfit type="1" looktype="133" name="Summoner" premium="yes" unlocked="yes" enabled="yes" />
    <outfit type="1" looktype="134" name="Warrior" premium="yes" unlocked="yes" enabled="yes" />
</outfits>

protocolgame.cpp:
C++:
void ProtocolGame::sendOutfitWindow()
{
    NetworkMessage msg;
    msg.addByte(0xC8);

    Outfit_t currentOutfit = player->getDefaultOutfit();

    AddOutfit(msg, currentOutfit);

    std::vector<ProtocolOutfit> protocolOutfits;
    if (player->isAccessPlayer()) {
        static const std::string gamemasterOutfitName = "Gamemaster";
        protocolOutfits.emplace_back(gamemasterOutfitName, 75, 0);
    }

    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() == 100) { // Game client doesn't allow more than 100 outfits
            break;
        }
    }

    msg.addByte(protocolOutfits.size());
    for (const ProtocolOutfit& outfit : protocolOutfits) {
        msg.add<uint16_t>(outfit.lookType);
        msg.addString(outfit.name);
        msg.addByte(outfit.addons);
    }

    writeToOutputBuffer(msg);
}

player.cpp:
C++:
bool Player::canWear(uint32_t lookType, uint8_t addons) const
{
    if (group->access) {
        return true;
    }

    const Outfit* outfit = Outfits::getInstance()->getOutfitByLookType(sex, lookType);
    if (!outfit) {
        return false;
    }

    if (outfit->premium && !isPremium()) {
        return false;
    }

    if (outfit->unlocked && addons == 0) {
        return true;
    }

    for (const OutfitEntry& outfitEntry : outfits) {
        if (outfitEntry.lookType != lookType) {
            continue;
        }
        return (outfitEntry.addons & addons) == addons;
    }
    return false;
}
obs: i created two new files on source code that implements the outfits.xml, outfit.cpp and outfit.h, added the .cpp on CMakeLists.txt to has the possiblity to compile it. as i can see everything about the outfits was made.
just one thing that i didn't changed values and codes was about addplayerstorage with the "reserved" values for outfits, i was tried change it but started appears too much different errors about other contents... can be it?


any angel? :D
thanks in advance!
Post automatically merged:

bummmmp
Post automatically merged:

i think i got whats going on...

even if i put some trash inside the "outfits.xml", when i start the server i dont receive a any log about problem to load the file... probably have a issue about the implementation of the outfits.xml, i will try deal with it if i have any results i will post here.
 
Last edited:
solved.

1669821603694.png
1669821861112.png


if you trying to apply the outfits.xml in a TFS engine that didn't have it, for the first you must found a TFS engine that haves this implementation then you must implement the files that has this features on your engine and after all you must pay attention on "otserv.cpp", there you must add the call for the feature of outfit.XML.


if you did everything right in the implementation, adding the correct codes in the correct files about addons and outfit.xml feature, you compile your engine again, adjust the features on the clientside adding the features that i mentioned above and probably everything gonna works like a charm.
 
solved.

View attachment 72034
View attachment 72035


if you trying to apply the outfits.xml in a TFS engine that didn't have it, for the first you must found a TFS engine that haves this implementation then you must implement the files that has this features on your engine and after all you must pay attention on "otserv.cpp", there you must add the call for the feature of outfit.XML.


if you did everything right in the implementation, adding the correct codes in the correct files about addons and outfit.xml feature, you compile your engine again, adjust the features on the clientside adding the features that i mentioned above and probably everything gonna works like a charm.
very helpful borther... thanks for share!
 
solved.

View attachment 72034
View attachment 72035


if you trying to apply the outfits.xml in a TFS engine that didn't have it, for the first you must found a TFS engine that haves this implementation then you must implement the files that has this features on your engine and after all you must pay attention on "otserv.cpp", there you must add the call for the feature of outfit.XML.


if you did everything right in the implementation, adding the correct codes in the correct files about addons and outfit.xml feature, you compile your engine again, adjust the features on the clientside adding the features that i mentioned above and probably everything gonna works like a charm.
Thanks bro, it will help a lot of people. Can u share .ODB sprites outfits with us?
 
Thanks bro, it will help a lot of people. Can u share .ODB sprites outfits with us?
the .odb files its not a big deal dud, get another .spr and .dat files like a protocol 780, open it on object builder and then export the new outfits with addons..

then go to your .dat .spr in object builder, import the new outfits with addons, get the outfit of a old one and overwrite it in the outfit with addons, save and compile and so you will have a old outfit with the new addons as i show above.
 
the .odb files its not a big deal dud, get another .spr and .dat files like a protocol 780, open it on object builder and then export the new outfits with addons..

then go to your .dat .spr in object builder, import the new outfits with addons, get the outfit of a old one and overwrite it in the outfit with addons, save and compile and so you will have a old outfit with the new addons as i show above.
are you using otc? classic tibia client doesn't know how to toggle addons individually.
 
are you using otc? classic tibia client doesn't know how to toggle addons individually.
yess, with OTC as i can see you can deal with all the addons and diferent sprites... its better, but using it you lose the classic UI...
other possibility is try customize OTC to a classic UI, i tried it but without success, too much bugs ahead. and without time to handle with client side bugs, server bugs and etcs :D
 
I'm using classic ui with newer outfit windows, work perfectly
TZseVBy.png
 
Hi, for me return this screen:
1693125580109.png


My player.cpp:
Lua:
bool Player::canWear(uint32_t lookType, uint8_t addons) const
{
    if (group->access) {
        return true;
    }
    const Outfit* outfit = Outfits::getInstance().getOutfitByLookType(sex, lookType);
    if (!outfit) {
        return false;
    }
    if (outfit->premium && !isPremium()) {
        return false;
    }
    if (outfit->unlocked && addons == 0) {
        return true;
    }
    for (const OutfitEntry& outfitEntry : outfits) {
        if (outfitEntry.lookType == lookType) {
            if (outfitEntry.addons == addons || outfitEntry.addons == 3 || addons == 0) {
                return true;
            }
            return false; //have lookType on list and addons don't match
        }
    }
    return false;
}

My protocolgame.cpp:
C++:
void ProtocolGame::sendOutfitWindow()
{
    const auto& outfits = Outfits::getInstance().getOutfits(player->getSex());
    if (outfits.size() == 0) {
        return;
    }
    NetworkMessage msg;
    msg.addByte(0xC8);
    Outfit_t currentOutfit = player->getDefaultOutfit();
    if (currentOutfit.lookType == 0) {
        Outfit_t newOutfit;
        newOutfit.lookType = outfits.front().lookType;
        currentOutfit = newOutfit;
    }
    AddOutfit(msg, currentOutfit);
    std::vector<ProtocolOutfit> protocolOutfits;
    if (player->isAccessPlayer()) {
        static const std::string gamemasterOutfitName = "Gamemaster";
        protocolOutfits.emplace_back(gamemasterOutfitName, 75, 0);
    }
    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() == 999) { // 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);
        msg.addByte(outfit.addons);
    }
    writeToOutputBuffer(msg);
}

In my OTC i enable this features:

Lua:
g_game.enableFeature(GameLooktypeU16)
    g_game.enableFeature(GameExtendedOpcode)
    g_game.enableFeature(GameChangeMapAwareRange)
    g_game.enableFeature(GameBiggerMapCache)
    g_game.enableFeature(GameNewOutfitProtocol)
    g_game.enableFeature(GamePlayerAddons)

If i remove the
Lua:
g_game.enableFeature(GamePlayerAddons)
i not have the black screen, but not have the addons too.

Its possible to activate the addons? Please help me...

I'm using the nekiro tfs 1.5 downgrade protocol 7.72
 
Hi, for me return this screen:
View attachment 77943


My player.cpp:
Lua:
bool Player::canWear(uint32_t lookType, uint8_t addons) const
{
    if (group->access) {
        return true;
    }
    const Outfit* outfit = Outfits::getInstance().getOutfitByLookType(sex, lookType);
    if (!outfit) {
        return false;
    }
    if (outfit->premium && !isPremium()) {
        return false;
    }
    if (outfit->unlocked && addons == 0) {
        return true;
    }
    for (const OutfitEntry& outfitEntry : outfits) {
        if (outfitEntry.lookType == lookType) {
            if (outfitEntry.addons == addons || outfitEntry.addons == 3 || addons == 0) {
                return true;
            }
            return false; //have lookType on list and addons don't match
        }
    }
    return false;
}

My protocolgame.cpp:
C++:
void ProtocolGame::sendOutfitWindow()
{
    const auto& outfits = Outfits::getInstance().getOutfits(player->getSex());
    if (outfits.size() == 0) {
        return;
    }
    NetworkMessage msg;
    msg.addByte(0xC8);
    Outfit_t currentOutfit = player->getDefaultOutfit();
    if (currentOutfit.lookType == 0) {
        Outfit_t newOutfit;
        newOutfit.lookType = outfits.front().lookType;
        currentOutfit = newOutfit;
    }
    AddOutfit(msg, currentOutfit);
    std::vector<ProtocolOutfit> protocolOutfits;
    if (player->isAccessPlayer()) {
        static const std::string gamemasterOutfitName = "Gamemaster";
        protocolOutfits.emplace_back(gamemasterOutfitName, 75, 0);
    }
    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() == 999) { // 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);
        msg.addByte(outfit.addons);
    }
    writeToOutputBuffer(msg);
}

In my OTC i enable this features:

Lua:
g_game.enableFeature(GameLooktypeU16)
    g_game.enableFeature(GameExtendedOpcode)
    g_game.enableFeature(GameChangeMapAwareRange)
    g_game.enableFeature(GameBiggerMapCache)
    g_game.enableFeature(GameNewOutfitProtocol)
    g_game.enableFeature(GamePlayerAddons)

If i remove the
Lua:
g_game.enableFeature(GamePlayerAddons)
i not have the black screen, but not have the addons too.

Its possible to activate the addons? Please help me...

I'm using the nekiro tfs 1.5 downgrade protocol 7.72
take the protocol 8.0 from nekiro and search for the word addon in the whole proyect and add the code into yours, otherwise just use 8.0 as 7.72. they are the same thing
 
take the protocol 8.0 from nekiro and search for the word addon in the whole proyect and add the code into yours, otherwise just use 8.0 as 7.72. they are the same thing
But i need the change client 7.72 to 8.0 to in the object builder? Sprites can bug?
 
Back
Top