Hello, my name is Ray and this is my first attemt using otland,
I have a weird problem in my ot and was told I could get proper help here
I'm using sources you find here: https://github.com/otland/forgottenserver
And I've downgraded it to use client 8.60, and everything have been working fine for me but I found something really strange that I seem cannot solve, I've tried for hours but I just can't find what's causing it.
The problem occur when you own a house and make the command /owner none, the items is supposed to be sent to the depot which the house belongs to.
It works fine if the owner of the house is online, but if he's not, the items just disappear, they don't end up in any depots, there's no new records in the database.
I've tried multiple times to solve it but it seems to be impossible..
So I'd really appreciate if I could get help with this one
House.cpp
Notice, the tmpPlayer seems to be valid, because if I put std::cout to debug and write like tmpPlayer.getName() the name of the owner is displayed in the console.
I also tried to make tmpPlayer.addExperience thing, making owner get 10k experience when offline and house is left, and it works, I login the owner and he has 10k more in experience..
House.cpp
player.cpp
game.cpp
If you need more functions from the sources tell me and I'll add them in here, but hopefully you guys can see something in these codes that I couldn't.
The server is going to be a custom server using 8.60 custom edited client but that shouldn't matter much I think
I have a weird problem in my ot and was told I could get proper help here
I'm using sources you find here: https://github.com/otland/forgottenserver
And I've downgraded it to use client 8.60, and everything have been working fine for me but I found something really strange that I seem cannot solve, I've tried for hours but I just can't find what's causing it.
The problem occur when you own a house and make the command /owner none, the items is supposed to be sent to the depot which the house belongs to.
It works fine if the owner of the house is online, but if he's not, the items just disappear, they don't end up in any depots, there's no new records in the database.
I've tried multiple times to solve it but it seems to be impossible..
So I'd really appreciate if I could get help with this one
House.cpp
PHP:
bool House::transferToDepot() const
{
if (townid == 0 || owner == 0) {
return false;
}
Player* player = g_game.getPlayerByGUID(owner);
if (player) {
transferToDepot(player);
} else {
Player tmpPlayer(nullptr);
if (!IOLoginData::loadPlayerById(&tmpPlayer, owner)) {
return false;
}
transferToDepot(&tmpPlayer);
IOLoginData::savePlayer(&tmpPlayer);
}
return true;
}
I also tried to make tmpPlayer.addExperience thing, making owner get 10k experience when offline and house is left, and it works, I login the owner and he has 10k more in experience..
House.cpp
PHP:
bool House::transferToDepot(Player* player) const
{
if (townid == 0 || owner == 0) {
return false;
}
ItemList moveItemList;
for (HouseTile* tile : houseTiles) {
if (const TileItemVector* items = tile->getItemList()) {
for (Item* item : *items) {
if (item->isPickupable()) {
moveItemList.push_back(item);
} else {
Container* container = item->getContainer();
if (container) {
for (Item* containerItem : container->getItemList()) {
moveItemList.push_back(containerItem);
}
}
}
}
}
}
DepotLocker* depotLocker = player->getDepotLocker(townid);
if (depotLocker) {
for (Item* item : moveItemList) {
g_game.internalMoveItem(item->getParent(), depotLocker, INDEX_WHEREEVER, item, item->getItemCount(), nullptr, FLAG_NOLIMIT);
}
}
return true;
}
player.cpp
PHP:
DepotLocker* Player::getDepotLocker(uint32_t depotId)
{
auto it = depotLockerMap.find(depotId);
if (it != depotLockerMap.end()) {
return it->second;
}
DepotLocker* depotLocker = new DepotLocker(ITEM_LOCKER);
depotLocker->setDepotId(depotId);
depotLocker->internalAddThing(getDepotChest(depotId, true));
depotLockerMap[depotId] = depotLocker;
return depotLocker;
}
game.cpp
PHP:
ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder, int32_t index,
Item* item, uint32_t count, Item** _moveItem, uint32_t flags /*= 0*/, Creature* actor/* = nullptr*/, Item* tradeItem/* = nullptr*/)
{
Item* toItem = nullptr;
Cylinder* subCylinder;
int floorN = 0;
while ((subCylinder = toCylinder->queryDestination(index, *item, &toItem, flags)) != toCylinder) {
toCylinder = subCylinder;
flags = 0;
//to prevent infinite loop
if (++floorN >= MAP_MAX_LAYERS) {
break;
}
}
//destination is the same as the source?
if (item == toItem) {
return RETURNVALUE_NOERROR; //silently ignore move
}
//check if we can add this item
ReturnValue ret = toCylinder->queryAdd(index, *item, count, flags, actor);
if (ret == RETURNVALUE_NEEDEXCHANGE) {
//check if we can add it to source cylinder
ret = fromCylinder->queryAdd(fromCylinder->getThingIndex(item), *toItem, toItem->getItemCount(), 0);
if (ret == RETURNVALUE_NOERROR) {
//check how much we can move
uint32_t maxExchangeQueryCount = 0;
ReturnValue retExchangeMaxCount = fromCylinder->queryMaxCount(INDEX_WHEREEVER, *toItem, toItem->getItemCount(), maxExchangeQueryCount, 0);
if (retExchangeMaxCount != RETURNVALUE_NOERROR && maxExchangeQueryCount == 0) {
return retExchangeMaxCount;
}
if (toCylinder->queryRemove(*toItem, toItem->getItemCount(), flags) == RETURNVALUE_NOERROR) {
int32_t oldToItemIndex = toCylinder->getThingIndex(toItem);
toCylinder->removeThing(toItem, toItem->getItemCount());
fromCylinder->addThing(toItem);
if (oldToItemIndex != -1) {
toCylinder->postRemoveNotification(toItem, fromCylinder, oldToItemIndex);
}
int32_t newToItemIndex = fromCylinder->getThingIndex(toItem);
if (newToItemIndex != -1) {
fromCylinder->postAddNotification(toItem, toCylinder, newToItemIndex);
}
ret = toCylinder->queryAdd(index, *item, count, flags);
toItem = nullptr;
}
}
}
if (ret != RETURNVALUE_NOERROR) {
return ret;
}
//check how much we can move
uint32_t maxQueryCount = 0;
ReturnValue retMaxCount = toCylinder->queryMaxCount(index, *item, count, maxQueryCount, flags);
if (retMaxCount != RETURNVALUE_NOERROR && maxQueryCount == 0) {
return retMaxCount;
}
uint32_t m;
if (item->isStackable()) {
if (item->isRune()) {
m = std::min<uint32_t>(item->getItemCount(), maxQueryCount);
} else {
m = std::min<uint32_t>(count, maxQueryCount);
}
} else {
m = maxQueryCount;
}
Item* moveItem = item;
//check if we can remove this item
ret = fromCylinder->queryRemove(*item, m, flags);
if (ret != RETURNVALUE_NOERROR) {
return ret;
}
if (tradeItem) {
if (toCylinder->getItem() == tradeItem) {
return RETURNVALUE_NOTENOUGHROOM;
}
Cylinder* tmpCylinder = toCylinder->getParent();
while (tmpCylinder) {
if (tmpCylinder->getItem() == tradeItem) {
return RETURNVALUE_NOTENOUGHROOM;
}
tmpCylinder = tmpCylinder->getParent();
}
}
//remove the item
int32_t itemIndex = fromCylinder->getThingIndex(item);
Item* updateItem = nullptr;
fromCylinder->removeThing(item, m);
//update item(s)
if (item->isStackable()) {
uint32_t n;
if (!item->isRune() && item->equals(toItem)) {
n = std::min<uint32_t>(100 - toItem->getItemCount(), m);
toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + n);
updateItem = toItem;
} else {
n = 0;
}
int32_t newCount = m - n;
if (newCount > 0) {
moveItem = item->clone();
moveItem->setItemCount(newCount);
} else {
moveItem = nullptr;
}
if (item->isRemoved()) {
ReleaseItem(item);
}
}
//add item
if (moveItem /*m - n > 0*/) {
toCylinder->addThing(index, moveItem);
}
if (itemIndex != -1) {
fromCylinder->postRemoveNotification(item, toCylinder, itemIndex);
}
if (moveItem) {
int32_t moveItemIndex = toCylinder->getThingIndex(moveItem);
if (moveItemIndex != -1) {
toCylinder->postAddNotification(moveItem, fromCylinder, moveItemIndex);
}
}
if (updateItem) {
int32_t updateItemIndex = toCylinder->getThingIndex(updateItem);
if (updateItemIndex != -1) {
toCylinder->postAddNotification(updateItem, fromCylinder, updateItemIndex);
}
}
if (_moveItem) {
if (moveItem) {
*_moveItem = moveItem;
} else {
*_moveItem = item;
}
}
//we could not move all, inform the player
if (item->isStackable() && maxQueryCount < count) {
return retMaxCount;
}
return ret;
}
If you need more functions from the sources tell me and I'll add them in here, but hopefully you guys can see something in these codes that I couldn't.
The server is going to be a custom server using 8.60 custom edited client but that shouldn't matter much I think