• 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!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

TFS 1.1 and Tibia 10.76

Ugh, all the work me and my server partner put down for the flash client and protocol updates down the drain :c

nice share though
I don't see your work as wasted time. Someone still has to code and implement what I've outlined. They can't just copy-and-paste.
 
About EquipObject:

Is it possible to use the combination of player::removeItemOfType and Game::internalPlayerAddItem()

1. Firstly check if player has item using Game::findItemOfType(player, itemId, deepSearch, subType)
2. Copy the item object
3. Remove the item object using Game::internalRemoveItem
4. Add the item to player with the attributtes from the copied object, like count, subtype, etc... (so it automatically adds to BP if player has it already equipped)
 
About EquipObject:

Is it possible to use the combination of player::removeItemOfType and Game::internalPlayerAddItem()

1. Firstly check if player has item using Game::findItemOfType(player, itemId, deepSearch, subType)
2. Copy the item object
3. Remove the item object using Game::internalRemoveItem
4. Add the item to player with the attributtes from the copied object, like count, subtype, etc... (so it automatically adds to BP if player has it already equipped)
I honestly can't say. Give it a try and see if it works for you.
 
I spent my whole day doing that, I think it works like 95% for me now.

The problems are:
1. Two-handed weapons. I do not know if I can deEquip both shield and weapon since player can have full bp and than some of those 2 items appear under him.
2. Also the problem can be also the item attributes since I do not copy them to new object. I do not use those attributes on my server so it is not important for me.
3. If you have two stacks of 50 arrows, only the first stack is equipped. (needs some more magic in code ;/ )

The whole function is 200 lines code which is pretty much but works. :)

Also I have written the function to send all the player objects which is called pretty often. It is based on Player::__getAllItemTypeCount. Can it have some performance impact ?
Code:
std::map<uint32_t, uint32_t>& Player::getAllItemClientIdCount(std::map<uint32_t, uint32_t>& countMap) const
{
  for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) {
  Item* item = inventory[i];
  if (!item) {
  continue;
  }

  const ItemType& item_type = Item::items[item->getID()];
  countMap[item_type.clientId] += Item::countByType(item, -1);

  if (Container* container = item->getContainer()) {
  for (ContainerIterator it = container->begin(), end = container->end(); it != end; ++it) {
  const ItemType& item_type = Item::items[(*it)->getID()];
  countMap[item_type.clientId] += Item::countByType(*it, -1);
  }
  }
  }
  return countMap;
}
 
I spent my whole day doing that, I think it works like 95% for me now.

The problems are:
1. Two-handed weapons. I do not know if I can deEquip both shield and weapon since player can have full bp and than some of those 2 items appear under him.
2. Also the problem can be also the item attributes since I do not copy them to new object. I do not use those attributes on my server so it is not important for me.
3. If you have two stacks of 50 arrows, only the first stack is equipped. (needs some more magic in code ;/ )

The whole function is 200 lines code which is pretty much but works. :)

Also I have written the function to send all the player objects which is called pretty often. It is based on Player::__getAllItemTypeCount. Can it have some performance impact ?
Code:
std::map<uint32_t, uint32_t>& Player::getAllItemClientIdCount(std::map<uint32_t, uint32_t>& countMap) const
{
  for (int32_t i = CONST_SLOT_FIRST; i <= CONST_SLOT_LAST; i++) {
  Item* item = inventory[i];
  if (!item) {
  continue;
  }

  const ItemType& item_type = Item::items[item->getID()];
  countMap[item_type.clientId] += Item::countByType(item, -1);

  if (Container* container = item->getContainer()) {
  for (ContainerIterator it = container->begin(), end = container->end(); it != end; ++it) {
  const ItemType& item_type = Item::items[(*it)->getID()];
  countMap[item_type.clientId] += Item::countByType(*it, -1);
  }
  }
  }
  return countMap;
}
I think that Game::internalMoveItem is better for you, if you already have the item object.
Your function will send only the equipped items, as well as what's in the first bp, but not what's inside of a bp inside your bp for example.

