Skip to content

Commit 0f62a8c

Browse files
committed
Fix torn notes not combining when moved into inventory
Fixes #8487 Torn notes were only combined when picked up from the ground via CheckQuestItem(). When notes entered the inventory through other paths (e.g. stash transfers, item swaps), the combine logic never ran. Add CheckSpecialInventoryItem() which checks whether all three torn notes are present after an item is placed into InvList, and combines them into the full note if so. Called from: - ChangeInvItem (empty slot path) - ChangeInvItem (swap path) - AutoPlaceItemInInventory (covers stash-to-inventory transfers)
1 parent 5a08031 commit 0f62a8c

2 files changed

Lines changed: 58 additions & 2 deletions

File tree

Source/inv.cpp

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ bool ChangeInvItem(Player &player, int slot, Size itemSize)
498498
if (prevItemId == 0) {
499499
player.InvList[player._pNumInv] = player.HoldItem.pop();
500500
player._pNumInv++;
501-
prevItemId = player._pNumInv;
501+
prevItemId = CheckSpecialInventoryItem(player, player._pNumInv - 1) + 1;
502502
} else {
503503
const int invIndex = prevItemId - 1;
504504
if (player.HoldItem._itype == ItemType::Gold)
@@ -512,8 +512,11 @@ bool ChangeInvItem(Player &player, int slot, Size itemSize)
512512
if (itemIndex == -prevItemId)
513513
itemIndex = 0;
514514
}
515+
prevItemId = CheckSpecialInventoryItem(player, invIndex) + 1;
515516
}
516517

518+
itemSize = GetInventorySize(player.InvList[prevItemId - 1]);
519+
517520
AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, prevItemId, itemSize, &player == MyPlayer);
518521
}
519522

@@ -1121,6 +1124,49 @@ int CreateGoldItemInInventorySlot(Player &player, int slotIndex, int value)
11211124

11221125
} // namespace
11231126

1127+
int CheckSpecialInventoryItem(Player &player, int invIndex)
1128+
{
1129+
if (invIndex < 0 || invIndex >= player._pNumInv) {
1130+
return invIndex;
1131+
}
1132+
1133+
const _item_indexes currentId = player.InvList[invIndex].IDidx;
1134+
const _item_indexes notes[] = { IDI_NOTE1, IDI_NOTE2, IDI_NOTE3 };
1135+
1136+
if (IsNoneOf(currentId, IDI_NOTE1, IDI_NOTE2, IDI_NOTE3)) {
1137+
return invIndex;
1138+
}
1139+
1140+
for (const _item_indexes note : notes) {
1141+
if (!HasInventoryItemWithId(player, note)) {
1142+
return invIndex;
1143+
}
1144+
}
1145+
1146+
player.Say(HeroSpeech::JustWhatIWasLookingFor, 10);
1147+
1148+
for (const _item_indexes note : notes) {
1149+
if (note != currentId) {
1150+
RemoveInventoryItemById(player, note);
1151+
}
1152+
}
1153+
1154+
for (int i = 0; i < player._pNumInv; i++) {
1155+
Item &noteItem = player.InvList[i];
1156+
if (noteItem.IDidx != currentId) {
1157+
continue;
1158+
}
1159+
1160+
noteItem = {};
1161+
GetItemAttrs(noteItem, IDI_FULLNOTE, 16);
1162+
SetupItem(noteItem);
1163+
noteItem.updateRequiredStatsCacheForPlayer(player);
1164+
return i;
1165+
}
1166+
1167+
return invIndex;
1168+
}
1169+
11241170
void InvDrawSlotBack(const Surface &out, Point targetPosition, Size size, item_quality itemQuality)
11251171
{
11261172
SDL_Rect srcRect = MakeSdlRect(0, 0, size.width, size.height);
@@ -1400,8 +1446,9 @@ bool AutoPlaceItemInInventory(Player &player, const Item &item, bool sendNetwork
14001446
if (targetSlot) {
14011447
player.InvList[player._pNumInv] = item;
14021448
player._pNumInv++;
1449+
const int invIndex = CheckSpecialInventoryItem(player, player._pNumInv - 1);
14031450

1404-
AddItemToInvGrid(player, *targetSlot, player._pNumInv, itemSize, sendNetworkMessage);
1451+
AddItemToInvGrid(player, *targetSlot, invIndex + 1, GetInventorySize(player.InvList[invIndex]), sendNetworkMessage);
14051452
player.CalcScrolls();
14061453

14071454
return true;

Source/inv.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ bool AutoEquip(Player &player, const Item &item, bool persistItem = true, bool s
148148
*/
149149
bool CanFitItemInInventory(const Player &player, const Item &item);
150150

151+
/**
152+
* @brief Handles special item behavior after an item has been inserted into InvList.
153+
* @param player The player whose inventory was modified.
154+
* @param invIndex Index of the inserted item in InvList.
155+
* @return The item's current InvList index. This can change if handling the item
156+
* removes other inventory entries and the inventory gets compacted.
157+
*/
158+
int CheckSpecialInventoryItem(Player &player, int invIndex);
159+
151160
/**
152161
* @brief Attempts to place the given item in the specified player's inventory.
153162
* @param player The player whose inventory will be used.

0 commit comments

Comments
 (0)