Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions Source/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -959,15 +959,20 @@ void DoPanBtn()
}
}
}
if (!spselflag && MousePosition.x >= 565 + mainPanelPosition.x && MousePosition.x < 621 + mainPanelPosition.x && MousePosition.y >= 64 + mainPanelPosition.y && MousePosition.y < 120 + mainPanelPosition.y) {
if (MousePosition.x >= 565 + mainPanelPosition.x && MousePosition.x < 621 + mainPanelPosition.x && MousePosition.y >= 64 + mainPanelPosition.y && MousePosition.y < 120 + mainPanelPosition.y) {
if ((SDL_GetModState() & KMOD_SHIFT) != 0) {
Player &myPlayer = *MyPlayer;
myPlayer._pRSpell = SpellID::Invalid;
myPlayer._pRSplType = SpellType::Invalid;
spselflag = false;
RedrawEverything();
return;
}
DoSpeedBook();
if (spselflag) {
spselflag = false;
} else {
DoSpeedBook();
}
gamemenu_off();
}
}
Expand Down Expand Up @@ -1165,12 +1170,13 @@ void FreeControlPan()
void DrawInfoBox(const Surface &out)
{
DrawPanelBox(out, { 177, 62, InfoBoxSize.width, InfoBoxSize.height }, GetMainPanel().position + InfoBoxTopLeft);
if (!panelflag && !trigflag && pcursinvitem == -1 && pcursstashitem == StashStruct::EmptyCell && !spselflag) {
bool spellListActive = spselflag && (ControlMode != ControlTypes::KeyboardAndMouse || IsMouseOverSpellList());
if (!panelflag && !trigflag && pcursinvitem == -1 && pcursstashitem == StashStruct::EmptyCell && !spellListActive) {
InfoString = {};
InfoColor = UiFlags::ColorWhite;
}
Player &myPlayer = *MyPlayer;
if (spselflag || trigflag) {
if (spellListActive || trigflag) {
InfoColor = UiFlags::ColorWhite;
} else if (!myPlayer.HoldItem.isEmpty()) {
if (myPlayer.HoldItem._itype == ItemType::Gold) {
Expand Down
2 changes: 1 addition & 1 deletion Source/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ void CheckCursMove()
if (myPlayer._pInvincible) {
return;
}
if (!myPlayer.HoldItem.isEmpty() || spselflag) {
if (!myPlayer.HoldItem.isEmpty() || (spselflag && ControlMode != ControlTypes::KeyboardAndMouse)) {
cursPosition = { mx, my };
return;
}
Expand Down
24 changes: 19 additions & 5 deletions Source/diablo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,15 @@ void LeftMouseDown(uint16_t modState)
}

if (spselflag) {
SetSpell();
return;
if (ControlMode == ControlTypes::KeyboardAndMouse) {
if (IsMouseOverSpellList()) {
SetSpell();
return;
}
} else {
SetSpell();
return;
}
}

if (stextflag != TalkID::None) {
Expand Down Expand Up @@ -428,8 +435,15 @@ void RightMouseDown(bool isShiftHeld)
if (stextflag != TalkID::None)
return;
if (spselflag) {
SetSpell();
return;
if (ControlMode == ControlTypes::KeyboardAndMouse) {
if (IsMouseOverSpellList()) {
SetSpell();
return;
}
} else {
SetSpell();
return;
}
}
if (sbookflag && GetRightPanel().contains(MousePosition))
return;
Expand Down Expand Up @@ -1633,7 +1647,7 @@ void InitKeymapActions()
N_("Hotkey for skill or spell."),
i < 4 ? static_cast<uint32_t>(SDLK_F5) + i : static_cast<uint32_t>(SDLK_UNKNOWN),
[i]() {
if (spselflag) {
if (spselflag && IsMouseOverSpellList()) {
SetSpeedSpell(i);
return;
}
Expand Down
11 changes: 11 additions & 0 deletions Source/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,17 @@ void InitDiabloMsg(string_view msg, uint32_t duration /*= 3500*/)
}
}

void AppendToDiabloMsg(string_view appendText)
{
if (DiabloMessages.empty())
return;
DiabloMessages.back().text += "\n\n";
DiabloMessages.back().text += appendText;
if (DiabloMessages.size() == 1) {
InitNextLines();
}
}

bool IsDiabloMsgAvailable()
{
return !DiabloMessages.empty();
Expand Down
1 change: 1 addition & 0 deletions Source/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum diablo_message : uint8_t {

void InitDiabloMsg(diablo_message e, uint32_t duration = 3500);
void InitDiabloMsg(string_view msg, uint32_t duration = 3500);
void AppendToDiabloMsg(string_view appendText);
bool IsDiabloMsgAvailable();
void CancelCurrentDiabloMsg();
void ClrDiabloMsg();
Expand Down
115 changes: 107 additions & 8 deletions Source/inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,24 @@ void CheckInvPaste(Player &player, Point cursorPosition)
NetSendCmdChInvItem(false, ii);
}
} else {
if (it != 0 && player.HoldItem.isStackablePotion()) {
int invIndex = it - 1;
Item &existing = player.InvList[invIndex];
if (existing._iMiscId == player.HoldItem._iMiscId && existing._iQuantity > 0 && existing._iQuantity < MaxPotionStack) {
uint8_t canAdd = MaxPotionStack - existing._iQuantity;
uint8_t toAdd = std::min(canAdd, player.HoldItem._iQuantity);
existing._iQuantity += toAdd;
player.HoldItem._iQuantity -= toAdd;
if (player.HoldItem._iQuantity == 0)
player.HoldItem.clear();
if (&player == MyPlayer) {
int ii = slot - SLOTXY_INV_FIRST;
NetSendCmdChInvItem(false, ii);
}
break;
}
}

if (it == 0) {
player.InvList[player._pNumInv] = player.HoldItem.pop();
player._pNumInv++;
Expand All @@ -538,7 +556,13 @@ void CheckInvPaste(Player &player, Point cursorPosition)
case ILOC_BELT: {
int ii = slot - SLOTXY_BELT_FIRST;
if (player.SpdList[ii].isEmpty()) {
player.SpdList[ii] = player.HoldItem.pop();
if (player.HoldItem.isStackablePotion() && player.HoldItem._iQuantity > 1) {
player.SpdList[ii] = player.HoldItem;
player.SpdList[ii]._iQuantity = 1;
player.HoldItem._iQuantity--;
} else {
player.SpdList[ii] = player.HoldItem.pop();
}
} else {
std::swap(player.SpdList[ii], player.HoldItem);
if (player.HoldItem._itype == ItemType::Gold)
Expand Down Expand Up @@ -696,7 +720,13 @@ void CheckInvCut(Player &player, Point cursorPosition, bool automaticMove, bool
holdItem = player.InvList[iv - 1];
if (automaticMove) {
if (CanBePlacedOnBelt(holdItem)) {
automaticallyMoved = AutoPlaceItemInBelt(player, holdItem, true);
if (holdItem.isStackablePotion() && holdItem._iQuantity > 1) {
Item singlePotion = holdItem;
singlePotion._iQuantity = 1;
automaticallyMoved = AutoPlaceItemInBelt(player, singlePotion, true);
} else {
automaticallyMoved = AutoPlaceItemInBelt(player, holdItem, true);
}
} else if (CanEquip(holdItem)) {
/*
* Move the respective InvBodyItem to inventory before moving the item from inventory
Expand Down Expand Up @@ -770,11 +800,16 @@ void CheckInvCut(Player &player, Point cursorPosition, bool automaticMove, bool
}
}

if (!automaticMove || automaticallyMoved) {
if (!automaticMove || automaticallyMoved) {
if (automaticallyMoved && player.InvList[iv - 1].isStackablePotion() && player.InvList[iv - 1]._iQuantity > 1) {
player.InvList[iv - 1]._iQuantity--;
NetSyncInvItem(player, iv - 1);
} else {
player.RemoveInvItem(iv - 1, false);
}
}
}
}

if (r >= SLOTXY_BELT_FIRST) {
Item &beltItem = player.SpdList[r - SLOTXY_BELT_FIRST];
Expand Down Expand Up @@ -1141,6 +1176,12 @@ void DrawInv(const Surface &out)
}

DrawItem(myPlayer.InvList[ii], out, position, sprite);

if (myPlayer.InvList[ii]._iQuantity > 1) {
DrawString(out, StrCat("x", myPlayer.InvList[ii]._iQuantity),
{ position - Displacement { 0, 12 }, InventorySlotSizeInPixels },
{ UiFlags::ColorWhite | UiFlags::AlignRight });
}
}
}
}
Expand Down Expand Up @@ -1259,8 +1300,36 @@ bool AutoEquipEnabled(const Player &player, const Item &item)
return true;
}

bool TryStackPotionInInventory(Player &player, const Item &item, bool persistItem)
{
if (!item.isStackablePotion() || item._iQuantity == 0)
return false;

for (int i = 0; i < player._pNumInv; i++) {
Item &existing = player.InvList[i];
if (existing._iMiscId != item._iMiscId)
continue;
if (existing._iQuantity >= MaxPotionStack || existing._iQuantity == 0)
continue;

uint8_t canAdd = MaxPotionStack - existing._iQuantity;
if (canAdd < item._iQuantity)
continue;

if (persistItem) {
existing._iQuantity += item._iQuantity;
NetSyncInvItem(player, i);
}
return true;
}
return false;
}

bool AutoPlaceItemInInventory(Player &player, const Item &item, bool persistItem)
{
if (TryStackPotionInInventory(player, item, persistItem))
return true;

Size itemSize = GetInventorySize(item);

if (itemSize.height == 1) {
Expand Down Expand Up @@ -1635,7 +1704,26 @@ void AutoGetItem(Player &player, Item *itemPointer, int ii)
autoEquipped = true;
}

if (!done) {
if (!done && item.isStackablePotion() && item._iQuantity > 1) {
uint8_t remaining = item._iQuantity;

Item singlePotion = item;
singlePotion._iQuantity = 1;

while (remaining > 0 && AutoPlaceItemInBelt(player, singlePotion, true)) {
remaining--;
}

if (remaining > 0) {
Item leftover = item;
leftover._iQuantity = remaining;
if (AutoPlaceItemInInventory(player, leftover, true)) {
remaining = 0;
}
}

done = (remaining == 0);
} else if (!done) {
done = AutoPlaceItemInBelt(player, item, true);
}
if (!done) {
Expand Down Expand Up @@ -1774,7 +1862,8 @@ int SyncDropItem(Point position, _item_indexes idx, uint16_t icreateinfo, int is
item._iPLToHit = ClampToHit(item, toHit);
item._iMaxDam = ClampMaxDam(item, maxDam);
}
item.dwBuff = ibuff;
item.dwBuff = ibuff & 0xFF;
item._iQuantity = static_cast<uint8_t>((ibuff >> 8) & 0xFF);

return PlaceItemInWorld(std::move(item), position);
}
Expand Down Expand Up @@ -1864,7 +1953,11 @@ int8_t CheckInvHLight()
InfoString = fmt::format(fmt::runtime(ngettext("{:s} gold piece", "{:s} gold pieces", nGold)), FormatInteger(nGold));
} else {
InfoColor = pi->getTextColor();
InfoString = pi->getName();
if (pi->_iQuantity > 1) {
InfoString = StrCat(pi->getName().str(), " (x", pi->_iQuantity, ")");
} else {
InfoString = pi->getName();
}
if (pi->_iIdentified) {
PrintItemDetails(*pi);
} else {
Expand Down Expand Up @@ -2081,8 +2174,14 @@ bool UseInvItem(int cii)
CloseInventory();
return true;
}
if (!item->isScroll() && !item->isRune())
player.RemoveInvItem(c);
if (!item->isScroll() && !item->isRune()) {
if (player.InvList[c].isStackablePotion() && player.InvList[c]._iQuantity > 1) {
player.InvList[c]._iQuantity--;
NetSyncInvItem(player, c);
} else {
player.RemoveInvItem(c);
}
}

return true;
}
Expand Down
9 changes: 9 additions & 0 deletions Source/inv.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ bool AutoEquip(Player &player, const Item &item, bool persistItem = true);
* @param persistItem Pass 'True' to actually place the item in the inventory. The default is 'False'.
* @return 'True' in case the item can be placed on the player's inventory and 'False' otherwise.
*/
/**
* @brief Tries to stack a potion into an existing incomplete stack in the player's inventory.
* @param player The player whose inventory will be checked.
* @param item The potion item to stack.
* @param persistItem Pass 'True' to actually modify the stack quantity. 'False' only checks feasibility.
* @return 'True' if the potion was stacked into an existing slot, 'False' otherwise.
*/
bool TryStackPotionInInventory(Player &player, const Item &item, bool persistItem = false);

bool AutoPlaceItemInInventory(Player &player, const Item &item, bool persistItem = false);

/**
Expand Down
Loading
Loading