Browse Source

Add gamepad support for stash

pull/4274/head
staphen 4 years ago committed by Anders Jenbo
parent
commit
6a30cd3950
  1. 5
      Source/controls/game_controls.cpp
  2. 239
      Source/controls/plrctrls.cpp
  3. 13
      Source/controls/touch/renderers.cpp
  4. 3
      Source/cursor.cpp
  5. 60
      Source/inv.cpp
  6. 2
      Source/inv.h
  7. 10
      Source/miniwin/misc_msg.cpp
  8. 1
      Source/player.cpp
  9. 107
      Source/qol/stash.cpp
  10. 2
      Source/qol/stash.h

5
Source/controls/game_controls.cpp

@ -15,6 +15,7 @@
#include "doom.h"
#include "gmenu.h"
#include "options.h"
#include "qol/stash.h"
#include "stores.h"
namespace devilution {
@ -164,6 +165,10 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrlEvent, Game
}
}
#endif
if (IsStashOpen && ctrlEvent.button == ControllerButton_BUTTON_BACK) {
StartGoldWithdraw();
return false;
}
if (HandleStartAndSelect(ctrlEvent, action))
return true;

239
Source/controls/plrctrls.cpp

@ -60,6 +60,7 @@ namespace {
int Slot = SLOTXY_INV_FIRST;
Point ActiveStashSlot = InvalidStashPoint;
int PreviousInventoryColumn = -1;
bool BeltReturnsToStash = false;
const Direction FaceDir[3][3] = {
// NONE UP DOWN
@ -590,28 +591,29 @@ Point InvGetEquipSlotCoord(const inv_body_loc invSlot)
Point InvGetEquipSlotCoordFromInvSlot(const inv_xy_slot slot)
{
switch (slot) {
case SLOTXY_HEAD_FIRST:
case SLOTXY_HEAD_LAST:
if (slot >= SLOTXY_HEAD_FIRST && slot <= SLOTXY_HEAD_LAST) {
return InvGetEquipSlotCoord(INVLOC_HEAD);
case SLOTXY_RING_LEFT:
}
if (slot == SLOTXY_RING_LEFT) {
return InvGetEquipSlotCoord(INVLOC_RING_LEFT);
case SLOTXY_RING_RIGHT:
}
if (slot == SLOTXY_RING_RIGHT) {
return InvGetEquipSlotCoord(INVLOC_RING_RIGHT);
case SLOTXY_AMULET:
}
if (slot == SLOTXY_AMULET) {
return InvGetEquipSlotCoord(INVLOC_AMULET);
case SLOTXY_HAND_LEFT_FIRST:
case SLOTXY_HAND_LEFT_LAST:
}
if (slot >= SLOTXY_HAND_LEFT_FIRST && slot <= SLOTXY_HAND_LEFT_LAST) {
return InvGetEquipSlotCoord(INVLOC_HAND_LEFT);
case SLOTXY_HAND_RIGHT_FIRST:
case SLOTXY_HAND_RIGHT_LAST:
}
if (slot >= SLOTXY_HAND_RIGHT_FIRST && slot <= SLOTXY_HAND_RIGHT_LAST) {
return InvGetEquipSlotCoord(INVLOC_HAND_RIGHT);
case SLOTXY_CHEST_FIRST:
case SLOTXY_CHEST_LAST:
}
if (slot >= SLOTXY_CHEST_FIRST && slot <= SLOTXY_CHEST_LAST) {
return InvGetEquipSlotCoord(INVLOC_CHEST);
default:
return {};
}
return {};
}
/**
@ -695,20 +697,28 @@ void ResetInvCursorPosition()
Point mousePos {};
if (Slot >= SLOTXY_INV_FIRST && Slot <= SLOTXY_INV_LAST) {
int8_t itemInvId = GetItemIdOnSlot(Slot);
int itemSlot = FindFirstSlotOnItem(itemInvId);
if (itemSlot >= 0)
Slot = itemSlot;
if (itemInvId != 0) {
mousePos = GetSlotCoord(FindFirstSlotOnItem(itemInvId));
Size itemSize = GetItemSizeOnSlot(Slot);
mousePos.x += ((itemSize.width - 1) * InventorySlotSizeInPixels.width) / 2;
mousePos.y += ((itemSize.height - 1) * InventorySlotSizeInPixels.height) / 2;
} else {
mousePos = GetSlotCoord(Slot);
}
// offset the slot to always move to the top-left most slot of that item
Size itemSize = GetItemSizeOnSlot(Slot);
Slot -= ((itemSize.height - 1) * INV_ROW_SLOT_SIZE);
mousePos = GetSlotCoord(Slot);
mousePos.x += ((itemSize.width - 1) * InventorySlotSizeInPixels.width) / 2;
mousePos.y += ((itemSize.height - 1) * InventorySlotSizeInPixels.height) / 2;
if (pcurs >= CURSOR_FIRSTITEM) {
mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX };
}
} else if (Slot >= SLOTXY_BELT_FIRST && Slot <= SLOTXY_BELT_LAST) {
mousePos = GetSlotCoord(Slot);
if (pcurs >= CURSOR_FIRSTITEM)
mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX };
} else {
mousePos = InvGetEquipSlotCoordFromInvSlot((inv_xy_slot)Slot);
if (pcurs >= CURSOR_FIRSTITEM) {
Size itemSize = GetInventorySize(MyPlayer->HoldItem);
mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX * itemSize.height };
}
}
mousePos.x += (InventorySlotSizeInPixels.width / 2);
@ -738,7 +748,7 @@ Point FindClosestStashSlot(Point mousePos)
{
int shortestDistance = std::numeric_limits<int>::max();
Point bestSlot = {};
mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, INV_SLOT_HALF_SIZE_PX };
mousePos += Displacement { -INV_SLOT_HALF_SIZE_PX, -INV_SLOT_HALF_SIZE_PX };
for (auto point : PointsInRectangleRange({ { 0, 0 }, { 10, 10 } })) {
int distance = mousePos.ManhattanDistance(GetStashSlotCoord(point));
@ -754,7 +764,7 @@ Point FindClosestStashSlot(Point mousePos)
/**
* @brief Figures out where on the body to move when on the first row
*/
Point InvMoveToBody(int slot)
Point InventoryMoveToBody(int slot)
{
PreviousInventoryColumn = slot - SLOTXY_INV_ROW1_FIRST;
if (slot <= SLOTXY_INV_ROW1_FIRST + 2) { // first 3 general slots
@ -771,18 +781,8 @@ Point InvMoveToBody(int slot)
return GetSlotCoord(0);
}
/**
* Move the cursor around in our inventory
* If mouse coords are at SLOTXY_CHEST_LAST, consider this center of equipment
* small inventory squares are 29x29 (roughly)
*/
void InvMove(AxisDirection dir)
void InventoryMove(AxisDirection dir)
{
static AxisDirectionRepeater repeater(/*min_interval_ms=*/150);
dir = repeater.Get(dir);
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
Point mousePos = MousePosition;
const bool isHoldingItem = pcurs >= CURSOR_FIRSTITEM;
@ -923,7 +923,7 @@ void InvMove(AxisDirection dir)
}
} else {
if (Slot >= SLOTXY_INV_ROW1_FIRST && Slot <= SLOTXY_INV_ROW1_LAST) {
mousePos = InvMoveToBody(Slot);
mousePos = InventoryMoveToBody(Slot);
} else if (Slot == SLOTXY_CHEST_FIRST || Slot == SLOTXY_HAND_LEFT_FIRST) {
Slot = SLOTXY_HEAD_FIRST;
mousePos = InvGetEquipSlotCoord(INVLOC_HEAD);
@ -941,7 +941,7 @@ void InvMove(AxisDirection dir)
if (itemId != 0) {
for (int i = 1; i < 5; i++) {
if (Slot - i * INV_ROW_SLOT_SIZE < SLOTXY_INV_ROW1_FIRST) {
mousePos = InvMoveToBody(Slot - (i - 1) * INV_ROW_SLOT_SIZE);
mousePos = InventoryMoveToBody(Slot - (i - 1) * INV_ROW_SLOT_SIZE);
break;
}
if (itemId != GetItemIdOnSlot(Slot - i * INV_ROW_SLOT_SIZE)) {
@ -1059,6 +1059,140 @@ void InvMove(AxisDirection dir)
SetCursorPos(mousePos);
}
/**
* Move the cursor around in the inventory
* If mouse coords are at SLOTXY_CHEST_LAST, consider this center of equipment
* small inventory squares are 29x29 (roughly)
*/
void CheckInventoryMove(AxisDirection dir)
{
static AxisDirectionRepeater repeater(/*min_interval_ms=*/150);
dir = repeater.Get(dir);
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
InventoryMove(dir);
}
void StashMove(AxisDirection dir)
{
static AxisDirectionRepeater repeater(/*min_interval_ms=*/150);
dir = repeater.Get(dir);
if (dir.x == AxisDirectionX_NONE && dir.y == AxisDirectionY_NONE)
return;
if (Slot < 0 && ActiveStashSlot == InvalidStashPoint) {
int invSlot = FindClosestInventorySlot(MousePosition);
Point invSlotCoord = GetSlotCoord(invSlot);
int invDistance = MousePosition.ManhattanDistance(invSlotCoord);
Point stashSlot = FindClosestStashSlot(MousePosition);
Point stashSlotCoord = GetStashSlotCoord(stashSlot);
int stashDistance = MousePosition.ManhattanDistance(stashSlotCoord);
if (invDistance < stashDistance) {
BeltReturnsToStash = false;
InventoryMove(dir);
return;
}
ActiveStashSlot = stashSlot;
}
Item &holdItem = MyPlayer->HoldItem;
Size itemSize = holdItem.isEmpty() ? Size { 1, 1 } : GetInventorySize(holdItem);
// Jump from belt to stash
if (BeltReturnsToStash && Slot >= SLOTXY_BELT_FIRST && Slot <= SLOTXY_BELT_LAST) {
if (dir.y == AxisDirectionY_UP) {
int beltSlot = Slot - SLOTXY_BELT_FIRST;
InvalidateInventorySlot();
ActiveStashSlot = { 2 + beltSlot, 10 - itemSize.height };
dir.y = AxisDirectionY_NONE;
}
}
// Jump from general inventory to stash
if (Slot >= SLOTXY_INV_FIRST && Slot <= SLOTXY_INV_LAST) {
int firstSlot = Slot;
if (pcurs < CURSOR_FIRSTITEM) {
int8_t itemId = GetItemIdOnSlot(Slot);
if (itemId != 0) {
firstSlot = FindFirstSlotOnItem(itemId);
}
}
if (IsAnyOf(firstSlot, SLOTXY_INV_ROW1_FIRST, SLOTXY_INV_ROW2_FIRST, SLOTXY_INV_ROW3_FIRST, SLOTXY_INV_ROW4_FIRST)) {
if (dir.x == AxisDirectionX_LEFT) {
Point slotCoord = GetSlotCoord(Slot);
InvalidateInventorySlot();
ActiveStashSlot = FindClosestStashSlot(slotCoord) - Displacement { itemSize.width - 1, 0 };
dir.x = AxisDirectionX_NONE;
}
}
}
bool isHeadSlot = SLOTXY_HEAD_FIRST <= Slot && Slot <= SLOTXY_HEAD_LAST;
bool isLeftHandSlot = SLOTXY_HAND_LEFT_FIRST <= Slot && Slot <= SLOTXY_HAND_LEFT_LAST;
bool isLeftRingSlot = Slot == SLOTXY_RING_LEFT;
if (isHeadSlot || isLeftHandSlot || isLeftRingSlot) {
if (dir.x == AxisDirectionX_LEFT) {
Point slotCoord = GetSlotCoord(Slot);
InvalidateInventorySlot();
ActiveStashSlot = FindClosestStashSlot(slotCoord) - Displacement { itemSize.width - 1, 0 };
dir.x = AxisDirectionX_NONE;
}
}
if (Slot >= 0) {
InventoryMove(dir);
return;
}
if (dir.x == AxisDirectionX_LEFT) {
if (ActiveStashSlot.x > 0)
ActiveStashSlot.x--;
} else if (dir.x == AxisDirectionX_RIGHT) {
if (ActiveStashSlot.x < 10 - itemSize.width) {
ActiveStashSlot.x++;
} else {
Point stashSlotCoord = GetStashSlotCoord(ActiveStashSlot);
Point rightPanelCoord = { GetRightPanel().position.x, stashSlotCoord.y };
Slot = FindClosestInventorySlot(rightPanelCoord);
ActiveStashSlot = InvalidStashPoint;
BeltReturnsToStash = false;
}
}
if (dir.y == AxisDirectionY_UP) {
if (ActiveStashSlot.y > 0)
ActiveStashSlot.y--;
} else if (dir.y == AxisDirectionY_DOWN) {
if (ActiveStashSlot.y < 10 - itemSize.height) {
ActiveStashSlot.y++;
} else if ((holdItem.isEmpty() || CanBePlacedOnBelt(holdItem)) && ActiveStashSlot.x > 1) {
int beltSlot = ActiveStashSlot.x - 2;
Slot = SLOTXY_BELT_FIRST + beltSlot;
ActiveStashSlot = InvalidStashPoint;
BeltReturnsToStash = true;
}
}
if (Slot >= 0) {
ResetInvCursorPosition();
return;
}
if (ActiveStashSlot != InvalidStashPoint) {
Point mousePos = GetStashSlotCoord(ActiveStashSlot);
if (pcurs == CURSOR_HAND) {
mousePos += Displacement { INV_SLOT_HALF_SIZE_PX, INV_SLOT_HALF_SIZE_PX };
}
SetCursorPos(mousePos);
return;
}
FocusOnInventory();
}
void HotSpellMove(AxisDirection dir)
{
static AxisDirectionRepeater repeater;
@ -1215,8 +1349,11 @@ using HandleLeftStickOrDPadFn = void (*)(devilution::AxisDirection);
HandleLeftStickOrDPadFn GetLeftStickOrDPadGameUIHandler()
{
if (IsStashOpen) {
return &StashMove;
}
if (invflag) {
return &InvMove;
return &CheckInventoryMove;
}
if (chrflag && Players[MyPlayerId]._pStatPts > 0) {
return &AttrIncBtnSnap;
@ -1440,6 +1577,7 @@ void HandleRightStickMotion()
void InvalidateInventorySlot()
{
Slot = -1;
ActiveStashSlot = InvalidStashPoint;
}
/**
@ -1729,26 +1867,17 @@ void PerformSpellAction()
void CtrlUseInvItem()
{
Item *item;
if (pcursinvitem == -1)
return;
auto &myPlayer = Players[MyPlayerId];
if (pcursinvitem < INVITEM_INV_FIRST)
item = &myPlayer.InvBody[pcursinvitem];
else if (pcursinvitem <= INVITEM_INV_LAST)
item = &myPlayer.InvList[pcursinvitem - INVITEM_INV_FIRST];
else
item = &myPlayer.SpdList[pcursinvitem - INVITEM_BELT_FIRST];
if (item->IsScroll() && spelldata[item->_iSpell].sTargeted) {
Item &item = GetInventoryItem(myPlayer, pcursinvitem);
if (item.IsScroll() && spelldata[item._iSpell].sTargeted) {
return;
}
int itemId = GetItemIdOnSlot(Slot);
if (item->isEquipment()) {
if (item.isEquipment()) {
CheckInvItem(true, false); // auto-equip if it's an equipment
} else {
UseInvItem(MyPlayerId, pcursinvitem);
@ -1777,10 +1906,17 @@ void CtrlUseStashItem()
void PerformSecondaryAction()
{
auto &myPlayer = Players[MyPlayerId];
if (invflag) {
if (pcurs > CURSOR_HAND && pcurs < CURSOR_FIRSTITEM) {
TryIconCurs();
NewCursor(CURSOR_HAND);
} else if (IsStashOpen) {
if (pcursstashitem != uint16_t(-1)) {
TransferItemToInventory(myPlayer, pcursstashitem);
} else if (pcursinvitem != -1) {
TransferItemToStash(myPlayer, pcursinvitem);
}
} else {
CtrlUseInvItem();
}
@ -1797,7 +1933,6 @@ void PerformSecondaryAction()
} else if (pcursobj != -1) {
NetSendCmdLocParam1(true, CMD_OPOBJXY, cursPosition, pcursobj);
} else {
auto &myPlayer = Players[MyPlayerId];
if (pcursmissile != nullptr) {
MakePlrPath(myPlayer, pcursmissile->position.tile, true);
myPlayer.destAction = ACTION_WALK;

13
Source/controls/touch/renderers.cpp

@ -452,16 +452,9 @@ VirtualGamepadButtonType SecondaryActionButtonRenderer::GetButtonType()
return GetApplyButtonType(virtualPadButton->isHeld);
if (pcursinvitem != -1) {
Item *item;
if (pcursinvitem < INVITEM_INV_FIRST)
item = &MyPlayer->InvBody[pcursinvitem];
else if (pcursinvitem <= INVITEM_INV_LAST)
item = &MyPlayer->InvList[pcursinvitem - INVITEM_INV_FIRST];
else
item = &MyPlayer->SpdList[pcursinvitem - INVITEM_BELT_FIRST];
if (!item->IsScroll() || !spelldata[item->_iSpell].sTargeted) {
if (!item->isEquipment()) {
Item &item = GetInventoryItem(*MyPlayer, pcursinvitem);
if (!item.IsScroll() || !spelldata[item._iSpell].sTargeted) {
if (!item.isEquipment()) {
return GetApplyButtonType(virtualPadButton->isHeld);
}
}

3
Source/cursor.cpp

@ -177,6 +177,9 @@ void ResetCursor()
void NewCursor(int cursId)
{
if (cursId < CURSOR_FIRSTITEM && MyPlayer != nullptr) {
MyPlayer->HoldItem._itype = ItemType::None;
}
pcurs = cursId;
cursSize = GetInvItemSize(cursId);
SetICursor(cursId);

60
Source/inv.cpp

@ -348,16 +348,8 @@ void CheckInvPaste(int pnum, Point cursorPosition)
il = ILOC_TWOHAND;
done = true;
}
if (player.GetItemLocation(player.HoldItem) == ILOC_UNEQUIPABLE && il == ILOC_BELT) {
if (itemSize == Size { 1, 1 }) {
done = true;
if (!AllItemsList[player.HoldItem.IDidx].iUsable)
done = false;
if (!player.CanUseItem(player.HoldItem))
done = false;
if (player.HoldItem._itype == ItemType::Gold)
done = false;
}
if (il == ILOC_BELT) {
done = CanBePlacedOnBelt(player.HoldItem);
}
int8_t it = 0;
@ -911,16 +903,7 @@ void CheckInvCut(int pnum, Point cursorPosition, bool automaticMove, bool dropIt
}
if (dropItem && !holdItem.isEmpty()) {
if (IsStashOpen) {
if (AutoPlaceItemInStash(player, holdItem, true)) {
holdItem._itype = ItemType::None;
NewCursor(CURSOR_HAND);
} else {
player.SaySpecific(HeroSpeech::WhereWouldIPutThis);
}
} else {
TryDropItem();
}
TryDropItem();
}
}
@ -1190,7 +1173,7 @@ bool CanBePlacedOnBelt(const Item &item)
{
return FitsInBeltSlot(item)
&& item._itype != ItemType::Gold
&& item._iStatFlag
&& MyPlayer->CanUseItem(item)
&& AllItemsList[item.IDidx].iUsable;
}
@ -1628,10 +1611,34 @@ void inv_update_rem_item(Player &player, inv_body_loc iv)
CalcPlrInv(player, player._pmode != PM_DEATH);
}
void TransferItemToStash(Player &player, int location)
{
if (location == -1) {
return;
}
Item &item = GetInventoryItem(player, location);
if (!AutoPlaceItemInStash(player, item, true)) {
player.SaySpecific(HeroSpeech::WhereWouldIPutThis);
return;
}
PlaySFX(ItemInvSnds[ItemCAnimTbl[item._iCurs]]);
if (location < INVITEM_INV_FIRST)
player.InvBody[location]._itype = ItemType::None;
else if (location <= INVITEM_INV_LAST)
player.RemoveInvItem(location - INVITEM_INV_FIRST);
else
player.RemoveSpdBarItem(location - INVITEM_BELT_FIRST);
}
void CheckInvItem(bool isShiftHeld, bool isCtrlHeld)
{
if (pcurs >= CURSOR_FIRSTITEM) {
CheckInvPaste(MyPlayerId, MousePosition);
} else if (IsStashOpen && isCtrlHeld) {
TransferItemToStash(*MyPlayer, pcursinvitem);
} else {
CheckInvCut(MyPlayerId, MousePosition, isShiftHeld, isCtrlHeld);
}
@ -2073,6 +2080,17 @@ bool UseStaff()
return CanUseStaff(myPlayer.InvBody[INVLOC_HAND_LEFT], myPlayer._pRSpell);
}
Item &GetInventoryItem(Player &player, int location)
{
if (location < INVITEM_INV_FIRST)
return player.InvBody[location];
if (location <= INVITEM_INV_LAST)
return player.InvList[location - INVITEM_INV_FIRST];
return player.SpdList[location - INVITEM_BELT_FIRST];
}
bool UseInvItem(int pnum, int cii)
{
int c;

2
Source/inv.h

@ -180,6 +180,7 @@ int AddGoldToInventory(Player &player, int value);
bool GoldAutoPlace(Player &player, Item &goldStack);
void CheckInvSwap(Player &player, inv_body_loc bLoc, int idx, uint16_t wCI, int seed, bool bId, uint32_t dwBuff);
void inv_update_rem_item(Player &player, inv_body_loc iv);
void TransferItemToStash(Player &player, int location);
void CheckInvItem(bool isShiftHeld = false, bool isCtrlHeld = false);
/**
@ -208,6 +209,7 @@ void RemoveScroll(Player &player);
bool UseScroll();
void UseStaffCharge(Player &player);
bool UseStaff();
Item &GetInventoryItem(Player &player, int location);
bool UseInvItem(int pnum, int cii);
void DoTelekinesis();
int CalculateGold(Player &player);

10
Source/miniwin/misc_msg.cpp

@ -319,10 +319,16 @@ void ProcessGamepadEvents(GameAction &action)
case GameActionType_SEND_KEY:
break;
case GameActionType_USE_HEALTH_POTION:
UseBeltItem(BLT_HEALING);
if (IsStashOpen)
Stash.SetPage(Stash.GetPage() - 1);
else
UseBeltItem(BLT_HEALING);
break;
case GameActionType_USE_MANA_POTION:
UseBeltItem(BLT_MANA);
if (IsStashOpen)
Stash.SetPage(Stash.GetPage() + 1);
else
UseBeltItem(BLT_MANA);
break;
case GameActionType_PRIMARY_ACTION:
PerformPrimaryAction();

1
Source/player.cpp

@ -3136,7 +3136,6 @@ StartPlayerKill(int pnum, int earflag)
if (pcurs >= CURSOR_FIRSTITEM) {
DeadItem(player, std::move(player.HoldItem), { 0, 0 });
player.HoldItem._itype = ItemType::None;
NewCursor(CURSOR_HAND);
}

107
Source/qol/stash.cpp

@ -91,7 +91,6 @@ void CheckStashPaste(Point cursorPosition)
if (player.HoldItem._itype == ItemType::Gold) {
Stash.gold += player.HoldItem._ivalue;
Stash.dirty = true;
player.HoldItem._itype = ItemType::None;
if (!IsHardwareCursor())
SetCursorPos(cursorPosition);
NewCursor(CURSOR_HAND);
@ -150,7 +149,7 @@ void CheckStashPaste(Point cursorPosition)
NewCursor(cn);
}
void CheckStashCut(Point cursorPosition, bool automaticMove, bool dropItem)
void CheckStashCut(Point cursorPosition, bool automaticMove)
{
auto &player = Players[MyPlayerId];
@ -223,43 +222,12 @@ void CheckStashCut(Point cursorPosition, bool automaticMove, bool dropItem)
holdItem._itype = ItemType::None;
} else {
NewCursor(holdItem._iCurs + CURSOR_FIRSTITEM);
if (!IsHardwareCursor() && !dropItem) {
if (!IsHardwareCursor()) {
// For a hardware cursor, we set the "hot point" to the center of the item instead.
SetCursorPos(cursorPosition - Displacement(cursSize / 2));
}
}
}
if (dropItem && !holdItem.isEmpty()) {
if (invflag) {
if (AutoPlaceItemInInventory(player, holdItem, true)) {
holdItem._itype = ItemType::None;
NewCursor(CURSOR_HAND);
} else {
player.SaySpecific(HeroSpeech::IHaveNoRoom);
}
} else {
TryDropItem();
}
}
}
void StartGoldWithdraw()
{
CloseGoldDrop();
InitialWithdrawGoldValue = std::min(RoomForGold(), Stash.gold);
if (talkflag)
control_reset_talk();
Point start = GetPanelPosition(UiPanels::Stash, { 67, 128 });
SDL_Rect rect = MakeSdlRect(start.x, start.y, 180, 20);
SDL_SetTextInputRect(&rect);
IsWithdrawGoldOpen = true;
WithdrawGoldValue = 0;
SDL_StartTextInput();
}
void WithdrawGold(Player &player, int amount)
@ -292,6 +260,27 @@ void InitStash()
LoadArt("data\\stashnavbtns.pcx", &StashNavButtonArt, 5);
}
void TransferItemToInventory(Player &player, uint16_t itemId)
{
if (itemId == uint16_t(-1)) {
return;
}
Item &item = Stash.stashList[itemId];
if (item.isEmpty()) {
return;
}
if (!AutoPlaceItemInInventory(player, item, true)) {
player.SaySpecific(HeroSpeech::IHaveNoRoom);
return;
}
PlaySFX(ItemInvSnds[ItemCAnimTbl[item._iCurs]]);
Stash.RemoveStashItem(itemId);
}
int StashButtonPressed = -1;
void CheckStashButtonRelease(Point mousePosition)
@ -358,16 +347,17 @@ void DrawStash(const Surface &out)
}
for (auto slot : PointsInRectangleRange({ { 0, 0 }, { 10, 10 } })) {
if (Stash.stashGrids[Stash.GetPage()][slot.x][slot.y] == 0) {
uint16_t itemId = Stash.stashGrids[Stash.GetPage()][slot.x][slot.y];
if (itemId == 0) {
continue; // No item in the given slot
}
uint16_t itemId = Stash.stashGrids[Stash.GetPage()][slot.x][slot.y] - 1;
if (Stash.stashList[itemId].position != slot) {
itemId -= 1;
Item &item = Stash.stashList[itemId];
if (item.position != slot) {
continue; // Not the first slot of the item
}
Item &item = Stash.stashList[itemId];
int frame = item._iCurs + CURSOR_FIRSTITEM;
const Point position = GetStashSlotCoord(item.position) + offset;
@ -375,11 +365,11 @@ void DrawStash(const Surface &out)
const int celFrame = GetInvItemFrame(frame);
if (pcursstashitem == itemId) {
uint8_t color = GetOutlineColor(Stash.stashList[itemId], true);
uint8_t color = GetOutlineColor(item, true);
CelBlitOutlineTo(out, color, position, cel, celFrame, false);
}
CelDrawItem(Stash.stashList[itemId], out, position, cel, celFrame);
CelDrawItem(item, out, position, cel, celFrame);
}
Point position = GetPanelPosition(UiPanels::Stash);
@ -393,8 +383,10 @@ void CheckStashItem(Point mousePosition, bool isShiftHeld, bool isCtrlHeld)
{
if (pcurs >= CURSOR_FIRSTITEM) {
CheckStashPaste(mousePosition);
} else if (isCtrlHeld) {
TransferItemToInventory(*MyPlayer, pcursstashitem);
} else {
CheckStashCut(mousePosition, isShiftHeld, isCtrlHeld);
CheckStashCut(mousePosition, isShiftHeld);
}
}
@ -420,15 +412,16 @@ uint16_t CheckStashHLight(Point mousePosition)
ClearPanel();
uint16_t itemId = abs(Stash.stashGrids[Stash.GetPage()][slot.x][slot.y]);
if (itemId == 0)
uint16_t itemId = Stash.stashGrids[Stash.GetPage()][slot.x][slot.y];
if (itemId == 0) {
return -1;
}
uint16_t ii = itemId - 1;
Item &item = Stash.stashList[ii];
if (item.isEmpty())
itemId -= 1;
Item &item = Stash.stashList[itemId];
if (item.isEmpty()) {
return -1;
}
InfoColor = item.getTextColor();
if (item._iIdentified) {
@ -439,7 +432,7 @@ uint16_t CheckStashHLight(Point mousePosition)
PrintItemDur(item);
}
return ii;
return itemId;
}
bool UseStashItem(uint16_t c)
@ -551,6 +544,24 @@ void StashStruct::RefreshItemStatFlags()
}
}
void StartGoldWithdraw()
{
CloseGoldDrop();
InitialWithdrawGoldValue = std::min(RoomForGold(), Stash.gold);
if (talkflag)
control_reset_talk();
Point start = GetPanelPosition(UiPanels::Stash, { 67, 128 });
SDL_Rect rect = MakeSdlRect(start.x, start.y, 180, 20);
SDL_SetTextInputRect(&rect);
IsWithdrawGoldOpen = true;
WithdrawGoldValue = 0;
SDL_StartTextInput();
}
void WithdrawGoldKeyPress(char vkey)
{
auto &myPlayer = Players[MyPlayerId];

2
Source/qol/stash.h

@ -47,6 +47,7 @@ extern int WithdrawGoldValue;
Point GetStashSlotCoord(Point slot);
void InitStash();
void FreeStashGFX();
void TransferItemToInventory(Player &player, uint16_t itemId);
/**
* @brief Render the inventory panel to the given buffer.
*/
@ -57,6 +58,7 @@ uint16_t CheckStashHLight(Point mousePosition);
void CheckStashButtonRelease(Point mousePosition);
void CheckStashButtonPress(Point mousePosition);
void StartGoldWithdraw();
void WithdrawGoldKeyPress(char vkey);
void DrawGoldWithdraw(const Surface &out, int amount);
void CloseGoldWithdraw();

Loading…
Cancel
Save