Browse Source

Add function to get item id at grid coords

Also introduced a few helper types and values to hopefully help document behaviour

correct spelling in comment

Co-authored-by: qndel <stefan551@o2.pl>
pull/4456/head
ephphatha 4 years ago committed by Anders Jenbo
parent
commit
907e1376b0
  1. 16
      Source/controls/plrctrls.cpp
  2. 50
      Source/qol/stash.cpp
  3. 23
      Source/qol/stash.h

16
Source/controls/plrctrls.cpp

@ -688,13 +688,13 @@ int FindFirstSlotOnItem(int8_t itemInvId)
return -1;
}
Point FindFirstStashSlotOnItem(uint16_t itemInvId)
Point FindFirstStashSlotOnItem(StashStruct::StashCell itemInvId)
{
if (itemInvId == 0)
if (itemInvId == StashStruct::EmptyCell)
return InvalidStashPoint;
for (auto point : PointsInRectangleRange({ { 0, 0 }, { 10, 10 } })) {
if (Stash.stashGrids[Stash.GetPage()][point.x][point.y] == itemInvId)
if (Stash.GetItemIdAtPosition(point) == itemInvId)
return point;
}
@ -1772,17 +1772,17 @@ void PerformPrimaryAction()
const Size cursorSizeInCells = MyPlayer->HoldItem.isEmpty() ? Size { 1, 1 } : GetInventorySize(MyPlayer->HoldItem);
// Find any item occupying a slot that is currently under the cursor
uint16_t itemUnderCursor = [](Point stashSlot, Size cursorSizeInCells) -> uint16_t {
StashStruct::StashCell itemUnderCursor = [](Point stashSlot, Size cursorSizeInCells) -> StashStruct::StashCell {
if (stashSlot != InvalidStashPoint)
return 0;
return StashStruct::EmptyCell;
for (Point slotUnderCursor : PointsInRectangleRange { { stashSlot, cursorSizeInCells } }) {
if (slotUnderCursor.x >= 10 || slotUnderCursor.y >= 10)
continue;
uint16_t itemId = Stash.stashGrids[Stash.GetPage()][slotUnderCursor.x][slotUnderCursor.y];
if (itemId != 0)
StashStruct::StashCell itemId = Stash.GetItemIdAtPosition(slotUnderCursor);
if (itemId != StashStruct::EmptyCell)
return itemId;
}
return 0;
return StashStruct::EmptyCell;
}(stashSlot, cursorSizeInCells);
// The cursor will need to be shifted to

50
Source/qol/stash.cpp

@ -107,14 +107,14 @@ void CheckStashPaste(Point cursorPosition)
return; // Item does not fit
}
// Check that no more then 1 item is replaced by the move
uint16_t it = 0;
// Check that no more than 1 item is replaced by the move
StashStruct::StashCell stashIndex = StashStruct::EmptyCell;
for (auto point : PointsInRectangleRange({ firstSlot, itemSize })) {
uint16_t iv = Stash.stashGrids[Stash.GetPage()][point.x][point.y];
if (iv == 0 || it == iv)
StashStruct::StashCell iv = Stash.GetItemIdAtPosition(point);
if (iv == StashStruct::EmptyCell || stashIndex == iv)
continue;
if (it == 0) {
it = iv; // Found first item
if (stashIndex == StashStruct::EmptyCell) {
stashIndex = iv; // Found first item
continue;
}
return; // Found a second item
@ -125,16 +125,16 @@ void CheckStashPaste(Point cursorPosition)
player.HoldItem.position = firstSlot + Displacement { 0, itemSize.height - 1 };
int cn = CURSOR_HAND;
uint16_t stashIndex;
if (it == 0) {
if (stashIndex == StashStruct::EmptyCell) {
Stash.stashList.push_back(player.HoldItem);
stashIndex = Stash.stashList.size() - 1;
// stashList will have at most 10 000 items, up to 65 535 are supported with uint16_t indexes
stashIndex = static_cast<uint16_t>(Stash.stashList.size() - 1);
} else {
stashIndex = it - 1;
// remove item from stash grid
cn = SwapItem(Stash.stashList[stashIndex], player.HoldItem);
for (auto &row : Stash.GetCurrentGrid()) {
for (auto &itemId : row) {
if (itemId == it)
if (itemId - 1 == stashIndex)
itemId = 0;
}
}
@ -185,10 +185,8 @@ void CheckStashCut(Point cursorPosition, bool automaticMove)
bool automaticallyMoved = false;
bool automaticallyEquipped = false;
uint16_t ii = Stash.stashGrids[Stash.GetPage()][slot.x][slot.y];
if (ii != 0) {
uint16_t iv = ii - 1;
StashStruct::StashCell iv = Stash.GetItemIdAtPosition(slot);
if (iv != StashStruct::EmptyCell) {
holdItem = Stash.stashList[iv];
if (automaticMove) {
if (CanBePlacedOnBelt(holdItem)) {
@ -343,18 +341,17 @@ void DrawStash(const Surface &out)
constexpr Displacement offset { 0, INV_SLOT_SIZE_PX - 1 };
for (auto slot : PointsInRectangleRange({ { 0, 0 }, { 10, 10 } })) {
if (Stash.stashGrids[Stash.GetPage()][slot.x][slot.y] != 0) {
if (Stash.IsItemAtPosition(slot)) {
InvDrawSlotBack(out, GetStashSlotCoord(slot) + offset, InventorySlotSizeInPixels);
}
}
for (auto slot : PointsInRectangleRange({ { 0, 0 }, { 10, 10 } })) {
uint16_t itemId = Stash.stashGrids[Stash.GetPage()][slot.x][slot.y];
if (itemId == 0) {
StashStruct::StashCell itemId = Stash.GetItemIdAtPosition(slot);
if (itemId == StashStruct::EmptyCell) {
continue; // No item in the given slot
}
itemId -= 1;
Item &item = Stash.stashList[itemId];
if (item.position != slot) {
continue; // Not the first slot of the item
@ -414,12 +411,11 @@ uint16_t CheckStashHLight(Point mousePosition)
ClearPanel();
uint16_t itemId = Stash.stashGrids[Stash.GetPage()][slot.x][slot.y];
if (itemId == 0) {
StashStruct::StashCell itemId = Stash.GetItemIdAtPosition(slot);
if (itemId == StashStruct::EmptyCell) {
return -1;
}
itemId -= 1;
Item &item = Stash.stashList[itemId];
if (item.isEmpty()) {
return -1;
@ -499,11 +495,11 @@ bool UseStashItem(uint16_t c)
return true;
}
void StashStruct::RemoveStashItem(uint16_t iv)
void StashStruct::RemoveStashItem(StashStruct::StashCell iv)
{
// Iterate through stashGrid and remove every reference to item
for (auto &row : Stash.GetCurrentGrid()) {
for (uint16_t &itemId : row) {
for (StashStruct::StashCell &itemId : row) {
if (itemId - 1 == iv) {
itemId = 0;
}
@ -515,14 +511,14 @@ void StashStruct::RemoveStashItem(uint16_t iv)
}
// If the item at the end of stash array isn't the one we removed, we need to swap its position in the array with the removed item
std::size_t lastItemIndex = stashList.size() - 1;
StashStruct::StashCell lastItemIndex = static_cast<StashStruct::StashCell>(stashList.size() - 1);
if (lastItemIndex != iv) {
stashList[iv] = stashList[lastItemIndex];
for (auto &pair : Stash.stashGrids) {
auto &grid = pair.second;
for (auto &row : grid) {
for (uint16_t &itemId : row) {
for (StashStruct::StashCell &itemId : row) {
if (itemId == lastItemIndex + 1) {
itemId = iv + 1;
}
@ -689,7 +685,7 @@ bool AutoPlaceItemInStash(Player &player, const Item &item, bool persistItem)
continue;
if (persistItem) {
Stash.stashList.push_back(item);
uint16_t stashIndex = Stash.stashList.size() - 1;
uint16_t stashIndex = static_cast<uint16_t>(Stash.stashList.size() - 1);
Stash.stashList[stashIndex].position = stashPosition + Displacement { 0, itemSize.height - 1 };
AddItemToStashGrid(pageIndex, stashPosition, stashIndex, itemSize);
Stash.dirty = true;

23
Source/qol/stash.h

@ -16,8 +16,11 @@ namespace devilution {
class StashStruct {
public:
void RemoveStashItem(uint16_t iv);
using StashGrid = std::array<std::array<uint16_t, 10>, 10>;
using StashCell = uint16_t;
using StashGrid = std::array<std::array<StashCell, 10>, 10>;
static constexpr StashCell EmptyCell = -1;
void RemoveStashItem(StashCell iv);
std::map<unsigned, StashGrid> stashGrids;
std::vector<Item> stashList;
int gold;
@ -33,6 +36,22 @@ public:
return stashGrids[GetPage()];
}
/**
* @brief Returns the 0-based index of the item at the specified position, or EmptyCell if no item occupies that slot
* @param gridPosition x,y coordinate of the current stash page
* @return a value which can be used to index into stashList or StashStruct::EmptyCell
*/
StashCell GetItemIdAtPosition(Point gridPosition)
{
// Because StashCell is an unsigned type we can let this underflow
return GetCurrentGrid()[gridPosition.x][gridPosition.y] - 1;
}
bool IsItemAtPosition(Point gridPosition)
{
return GetItemIdAtPosition(gridPosition) != EmptyCell;
}
void SetPage(unsigned newPage);
void NextPage(unsigned offset = 1);
void PreviousPage(unsigned offset = 1);

Loading…
Cancel
Save