From 107ec7d2fe0c23df7a2a616efc4d107122ebf333 Mon Sep 17 00:00:00 2001 From: matheusgomes28 Date: Sat, 3 Feb 2024 23:30:29 +0000 Subject: [PATCH 01/11] Splitting CheckInvPaste() into smaller functions Moved functions that were getting previous items into smaller ones with better names. At least you can see straight-away what each of these blocks of code do! --- Source/inv.cpp | 410 +++++++++++++++++++++++++++++-------------------- 1 file changed, 241 insertions(+), 169 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 5310670eae4..0e23e48acd3 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -325,13 +325,162 @@ int FindTargetSlotUnderItemCursor(Point cursorPosition, Size itemSize) return NUM_XY_SLOTS; } -void CheckInvPaste(Player &player, Point cursorPosition) +// TODO : Test that we haven't broken the change in appearance +// when equipping a new body armor +void ChangeBodyEquipment(int slot, Player &player, item_equip_type il) { - Size itemSize = GetInventorySize(player.HoldItem); + auto iLocToInvLoc = [&slot](item_equip_type loc) { + // Table? + switch (loc) { + case ILOC_HELM: + return INVLOC_HEAD; + case ILOC_RING: + return (slot == SLOTXY_RING_LEFT ? INVLOC_RING_LEFT : INVLOC_RING_RIGHT); + case ILOC_AMULET: + return INVLOC_AMULET; + case ILOC_ARMOR: + return INVLOC_CHEST; + default: + app_fatal("Unexpected equipment type"); + } + }; + const auto body_loc = iLocToInvLoc(il); + const Item previouslyEquippedItem = player.InvBody[slot]; + ChangeEquipment(player, body_loc, player.HoldItem.pop(), &player == MyPlayer); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + } +} - int slot = FindTargetSlotUnderItemCursor(cursorPosition, itemSize); - if (slot == NUM_XY_SLOTS) - return; +void ChangeEquippedItem(uint8_t slot, Player &player) +{ + const auto selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; + const auto otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; + + const bool pasteIntoSelectedHand = (player.InvBody[otherHand].isEmpty() || player.InvBody[otherHand]._iClass != player.HoldItem._iClass) + || (player._pClass == HeroClass::Bard && player.InvBody[otherHand]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON); + + const bool dequipTwoHandedWeapon = (!player.InvBody[otherHand].isEmpty() && player.GetItemLocation(player.InvBody[otherHand]) == ILOC_TWOHAND); + + const inv_body_loc pasteHand = pasteIntoSelectedHand ? selectedHand : otherHand; + const Item previouslyEquippedItem = dequipTwoHandedWeapon ? player.InvBody[otherHand] : player.InvBody[pasteHand]; + if (dequipTwoHandedWeapon) { + RemoveEquipment(player, otherHand, false); + } + ChangeEquipment(player, pasteHand, player.HoldItem.pop(), &player == MyPlayer); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + } +} + +void ChangeTwoHandItem(Player &player) +{ + if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && !player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { + inv_body_loc locationToUnequip = INVLOC_HAND_LEFT; + if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) { + locationToUnequip = INVLOC_HAND_RIGHT; + } + if (!AutoPlaceItemInInventory(player, player.InvBody[locationToUnequip], true)) { + return; // TODO this needs to return calling function + } + + if (locationToUnequip == INVLOC_HAND_RIGHT) { + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); + } else { + // CMD_CHANGEPLRITEMS will eventually be sent for the left hand + // Can we RemoveEquipment(player, INVLOC_HAND_RIGHT, false) anyway???? + player.InvBody[INVLOC_HAND_LEFT].clear(); + } + } + + if (player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem.pop(), &player == MyPlayer); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + } + } else { + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem, &player == MyPlayer); + player.HoldItem = previouslyEquippedItem; + } +} + +void ChangeInvItem(Player &player, int8_t prev_it, int slot, Size itemSize) +{ + if (player.HoldItem._itype == ItemType::Gold && prev_it == 0) { + const int ii = slot - SLOTXY_INV_FIRST; + if (player.InvGrid[ii] > 0) { + const int invIndex = player.InvGrid[ii] - 1; + const int gt = player.InvList[invIndex]._ivalue; + int ig = player.HoldItem._ivalue + gt; + if (ig <= MaxGold) { + player.InvList[invIndex]._ivalue = ig; + SetPlrHandGoldCurs(player.InvList[invIndex]); + player._pGold += player.HoldItem._ivalue; + player.HoldItem.clear(); + } else { + ig = MaxGold - gt; + player._pGold += ig; + player.HoldItem._ivalue -= ig; + SetPlrHandGoldCurs(player.HoldItem); + player.InvList[invIndex]._ivalue = MaxGold; + player.InvList[invIndex]._iCurs = ICURS_GOLD_LARGE; + } + } else { + const int invIndex = player._pNumInv; + player._pGold += player.HoldItem._ivalue; + player.InvList[invIndex] = player.HoldItem.pop(); + player._pNumInv++; + player.InvGrid[ii] = player._pNumInv; + } + if (&player == MyPlayer) { + NetSendCmdChInvItem(false, ii); + } + } else { + if (prev_it == 0) { + player.InvList[player._pNumInv] = player.HoldItem.pop(); + player._pNumInv++; + prev_it = player._pNumInv; + } else { + const int invIndex = prev_it - 1; + if (player.HoldItem._itype == ItemType::Gold) + player._pGold += player.HoldItem._ivalue; + std::swap(player.InvList[invIndex], player.HoldItem); + if (player.HoldItem._itype == ItemType::Gold) + player._pGold = CalculateGold(player); + for (auto &itemIndex : player.InvGrid) { + if (itemIndex == prev_it) + itemIndex = 0; + if (itemIndex == -prev_it) + itemIndex = 0; + } + } + + AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, prev_it, itemSize, &player == MyPlayer); + } +} + +void ChangeBeltItem(Player &player, int slot) +{ + const int ii = slot - SLOTXY_BELT_FIRST; + if (player.SpdList[ii].isEmpty()) { + player.SpdList[ii] = player.HoldItem.pop(); + } else { + std::swap(player.SpdList[ii], player.HoldItem); + + if (player.HoldItem._itype == ItemType::Gold) + player._pGold = CalculateGold(player); + } + if (&player == MyPlayer) { + NetSendCmdChBeltItem(false, ii); + } + RedrawComponent(PanelDrawComponent::Belt); +} + +item_equip_type GetItemEquipType(int slot, item_equip_type desired_loc, const Player &player) +{ item_equip_type il = ILOC_UNEQUIPABLE; if (slot == SLOTXY_HEAD) @@ -347,50 +496,89 @@ void CheckInvPaste(Player &player, Point cursorPosition) if (slot >= SLOTXY_BELT_FIRST && slot <= SLOTXY_BELT_LAST) il = ILOC_BELT; - item_equip_type desiredIl = player.GetItemLocation(player.HoldItem); - if (il == ILOC_ONEHAND && desiredIl == ILOC_TWOHAND) - il = ILOC_TWOHAND; - - int8_t it = 0; - if (il == ILOC_UNEQUIPABLE) { - int ii = slot - SLOTXY_INV_FIRST; - if (player.HoldItem._itype == ItemType::Gold) { - if (player.InvGrid[ii] != 0) { - int8_t iv = player.InvGrid[ii]; - if (iv > 0) { - if (player.InvList[iv - 1]._itype != ItemType::Gold) { - it = iv; + if (il == ILOC_ONEHAND && desired_loc == ILOC_TWOHAND) + return ILOC_TWOHAND; + + return il; +} + +std::optional CheckOverlappingItems(int slot, const Player &player, Size itemSize, int8_t prev_it) +{ + // check that the item we're pasting only overlaps one other item (or is going into empty space) + const unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); + + int8_t it = prev_it; + for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { + + for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { + unsigned testCell = originCell + rowOffset + columnOffset; + // FindTargetSlotUnderItemCursor returns the top left slot of the inventory region that fits the item, we can be confident this calculation is not going to read out of range. + assert(testCell < sizeof(player.InvGrid)); + if (player.InvGrid[testCell] != 0) { + int8_t iv = std::abs(player.InvGrid[testCell]); + if (it != 0) { + if (it != iv) { + // Found two different items that would be displaced by the held item, can't paste the item here. + return std::nullopt; } } else { - it = -iv; + it = iv; } } - } else { - // check that the item we're pasting only overlaps one other item (or is going into empty space) - unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); - for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { - for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { - unsigned testCell = originCell + rowOffset + columnOffset; - // FindTargetSlotUnderItemCursor returns the top left slot of the inventory region that fits the item, we can be confident this calculation is not going to read out of range. - assert(testCell < sizeof(player.InvGrid)); - if (player.InvGrid[testCell] != 0) { - int8_t iv = std::abs(player.InvGrid[testCell]); - if (it != 0) { - if (it != iv) { - // Found two different items that would be displaced by the held item, can't paste the item here. - return; - } - } else { - it = iv; - } - } + } + } + + return it; +} + +std::optional GetPrevItemId(int slot, const Player &player, const Size &itemSize) +{ + int8_t item_something = 0; + int cell_num = slot - SLOTXY_INV_FIRST; // Where in InvGrid + if (player.HoldItem._itype == ItemType::Gold) { + // Placing a gold item into the grid somewhere??? + if (player.InvGrid[cell_num] != 0) { + int8_t item_cell_begin = player.InvGrid[cell_num]; // item_cell_begin is not right name + if (item_cell_begin > 0) { + if (player.InvList[item_cell_begin - 1]._itype != ItemType::Gold) { + item_something = item_cell_begin; } + } else { + item_something = -item_cell_begin; } } - } else if (il == ILOC_BELT) { + } else { + auto const maybe_overlapped_item = CheckOverlappingItems(slot, player, itemSize, item_something); + if (!maybe_overlapped_item) { + return std::nullopt; + } + item_something = *maybe_overlapped_item; + } + + return item_something; +} + +void CheckInvPaste(Player &player, Point cursorPosition) +{ + const Size itemSize = GetInventorySize(player.HoldItem); + + const int slot = FindTargetSlotUnderItemCursor(cursorPosition, itemSize); + if (slot == NUM_XY_SLOTS) + return; + + auto const desired_loc = player.GetItemLocation(player.HoldItem); + const auto il = GetItemEquipType(slot, desired_loc, player); + if (il == ILOC_BELT) { if (!CanBePlacedOnBelt(player, player.HoldItem)) return; - } else if (desiredIl != il) { + } + + if ((il != ILOC_UNEQUIPABLE) && (desired_loc != il)) { + return; + } + + auto const maybe_it = (il == ILOC_UNEQUIPABLE) ? GetPrevItemId(slot, player, itemSize) : 0; + if ((il == ILOC_UNEQUIPABLE) && !maybe_it) { return; } @@ -405,155 +593,39 @@ void CheckInvPaste(Player &player, Point cursorPosition) if (&player == MyPlayer) PlaySFX(ItemInvSnds[ItemCAnimTbl[player.HoldItem._iCurs]]); + // Select the parameters that go into + // ChangeEquipment and add it to post switch switch (il) { case ILOC_HELM: case ILOC_RING: case ILOC_AMULET: case ILOC_ARMOR: { - auto iLocToInvLoc = [&slot](item_equip_type loc) { - switch (loc) { - case ILOC_HELM: - return INVLOC_HEAD; - case ILOC_RING: - return (slot == SLOTXY_RING_LEFT ? INVLOC_RING_LEFT : INVLOC_RING_RIGHT); - case ILOC_AMULET: - return INVLOC_AMULET; - case ILOC_ARMOR: - return INVLOC_CHEST; - default: - app_fatal("Unexpected equipment type"); - } - }; - inv_body_loc slot = iLocToInvLoc(il); - Item previouslyEquippedItem = player.InvBody[slot]; - ChangeEquipment(player, slot, player.HoldItem.pop(), &player == MyPlayer); - if (!previouslyEquippedItem.isEmpty()) { - player.HoldItem = previouslyEquippedItem; - } + ChangeBodyEquipment(slot, player, il); + // Calls ChangeEquipment break; } case ILOC_ONEHAND: { - inv_body_loc selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; - inv_body_loc otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; - - bool pasteIntoSelectedHand = (player.InvBody[otherHand].isEmpty() || player.InvBody[otherHand]._iClass != player.HoldItem._iClass) - || (player._pClass == HeroClass::Bard && player.InvBody[otherHand]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON); - - bool dequipTwoHandedWeapon = (!player.InvBody[otherHand].isEmpty() && player.GetItemLocation(player.InvBody[otherHand]) == ILOC_TWOHAND); - - inv_body_loc pasteHand = pasteIntoSelectedHand ? selectedHand : otherHand; - Item previouslyEquippedItem = dequipTwoHandedWeapon ? player.InvBody[otherHand] : player.InvBody[pasteHand]; - if (dequipTwoHandedWeapon) { - RemoveEquipment(player, otherHand, false); - } - ChangeEquipment(player, pasteHand, player.HoldItem.pop(), &player == MyPlayer); - if (!previouslyEquippedItem.isEmpty()) { - player.HoldItem = previouslyEquippedItem; - } + ChangeEquippedItem(slot, player); + // Calls ChangeEquipment break; } case ILOC_TWOHAND: - if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && !player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { - inv_body_loc locationToUnequip = INVLOC_HAND_LEFT; - if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) { - locationToUnequip = INVLOC_HAND_RIGHT; - } - bool done2h = AutoPlaceItemInInventory(player, player.InvBody[locationToUnequip], true); - if (!done2h) - return; - - if (locationToUnequip == INVLOC_HAND_RIGHT) { - RemoveEquipment(player, INVLOC_HAND_RIGHT, false); - } else { - // CMD_CHANGEPLRITEMS will eventually be sent for the left hand - player.InvBody[INVLOC_HAND_LEFT].clear(); - } - } - - if (player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { - Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; - ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem.pop(), &player == MyPlayer); - if (!previouslyEquippedItem.isEmpty()) { - player.HoldItem = previouslyEquippedItem; - } - } else { - Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; - RemoveEquipment(player, INVLOC_HAND_RIGHT, false); - ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem, &player == MyPlayer); - player.HoldItem = previouslyEquippedItem; - } + ChangeTwoHandItem(player); break; - case ILOC_UNEQUIPABLE: - if (player.HoldItem._itype == ItemType::Gold && it == 0) { - int ii = slot - SLOTXY_INV_FIRST; - if (player.InvGrid[ii] > 0) { - int invIndex = player.InvGrid[ii] - 1; - int gt = player.InvList[invIndex]._ivalue; - int ig = player.HoldItem._ivalue + gt; - if (ig <= MaxGold) { - player.InvList[invIndex]._ivalue = ig; - SetPlrHandGoldCurs(player.InvList[invIndex]); - player._pGold += player.HoldItem._ivalue; - player.HoldItem.clear(); - } else { - ig = MaxGold - gt; - player._pGold += ig; - player.HoldItem._ivalue -= ig; - SetPlrHandGoldCurs(player.HoldItem); - player.InvList[invIndex]._ivalue = MaxGold; - player.InvList[invIndex]._iCurs = ICURS_GOLD_LARGE; - } - } else { - int invIndex = player._pNumInv; - player._pGold += player.HoldItem._ivalue; - player.InvList[invIndex] = player.HoldItem.pop(); - player._pNumInv++; - player.InvGrid[ii] = player._pNumInv; - } - if (&player == MyPlayer) { - NetSendCmdChInvItem(false, ii); - } - } else { - if (it == 0) { - player.InvList[player._pNumInv] = player.HoldItem.pop(); - player._pNumInv++; - it = player._pNumInv; - } else { - int invIndex = it - 1; - if (player.HoldItem._itype == ItemType::Gold) - player._pGold += player.HoldItem._ivalue; - std::swap(player.InvList[invIndex], player.HoldItem); - if (player.HoldItem._itype == ItemType::Gold) - player._pGold = CalculateGold(player); - for (auto &itemIndex : player.InvGrid) { - if (itemIndex == it) - itemIndex = 0; - if (itemIndex == -it) - itemIndex = 0; - } - } + case ILOC_UNEQUIPABLE: { - AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, it, itemSize, &player == MyPlayer); - } + // PlaceInvitem + ChangeInvItem(player, *maybe_it, slot, itemSize); break; + } case ILOC_BELT: { - int ii = slot - SLOTXY_BELT_FIRST; - if (player.SpdList[ii].isEmpty()) { - player.SpdList[ii] = player.HoldItem.pop(); - } else { - std::swap(player.SpdList[ii], player.HoldItem); - if (player.HoldItem._itype == ItemType::Gold) - player._pGold = CalculateGold(player); - } - if (&player == MyPlayer) { - NetSendCmdChBeltItem(false, ii); - } - RedrawComponent(PanelDrawComponent::Belt); + ChangeBeltItem(player, slot); } break; case ILOC_NONE: case ILOC_INVALID: break; } + CalcPlrInv(player, true); if (&player == MyPlayer) { NewCursor(player.HoldItem); From dbefe87b00d953a0d166598a2799e430e914a5b8 Mon Sep 17 00:00:00 2001 From: matheusgomes28 Date: Sat, 3 Feb 2024 23:30:29 +0000 Subject: [PATCH 02/11] Splitting CheckInvPaste() into smaller functions Moved functions that were getting previous items into smaller ones with better names. At least you can see straight-away what each of these blocks of code do! --- Source/inv.cpp | 400 ++++++++++++++++++++++++++++--------------------- 1 file changed, 230 insertions(+), 170 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 5310670eae4..ba73f9154e1 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -325,14 +325,158 @@ int FindTargetSlotUnderItemCursor(Point cursorPosition, Size itemSize) return NUM_XY_SLOTS; } -void CheckInvPaste(Player &player, Point cursorPosition) +void ChangeBodyEquipment(int slot, Player &player, item_equip_type il) { - Size itemSize = GetInventorySize(player.HoldItem); + auto iLocToInvLoc = [&slot](item_equip_type loc) { + // Table? + switch (loc) { + case ILOC_HELM: + return INVLOC_HEAD; + case ILOC_RING: + return (slot == SLOTXY_RING_LEFT ? INVLOC_RING_LEFT : INVLOC_RING_RIGHT); + case ILOC_AMULET: + return INVLOC_AMULET; + case ILOC_ARMOR: + return INVLOC_CHEST; + default: + app_fatal("Unexpected equipment type"); + } + }; + const auto body_loc = iLocToInvLoc(il); + const Item previouslyEquippedItem = player.InvBody[slot]; + ChangeEquipment(player, body_loc, player.HoldItem.pop(), &player == MyPlayer); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + } +} - int slot = FindTargetSlotUnderItemCursor(cursorPosition, itemSize); - if (slot == NUM_XY_SLOTS) - return; +void ChangeEquippedItem(uint8_t slot, Player &player) +{ + const auto selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; + const auto otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; + + const bool pasteIntoSelectedHand = (player.InvBody[otherHand].isEmpty() || player.InvBody[otherHand]._iClass != player.HoldItem._iClass) + || (player._pClass == HeroClass::Bard && player.InvBody[otherHand]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON); + + const bool dequipTwoHandedWeapon = (!player.InvBody[otherHand].isEmpty() && player.GetItemLocation(player.InvBody[otherHand]) == ILOC_TWOHAND); + + const inv_body_loc pasteHand = pasteIntoSelectedHand ? selectedHand : otherHand; + const Item previouslyEquippedItem = dequipTwoHandedWeapon ? player.InvBody[otherHand] : player.InvBody[pasteHand]; + if (dequipTwoHandedWeapon) { + RemoveEquipment(player, otherHand, false); + } + ChangeEquipment(player, pasteHand, player.HoldItem.pop(), &player == MyPlayer); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + } +} + +void ChangeTwoHandItem(Player &player) +{ + if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && !player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { + inv_body_loc locationToUnequip = INVLOC_HAND_LEFT; + if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) { + locationToUnequip = INVLOC_HAND_RIGHT; + } + if (!AutoPlaceItemInInventory(player, player.InvBody[locationToUnequip], true)) { + return; + } + if (locationToUnequip == INVLOC_HAND_RIGHT) { + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); + } else { + player.InvBody[INVLOC_HAND_LEFT].clear(); + } + } + + if (player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem.pop(), &player == MyPlayer); + if (!previouslyEquippedItem.isEmpty()) { + player.HoldItem = previouslyEquippedItem; + } + } else { + Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; + RemoveEquipment(player, INVLOC_HAND_RIGHT, false); + ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem, &player == MyPlayer); + player.HoldItem = previouslyEquippedItem; + } +} + +void ChangeInvItem(Player &player, int8_t prev_it, int slot, Size itemSize) +{ + if (player.HoldItem._itype == ItemType::Gold && prev_it == 0) { + const int ii = slot - SLOTXY_INV_FIRST; + if (player.InvGrid[ii] > 0) { + const int invIndex = player.InvGrid[ii] - 1; + const int gt = player.InvList[invIndex]._ivalue; + int ig = player.HoldItem._ivalue + gt; + if (ig <= MaxGold) { + player.InvList[invIndex]._ivalue = ig; + SetPlrHandGoldCurs(player.InvList[invIndex]); + player._pGold += player.HoldItem._ivalue; + player.HoldItem.clear(); + } else { + ig = MaxGold - gt; + player._pGold += ig; + player.HoldItem._ivalue -= ig; + SetPlrHandGoldCurs(player.HoldItem); + player.InvList[invIndex]._ivalue = MaxGold; + player.InvList[invIndex]._iCurs = ICURS_GOLD_LARGE; + } + } else { + const int invIndex = player._pNumInv; + player._pGold += player.HoldItem._ivalue; + player.InvList[invIndex] = player.HoldItem.pop(); + player._pNumInv++; + player.InvGrid[ii] = player._pNumInv; + } + if (&player == MyPlayer) { + NetSendCmdChInvItem(false, ii); + } + } else { + if (prev_it == 0) { + player.InvList[player._pNumInv] = player.HoldItem.pop(); + player._pNumInv++; + prev_it = player._pNumInv; + } else { + const int invIndex = prev_it - 1; + if (player.HoldItem._itype == ItemType::Gold) + player._pGold += player.HoldItem._ivalue; + std::swap(player.InvList[invIndex], player.HoldItem); + if (player.HoldItem._itype == ItemType::Gold) + player._pGold = CalculateGold(player); + for (auto &itemIndex : player.InvGrid) { + if (itemIndex == prev_it) + itemIndex = 0; + if (itemIndex == -prev_it) + itemIndex = 0; + } + } + + AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, prev_it, itemSize, &player == MyPlayer); + } +} + +void ChangeBeltItem(Player &player, int slot) +{ + const int ii = slot - SLOTXY_BELT_FIRST; + if (player.SpdList[ii].isEmpty()) { + player.SpdList[ii] = player.HoldItem.pop(); + } else { + std::swap(player.SpdList[ii], player.HoldItem); + + if (player.HoldItem._itype == ItemType::Gold) + player._pGold = CalculateGold(player); + } + if (&player == MyPlayer) { + NetSendCmdChBeltItem(false, ii); + } + RedrawComponent(PanelDrawComponent::Belt); +} + +item_equip_type GetItemEquipType(int slot, item_equip_type desired_loc, const Player &player) { + item_equip_type il = ILOC_UNEQUIPABLE; if (slot == SLOTXY_HEAD) il = ILOC_HELM; @@ -347,50 +491,88 @@ void CheckInvPaste(Player &player, Point cursorPosition) if (slot >= SLOTXY_BELT_FIRST && slot <= SLOTXY_BELT_LAST) il = ILOC_BELT; - item_equip_type desiredIl = player.GetItemLocation(player.HoldItem); - if (il == ILOC_ONEHAND && desiredIl == ILOC_TWOHAND) - il = ILOC_TWOHAND; - - int8_t it = 0; - if (il == ILOC_UNEQUIPABLE) { - int ii = slot - SLOTXY_INV_FIRST; - if (player.HoldItem._itype == ItemType::Gold) { - if (player.InvGrid[ii] != 0) { - int8_t iv = player.InvGrid[ii]; - if (iv > 0) { - if (player.InvList[iv - 1]._itype != ItemType::Gold) { - it = iv; + if (il == ILOC_ONEHAND && desired_loc == ILOC_TWOHAND) + return ILOC_TWOHAND; + + return il; +} + +std::optional CheckOverlappingItems(int slot, const Player &player, Size itemSize, int8_t prev_it) { + // check that the item we're pasting only overlaps one other item (or is going into empty space) + const unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); + + int8_t it = prev_it; + for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { + + for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { + unsigned testCell = originCell + rowOffset + columnOffset; + // FindTargetSlotUnderItemCursor returns the top left slot of the inventory region that fits the item, we can be confident this calculation is not going to read out of range. + assert(testCell < sizeof(player.InvGrid)); + if (player.InvGrid[testCell] != 0) { + int8_t iv = std::abs(player.InvGrid[testCell]); + if (it != 0) { + if (it != iv) { + // Found two different items that would be displaced by the held item, can't paste the item here. + return std::nullopt; } } else { - it = -iv; + it = iv; } } - } else { - // check that the item we're pasting only overlaps one other item (or is going into empty space) - unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); - for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { - for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { - unsigned testCell = originCell + rowOffset + columnOffset; - // FindTargetSlotUnderItemCursor returns the top left slot of the inventory region that fits the item, we can be confident this calculation is not going to read out of range. - assert(testCell < sizeof(player.InvGrid)); - if (player.InvGrid[testCell] != 0) { - int8_t iv = std::abs(player.InvGrid[testCell]); - if (it != 0) { - if (it != iv) { - // Found two different items that would be displaced by the held item, can't paste the item here. - return; - } - } else { - it = iv; - } - } + } + } + + return it; +} + +std::optional GetPrevItemId(int slot, const Player &player, const Size& itemSize) +{ + int8_t item_something = 0; + int cell_num = slot - SLOTXY_INV_FIRST; // Where in InvGrid + if (player.HoldItem._itype == ItemType::Gold) { + // Placing a gold item into the grid somewhere??? + if (player.InvGrid[cell_num] != 0) { + int8_t item_cell_begin = player.InvGrid[cell_num]; // item_cell_begin is not right name + if (item_cell_begin > 0) { + if (player.InvList[item_cell_begin - 1]._itype != ItemType::Gold) { + item_something = item_cell_begin; } + } else { + item_something = -item_cell_begin; } } - } else if (il == ILOC_BELT) { + } else { + auto const maybe_overlapped_item = CheckOverlappingItems(slot, player, itemSize, item_something); + if (!maybe_overlapped_item) { + return std::nullopt; + } + item_something = *maybe_overlapped_item; + } + + return item_something; +} + +void CheckInvPaste(Player &player, Point cursorPosition) +{ + const Size itemSize = GetInventorySize(player.HoldItem); + + const int slot = FindTargetSlotUnderItemCursor(cursorPosition, itemSize); + if (slot == NUM_XY_SLOTS) + return; + + auto const desired_loc = player.GetItemLocation(player.HoldItem); + const auto il = GetItemEquipType(slot, desired_loc, player); + if (il == ILOC_BELT) { if (!CanBePlacedOnBelt(player, player.HoldItem)) return; - } else if (desiredIl != il) { + } + + if ((il != ILOC_UNEQUIPABLE) && (desired_loc != il)) { + return; + } + + auto const maybe_it = (il == ILOC_UNEQUIPABLE) ? GetPrevItemId(slot, player, itemSize) : 0; + if ((il == ILOC_UNEQUIPABLE) && !maybe_it) { return; } @@ -410,150 +592,28 @@ void CheckInvPaste(Player &player, Point cursorPosition) case ILOC_RING: case ILOC_AMULET: case ILOC_ARMOR: { - auto iLocToInvLoc = [&slot](item_equip_type loc) { - switch (loc) { - case ILOC_HELM: - return INVLOC_HEAD; - case ILOC_RING: - return (slot == SLOTXY_RING_LEFT ? INVLOC_RING_LEFT : INVLOC_RING_RIGHT); - case ILOC_AMULET: - return INVLOC_AMULET; - case ILOC_ARMOR: - return INVLOC_CHEST; - default: - app_fatal("Unexpected equipment type"); - } - }; - inv_body_loc slot = iLocToInvLoc(il); - Item previouslyEquippedItem = player.InvBody[slot]; - ChangeEquipment(player, slot, player.HoldItem.pop(), &player == MyPlayer); - if (!previouslyEquippedItem.isEmpty()) { - player.HoldItem = previouslyEquippedItem; - } + ChangeBodyEquipment(slot, player, il); break; } case ILOC_ONEHAND: { - inv_body_loc selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; - inv_body_loc otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; - - bool pasteIntoSelectedHand = (player.InvBody[otherHand].isEmpty() || player.InvBody[otherHand]._iClass != player.HoldItem._iClass) - || (player._pClass == HeroClass::Bard && player.InvBody[otherHand]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON); - - bool dequipTwoHandedWeapon = (!player.InvBody[otherHand].isEmpty() && player.GetItemLocation(player.InvBody[otherHand]) == ILOC_TWOHAND); - - inv_body_loc pasteHand = pasteIntoSelectedHand ? selectedHand : otherHand; - Item previouslyEquippedItem = dequipTwoHandedWeapon ? player.InvBody[otherHand] : player.InvBody[pasteHand]; - if (dequipTwoHandedWeapon) { - RemoveEquipment(player, otherHand, false); - } - ChangeEquipment(player, pasteHand, player.HoldItem.pop(), &player == MyPlayer); - if (!previouslyEquippedItem.isEmpty()) { - player.HoldItem = previouslyEquippedItem; - } + ChangeEquippedItem(slot, player); break; } case ILOC_TWOHAND: - if (!player.InvBody[INVLOC_HAND_LEFT].isEmpty() && !player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { - inv_body_loc locationToUnequip = INVLOC_HAND_LEFT; - if (player.InvBody[INVLOC_HAND_RIGHT]._itype == ItemType::Shield) { - locationToUnequip = INVLOC_HAND_RIGHT; - } - bool done2h = AutoPlaceItemInInventory(player, player.InvBody[locationToUnequip], true); - if (!done2h) - return; - - if (locationToUnequip == INVLOC_HAND_RIGHT) { - RemoveEquipment(player, INVLOC_HAND_RIGHT, false); - } else { - // CMD_CHANGEPLRITEMS will eventually be sent for the left hand - player.InvBody[INVLOC_HAND_LEFT].clear(); - } - } - - if (player.InvBody[INVLOC_HAND_RIGHT].isEmpty()) { - Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_LEFT]; - ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem.pop(), &player == MyPlayer); - if (!previouslyEquippedItem.isEmpty()) { - player.HoldItem = previouslyEquippedItem; - } - } else { - Item previouslyEquippedItem = player.InvBody[INVLOC_HAND_RIGHT]; - RemoveEquipment(player, INVLOC_HAND_RIGHT, false); - ChangeEquipment(player, INVLOC_HAND_LEFT, player.HoldItem, &player == MyPlayer); - player.HoldItem = previouslyEquippedItem; - } + ChangeTwoHandItem(player); break; - case ILOC_UNEQUIPABLE: - if (player.HoldItem._itype == ItemType::Gold && it == 0) { - int ii = slot - SLOTXY_INV_FIRST; - if (player.InvGrid[ii] > 0) { - int invIndex = player.InvGrid[ii] - 1; - int gt = player.InvList[invIndex]._ivalue; - int ig = player.HoldItem._ivalue + gt; - if (ig <= MaxGold) { - player.InvList[invIndex]._ivalue = ig; - SetPlrHandGoldCurs(player.InvList[invIndex]); - player._pGold += player.HoldItem._ivalue; - player.HoldItem.clear(); - } else { - ig = MaxGold - gt; - player._pGold += ig; - player.HoldItem._ivalue -= ig; - SetPlrHandGoldCurs(player.HoldItem); - player.InvList[invIndex]._ivalue = MaxGold; - player.InvList[invIndex]._iCurs = ICURS_GOLD_LARGE; - } - } else { - int invIndex = player._pNumInv; - player._pGold += player.HoldItem._ivalue; - player.InvList[invIndex] = player.HoldItem.pop(); - player._pNumInv++; - player.InvGrid[ii] = player._pNumInv; - } - if (&player == MyPlayer) { - NetSendCmdChInvItem(false, ii); - } - } else { - if (it == 0) { - player.InvList[player._pNumInv] = player.HoldItem.pop(); - player._pNumInv++; - it = player._pNumInv; - } else { - int invIndex = it - 1; - if (player.HoldItem._itype == ItemType::Gold) - player._pGold += player.HoldItem._ivalue; - std::swap(player.InvList[invIndex], player.HoldItem); - if (player.HoldItem._itype == ItemType::Gold) - player._pGold = CalculateGold(player); - for (auto &itemIndex : player.InvGrid) { - if (itemIndex == it) - itemIndex = 0; - if (itemIndex == -it) - itemIndex = 0; - } - } - - AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, it, itemSize, &player == MyPlayer); - } + case ILOC_UNEQUIPABLE: { + ChangeInvItem(player, *maybe_it, slot, itemSize); break; + } case ILOC_BELT: { - int ii = slot - SLOTXY_BELT_FIRST; - if (player.SpdList[ii].isEmpty()) { - player.SpdList[ii] = player.HoldItem.pop(); - } else { - std::swap(player.SpdList[ii], player.HoldItem); - if (player.HoldItem._itype == ItemType::Gold) - player._pGold = CalculateGold(player); - } - if (&player == MyPlayer) { - NetSendCmdChBeltItem(false, ii); - } - RedrawComponent(PanelDrawComponent::Belt); + ChangeBeltItem(player, slot); } break; case ILOC_NONE: case ILOC_INVALID: break; } + CalcPlrInv(player, true); if (&player == MyPlayer) { NewCursor(player.HoldItem); From 83b548e8a42d417b97d8a6afe7c7244e0ea5aede Mon Sep 17 00:00:00 2001 From: matheusgomes28 Date: Wed, 6 Mar 2024 22:02:19 +0000 Subject: [PATCH 03/11] removing unecessary comments --- Source/inv.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index adb5e0a3f35..800d6befa22 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -379,14 +379,12 @@ void ChangeTwoHandItem(Player &player) locationToUnequip = INVLOC_HAND_RIGHT; } if (!AutoPlaceItemInInventory(player, player.InvBody[locationToUnequip], true)) { - return; // TODO this needs to return calling function + return; } if (locationToUnequip == INVLOC_HAND_RIGHT) { RemoveEquipment(player, INVLOC_HAND_RIGHT, false); } else { - // CMD_CHANGEPLRITEMS will eventually be sent for the left hand - // Can we RemoveEquipment(player, INVLOC_HAND_RIGHT, false) anyway???? player.InvBody[INVLOC_HAND_LEFT].clear(); } } From 7c8a05f9d987657ee177db8978eec0c90ef1857d Mon Sep 17 00:00:00 2001 From: matheusgomes28 Date: Tue, 12 Mar 2024 21:54:44 +0000 Subject: [PATCH 04/11] Changing item_id variable name --- Source/inv.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 800d6befa22..c67c4dd2143 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -531,9 +531,8 @@ std::optional GetPrevItemId(int slot, const Player &player, const Size & int8_t item_something = 0; int cell_num = slot - SLOTXY_INV_FIRST; // Where in InvGrid if (player.HoldItem._itype == ItemType::Gold) { - // Placing a gold item into the grid somewhere??? if (player.InvGrid[cell_num] != 0) { - int8_t item_cell_begin = player.InvGrid[cell_num]; // item_cell_begin is not right name + int8_t item_cell_begin = player.InvGrid[cell_num]; if (item_cell_begin > 0) { if (player.InvList[item_cell_begin - 1]._itype != ItemType::Gold) { item_something = item_cell_begin; @@ -572,8 +571,8 @@ void CheckInvPaste(Player &player, Point cursorPosition) return; } - auto const maybe_it = (il == ILOC_UNEQUIPABLE) ? GetPrevItemId(slot, player, itemSize) : 0; - if ((il == ILOC_UNEQUIPABLE) && !maybe_it) { + auto const maybe_item_id = (il == ILOC_UNEQUIPABLE) ? GetPrevItemId(slot, player, itemSize) : 0; + if ((il == ILOC_UNEQUIPABLE) && !maybe_item_id) { return; } @@ -606,7 +605,7 @@ void CheckInvPaste(Player &player, Point cursorPosition) ChangeTwoHandItem(player); break; case ILOC_UNEQUIPABLE: { - ChangeInvItem(player, *maybe_it, slot, itemSize); + ChangeInvItem(player, *maybe_item_id, slot, itemSize); break; } case ILOC_BELT: { From 7ce625608ccaa4be81e38a984a4489a7f95f7819 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 08:06:11 +0200 Subject: [PATCH 05/11] Apply suggestions from code review --- Source/inv.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index c67c4dd2143..e9100346100 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -327,8 +327,7 @@ int FindTargetSlotUnderItemCursor(Point cursorPosition, Size itemSize) void ChangeBodyEquipment(int slot, Player &player, item_equip_type il) { - auto iLocToInvLoc = [&slot](item_equip_type loc) { - // Table? + const auto body_loc = [&slot](item_equip_type loc) { switch (loc) { case ILOC_HELM: return INVLOC_HEAD; @@ -341,8 +340,7 @@ void ChangeBodyEquipment(int slot, Player &player, item_equip_type il) default: app_fatal("Unexpected equipment type"); } - }; - const auto body_loc = iLocToInvLoc(il); + }(il); const Item previouslyEquippedItem = player.InvBody[slot]; ChangeEquipment(player, body_loc, player.HoldItem.pop(), &player == MyPlayer); if (!previouslyEquippedItem.isEmpty()) { @@ -542,11 +540,11 @@ std::optional GetPrevItemId(int slot, const Player &player, const Size & } } } else { - auto const maybe_overlapped_item = CheckOverlappingItems(slot, player, itemSize, item_something); - if (!maybe_overlapped_item) { + const std::optional overlappingItemId = CheckOverlappingItems(slot, player, itemSize, item_something); + if (!overlappingItemId) { return std::nullopt; } - item_something = *maybe_overlapped_item; + item_something = *overlappingItemId; } return item_something; From 591595ebfb7618e7f033aad80880d8d57ac93e00 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 08:07:17 +0200 Subject: [PATCH 06/11] Update inv.cpp --- Source/inv.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index e9100346100..4c85ba882ae 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -526,28 +526,28 @@ std::optional CheckOverlappingItems(int slot, const Player &player, Size std::optional GetPrevItemId(int slot, const Player &player, const Size &itemSize) { - int8_t item_something = 0; + int8_t prevItemId = 0; int cell_num = slot - SLOTXY_INV_FIRST; // Where in InvGrid if (player.HoldItem._itype == ItemType::Gold) { if (player.InvGrid[cell_num] != 0) { int8_t item_cell_begin = player.InvGrid[cell_num]; if (item_cell_begin > 0) { if (player.InvList[item_cell_begin - 1]._itype != ItemType::Gold) { - item_something = item_cell_begin; + prevItemId = item_cell_begin; } } else { - item_something = -item_cell_begin; + prevItemId = -item_cell_begin; } } } else { - const std::optional overlappingItemId = CheckOverlappingItems(slot, player, itemSize, item_something); + const std::optional overlappingItemId = CheckOverlappingItems(slot, player, itemSize, prevItemId); if (!overlappingItemId) { return std::nullopt; } - item_something = *overlappingItemId; + prevItemId = *overlappingItemId; } - return item_something; + return prevItemId; } void CheckInvPaste(Player &player, Point cursorPosition) From abf8b84bfd4a76241e35eea576f4eb17b4b13d01 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 08:08:03 +0200 Subject: [PATCH 07/11] Update inv.cpp --- Source/inv.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 4c85ba882ae..3eef817c392 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -591,24 +591,21 @@ void CheckInvPaste(Player &player, Point cursorPosition) case ILOC_HELM: case ILOC_RING: case ILOC_AMULET: - case ILOC_ARMOR: { + case ILOC_ARMOR: ChangeBodyEquipment(slot, player, il); break; - } - case ILOC_ONEHAND: { + case ILOC_ONEHAND: ChangeEquippedItem(slot, player); break; - } case ILOC_TWOHAND: ChangeTwoHandItem(player); break; - case ILOC_UNEQUIPABLE: { + case ILOC_UNEQUIPABLE: ChangeInvItem(player, *maybe_item_id, slot, itemSize); break; - } - case ILOC_BELT: { + case ILOC_BELT: ChangeBeltItem(player, slot); - } break; + break; case ILOC_NONE: case ILOC_INVALID: break; From 2a04009cb3c58791136a3bd052fc58dae3f869cb Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 08:29:12 +0200 Subject: [PATCH 08/11] Update Source/inv.cpp --- Source/inv.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 3eef817c392..6ba2338ec34 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -569,9 +569,10 @@ void CheckInvPaste(Player &player, Point cursorPosition) return; } - auto const maybe_item_id = (il == ILOC_UNEQUIPABLE) ? GetPrevItemId(slot, player, itemSize) : 0; - if ((il == ILOC_UNEQUIPABLE) && !maybe_item_id) { - return; + std::optional maybe_item_id = 0; + if (il == ILOC_UNEQUIPABLE) { + maybe_item_id = GetPrevItemId(slot, player, itemSize); + if (!maybe_item_id) return; } if (IsNoneOf(il, ILOC_UNEQUIPABLE, ILOC_BELT) && !player.CanUseItem(player.HoldItem)) { From 94492ef858e70b09d09d6d7bbe6f886327e36238 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 09:12:20 +0200 Subject: [PATCH 09/11] Clean up GetPrevItemId() --- Source/inv.cpp | 139 ++++++++++++++++++++++--------------------------- 1 file changed, 62 insertions(+), 77 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 6ba2338ec34..8ad659a2ce4 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -325,7 +325,7 @@ int FindTargetSlotUnderItemCursor(Point cursorPosition, Size itemSize) return NUM_XY_SLOTS; } -void ChangeBodyEquipment(int slot, Player &player, item_equip_type il) +void ChangeBodyEquipment(Player &player, int slot, item_equip_type il) { const auto body_loc = [&slot](item_equip_type loc) { switch (loc) { @@ -348,7 +348,7 @@ void ChangeBodyEquipment(int slot, Player &player, item_equip_type il) } } -void ChangeEquippedItem(uint8_t slot, Player &player) +void ChangeEquippedItem(Player &player, uint8_t slot) { const auto selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; const auto otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; @@ -401,9 +401,55 @@ void ChangeTwoHandItem(Player &player) } } -void ChangeInvItem(Player &player, int8_t prev_it, int slot, Size itemSize) +int8_t CheckOverlappingItems(int slot, const Player &player, Size itemSize, int8_t prev_it) { - if (player.HoldItem._itype == ItemType::Gold && prev_it == 0) { + // check that the item we're pasting only overlaps one other item (or is going into empty space) + const unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); + + int8_t it = prev_it; + for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { + + for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { + unsigned testCell = originCell + rowOffset + columnOffset; + // FindTargetSlotUnderItemCursor returns the top left slot of the inventory region that fits the item, we can be confident this calculation is not going to read out of range. + assert(testCell < sizeof(player.InvGrid)); + if (player.InvGrid[testCell] != 0) { + int8_t iv = std::abs(player.InvGrid[testCell]); + if (it != 0) { + if (it != iv) { + // Found two different items that would be displaced by the held item, can't paste the item here. + return -1; + } + } else { + it = iv; + } + } + } + } + + return it; +} + +int8_t GetPrevItemId(int slot, const Player &player, const Size &itemSize) +{ + if (player.HoldItem._itype != ItemType::Gold) + return CheckOverlappingItems(slot, player, itemSize, 0); + int8_t item_cell_begin = player.InvGrid[slot - SLOTXY_INV_FIRST]; + if (item_cell_begin == 0) + return 0; + if (item_cell_begin <= 0) + return -item_cell_begin; + if (player.InvList[item_cell_begin - 1]._itype != ItemType::Gold) + return item_cell_begin; + return 0; +} + +bool ChangeInvItem(Player &player, int slot, Size itemSize) +{ + int8_t prevItemId = GetPrevItemId(slot, player, itemSize); + if (prevItemId < 0) return false; + + if (player.HoldItem._itype == ItemType::Gold && prevItemId == 0) { const int ii = slot - SLOTXY_INV_FIRST; if (player.InvGrid[ii] > 0) { const int invIndex = player.InvGrid[ii] - 1; @@ -433,27 +479,29 @@ void ChangeInvItem(Player &player, int8_t prev_it, int slot, Size itemSize) NetSendCmdChInvItem(false, ii); } } else { - if (prev_it == 0) { + if (prevItemId == 0) { player.InvList[player._pNumInv] = player.HoldItem.pop(); player._pNumInv++; - prev_it = player._pNumInv; + prevItemId = player._pNumInv; } else { - const int invIndex = prev_it - 1; + const int invIndex = prevItemId - 1; if (player.HoldItem._itype == ItemType::Gold) player._pGold += player.HoldItem._ivalue; std::swap(player.InvList[invIndex], player.HoldItem); if (player.HoldItem._itype == ItemType::Gold) player._pGold = CalculateGold(player); for (auto &itemIndex : player.InvGrid) { - if (itemIndex == prev_it) + if (itemIndex == prevItemId) itemIndex = 0; - if (itemIndex == -prev_it) + if (itemIndex == -prevItemId) itemIndex = 0; } } - AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, prev_it, itemSize, &player == MyPlayer); + AddItemToInvGrid(player, slot - SLOTXY_INV_FIRST, prevItemId, itemSize, &player == MyPlayer); } + + return true; } void ChangeBeltItem(Player &player, int slot) @@ -495,61 +543,6 @@ item_equip_type GetItemEquipType(int slot, item_equip_type desired_loc, const Pl return il; } -std::optional CheckOverlappingItems(int slot, const Player &player, Size itemSize, int8_t prev_it) -{ - // check that the item we're pasting only overlaps one other item (or is going into empty space) - const unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); - - int8_t it = prev_it; - for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { - - for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { - unsigned testCell = originCell + rowOffset + columnOffset; - // FindTargetSlotUnderItemCursor returns the top left slot of the inventory region that fits the item, we can be confident this calculation is not going to read out of range. - assert(testCell < sizeof(player.InvGrid)); - if (player.InvGrid[testCell] != 0) { - int8_t iv = std::abs(player.InvGrid[testCell]); - if (it != 0) { - if (it != iv) { - // Found two different items that would be displaced by the held item, can't paste the item here. - return std::nullopt; - } - } else { - it = iv; - } - } - } - } - - return it; -} - -std::optional GetPrevItemId(int slot, const Player &player, const Size &itemSize) -{ - int8_t prevItemId = 0; - int cell_num = slot - SLOTXY_INV_FIRST; // Where in InvGrid - if (player.HoldItem._itype == ItemType::Gold) { - if (player.InvGrid[cell_num] != 0) { - int8_t item_cell_begin = player.InvGrid[cell_num]; - if (item_cell_begin > 0) { - if (player.InvList[item_cell_begin - 1]._itype != ItemType::Gold) { - prevItemId = item_cell_begin; - } - } else { - prevItemId = -item_cell_begin; - } - } - } else { - const std::optional overlappingItemId = CheckOverlappingItems(slot, player, itemSize, prevItemId); - if (!overlappingItemId) { - return std::nullopt; - } - prevItemId = *overlappingItemId; - } - - return prevItemId; -} - void CheckInvPaste(Player &player, Point cursorPosition) { const Size itemSize = GetInventorySize(player.HoldItem); @@ -569,12 +562,6 @@ void CheckInvPaste(Player &player, Point cursorPosition) return; } - std::optional maybe_item_id = 0; - if (il == ILOC_UNEQUIPABLE) { - maybe_item_id = GetPrevItemId(slot, player, itemSize); - if (!maybe_item_id) return; - } - if (IsNoneOf(il, ILOC_UNEQUIPABLE, ILOC_BELT) && !player.CanUseItem(player.HoldItem)) { player.Say(HeroSpeech::ICantUseThisYet); return; @@ -583,9 +570,6 @@ void CheckInvPaste(Player &player, Point cursorPosition) if (player._pmode > PM_WALK_SIDEWAYS && IsNoneOf(il, ILOC_UNEQUIPABLE, ILOC_BELT)) return; - if (&player == MyPlayer) - PlaySFX(ItemInvSnds[ItemCAnimTbl[player.HoldItem._iCurs]]); - // Select the parameters that go into // ChangeEquipment and add it to post switch switch (il) { @@ -593,16 +577,16 @@ void CheckInvPaste(Player &player, Point cursorPosition) case ILOC_RING: case ILOC_AMULET: case ILOC_ARMOR: - ChangeBodyEquipment(slot, player, il); + ChangeBodyEquipment(player, slot, il); break; case ILOC_ONEHAND: - ChangeEquippedItem(slot, player); + ChangeEquippedItem(player, slot); break; case ILOC_TWOHAND: ChangeTwoHandItem(player); break; case ILOC_UNEQUIPABLE: - ChangeInvItem(player, *maybe_item_id, slot, itemSize); + if (!ChangeInvItem(player, slot, itemSize)) return; break; case ILOC_BELT: ChangeBeltItem(player, slot); @@ -614,6 +598,7 @@ void CheckInvPaste(Player &player, Point cursorPosition) CalcPlrInv(player, true); if (&player == MyPlayer) { + PlaySFX(ItemInvSnds[ItemCAnimTbl[player.HoldItem._iCurs]]); NewCursor(player.HoldItem); } } From f2313c91cbbbacafa5d57c8bf2c88e73623353fa Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 11:06:15 +0200 Subject: [PATCH 10/11] Fix belt and clean up some names and types --- Source/control.cpp | 2 +- Source/controls/plrctrls.cpp | 6 +- Source/controls/touch/renderers.cpp | 2 +- Source/diablo.cpp | 4 +- Source/inv.cpp | 94 ++++++++++++++--------------- Source/loadsave.cpp | 2 +- Source/missiles.cpp | 22 +++---- Source/monster.cpp | 24 ++++---- Source/msg.cpp | 6 +- Source/objects.cpp | 2 +- Source/player.cpp | 14 ++--- Source/sync.cpp | 4 +- 12 files changed, 90 insertions(+), 92 deletions(-) diff --git a/Source/control.cpp b/Source/control.cpp index 7919cff8d78..89e80f5d4f6 100644 --- a/Source/control.cpp +++ b/Source/control.cpp @@ -1212,7 +1212,7 @@ void DrawInfoBox(const Surface &out) GetObjectStr(*ObjectUnderCursor); if (pcursmonst != -1) { if (leveltype != DTYPE_TOWN) { - const auto &monster = Monsters[pcursmonst]; + const Monster &monster = Monsters[pcursmonst]; InfoColor = UiFlags::ColorWhite; InfoString = monster.name(); if (monster.isUnique()) { diff --git a/Source/controls/plrctrls.cpp b/Source/controls/plrctrls.cpp index 3d2e0320144..00d63c0be4f 100644 --- a/Source/controls/plrctrls.cpp +++ b/Source/controls/plrctrls.cpp @@ -165,7 +165,7 @@ void FindItemOrObject() continue; } - auto &item = Items[itemId]; + Item &item = Items[itemId]; if (item.isEmpty() || item._iSelFlag == 0) { continue; } @@ -264,7 +264,7 @@ void FindRangedTarget() for (size_t i = 0; i < ActiveMonsterCount; i++) { int mi = ActiveMonsters[i]; - const auto &monster = Monsters[mi]; + const Monster &monster = Monsters[mi]; if (!CanTargetMonster(monster)) continue; @@ -330,7 +330,7 @@ void FindMeleeTarget() if (dMonster[dx][dy] != 0) { const int mi = std::abs(dMonster[dx][dy]) - 1; - const auto &monster = Monsters[mi]; + const Monster &monster = Monsters[mi]; if (CanTargetMonster(monster)) { const bool newCanTalk = CanTalkToMonst(monster); if (pcursmonst != -1 && !canTalk && newCanTalk) diff --git a/Source/controls/touch/renderers.cpp b/Source/controls/touch/renderers.cpp index 5a610f9996b..a10f7b564d7 100644 --- a/Source/controls/touch/renderers.cpp +++ b/Source/controls/touch/renderers.cpp @@ -438,7 +438,7 @@ VirtualGamepadButtonType PrimaryActionButtonRenderer::GetTownButtonType() VirtualGamepadButtonType PrimaryActionButtonRenderer::GetDungeonButtonType() { if (pcursmonst != -1) { - const auto &monster = Monsters[pcursmonst]; + const Monster &monster = Monsters[pcursmonst]; if (M_Talker(monster) || monster.talkMsg != TEXT_NONE) return GetTalkButtonType(virtualPadButton->isHeld); } diff --git a/Source/diablo.cpp b/Source/diablo.cpp index fe3a610e6ea..00b21ba5b5c 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -1389,7 +1389,7 @@ void UnstuckChargers() } } for (size_t i = 0; i < ActiveMonsterCount; i++) { - auto &monster = Monsters[ActiveMonsters[i]]; + Monster &monster = Monsters[ActiveMonsters[i]]; if (monster.mode == MonsterMode::Charge) monster.mode = MonsterMode::Stand; } @@ -1398,7 +1398,7 @@ void UnstuckChargers() void UpdateMonsterLights() { for (size_t i = 0; i < ActiveMonsterCount; i++) { - auto &monster = Monsters[ActiveMonsters[i]]; + Monster &monster = Monsters[ActiveMonsters[i]]; if ((monster.flags & MFLAG_BERSERK) != 0) { int lightRadius = leveltype == DTYPE_NEST ? 9 : 3; diff --git a/Source/inv.cpp b/Source/inv.cpp index 8ad659a2ce4..963862262a3 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -325,10 +325,10 @@ int FindTargetSlotUnderItemCursor(Point cursorPosition, Size itemSize) return NUM_XY_SLOTS; } -void ChangeBodyEquipment(Player &player, int slot, item_equip_type il) +void ChangeBodyEquipment(Player &player, int slot, item_equip_type location) { - const auto body_loc = [&slot](item_equip_type loc) { - switch (loc) { + const inv_body_loc bodyLocation = [&slot](item_equip_type location) { + switch (location) { case ILOC_HELM: return INVLOC_HEAD; case ILOC_RING: @@ -340,9 +340,9 @@ void ChangeBodyEquipment(Player &player, int slot, item_equip_type il) default: app_fatal("Unexpected equipment type"); } - }(il); + }(location); const Item previouslyEquippedItem = player.InvBody[slot]; - ChangeEquipment(player, body_loc, player.HoldItem.pop(), &player == MyPlayer); + ChangeEquipment(player, bodyLocation, player.HoldItem.pop(), &player == MyPlayer); if (!previouslyEquippedItem.isEmpty()) { player.HoldItem = previouslyEquippedItem; } @@ -350,8 +350,8 @@ void ChangeBodyEquipment(Player &player, int slot, item_equip_type il) void ChangeEquippedItem(Player &player, uint8_t slot) { - const auto selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; - const auto otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; + const inv_body_loc selectedHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_LEFT : INVLOC_HAND_RIGHT; + const inv_body_loc otherHand = slot == SLOTXY_HAND_LEFT ? INVLOC_HAND_RIGHT : INVLOC_HAND_LEFT; const bool pasteIntoSelectedHand = (player.InvBody[otherHand].isEmpty() || player.InvBody[otherHand]._iClass != player.HoldItem._iClass) || (player._pClass == HeroClass::Bard && player.InvBody[otherHand]._iClass == ICLASS_WEAPON && player.HoldItem._iClass == ICLASS_WEAPON); @@ -490,7 +490,7 @@ bool ChangeInvItem(Player &player, int slot, Size itemSize) std::swap(player.InvList[invIndex], player.HoldItem); if (player.HoldItem._itype == ItemType::Gold) player._pGold = CalculateGold(player); - for (auto &itemIndex : player.InvGrid) { + for (int8_t &itemIndex : player.InvGrid) { if (itemIndex == prevItemId) itemIndex = 0; if (itemIndex == -prevItemId) @@ -521,26 +521,25 @@ void ChangeBeltItem(Player &player, int slot) RedrawComponent(PanelDrawComponent::Belt); } -item_equip_type GetItemEquipType(int slot, item_equip_type desired_loc, const Player &player) +item_equip_type GetItemEquipType(const Player &player, int slot, item_equip_type desiredLocation) { - item_equip_type il = ILOC_UNEQUIPABLE; if (slot == SLOTXY_HEAD) - il = ILOC_HELM; + return ILOC_HELM; if (slot == SLOTXY_RING_LEFT || slot == SLOTXY_RING_RIGHT) - il = ILOC_RING; + return ILOC_RING; if (slot == SLOTXY_AMULET) - il = ILOC_AMULET; - if (slot == SLOTXY_HAND_LEFT || slot == SLOTXY_HAND_RIGHT) - il = ILOC_ONEHAND; + return ILOC_AMULET; + if (slot == SLOTXY_HAND_LEFT || slot == SLOTXY_HAND_RIGHT) { + if (desiredLocation == ILOC_TWOHAND) + return ILOC_TWOHAND; + return ILOC_ONEHAND; + } if (slot == SLOTXY_CHEST) - il = ILOC_ARMOR; + return ILOC_ARMOR; if (slot >= SLOTXY_BELT_FIRST && slot <= SLOTXY_BELT_LAST) - il = ILOC_BELT; - - if (il == ILOC_ONEHAND && desired_loc == ILOC_TWOHAND) - return ILOC_TWOHAND; + return ILOC_BELT; - return il; + return ILOC_UNEQUIPABLE; } void CheckInvPaste(Player &player, Point cursorPosition) @@ -551,33 +550,32 @@ void CheckInvPaste(Player &player, Point cursorPosition) if (slot == NUM_XY_SLOTS) return; - auto const desired_loc = player.GetItemLocation(player.HoldItem); - const auto il = GetItemEquipType(slot, desired_loc, player); - if (il == ILOC_BELT) { - if (!CanBePlacedOnBelt(player, player.HoldItem)) - return; - } + const item_equip_type desiredLocation = player.GetItemLocation(player.HoldItem); + const item_equip_type location = GetItemEquipType(player, slot, desiredLocation); - if ((il != ILOC_UNEQUIPABLE) && (desired_loc != il)) { - return; + if (location == ILOC_BELT) { + if (!CanBePlacedOnBelt(player, player.HoldItem)) return; + } else if (location != ILOC_UNEQUIPABLE) { + if (desiredLocation != location) return; } - if (IsNoneOf(il, ILOC_UNEQUIPABLE, ILOC_BELT) && !player.CanUseItem(player.HoldItem)) { - player.Say(HeroSpeech::ICantUseThisYet); - return; + if (IsNoneOf(location, ILOC_UNEQUIPABLE, ILOC_BELT)) { + if (!player.CanUseItem(player.HoldItem)) { + player.Say(HeroSpeech::ICantUseThisYet); + return; + } + if (player._pmode > PM_WALK_SIDEWAYS) + return; } - if (player._pmode > PM_WALK_SIDEWAYS && IsNoneOf(il, ILOC_UNEQUIPABLE, ILOC_BELT)) - return; - // Select the parameters that go into // ChangeEquipment and add it to post switch - switch (il) { + switch (location) { case ILOC_HELM: case ILOC_RING: case ILOC_AMULET: case ILOC_ARMOR: - ChangeBodyEquipment(player, slot, il); + ChangeBodyEquipment(player, slot, location); break; case ILOC_ONEHAND: ChangeEquippedItem(player, slot); @@ -960,7 +958,7 @@ void CheckQuestItem(Player &player, Item &questItem) void CleanupItems(int ii) { - auto &item = Items[ii]; + Item &item = Items[ii]; dItem[item.position.x][item.position.y] = 0; if (CornerStone.isAvailable() && item.position == CornerStone.position) { @@ -1133,7 +1131,7 @@ void DrawInv(const Surface &out) const int cursId = myPlayer.InvBody[slot]._iCurs + CURSOR_FIRSTITEM; - auto frameSize = GetInvItemSize(cursId); + Size frameSize = GetInvItemSize(cursId); // calc item offsets for weapons/armor smaller than 2x3 slots if (IsAnyOf(slot, INVLOC_HAND_LEFT, INVLOC_HAND_RIGHT, INVLOC_CHEST)) { @@ -1243,7 +1241,7 @@ bool AutoPlaceItemInBelt(Player &player, const Item &item, bool persistItem, boo return false; } - for (auto &beltItem : player.SpdList) { + for (Item &beltItem : player.SpdList) { if (beltItem.isEmpty()) { if (persistItem) { beltItem = item; @@ -1496,7 +1494,7 @@ void inv_update_rem_item(Player &player, inv_body_loc iv) void CheckInvSwap(Player &player, const Item &item, int invGridIndex) { - auto itemSize = GetInventorySize(item); + Size itemSize = GetInventorySize(item); const int pitch = 10; int invListIndex = [&]() -> int { @@ -1513,7 +1511,7 @@ void CheckInvSwap(Player &player, const Item &item, int invGridIndex) }(); if (invListIndex < player._pNumInv) { - for (auto &itemIndex : player.InvGrid) { + for (int8_t &itemIndex : player.InvGrid) { if (itemIndex == invListIndex) itemIndex = 0; if (itemIndex == -invListIndex) @@ -1592,7 +1590,7 @@ void CheckInvScrn(bool isShiftHeld, bool isCtrlHeld) void InvGetItem(Player &player, int ii) { - auto &item = Items[ii]; + Item &item = Items[ii]; CloseGoldDrop(); if (dItem[item.position.x][item.position.y] == 0) @@ -1714,7 +1712,7 @@ void AutoGetItem(Player &player, Item *itemPointer, int ii) int FindGetItem(uint32_t iseed, _item_indexes idx, uint16_t createInfo) { for (uint8_t i = 0; i < ActiveItemCount; i++) { - auto &item = Items[ActiveItems[i]]; + Item &item = Items[ActiveItems[i]]; if (item.keyAttributesMatch(iseed, idx, createInfo)) { return i; } @@ -1931,7 +1929,7 @@ void ConsumeScroll(Player &player) { const SpellID spellId = player.executedSpell.spellId; - const auto isCurrentSpell = [spellId](const Item &item) { + const auto isCurrentSpell = [spellId](const Item &item) -> bool { return item.isScrollOf(spellId) || item.isRuneOf(spellId); }; @@ -1972,7 +1970,7 @@ bool CanUseScroll(Player &player, SpellID spell) void ConsumeStaffCharge(Player &player) { - auto &staff = player.InvBody[INVLOC_HAND_LEFT]; + Item &staff = player.InvBody[INVLOC_HAND_LEFT]; if (!CanUseStaff(staff, player.executedSpell.spellId)) return; @@ -2176,7 +2174,7 @@ void DoTelekinesis() if (pcursitem != -1) NetSendCmdGItem(true, CMD_REQUESTAGITEM, *MyPlayer, pcursitem); if (pcursmonst != -1) { - auto &monter = Monsters[pcursmonst]; + Monster &monter = Monsters[pcursmonst]; if (!M_Talker(monter) && monter.talkMsg == TEXT_NONE) NetSendCmdParam1(true, CMD_KNOCKBACK, pcursmonst); } @@ -2198,7 +2196,7 @@ int CalculateGold(Player &player) Size GetInventorySize(const Item &item) { int itemSizeIndex = item._iCurs + CURSOR_FIRSTITEM; - auto size = GetInvItemSize(itemSizeIndex); + Size size = GetInvItemSize(itemSizeIndex); return { size.width / InventorySlotSizeInPixels.width, size.height / InventorySlotSizeInPixels.height }; } diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index c3b9eca1df6..8d14d59ed96 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -688,7 +688,7 @@ void SyncPackSize(Monster &leader) leader.packSize = 0; for (size_t i = 0; i < ActiveMonsterCount; i++) { - auto &minion = Monsters[ActiveMonsters[i]]; + Monster &minion = Monsters[ActiveMonsters[i]]; if (minion.leaderRelation == LeaderRelation::Leashed && minion.getLeader() == &leader) leader.packSize++; } diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 4e0e090bc3d..9516e6dc1f3 100644 --- a/Source/missiles.cpp +++ b/Source/missiles.cpp @@ -204,7 +204,7 @@ int ProjectileTrapDamage(Missile &missile) bool MonsterMHit(const Player &player, int monsterId, int mindam, int maxdam, int dist, MissileID t, DamageType damageType, bool shift) { - auto &monster = Monsters[monsterId]; + Monster &monster = Monsters[monsterId]; if (!monster.isPossibleToHit() || monster.isImmune(t, damageType)) return false; @@ -937,7 +937,7 @@ Direction16 GetDirection16(Point p1, Point p2) bool MonsterTrapHit(int monsterId, int mindam, int maxdam, int dist, MissileID t, DamageType damageType, bool shift) { - auto &monster = Monsters[monsterId]; + Monster &monster = Monsters[monsterId]; if (!monster.isPossibleToHit() || monster.isImmune(t, damageType)) return false; @@ -1247,7 +1247,7 @@ void AddBerserk(Missile &missile, AddMissileParameter ¶meter) parameter.dst, 0, 5); if (targetMonsterPosition) { - auto &monster = Monsters[std::abs(dMonster[targetMonsterPosition->x][targetMonsterPosition->y]) - 1]; + Monster &monster = Monsters[std::abs(dMonster[targetMonsterPosition->x][targetMonsterPosition->y]) - 1]; Player &player = *missile.sourcePlayer(); const int slvl = player.GetSpellLevel(SpellID::Berserk); monster.flags |= MFLAG_BERSERK | MFLAG_GOLEM; @@ -2207,7 +2207,7 @@ void AddGenericMagicMissile(Missile &missile, AddMissileParameter ¶meter) missile.var2 = missile.position.start.y; missile._mlid = AddLight(missile.position.start, 8); if (missile._micaster != TARGET_MONSTERS && missile._misource > 0) { - auto &monster = Monsters[missile._misource]; + Monster &monster = Monsters[missile._misource]; if (monster.type().type == MT_SUCCUBUS) SetMissAnim(missile, MissileGraphicID::BloodStar); if (monster.type().type == MT_SNOWWICH) @@ -2287,7 +2287,7 @@ void AddStoneCurse(Missile &missile, AddMissileParameter ¶meter) return false; } - auto &monster = Monsters[monsterId]; + Monster &monster = Monsters[monsterId]; if (IsAnyOf(monster.type().type, MT_GOLEM, MT_DIABLO, MT_NAKRUL)) { return false; @@ -2308,7 +2308,7 @@ void AddStoneCurse(Missile &missile, AddMissileParameter ¶meter) // Petrify the targeted monster int monsterId = std::abs(dMonster[targetMonsterPosition->x][targetMonsterPosition->y]) - 1; - auto &monster = Monsters[monsterId]; + Monster &monster = Monsters[monsterId]; if (monster.mode == MonsterMode::Petrified) { // Monster is already petrified and StoneCurse doesn't stack @@ -2588,7 +2588,7 @@ void AddInferno(Missile &missile, AddMissileParameter ¶meter) int i = GenerateRnd(Players[missile._misource].getCharacterLevel()) + GenerateRnd(2); missile._midam = 8 * i + 16 + ((8 * i + 16) / 2); } else { - auto &monster = Monsters[missile._misource]; + Monster &monster = Monsters[missile._misource]; missile._midam = monster.minDamage + GenerateRnd(monster.maxDamage - monster.minDamage + 1); } } @@ -3010,7 +3010,7 @@ void ProcessFireball(Missile &missile) int maxDam = missile._midam; if (missile._micaster != TARGET_MONSTERS) { - auto &monster = Monsters[missile._misource]; + Monster &monster = Monsters[missile._misource]; minDam = monster.minDamage; maxDam = monster.maxDamage; } @@ -3303,7 +3303,7 @@ void ProcessLightningControl(Missile &missile) // BUGFIX: damage of missile should be encoded in missile struct; player can be dead/have left the game before missile arrives. dam = (GenerateRnd(2) + GenerateRnd(Players[missile._misource].getCharacterLevel()) + 2) << 6; } else { - auto &monster = Monsters[missile._misource]; + Monster &monster = Monsters[missile._misource]; dam = 2 * (monster.minDamage + GenerateRnd(monster.maxDamage - monster.minDamage + 1)); } @@ -3654,7 +3654,7 @@ void ProcessTeleport(Missile &missile) void ProcessStoneCurse(Missile &missile) { missile._mirange--; - auto &monster = Monsters[missile.var2]; + Monster &monster = Monsters[missile.var2]; if (monster.hitPoints == 0 && missile._miAnimType != MissileGraphicID::StoneCurseShatter) { missile._mimfnum = 0; missile._miDrawFlag = true; @@ -3694,7 +3694,7 @@ void ProcessApocalypseBoom(Missile &missile) void ProcessRhino(Missile &missile) { int monst = missile._misource; - auto &monster = Monsters[monst]; + Monster &monster = Monsters[monst]; if (monster.mode != MonsterMode::Charge) { missile._miDelFlag = true; return; diff --git a/Source/monster.cpp b/Source/monster.cpp index b17d8e2268c..1eab86ed431 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -255,7 +255,7 @@ void PlaceGroup(size_t typeIndex, size_t num, Monster *leader = nullptr, bool le while (placed != 0) { ActiveMonsterCount--; placed--; - const auto &position = Monsters[ActiveMonsterCount].position.tile; + const Point &position = Monsters[ActiveMonsterCount].position.tile; dMonster[position.x][position.y] = 0; } @@ -290,7 +290,7 @@ void PlaceGroup(size_t typeIndex, size_t num, Monster *leader = nullptr, bool le PlaceMonster(ActiveMonsterCount, typeIndex, { xp, yp }); if (leader != nullptr) { - auto &minion = Monsters[ActiveMonsterCount]; + Monster &minion = Monsters[ActiveMonsterCount]; minion.maxHitPoints *= 2; minion.hitPoints = minion.maxHitPoints; minion.intelligence = leader->intelligence; @@ -332,7 +332,7 @@ size_t GetMonsterTypeIndex(_monster_id type) void PlaceUniqueMonst(UniqueMonsterType uniqindex, size_t minionType, int bosspacksize) { - auto &monster = Monsters[ActiveMonsterCount]; + Monster &monster = Monsters[ActiveMonsterCount]; const auto &uniqueMonsterData = UniqueMonstersData[static_cast(uniqindex)]; int count = 0; @@ -567,7 +567,7 @@ void LoadDiabMonsts() void DeleteMonster(size_t activeIndex) { - const auto &monster = Monsters[ActiveMonsters[activeIndex]]; + const Monster &monster = Monsters[ActiveMonsters[activeIndex]]; if ((monster.flags & MFLAG_BERSERK) != 0) { AddUnLight(monster.lightId); } @@ -1454,7 +1454,7 @@ bool MonsterGotHit(Monster &monster) void ReleaseMinions(const Monster &leader) { for (size_t i = 0; i < ActiveMonsterCount; i++) { - auto &minion = Monsters[ActiveMonsters[i]]; + Monster &minion = Monsters[ActiveMonsters[i]]; if (minion.leaderRelation == LeaderRelation::Leashed && minion.getLeader() == &leader) { minion.setLeader(nullptr); } @@ -2243,7 +2243,7 @@ void FallenAi(Monster &monster) if (m <= 0) continue; - auto &otherMonster = Monsters[m - 1]; + Monster &otherMonster = Monsters[m - 1]; if (otherMonster.ai != MonsterAIID::Fallen) continue; @@ -3531,7 +3531,7 @@ void WeakenNaKrul() if (currlevel != 24 || static_cast(UberDiabloMonsterIndex) >= ActiveMonsterCount) return; - auto &monster = Monsters[UberDiabloMonsterIndex]; + Monster &monster = Monsters[UberDiabloMonsterIndex]; PlayEffect(monster, MonsterSound::Death); monster.armorClass -= 50; int hp = monster.maxHitPoints / 2; @@ -4022,7 +4022,7 @@ void GolumAi(Monster &golem) } if ((golem.flags & MFLAG_NO_ENEMY) == 0) { - auto &enemy = Monsters[golem.enemy]; + Monster &enemy = Monsters[golem.enemy]; int mex = golem.position.tile.x - enemy.position.future.x; int mey = golem.position.tile.y - enemy.position.future.y; golem.direction = GetDirection(golem.position.tile, enemy.position.tile); @@ -4069,7 +4069,7 @@ void GolumAi(Monster &golem) void DeleteMonsterList() { for (int i = 0; i < MAX_PLRS; i++) { - auto &golem = Monsters[i]; + Monster &golem = Monsters[i]; if (!golem.isInvalid) continue; @@ -4438,7 +4438,7 @@ void PrintMonstHistory(int mt) void PrintUniqueHistory() { - auto &monster = Monsters[pcursmonst]; + Monster &monster = Monsters[pcursmonst]; if (*sgOptions.Gameplay.showMonsterType) { AddPanelString(fmt::format(fmt::runtime(_("Type: {:s}")), GetMonsterTypeText(monster.data()))); } @@ -4487,7 +4487,7 @@ void PlayEffect(Monster &monster, MonsterSound mode) void MissToMonst(Missile &missile, Point position) { assert(static_cast(missile._misource) < MaxMonsters); - auto &monster = Monsters[missile._misource]; + Monster &monster = Monsters[missile._misource]; Point oldPosition = missile.position.tile; monster.occupyTile(position, false); @@ -4561,7 +4561,7 @@ Monster *FindUniqueMonster(UniqueMonsterType monsterType) { for (size_t i = 0; i < ActiveMonsterCount; i++) { int monsterId = ActiveMonsters[i]; - auto &monster = Monsters[monsterId]; + Monster &monster = Monsters[monsterId]; if (monster.uniqueType == monsterType) return &monster; } diff --git a/Source/msg.cpp b/Source/msg.cpp index c8dc860c2de..2824c8f2dd4 100644 --- a/Source/msg.cpp +++ b/Source/msg.cpp @@ -758,7 +758,7 @@ void DeltaLeaveSync(uint8_t bLevel) for (size_t i = 0; i < ActiveMonsterCount; i++) { int ma = ActiveMonsters[i]; - auto &monster = Monsters[ma]; + Monster &monster = Monsters[ma]; if (monster.hitPoints == 0) continue; DMonsterStr &delta = deltaLevel.monster[ma]; @@ -1816,7 +1816,7 @@ size_t OnMonstDamage(const TCmd *pCmd, Player &player) if (gbBufferMsgs != 1) { if (&player != MyPlayer) { if (player.isOnActiveLevel() && monsterIdx < MaxMonsters) { - auto &monster = Monsters[monsterIdx]; + Monster &monster = Monsters[monsterIdx]; monster.tag(player); if (monster.hitPoints > 0) { monster.hitPoints -= SDL_SwapLE32(message.dwDam); @@ -2692,7 +2692,7 @@ void DeltaLoadLevel() if (deltaLevel.monster[i].position.x == 0xFF) continue; - auto &monster = Monsters[i]; + Monster &monster = Monsters[i]; M_ClearSquares(monster); { const WorldTilePosition position = deltaLevel.monster[i].position; diff --git a/Source/objects.cpp b/Source/objects.cpp index 4dc47694f50..08dd360678f 100644 --- a/Source/objects.cpp +++ b/Source/objects.cpp @@ -3125,7 +3125,7 @@ void OperateBookcase(Object &bookcase, bool sendmsg, bool sendLootMsg) CreateTypeItem(bookcase.position, false, ItemType::Misc, IMISC_BOOK, sendLootMsg, false); if (Quests[Q_ZHAR].IsAvailable()) { - auto &zhar = Monsters[MAX_PLRS]; + Monster &zhar = Monsters[MAX_PLRS]; if (zhar.mode == MonsterMode::Stand // prevents playing the "angry" message for the second time if zhar got aggroed by losing vision and talking again && zhar.uniqueType == UniqueMonsterType::Zhar && zhar.activeForTicks == UINT8_MAX diff --git a/Source/player.cpp b/Source/player.cpp index 5b93ef5329f..2c3df00c1af 100644 --- a/Source/player.cpp +++ b/Source/player.cpp @@ -358,7 +358,7 @@ void DeadItem(Player &player, Item &&itm, Displacement direction) int DropGold(Player &player, int amount, bool skipFullStacks) { for (int i = 0; i < player._pNumInv && amount > 0; i++) { - auto &item = player.InvList[i]; + Item &item = player.InvList[i]; if (item._itype != ItemType::Gold || (skipFullStacks && item._ivalue == MaxGold)) continue; @@ -1819,7 +1819,7 @@ void Player::RestorePartialMana() void Player::ReadySpellFromEquipment(inv_body_loc bodyLocation, bool forceSpell) { - auto &item = InvBody[bodyLocation]; + Item &item = InvBody[bodyLocation]; if (item._itype == ItemType::Staff && IsValidSpell(item._iSpell) && item._iCharges > 0 && item._iStatFlag) { if (forceSpell || _pRSpell == SpellID::Invalid || _pRSplType == SpellType::Invalid) { _pRSpell = item._iSpell; @@ -1917,19 +1917,19 @@ void Player::UpdatePreviewCelSprite(_cmd_id cmdId, Point point, uint16_t wParam1 switch (cmdId) { case _cmd_id::CMD_RATTACKID: { - auto &monster = Monsters[wParam1]; + Monster &monster = Monsters[wParam1]; dir = GetDirection(position.future, monster.position.future); graphic = player_graphic::Attack; break; } case _cmd_id::CMD_SPELLID: { - auto &monster = Monsters[wParam1]; + Monster &monster = Monsters[wParam1]; dir = GetDirection(position.future, monster.position.future); graphic = GetPlayerGraphicForSpell(static_cast(wParam2)); break; } case _cmd_id::CMD_ATTACKID: { - auto &monster = Monsters[wParam1]; + Monster &monster = Monsters[wParam1]; point = monster.position.future; minimalWalkDistance = 2; if (!CanTalkToMonst(monster)) { @@ -2714,7 +2714,7 @@ StartPlayerKill(Player &player, DeathReason deathReason) if (&player != MyPlayer && dropItems) { // Ensure that items are removed for remote players // The dropped items will be synced seperatly (by the remote client) - for (auto &item : player.InvBody) { + for (Item &item : player.InvBody) { item.clear(); } CalcPlrInv(player, false); @@ -2768,7 +2768,7 @@ StartPlayerKill(Player &player, DeathReason deathReason) } if (dropItems) { Direction pdd = player._pdir; - for (auto &item : player.InvBody) { + for (Item &item : player.InvBody) { pdd = Left(pdd); DeadItem(player, item.pop(), Displacement(pdd)); } diff --git a/Source/sync.cpp b/Source/sync.cpp index 5ab54e17ce3..9a93f2867ad 100644 --- a/Source/sync.cpp +++ b/Source/sync.cpp @@ -25,7 +25,7 @@ void SyncOneMonster() { for (size_t i = 0; i < ActiveMonsterCount; i++) { int m = ActiveMonsters[i]; - auto &monster = Monsters[m]; + Monster &monster = Monsters[m]; sgnMonsterPriority[m] = MyPlayer->position.tile.ManhattanDistance(monster.position.tile); if (monster.activeForTicks == 0) { sgnMonsterPriority[m] += 0x1000; @@ -37,7 +37,7 @@ void SyncOneMonster() void SyncMonsterPos(TSyncMonster &monsterSync, int ndx) { - auto &monster = Monsters[ndx]; + Monster &monster = Monsters[ndx]; monsterSync._mndx = ndx; monsterSync._mx = monster.position.tile.x; monsterSync._my = monster.position.tile.y; From 9766770cd9478e78a6a78fc81273aa8ebb1e71a9 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Sat, 20 Apr 2024 11:22:29 +0200 Subject: [PATCH 11/11] Init local variable instead of passing it --- Source/inv.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/inv.cpp b/Source/inv.cpp index 963862262a3..979a808f621 100644 --- a/Source/inv.cpp +++ b/Source/inv.cpp @@ -401,12 +401,12 @@ void ChangeTwoHandItem(Player &player) } } -int8_t CheckOverlappingItems(int slot, const Player &player, Size itemSize, int8_t prev_it) +int8_t CheckOverlappingItems(int slot, const Player &player, Size itemSize) { // check that the item we're pasting only overlaps one other item (or is going into empty space) const unsigned originCell = static_cast(slot - SLOTXY_INV_FIRST); - int8_t it = prev_it; + int8_t overlappingId = 0; for (unsigned rowOffset = 0; rowOffset < static_cast(itemSize.height * InventorySizeInSlots.width); rowOffset += InventorySizeInSlots.width) { for (unsigned columnOffset = 0; columnOffset < static_cast(itemSize.width); columnOffset++) { @@ -415,25 +415,25 @@ int8_t CheckOverlappingItems(int slot, const Player &player, Size itemSize, int8 assert(testCell < sizeof(player.InvGrid)); if (player.InvGrid[testCell] != 0) { int8_t iv = std::abs(player.InvGrid[testCell]); - if (it != 0) { - if (it != iv) { + if (overlappingId != 0) { + if (overlappingId != iv) { // Found two different items that would be displaced by the held item, can't paste the item here. return -1; } } else { - it = iv; + overlappingId = iv; } } } } - return it; + return overlappingId; } int8_t GetPrevItemId(int slot, const Player &player, const Size &itemSize) { if (player.HoldItem._itype != ItemType::Gold) - return CheckOverlappingItems(slot, player, itemSize, 0); + return CheckOverlappingItems(slot, player, itemSize); int8_t item_cell_begin = player.InvGrid[slot - SLOTXY_INV_FIRST]; if (item_cell_begin == 0) return 0;