Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't recreate stackables every move #4873

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 33 additions & 28 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1168,17 +1168,15 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
return retMaxCount;
}

uint32_t m;
uint32_t moveCount;
if (item->isStackable()) {
m = std::min<uint32_t>(count, maxQueryCount);
moveCount = std::min<uint32_t>(count, maxQueryCount);
} else {
m = maxQueryCount;
moveCount = maxQueryCount;
}

Item* moveItem = item;

// check if we can remove this item
ret = fromCylinder->queryRemove(*item, m, flags, actor);
ret = fromCylinder->queryRemove(*item, moveCount, flags, actor);
if (ret != RETURNVALUE_NOERROR) {
return ret;
}
Expand All @@ -1198,38 +1196,45 @@ ReturnValue Game::internalMoveItem(Cylinder* fromCylinder, Cylinder* toCylinder,
}
}

// remove the item
Item* moveItem = 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->equals(toItem)) {
n = std::min<uint32_t>(ITEM_STACK_SIZE - 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);
// lets find out how much we need to move
uint32_t allowedCount = 0;

// when item is moved onto another equal item
if (item->equals(toItem) && moveCount != ITEM_STACK_SIZE) {
allowedCount = std::min<uint32_t>(ITEM_STACK_SIZE - toItem->getItemCount(), moveCount);
if (allowedCount > 0) {
fromCylinder->removeThing(item, allowedCount);
toCylinder->updateThing(toItem, toItem->getID(), toItem->getItemCount() + allowedCount);
updateItem = toItem;
moveCount -= allowedCount;

// we fully merged two stacks, so we have nothing to move
if (moveCount == 0) {
moveItem = nullptr;
}
}
} else {
moveItem = nullptr;
}
int32_t newCount = moveCount - allowedCount;
if (newCount != item->getItemCount() && newCount > 0) {
// we get part of the source, clone the item and remove moved count from source
moveItem = item->clone();
moveItem->setItemCount(newCount);

if (item->isRemoved()) {
ReleaseItem(item);
if (item->isRemoved()) {
ReleaseItem(item);
}
}
}
}

// add item
if (moveItem /*m - n > 0*/) {
if (moveItem) {
fromCylinder->removeThing(item, moveCount);
toCylinder->addThing(index, moveItem);
}

Expand Down
Loading