If you want to map all items on the body of a player, I would recommend something like a cache, because it'll cause some lag if you recursively access every container inside a container to map it.

I have a simple function to verify if the player has a free slot in one of his containers, it's not really hard and easy to make something optimized.
 
I think that Game::internalMoveItem is better for you, if you already have the item object.
Your function will send only the equipped items, as well as what's in the first bp, but not what's inside of a bp inside your bp for example.

If you want to map all items on the body of a player, I would recommend something like a cache, because it'll cause some lag if you recursively access every container inside a container to map it.

I have a simple function to verify if the player has a free slot in one of his containers, it's not really hard and easy to make something optimized.

Ye I would like to but I do not know how to get the fromCylinder and toCylinder positions. If I get it using internalGetPosition, I will get RET_NOTPOSSIBLE after calling internalMoveItem. Any tips for that ? :)
 
I think that Game::internalMoveItem is better for you, if you already have the item object.
Your function will send only the equipped items, as well as what's in the first bp, but not what's inside of a bp inside your bp for example.

If you want to map all items on the body of a player, I would recommend something like a cache, because it'll cause some lag if you recursively access every container inside a container to map it.

I have a simple function to verify if the player has a free slot in one of his containers, it's not really hard and easy to make something optimized.

The function sends all the items even in the third level of containers. It is based on already existing function in TFS. You can try it. ;]

Anyway I've got the equip functionality working just using playerMoveItem even if the container is opened or not. Had to sleep some nights to find a solution. ;]
 
I don't know why I can't even get the hotkey equipment packet into to method parsePacket() in the protocolgame.cpp. Someone know why?
 
Can you help me ? When parse method 0x77 is initiated ? I've edited console , now it shows me every recvbyte even not existing in switch and there's not 0x77( i've added new equip hotkey, used it, tested in every way possible and nothing)
 
Can you help me ? When parse method 0x77 is initiated ? I've edited console , now it shows me every recvbyte even not existing in switch and there's not 0x77( i've added new equip hotkey, used it, tested in every way possible and nothing)

I've this same problem. Source isn't receiving this client even in the connecting.cpp in parseHeader, were it should show every single packet send to the server
 
I've this same problem. Source isn't receiving this client even in the connecting.cpp in parseHeader, were it should show every single packet send to the server


It's not 0x77...(Atleast what i'm using for equip hotkey) Try to find the correct byte first.
 
Last edited:
It's not 0x77... Try to find the correct byte first.

I said even parseHeader in connection.cpp didn't receive packet with, didn't said about 0x77... Server didn't get the packet anyone about Hotkey Equipment.
 
I said even parseHeader in connection.cpp didn't receive packet with, didn't said about 0x77... Server didn't get the packet anyone about Hotkey Equipment.
Same here. Server is not receiving any packet when using equip hotkey
 
Can you help me ? When parse method 0x77 is initiated ? I've edited console , now it shows me every recvbyte even not existing in switch and there's not 0x77( i've added new equip hotkey, used it, tested in every way possible and nothing)
I've this same problem. Source isn't receiving this client even in the connecting.cpp in parseHeader, were it should show every single packet send to the server
Go back and read my first post about Server->Client packet PlayerObjects. If this packet isn't sent to the client, then the client will never send the EquipObject (0x77) packet to the server.
 
Code:
#define CHANNEL_GUILD_FIRST 10000
#define CHANNEL_GUILD_LAST 19999
To give each guild their own, unique guild channel id, I just added their guild id to CHANNEL_GUILD_FIRST.

The only thing I didn't understand about your post in how to implement the new guild channel features, how are this supposed to work? Can you give me a little hint, please?
 
The only thing I didn't understand about your post in how to implement the new guild channel features, how are this supposed to work? Can you give me a little hint, please?
In guild.h:
Code:
int16_t getChannelId() const {
    return 10000 + id;
}
This will give each guild it's own, unique channel id. However, you'll have to make quite a few changes in chat.cpp to get the new guild channels working. I suggest using PrivateChatChannels since non-guild members can be invited and kicked from the channel.
 
I still can't get it working, but I'll keep trying, thanks for the info :)
 
Back
Top