Files
Robin Eklind 03f2aee78e inv: add BUGFIX for CheckInvCut
For consistency, use (mx, my) parameters in call to SetCursorPos.
As all callers of CheckInvCut pass (MouseX, MouseY) as arguments,
this BUGFIX is only for consistency, there is no functional
change.
2022-10-21 01:23:19 +02:00

2994 lines
84 KiB
C++

/**
* @file inv.cpp
*
* Implementation of player inventory.
*/
#include "all.h"
BOOL invflag;
BYTE *pInvCels;
BOOL drawsbarflag;
int sgdwLastTime; // check name
/**
* Maps from inventory slot to screen position. The inventory slots are
* arranged as follows:
* 00 01
* 02 03 06
* 07 08 19 20 13 14
* 09 10 21 22 15 16
* 11 12 23 24 17 18
* 04 05
* 25 26 27 28 29 30 31 32 33 34
* 35 36 37 38 39 40 41 42 43 44
* 45 46 47 48 49 50 51 52 53 54
* 55 56 57 58 59 60 61 62 63 64
* 65 66 67 68 69 70 71 72
* @see graphics/inv/inventory.png
*/
const InvXY InvRect[] = {
// clang-format off
// X, Y
{ RIGHT_PANEL + 132, 31 }, // helmet
{ RIGHT_PANEL + 160, 31 }, // helmet
{ RIGHT_PANEL + 132, 59 }, // helmet
{ RIGHT_PANEL + 160, 59 }, // helmet
{ RIGHT_PANEL + 45, 205 }, // left ring
{ RIGHT_PANEL + 247, 205 }, // right ring
{ RIGHT_PANEL + 204, 59 }, // amulet
{ RIGHT_PANEL + 17, 104 }, // left hand
{ RIGHT_PANEL + 46, 104 }, // left hand
{ RIGHT_PANEL + 17, 132 }, // left hand
{ RIGHT_PANEL + 46, 132 }, // left hand
{ RIGHT_PANEL + 17, 160 }, // left hand
{ RIGHT_PANEL + 46, 160 }, // left hand
{ RIGHT_PANEL + 247, 104 }, // right hand
{ RIGHT_PANEL + 276, 104 }, // right hand
{ RIGHT_PANEL + 247, 132 }, // right hand
{ RIGHT_PANEL + 276, 132 }, // right hand
{ RIGHT_PANEL + 247, 160 }, // right hand
{ RIGHT_PANEL + 276, 160 }, // right hand
{ RIGHT_PANEL + 132, 104 }, // chest
{ RIGHT_PANEL + 160, 104 }, // chest
{ RIGHT_PANEL + 132, 132 }, // chest
{ RIGHT_PANEL + 160, 132 }, // chest
{ RIGHT_PANEL + 132, 160 }, // chest
{ RIGHT_PANEL + 160, 160 }, // chest
{ RIGHT_PANEL + 17, 250 }, // inv row 1
{ RIGHT_PANEL + 46, 250 }, // inv row 1
{ RIGHT_PANEL + 74, 250 }, // inv row 1
{ RIGHT_PANEL + 103, 250 }, // inv row 1
{ RIGHT_PANEL + 131, 250 }, // inv row 1
{ RIGHT_PANEL + 160, 250 }, // inv row 1
{ RIGHT_PANEL + 189, 250 }, // inv row 1
{ RIGHT_PANEL + 218, 250 }, // inv row 1
{ RIGHT_PANEL + 247, 250 }, // inv row 1
{ RIGHT_PANEL + 276, 250 }, // inv row 1
{ RIGHT_PANEL + 17, 279 }, // inv row 2
{ RIGHT_PANEL + 46, 279 }, // inv row 2
{ RIGHT_PANEL + 74, 279 }, // inv row 2
{ RIGHT_PANEL + 103, 279 }, // inv row 2
{ RIGHT_PANEL + 131, 279 }, // inv row 2
{ RIGHT_PANEL + 160, 279 }, // inv row 2
{ RIGHT_PANEL + 189, 279 }, // inv row 2
{ RIGHT_PANEL + 218, 279 }, // inv row 2
{ RIGHT_PANEL + 247, 279 }, // inv row 2
{ RIGHT_PANEL + 276, 279 }, // inv row 2
{ RIGHT_PANEL + 17, 308 }, // inv row 3
{ RIGHT_PANEL + 46, 308 }, // inv row 3
{ RIGHT_PANEL + 74, 308 }, // inv row 3
{ RIGHT_PANEL + 103, 308 }, // inv row 3
{ RIGHT_PANEL + 131, 308 }, // inv row 3
{ RIGHT_PANEL + 160, 308 }, // inv row 3
{ RIGHT_PANEL + 189, 308 }, // inv row 3
{ RIGHT_PANEL + 218, 308 }, // inv row 3
{ RIGHT_PANEL + 247, 308 }, // inv row 3
{ RIGHT_PANEL + 276, 308 }, // inv row 3
{ RIGHT_PANEL + 17, 336 }, // inv row 4
{ RIGHT_PANEL + 46, 336 }, // inv row 4
{ RIGHT_PANEL + 74, 336 }, // inv row 4
{ RIGHT_PANEL + 103, 336 }, // inv row 4
{ RIGHT_PANEL + 131, 336 }, // inv row 4
{ RIGHT_PANEL + 160, 336 }, // inv row 4
{ RIGHT_PANEL + 189, 336 }, // inv row 4
{ RIGHT_PANEL + 218, 336 }, // inv row 4
{ RIGHT_PANEL + 247, 336 }, // inv row 4
{ RIGHT_PANEL + 276, 336 }, // inv row 4
{ PANEL_LEFT + 205, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 234, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 263, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 292, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 321, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 350, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 379, PANEL_TOP + 33 }, // belt
{ PANEL_LEFT + 408, PANEL_TOP + 33 } // belt
// clang-format on
};
/* data */
/** Specifies the starting inventory slots for placement of 2x2 items. */
int AP2x2Tbl[10] = { 8, 28, 6, 26, 4, 24, 2, 22, 0, 20 };
void FreeInvGFX()
{
MemFreeDbg(pInvCels);
}
void InitInv()
{
if (plr[myplr]._pClass == PC_WARRIOR) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv.CEL", NULL);
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv_rog.CEL", NULL);
} else if (plr[myplr]._pClass == PC_SORCERER) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv_Sor.CEL", NULL);
#endif
#ifdef HELLFIRE
} else if (plr[myplr]._pClass == PC_MONK) {
#ifndef SPAWN
pInvCels = LoadFileInMem("Data\\Inv\\Inv_Sor.CEL", NULL);
#else
pInvCels = LoadFileInMem("Data\\Inv\\Inv.CEL", NULL);
#endif
} else if (plr[myplr]._pClass == PC_BARD) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv_rog.CEL", NULL);
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
pInvCels = LoadFileInMem("Data\\Inv\\Inv.CEL", NULL);
#endif
}
invflag = FALSE;
drawsbarflag = FALSE;
}
void InvDrawSlotBack(int X, int Y, int W, int H)
{
BYTE *dst;
assert(gpBuffer);
dst = &gpBuffer[X + PitchTbl[Y]];
#ifdef USE_ASM
__asm {
mov edi, dst
xor edx, edx
xor ebx, ebx
mov dx, word ptr H
mov bx, word ptr W
label1:
mov ecx, ebx
label2:
mov al, [edi]
cmp al, PAL16_BLUE
jb label5
cmp al, PAL16_BLUE + 15
ja label3
sub al, PAL16_BLUE - PAL16_BEIGE
jmp label4
label3:
cmp al, PAL16_GRAY
jb label5
sub al, PAL16_GRAY - PAL16_BEIGE
label4:
mov [edi], al
label5:
inc edi
loop label2
sub edi, BUFFER_WIDTH
sub edi, ebx
dec edx
jnz label1
}
#else
int wdt, hgt;
BYTE pix;
for (hgt = H; hgt; hgt--, dst -= BUFFER_WIDTH + W) {
for (wdt = W; wdt; wdt--) {
pix = *dst;
if (pix >= PAL16_BLUE) {
if (pix <= PAL16_BLUE + 15)
pix -= PAL16_BLUE - PAL16_BEIGE;
else if (pix >= PAL16_GRAY)
pix -= PAL16_GRAY - PAL16_BEIGE;
}
*dst++ = pix;
}
}
#endif
}
/**
* @brief Render the inventory panel to the back buffer
*/
void DrawInv()
{
BOOL invtest[NUM_INV_GRID_ELEM];
int frame, frame_width, color, screen_x, screen_y, i, j, ii;
BYTE *pBuff;
CelDraw(RIGHT_PANEL_X, 351 + SCREEN_Y, pInvCels, 1, 320);
if (plr[myplr].InvBody[INVLOC_HEAD]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 133, 59 + SCREEN_Y, 2 * INV_SLOT_SIZE_PX, 2 * INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_HEAD]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == INVITEM_HEAD) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_HEAD]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_HEAD]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, RIGHT_PANEL_X + 133, 59 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, RIGHT_PANEL_X + 133, 59 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_HEAD]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(RIGHT_PANEL_X + 133, 59 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(RIGHT_PANEL_X + 133, 59 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(RIGHT_PANEL_X + 133, 59 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(RIGHT_PANEL_X + 133, 59 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
if (plr[myplr].InvBody[INVLOC_RING_LEFT]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 48, 205 + SCREEN_Y, INV_SLOT_SIZE_PX, INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_RING_LEFT]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == INVITEM_RING_LEFT) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_RING_LEFT]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_RING_LEFT]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, RIGHT_PANEL_X + 48, 205 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, RIGHT_PANEL_X + 48, 205 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_RING_LEFT]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(RIGHT_PANEL_X + 48, 205 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(RIGHT_PANEL_X + 48, 205 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(RIGHT_PANEL_X + 48, 205 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(RIGHT_PANEL_X + 48, 205 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
if (plr[myplr].InvBody[INVLOC_RING_RIGHT]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 249, 205 + SCREEN_Y, INV_SLOT_SIZE_PX, INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_RING_RIGHT]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == INVITEM_RING_RIGHT) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_RING_RIGHT]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_RING_RIGHT]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, RIGHT_PANEL_X + 249, 205 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, RIGHT_PANEL_X + 249, 205 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_RING_RIGHT]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(RIGHT_PANEL_X + 249, 205 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(RIGHT_PANEL_X + 249, 205 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(RIGHT_PANEL_X + 249, 205 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(RIGHT_PANEL_X + 249, 205 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
if (plr[myplr].InvBody[INVLOC_AMULET]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 205, 60 + SCREEN_Y, INV_SLOT_SIZE_PX, INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_AMULET]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == INVITEM_AMULET) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_AMULET]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_AMULET]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, RIGHT_PANEL_X + 205, 60 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, RIGHT_PANEL_X + 205, 60 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_AMULET]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(RIGHT_PANEL_X + 205, 60 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(RIGHT_PANEL_X + 205, 60 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(RIGHT_PANEL_X + 205, 60 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(RIGHT_PANEL_X + 205, 60 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 17, 160 + SCREEN_Y, 2 * INV_SLOT_SIZE_PX, 3 * INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_HAND_LEFT]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
// calc item offsets for weapons smaller than 2x3 slots
screen_x = frame_width == INV_SLOT_SIZE_PX ? (RIGHT_PANEL_X + 31) : (RIGHT_PANEL_X + 17);
screen_y = InvItemHeight[frame] == (3 * INV_SLOT_SIZE_PX) ? (160 + SCREEN_Y) : (146 + SCREEN_Y);
if (pcursinvitem == INVITEM_HAND_LEFT) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_HAND_LEFT]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, screen_x, screen_y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, screen_x, screen_y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(screen_x, screen_y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(screen_x, screen_y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(screen_x, screen_y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(screen_x, screen_y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._iLoc == ILOC_TWOHAND) {
#ifdef HELLFIRE
if (plr[myplr]._pClass != PC_BARBARIAN
|| plr[myplr].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_SWORD
&& plr[myplr].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_MACE) {
#endif
InvDrawSlotBack(RIGHT_PANEL_X + 247, 160 + SCREEN_Y, 2 * INV_SLOT_SIZE_PX, 3 * INV_SLOT_SIZE_PX);
light_table_index = 0;
cel_transparency_active = TRUE;
pBuff = frame_width == INV_SLOT_SIZE_PX
? &gpBuffer[SCREENXY(RIGHT_PANEL_X + 197, SCREEN_Y)]
: &gpBuffer[SCREENXY(RIGHT_PANEL_X + 183, SCREEN_Y)];
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedBlitLightTrans(pBuff, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedBlitLightTrans(pBuff, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
cel_transparency_active = FALSE;
#ifdef HELLFIRE
}
#endif
}
}
if (plr[myplr].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 247, 160 + SCREEN_Y, 2 * INV_SLOT_SIZE_PX, 3 * INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_HAND_RIGHT]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
// calc item offsets for weapons smaller than 2x3 slots
screen_x = frame_width == INV_SLOT_SIZE_PX ? (RIGHT_PANEL_X + 261) : (RIGHT_PANEL_X + 249);
screen_y = InvItemHeight[frame] == 3 * INV_SLOT_SIZE_PX ? (160 + SCREEN_Y) : (146 + SCREEN_Y);
if (pcursinvitem == INVITEM_HAND_RIGHT) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_HAND_RIGHT]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_HAND_RIGHT]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, screen_x, screen_y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, screen_x, screen_y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_HAND_RIGHT]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(screen_x, screen_y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(screen_x, screen_y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(screen_x, screen_y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(screen_x, screen_y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
if (plr[myplr].InvBody[INVLOC_CHEST]._itype != ITYPE_NONE) {
InvDrawSlotBack(RIGHT_PANEL_X + 133, 160 + SCREEN_Y, 2 * INV_SLOT_SIZE_PX, 3 * INV_SLOT_SIZE_PX);
frame = plr[myplr].InvBody[INVLOC_CHEST]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == INVITEM_CHEST) {
color = ICOL_WHITE;
if (plr[myplr].InvBody[INVLOC_CHEST]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvBody[INVLOC_CHEST]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(color, RIGHT_PANEL_X + 133, 160 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(color, RIGHT_PANEL_X + 133, 160 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvBody[INVLOC_CHEST]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(RIGHT_PANEL_X + 133, 160 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(RIGHT_PANEL_X + 133, 160 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(RIGHT_PANEL_X + 133, 160 + SCREEN_Y, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(RIGHT_PANEL_X + 133, 160 + SCREEN_Y, pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
invtest[i] = FALSE;
if (plr[myplr].InvGrid[i] != 0) {
InvDrawSlotBack(
InvRect[i + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[i + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
INV_SLOT_SIZE_PX,
INV_SLOT_SIZE_PX);
}
}
for (j = 0; j < NUM_INV_GRID_ELEM; j++) {
if (plr[myplr].InvGrid[j] > 0) // first slot of an item
{
ii = plr[myplr].InvGrid[j] - 1;
invtest[j] = TRUE;
frame = plr[myplr].InvList[ii]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == ii + INVITEM_INV_FIRST) {
color = ICOL_WHITE;
if (plr[myplr].InvList[ii]._iMagical != ITEM_QUALITY_NORMAL) {
color = ICOL_BLUE;
}
if (!plr[myplr].InvList[ii]._iStatFlag) {
color = ICOL_RED;
}
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelBlitOutline(
color,
InvRect[j + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[j + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelBlitOutline(
color,
InvRect[j + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[j + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
}
if (plr[myplr].InvList[ii]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelClippedDraw(
InvRect[j + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[j + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
} else {
CelClippedDraw(
InvRect[j + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[j + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
pCursCels2, frame - 179, frame_width, 0, 8);
}
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179) {
#endif
CelDrawLightRed(
InvRect[j + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[j + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
} else {
CelDrawLightRed(
InvRect[j + SLOTXY_INV_FIRST].X + SCREEN_X,
InvRect[j + SLOTXY_INV_FIRST].Y + SCREEN_Y - 1,
pCursCels2, frame - 179, frame_width, 0, 8, 1);
}
#endif
}
}
}
}
void DrawInvBelt()
{
int i, frame, frame_width, color;
BYTE fi, ff;
if (talkflag) {
return;
}
DrawPanelBox(205, 21, 232, 28, PANEL_X + 205, PANEL_Y + 5);
for (i = 0; i < MAXBELTITEMS; i++) {
if (plr[myplr].SpdList[i]._itype == ITYPE_NONE) {
continue;
}
InvDrawSlotBack(InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, INV_SLOT_SIZE_PX, INV_SLOT_SIZE_PX);
frame = plr[myplr].SpdList[i]._iCurs + CURSOR_FIRSTITEM;
frame_width = InvItemWidth[frame];
if (pcursinvitem == i + INVITEM_BELT_FIRST) {
color = ICOL_WHITE;
if (plr[myplr].SpdList[i]._iMagical)
color = ICOL_BLUE;
if (!plr[myplr].SpdList[i]._iStatFlag)
color = ICOL_RED;
#ifdef HELLFIRE
if (frame <= 179)
#endif
CelBlitOutline(color, InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
else
CelBlitOutline(color, InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, pCursCels2, frame - 179, frame_width, 0, 8);
#endif
}
if (plr[myplr].SpdList[i]._iStatFlag) {
#ifdef HELLFIRE
if (frame <= 179)
#endif
CelClippedDraw(InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, pCursCels, frame, frame_width, 0, 8);
#ifdef HELLFIRE
else
CelClippedDraw(InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, pCursCels2, frame - 179, frame_width, 0, 8);
#endif
} else {
#ifdef HELLFIRE
if (frame <= 179)
#endif
CelDrawLightRed(InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, pCursCels, frame, frame_width, 0, 8, 1);
#ifdef HELLFIRE
else
CelDrawLightRed(InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X, InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1, pCursCels2, frame - 179, frame_width, 0, 8, 1);
#endif
}
if (AllItemsList[plr[myplr].SpdList[i].IDidx].iUsable
&& plr[myplr].SpdList[i]._iStatFlag
&& plr[myplr].SpdList[i]._itype != ITYPE_GOLD) {
fi = i + 49;
ff = fontframe[gbFontTransTbl[fi]];
PrintChar(InvRect[i + SLOTXY_BELT_FIRST].X + SCREEN_X + PitchTbl[InvRect[i + SLOTXY_BELT_FIRST].Y + SCREEN_Y - 1] - fontkern[ff] + INV_SLOT_SIZE_PX, ff, 0);
}
}
}
BOOL AutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag)
{
int i, j, xx, yy;
BOOL done;
done = TRUE;
yy = 10 * (ii / 10);
if (yy < 0) {
yy = 0;
}
for (j = 0; j < sy && done; j++) {
if (yy >= NUM_INV_GRID_ELEM) {
done = FALSE;
}
xx = ii % 10;
if (xx < 0) {
xx = 0;
}
for (i = 0; i < sx && done; i++) {
if (xx >= 10) {
done = FALSE;
} else {
done = plr[pnum].InvGrid[xx + yy] == 0;
}
xx++;
}
yy += 10;
}
if (done && saveflag) {
plr[pnum].InvList[plr[pnum]._pNumInv] = plr[pnum].HoldItem;
plr[pnum]._pNumInv++;
yy = 10 * (ii / 10);
if (yy < 0) {
yy = 0;
}
for (j = 0; j < sy; j++) {
xx = ii % 10;
if (xx < 0) {
xx = 0;
}
for (i = 0; i < sx; i++) {
if (i != 0 || j != sy - 1) {
plr[pnum].InvGrid[xx + yy] = -plr[pnum]._pNumInv;
} else {
plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv;
}
xx++;
}
yy += 10;
}
CalcPlrScrolls(pnum);
}
return done;
}
BOOL SpecialAutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag)
{
int i, j, xx, yy;
BOOL done;
done = TRUE;
yy = 10 * (ii / 10);
if (yy < 0) {
yy = 0;
}
for (j = 0; j < sy && done; j++) {
if (yy >= NUM_INV_GRID_ELEM) {
done = FALSE;
}
xx = ii % 10;
if (xx < 0) {
xx = 0;
}
for (i = 0; i < sx && done; i++) {
if (xx >= 10) {
done = FALSE;
} else {
done = plr[pnum].InvGrid[xx + yy] == 0;
}
xx++;
}
yy += 10;
}
if (!done) {
if (sx > 1 || sy > 1) {
done = FALSE;
} else {
for (i = 0; i < MAXBELTITEMS; i++) {
if (plr[pnum].SpdList[i]._itype == ITYPE_NONE) {
done = TRUE;
break;
}
}
}
}
if (done && saveflag) {
plr[pnum].InvList[plr[pnum]._pNumInv] = plr[pnum].HoldItem;
plr[pnum]._pNumInv++;
yy = 10 * (ii / 10);
if (yy < 0) {
yy = 0;
}
for (j = 0; j < sy; j++) {
xx = ii % 10;
if (xx < 0) {
xx = 0;
}
for (i = 0; i < sx; i++) {
if (i != 0 || j != sy - 1) {
plr[pnum].InvGrid[xx + yy] = -plr[pnum]._pNumInv;
} else {
plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv;
}
xx++;
}
yy += 10;
}
CalcPlrScrolls(pnum);
}
return done;
}
BOOL GoldAutoPlace(int pnum)
{
int ii;
int xx, yy;
BOOL done;
done = FALSE;
for (int i = 0; i < plr[pnum]._pNumInv && !done; i++) {
if (plr[pnum].InvList[i]._itype == ITYPE_GOLD) {
int gold = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue;
#ifdef HELLFIRE
if (gold <= MaxGold) {
#else
if (plr[pnum].HoldItem._ivalue + plr[pnum].InvList[i]._ivalue <= GOLD_MAX_LIMIT) {
#endif
plr[pnum].InvList[i]._ivalue = gold;
if (gold >= GOLD_MEDIUM_LIMIT)
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_LARGE;
else if (gold <= GOLD_SMALL_LIMIT)
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_SMALL;
else
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_MEDIUM;
plr[pnum]._pGold = CalculateGold(pnum);
done = TRUE;
#ifdef HELLFIRE
plr[pnum].HoldItem._ivalue = 0;
} else {
int max_gold = MaxGold;
if (plr[pnum].InvList[i]._ivalue < max_gold) {
int gold = max_gold - plr[pnum].InvList[i]._ivalue;
plr[pnum].InvList[i]._ivalue = max_gold;
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_LARGE;
plr[pnum].HoldItem._ivalue -= gold;
if (plr[pnum].HoldItem._ivalue < 0) {
plr[pnum].HoldItem._ivalue = 0;
done = TRUE;
}
GetPlrHandSeed(&plr[pnum].HoldItem);
control_set_gold_curs(pnum);
plr[pnum]._pGold = CalculateGold(pnum);
}
#endif
}
}
}
#ifndef HELLFIRE
if (!done)
for (int i = 0; i < plr[pnum]._pNumInv && !done; i++) {
if (plr[pnum].InvList[i]._itype == ITYPE_GOLD && plr[pnum].InvList[i]._ivalue < GOLD_MAX_LIMIT) {
if (plr[pnum].HoldItem._ivalue + plr[pnum].InvList[i]._ivalue <= GOLD_MAX_LIMIT) {
plr[pnum].InvList[i]._ivalue = plr[pnum].HoldItem._ivalue + plr[pnum].InvList[i]._ivalue;
if (plr[pnum].InvList[i]._ivalue >= GOLD_MEDIUM_LIMIT)
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_LARGE;
else if (plr[pnum].InvList[i]._ivalue <= GOLD_SMALL_LIMIT)
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_SMALL;
else
plr[pnum].InvList[i]._iCurs = ICURS_GOLD_MEDIUM;
plr[pnum]._pGold = CalculateGold(pnum);
done = TRUE;
}
}
}
#endif
if (!done)
for (int i = 39; i >= 0 && !done; i--) {
yy = 10 * (i / 10);
xx = i % 10;
if (plr[pnum].InvGrid[xx + yy] == 0) {
ii = plr[pnum]._pNumInv;
plr[pnum].InvList[ii] = plr[pnum].HoldItem;
plr[pnum]._pNumInv = plr[pnum]._pNumInv + 1;
plr[pnum].InvGrid[xx + yy] = plr[pnum]._pNumInv;
if (plr[pnum].HoldItem._ivalue >= GOLD_MEDIUM_LIMIT)
plr[pnum].InvList[ii]._iCurs = ICURS_GOLD_LARGE;
else if (plr[pnum].HoldItem._ivalue <= GOLD_SMALL_LIMIT)
plr[pnum].InvList[ii]._iCurs = ICURS_GOLD_SMALL;
else
plr[pnum].InvList[ii]._iCurs = ICURS_GOLD_MEDIUM;
#ifdef HELLFIRE
int gold = plr[pnum].HoldItem._ivalue;
if (gold > MaxGold) {
gold -= MaxGold;
plr[pnum].HoldItem._ivalue = gold;
GetPlrHandSeed(&plr[pnum].HoldItem);
plr[pnum].InvList[ii]._ivalue = MaxGold;
} else {
plr[pnum].HoldItem._ivalue = 0;
done = TRUE;
plr[pnum]._pGold = CalculateGold(pnum);
SetCursor_(CURSOR_HAND);
}
#else
plr[pnum]._pGold = CalculateGold(pnum);
done = TRUE;
#endif
}
}
return done;
}
BOOL WeaponAutoPlace(int pnum)
{
#ifdef HELLFIRE
if (plr[pnum]._pClass == PC_MONK)
return FALSE;
#endif
if (plr[pnum].HoldItem._iLoc != ILOC_TWOHAND
#ifdef HELLFIRE
|| (plr[pnum]._pClass == PC_BARBARIAN && (plr[pnum].HoldItem._itype == ITYPE_SWORD || plr[pnum].HoldItem._itype == ITYPE_MACE))
#endif
) {
#ifdef HELLFIRE
if (plr[pnum]._pClass != PC_BARD)
#endif
{
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON)
return FALSE;
if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON)
return FALSE;
}
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE) {
NetSendCmdChItem(TRUE, INVLOC_HAND_LEFT);
plr[pnum].InvBody[INVLOC_HAND_LEFT] = plr[pnum].HoldItem;
return TRUE;
}
if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iLoc != ILOC_TWOHAND) {
NetSendCmdChItem(TRUE, INVLOC_HAND_RIGHT);
plr[pnum].InvBody[INVLOC_HAND_RIGHT] = plr[pnum].HoldItem;
return TRUE;
}
} else if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE) {
NetSendCmdChItem(TRUE, INVLOC_HAND_LEFT);
plr[pnum].InvBody[INVLOC_HAND_LEFT] = plr[pnum].HoldItem;
return TRUE;
}
return FALSE;
}
int SwapItem(ItemStruct *a, ItemStruct *b)
{
ItemStruct h;
h = *a;
*a = *b;
*b = h;
return h._iCurs + CURSOR_FIRSTITEM;
}
void CheckInvPaste(int pnum, int mx, int my)
{
int r, sx, sy;
int i, j, xx, yy, ii;
BOOL done, done2h;
int il, cn, it, iv, ig, gt;
ItemStruct tempitem;
SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
i = mx + (icursW >> 1);
j = my + (icursH >> 1);
sx = icursW28;
sy = icursH28;
done = FALSE;
for (r = 0; (DWORD)r < NUM_XY_SLOTS && !done; r++) {
if (i >= InvRect[r].X && i < InvRect[r].X + INV_SLOT_SIZE_PX) {
if (j >= InvRect[r].Y - INV_SLOT_SIZE_PX - 1 && j < InvRect[r].Y) {
done = TRUE;
r--;
}
}
if (r == SLOTXY_CHEST_LAST) {
if ((sx & 1) == 0)
i -= 14;
if ((sy & 1) == 0)
j -= 14;
}
if (r == SLOTXY_INV_LAST && (sy & 1) == 0)
j += 14;
}
if (!done)
return;
il = ILOC_UNEQUIPABLE;
if (r >= SLOTXY_HEAD_FIRST && r <= SLOTXY_HEAD_LAST)
il = ILOC_HELM;
if (r >= SLOTXY_RING_LEFT && r <= SLOTXY_RING_RIGHT)
il = ILOC_RING;
if (r == SLOTXY_AMULET)
il = ILOC_AMULET;
if (r >= SLOTXY_HAND_LEFT_FIRST && r <= SLOTXY_HAND_RIGHT_LAST)
il = ILOC_ONEHAND;
if (r >= SLOTXY_CHEST_FIRST && r <= SLOTXY_CHEST_LAST)
il = ILOC_ARMOR;
if (r >= SLOTXY_BELT_FIRST && r <= SLOTXY_BELT_LAST)
il = ILOC_BELT;
done = FALSE;
if (plr[pnum].HoldItem._iLoc == il)
done = TRUE;
if (il == ILOC_ONEHAND && plr[pnum].HoldItem._iLoc == ILOC_TWOHAND) {
#ifdef HELLFIRE
if (plr[pnum]._pClass == PC_BARBARIAN
&& (plr[pnum].HoldItem._itype == ITYPE_SWORD || plr[pnum].HoldItem._itype == ITYPE_MACE))
il = ILOC_ONEHAND;
else
#endif
il = ILOC_TWOHAND;
done = TRUE;
}
if (plr[pnum].HoldItem._iLoc == ILOC_UNEQUIPABLE && il == ILOC_BELT) {
if (sx == 1 && sy == 1) {
done = TRUE;
if (!AllItemsList[plr[pnum].HoldItem.IDidx].iUsable)
done = FALSE;
if (!plr[pnum].HoldItem._iStatFlag)
done = FALSE;
if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
done = FALSE;
}
}
if (il == ILOC_UNEQUIPABLE) {
done = TRUE;
it = 0;
ii = r - SLOTXY_INV_FIRST;
if (plr[pnum].HoldItem._itype == ITYPE_GOLD) {
yy = 10 * (ii / 10);
xx = ii % 10;
if (plr[pnum].InvGrid[xx + yy] != 0) {
iv = plr[pnum].InvGrid[xx + yy];
if (iv > 0) {
if (plr[pnum].InvList[iv - 1]._itype != ITYPE_GOLD) {
it = iv;
}
} else {
it = -iv;
}
}
} else {
yy = 10 * ((ii / 10) - ((sy - 1) >> 1));
if (yy < 0)
yy = 0;
for (j = 0; j < sy && done; j++) {
if (yy >= NUM_INV_GRID_ELEM)
done = FALSE;
xx = (ii % 10) - ((sx - 1) >> 1);
if (xx < 0)
xx = 0;
for (i = 0; i < sx && done; i++) {
if (xx >= 10) {
done = FALSE;
} else {
if (plr[pnum].InvGrid[xx + yy] != 0) {
iv = plr[pnum].InvGrid[xx + yy];
if (iv < 0)
iv = -iv;
if (it != 0) {
if (it != iv)
done = FALSE;
} else
it = iv;
}
}
xx++;
}
yy += 10;
}
}
}
if (!done)
return;
if (il != ILOC_UNEQUIPABLE && il != ILOC_BELT && !plr[pnum].HoldItem._iStatFlag) {
done = FALSE;
if (plr[pnum]._pClass == PC_WARRIOR)
PlaySFX(PS_WARR13);
#ifndef SPAWN
else if (plr[pnum]._pClass == PC_ROGUE)
PlaySFX(PS_ROGUE13);
else if (plr[pnum]._pClass == PC_SORCERER)
PlaySFX(PS_MAGE13);
#endif
#ifdef HELLFIRE
else if (plr[pnum]._pClass == PC_MONK)
PlaySFX(PS_MONK13);
#ifndef SPAWN
else if (plr[pnum]._pClass == PC_BARD)
PlaySFX(PS_ROGUE13);
#endif
else if (plr[pnum]._pClass == PC_BARBARIAN)
PlaySFX(PS_MAGE13);
#endif
}
if (!done)
return;
if (pnum == myplr)
PlaySFX(ItemInvSnds[ItemCAnimTbl[plr[pnum].HoldItem._iCurs]]);
cn = CURSOR_HAND;
switch (il) {
case ILOC_HELM:
NetSendCmdChItem(FALSE, INVLOC_HEAD);
if (plr[pnum].InvBody[INVLOC_HEAD]._itype == ITYPE_NONE)
plr[pnum].InvBody[INVLOC_HEAD] = plr[pnum].HoldItem;
else
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HEAD], &plr[pnum].HoldItem);
break;
case ILOC_RING:
if (r == SLOTXY_RING_LEFT) {
NetSendCmdChItem(FALSE, INVLOC_RING_LEFT);
if (plr[pnum].InvBody[INVLOC_RING_LEFT]._itype == ITYPE_NONE)
plr[pnum].InvBody[INVLOC_RING_LEFT] = plr[pnum].HoldItem;
else
cn = SwapItem(&plr[pnum].InvBody[INVLOC_RING_LEFT], &plr[pnum].HoldItem);
} else {
NetSendCmdChItem(FALSE, INVLOC_RING_RIGHT);
if (plr[pnum].InvBody[INVLOC_RING_RIGHT]._itype == ITYPE_NONE)
plr[pnum].InvBody[INVLOC_RING_RIGHT] = plr[pnum].HoldItem;
else
cn = SwapItem(&plr[pnum].InvBody[INVLOC_RING_RIGHT], &plr[pnum].HoldItem);
}
break;
case ILOC_AMULET:
NetSendCmdChItem(FALSE, INVLOC_AMULET);
if (plr[pnum].InvBody[INVLOC_AMULET]._itype == ITYPE_NONE)
plr[pnum].InvBody[INVLOC_AMULET] = plr[pnum].HoldItem;
else
cn = SwapItem(&plr[pnum].InvBody[INVLOC_AMULET], &plr[pnum].HoldItem);
break;
case ILOC_ONEHAND:
if (r <= SLOTXY_HAND_LEFT_LAST) {
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE) {
if ((plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass != plr[pnum].HoldItem._iClass)
#ifdef HELLFIRE
|| (plr[pnum]._pClass == PC_BARD && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON && plr[pnum].HoldItem._iClass == ICLASS_WEAPON)
#endif
) {
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
plr[pnum].InvBody[INVLOC_HAND_LEFT] = plr[pnum].HoldItem;
} else {
NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
}
break;
}
if ((plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass != plr[pnum].HoldItem._iClass)
#ifdef HELLFIRE
|| (plr[pnum]._pClass == PC_BARD && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._iClass == ICLASS_WEAPON && plr[pnum].HoldItem._iClass == ICLASS_WEAPON)
#endif
) {
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
break;
}
NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
break;
}
if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_NONE) {
if ((plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_LEFT]._iLoc != ILOC_TWOHAND)
#ifdef HELLFIRE
|| (plr[pnum]._pClass == PC_BARBARIAN && (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_SWORD || plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_MACE))
#endif
) {
if ((plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass != plr[pnum].HoldItem._iClass)
#ifdef HELLFIRE
|| (plr[pnum]._pClass == PC_BARD && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON && plr[pnum].HoldItem._iClass == ICLASS_WEAPON)
#endif
) {
NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
plr[pnum].InvBody[INVLOC_HAND_RIGHT] = plr[pnum].HoldItem;
break;
}
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
break;
}
#ifdef HELLFIRE
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
#else
NetSendCmdDelItem(FALSE, INVLOC_HAND_LEFT);
NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
#endif
SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].InvBody[INVLOC_HAND_LEFT]);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
break;
}
if ((plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass == plr[pnum].HoldItem._iClass)
#ifdef HELLFIRE
&& !(plr[pnum]._pClass == PC_BARD && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iClass == ICLASS_WEAPON && plr[pnum].HoldItem._iClass == ICLASS_WEAPON)
#endif
) {
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
break;
}
NetSendCmdChItem(FALSE, INVLOC_HAND_RIGHT);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_RIGHT], &plr[pnum].HoldItem);
break;
case ILOC_TWOHAND:
NetSendCmdDelItem(FALSE, INVLOC_HAND_RIGHT);
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE && plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE) {
tempitem = plr[pnum].HoldItem;
if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD)
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HAND_RIGHT];
else
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HAND_LEFT];
if (pnum == myplr)
SetCursor_(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
else
SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
done2h = FALSE;
for (i = 0; i < NUM_INV_GRID_ELEM && !done2h; i++)
done2h = AutoPlace(pnum, i, icursW28, icursH28, TRUE);
plr[pnum].HoldItem = tempitem;
if (pnum == myplr)
SetCursor_(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
else
SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
if (!done2h)
return;
if (plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype == ITYPE_SHIELD)
plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype = ITYPE_NONE;
else
plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype = ITYPE_NONE;
}
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE || plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE) {
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_NONE)
SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].InvBody[INVLOC_HAND_RIGHT]);
cn = SwapItem(&plr[pnum].InvBody[INVLOC_HAND_LEFT], &plr[pnum].HoldItem);
} else {
NetSendCmdChItem(FALSE, INVLOC_HAND_LEFT);
plr[pnum].InvBody[INVLOC_HAND_LEFT] = plr[pnum].HoldItem;
}
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_STAFF && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iSpell != SPL_NULL && plr[pnum].InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
plr[pnum]._pRSpell = plr[pnum].InvBody[INVLOC_HAND_LEFT]._iSpell;
plr[pnum]._pRSplType = RSPLTYPE_CHARGES;
force_redraw = 255;
}
break;
case ILOC_ARMOR:
NetSendCmdChItem(FALSE, INVLOC_CHEST);
if (plr[pnum].InvBody[INVLOC_CHEST]._itype == ITYPE_NONE)
plr[pnum].InvBody[INVLOC_CHEST] = plr[pnum].HoldItem;
else
cn = SwapItem(&plr[pnum].InvBody[INVLOC_CHEST], &plr[pnum].HoldItem);
break;
case ILOC_UNEQUIPABLE:
if (plr[pnum].HoldItem._itype == ITYPE_GOLD && it == 0) {
ii = r - SLOTXY_INV_FIRST;
yy = 10 * (ii / 10);
xx = ii % 10;
if (plr[pnum].InvGrid[yy + xx] > 0) {
il = plr[pnum].InvGrid[yy + xx];
il--;
gt = plr[pnum].InvList[il]._ivalue;
ig = plr[pnum].HoldItem._ivalue + gt;
if (ig <= GOLD_MAX_LIMIT) {
plr[pnum].InvList[il]._ivalue = ig;
plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
if (ig >= GOLD_MEDIUM_LIMIT)
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_LARGE;
else if (ig <= GOLD_SMALL_LIMIT)
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_SMALL;
else
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_MEDIUM;
} else {
ig = GOLD_MAX_LIMIT - gt;
plr[pnum]._pGold += ig;
plr[pnum].HoldItem._ivalue -= ig;
plr[pnum].InvList[il]._ivalue = GOLD_MAX_LIMIT;
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_LARGE;
// BUGFIX: incorrect values here are leftover from beta
if (plr[pnum].HoldItem._ivalue >= GOLD_MEDIUM_LIMIT)
cn = ICURS_GOLD_LARGE + CURSOR_FIRSTITEM;
else if (plr[pnum].HoldItem._ivalue <= GOLD_SMALL_LIMIT)
cn = ICURS_GOLD_SMALL + CURSOR_FIRSTITEM;
else
cn = ICURS_GOLD_MEDIUM + CURSOR_FIRSTITEM;
}
} else {
il = plr[pnum]._pNumInv;
plr[pnum].InvList[il] = plr[pnum].HoldItem;
plr[pnum]._pNumInv++;
plr[pnum].InvGrid[yy + xx] = plr[pnum]._pNumInv;
plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
if (plr[pnum].HoldItem._ivalue <= GOLD_MAX_LIMIT) {
if (plr[pnum].HoldItem._ivalue >= GOLD_MEDIUM_LIMIT)
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_LARGE;
else if (plr[pnum].HoldItem._ivalue <= GOLD_SMALL_LIMIT)
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_SMALL;
else
plr[pnum].InvList[il]._iCurs = ICURS_GOLD_MEDIUM;
#ifdef HELLFIRE
} else {
plr[pnum].InvList[ii]._iCurs = ICURS_GOLD_LARGE;
#endif
}
}
} else {
if (it == 0) {
plr[pnum].InvList[plr[pnum]._pNumInv] = plr[pnum].HoldItem;
plr[pnum]._pNumInv++;
it = plr[pnum]._pNumInv;
} else {
il = it - 1;
if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
cn = SwapItem(&plr[pnum].InvList[il], &plr[pnum].HoldItem);
if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
plr[pnum]._pGold = CalculateGold(pnum);
for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
if (plr[pnum].InvGrid[i] == it)
plr[pnum].InvGrid[i] = 0;
if (plr[pnum].InvGrid[i] == -it)
plr[pnum].InvGrid[i] = 0;
}
}
ii = r - SLOTXY_INV_FIRST;
yy = 10 * (ii / 10 - ((sy - 1) >> 1));
if (yy < 0)
yy = 0;
for (j = 0; j < sy; j++) {
xx = (ii % 10 - ((sx - 1) >> 1));
if (xx < 0)
xx = 0;
for (i = 0; i < sx; i++) {
if (i != 0 || j != sy - 1)
plr[pnum].InvGrid[xx + yy] = -it;
else
plr[pnum].InvGrid[xx + yy] = it;
xx++;
}
yy += 10;
}
}
break;
case ILOC_BELT:
ii = r - SLOTXY_BELT_FIRST;
if (plr[pnum].HoldItem._itype == ITYPE_GOLD) {
if (plr[pnum].SpdList[ii]._itype != ITYPE_NONE) {
if (plr[pnum].SpdList[ii]._itype == ITYPE_GOLD) {
i = plr[pnum].HoldItem._ivalue + plr[pnum].SpdList[ii]._ivalue;
if (i <= GOLD_MAX_LIMIT) {
plr[pnum].SpdList[ii]._ivalue += plr[pnum].HoldItem._ivalue;
plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
if (i >= GOLD_MEDIUM_LIMIT)
plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_LARGE;
else if (i <= GOLD_SMALL_LIMIT)
plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_SMALL;
else
plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_MEDIUM;
} else {
i = GOLD_MAX_LIMIT - plr[pnum].SpdList[ii]._ivalue;
plr[pnum]._pGold += i;
plr[pnum].HoldItem._ivalue -= i;
plr[pnum].SpdList[ii]._ivalue = GOLD_MAX_LIMIT;
plr[pnum].SpdList[ii]._iCurs = ICURS_GOLD_LARGE;
// BUGFIX: incorrect values here are leftover from beta
if (plr[pnum].HoldItem._ivalue >= GOLD_MEDIUM_LIMIT)
cn = ICURS_GOLD_LARGE + CURSOR_FIRSTITEM;
else if (plr[pnum].HoldItem._ivalue <= GOLD_SMALL_LIMIT)
cn = ICURS_GOLD_SMALL + CURSOR_FIRSTITEM;
else
cn = ICURS_GOLD_MEDIUM + CURSOR_FIRSTITEM;
}
} else {
plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem);
}
} else {
plr[pnum].SpdList[ii] = plr[pnum].HoldItem;
plr[pnum]._pGold += plr[pnum].HoldItem._ivalue;
}
} else if (plr[pnum].SpdList[ii]._itype == ITYPE_NONE) {
plr[pnum].SpdList[ii] = plr[pnum].HoldItem;
} else {
cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem);
if (plr[pnum].HoldItem._itype == ITYPE_GOLD)
plr[pnum]._pGold = CalculateGold(pnum);
}
drawsbarflag = TRUE;
break;
}
CalcPlrInv(pnum, TRUE);
if (pnum == myplr) {
if (cn == CURSOR_HAND)
SetCursorPos(MouseX + (cursW >> 1), MouseY + (cursH >> 1));
SetCursor_(cn);
}
}
void CheckInvSwap(int pnum, BYTE bLoc, int idx, WORD wCI, int seed, BOOL bId)
{
PlayerStruct *p;
RecreateItem(MAXITEMS, idx, wCI, seed, 0);
p = &plr[pnum];
p->HoldItem = item[MAXITEMS];
if (bId) {
p->HoldItem._iIdentified = TRUE;
}
if (bLoc < NUM_INVLOC) {
p->InvBody[bLoc] = p->HoldItem;
if (bLoc == INVLOC_HAND_LEFT && p->HoldItem._iLoc == ILOC_TWOHAND) {
p->InvBody[INVLOC_HAND_RIGHT]._itype = ITYPE_NONE;
} else if (bLoc == INVLOC_HAND_RIGHT && p->HoldItem._iLoc == ILOC_TWOHAND) {
p->InvBody[INVLOC_HAND_LEFT]._itype = ITYPE_NONE;
}
}
CalcPlrInv(pnum, TRUE);
}
void CheckInvCut(int pnum, int mx, int my)
{
int r;
BOOL done;
char ii;
int iv, i, j, offs, ig;
if (plr[pnum]._pmode > PM_WALK3) {
return;
}
if (dropGoldFlag) {
dropGoldFlag = FALSE;
dropGoldValue = 0;
}
done = FALSE;
for (r = 0; (DWORD)r < NUM_XY_SLOTS && !done; r++) {
// check which inventory rectangle the mouse is in, if any
if (mx >= InvRect[r].X
&& mx < InvRect[r].X + (INV_SLOT_SIZE_PX + 1)
&& my >= InvRect[r].Y - (INV_SLOT_SIZE_PX + 1)
&& my < InvRect[r].Y) {
done = TRUE;
r--;
}
}
if (!done) {
// not on an inventory slot rectangle
return;
}
plr[pnum].HoldItem._itype = ITYPE_NONE;
if (
r >= SLOTXY_HEAD_FIRST
&& r <= SLOTXY_HEAD_LAST
&& plr[pnum].InvBody[INVLOC_HEAD]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_HEAD);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HEAD];
plr[pnum].InvBody[INVLOC_HEAD]._itype = ITYPE_NONE;
}
if (
r == SLOTXY_RING_LEFT
&& plr[pnum].InvBody[INVLOC_RING_LEFT]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_RING_LEFT);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_RING_LEFT];
plr[pnum].InvBody[INVLOC_RING_LEFT]._itype = ITYPE_NONE;
}
if (
r == SLOTXY_RING_RIGHT
&& plr[pnum].InvBody[INVLOC_RING_RIGHT]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_RING_RIGHT);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_RING_RIGHT];
plr[pnum].InvBody[INVLOC_RING_RIGHT]._itype = ITYPE_NONE;
}
if (
r == SLOTXY_AMULET
&& plr[pnum].InvBody[INVLOC_AMULET]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_AMULET);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_AMULET];
plr[pnum].InvBody[INVLOC_AMULET]._itype = ITYPE_NONE;
}
if (
r >= SLOTXY_HAND_LEFT_FIRST
&& r <= SLOTXY_HAND_LEFT_LAST
&& plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_HAND_LEFT);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HAND_LEFT];
plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype = ITYPE_NONE;
}
if (
r >= SLOTXY_HAND_RIGHT_FIRST
&& r <= SLOTXY_HAND_RIGHT_LAST
&& plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_HAND_RIGHT);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_HAND_RIGHT];
plr[pnum].InvBody[INVLOC_HAND_RIGHT]._itype = ITYPE_NONE;
}
if (
r >= SLOTXY_CHEST_FIRST
&& r <= SLOTXY_CHEST_LAST
&& plr[pnum].InvBody[INVLOC_CHEST]._itype != ITYPE_NONE) {
NetSendCmdDelItem(FALSE, INVLOC_CHEST);
plr[pnum].HoldItem = plr[pnum].InvBody[INVLOC_CHEST];
plr[pnum].InvBody[INVLOC_CHEST]._itype = ITYPE_NONE;
}
if (r >= SLOTXY_INV_FIRST && r <= SLOTXY_INV_LAST) {
ig = r - SLOTXY_INV_FIRST;
ii = plr[pnum].InvGrid[ig];
if (ii != 0) {
iv = ii;
if (ii <= 0) {
iv = -ii;
}
for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
if (plr[pnum].InvGrid[i] == iv || plr[pnum].InvGrid[i] == -iv) {
plr[pnum].InvGrid[i] = 0;
}
}
iv--;
plr[pnum].HoldItem = plr[pnum].InvList[iv];
plr[pnum]._pNumInv--;
if (plr[pnum]._pNumInv > 0 && plr[pnum]._pNumInv != iv) {
plr[pnum].InvList[iv] = plr[pnum].InvList[plr[pnum]._pNumInv];
for (j = 0; j < NUM_INV_GRID_ELEM; j++) {
if (plr[pnum].InvGrid[j] == plr[pnum]._pNumInv + 1) {
plr[pnum].InvGrid[j] = iv + 1;
}
if (plr[pnum].InvGrid[j] == -(plr[pnum]._pNumInv + 1)) {
plr[pnum].InvGrid[j] = -iv - 1;
}
}
}
}
}
if (r >= SLOTXY_BELT_FIRST) {
offs = r - SLOTXY_BELT_FIRST;
if (plr[pnum].SpdList[offs]._itype != ITYPE_NONE) {
plr[pnum].HoldItem = plr[pnum].SpdList[offs];
plr[pnum].SpdList[offs]._itype = ITYPE_NONE;
drawsbarflag = TRUE;
}
}
if (plr[pnum].HoldItem._itype != ITYPE_NONE) {
if (plr[pnum].HoldItem._itype == ITYPE_GOLD) {
plr[pnum]._pGold = CalculateGold(pnum);
}
CalcPlrInv(pnum, TRUE);
CheckItemStats(pnum);
if (pnum == myplr) {
PlaySFX(IS_IGRAB);
SetCursor_(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
// BUGFIX: should be `my - (cursH >> 1)`, was `MouseY - (cursH >> 1)`.
SetCursorPos(mx - (cursW >> 1), MouseY - (cursH >> 1));
}
}
}
void inv_update_rem_item(int pnum, BYTE iv)
{
if (iv < NUM_INVLOC) {
plr[pnum].InvBody[iv]._itype = ITYPE_NONE;
}
if (plr[pnum]._pmode != PM_DEATH) {
CalcPlrInv(pnum, TRUE);
} else {
CalcPlrInv(pnum, FALSE);
}
}
void RemoveInvItem(int pnum, int iv)
{
int i, j;
iv++;
for (i = 0; i < NUM_INV_GRID_ELEM; i++) {
if (plr[pnum].InvGrid[i] == iv || plr[pnum].InvGrid[i] == -iv) {
plr[pnum].InvGrid[i] = 0;
}
}
iv--;
plr[pnum]._pNumInv--;
if (plr[pnum]._pNumInv > 0 && plr[pnum]._pNumInv != iv) {
plr[pnum].InvList[iv] = plr[pnum].InvList[plr[pnum]._pNumInv];
for (j = 0; j < NUM_INV_GRID_ELEM; j++) {
if (plr[pnum].InvGrid[j] == plr[pnum]._pNumInv + 1) {
plr[pnum].InvGrid[j] = iv + 1;
}
if (plr[pnum].InvGrid[j] == -(plr[pnum]._pNumInv + 1)) {
plr[pnum].InvGrid[j] = -(iv + 1);
}
}
}
CalcPlrScrolls(pnum);
if (plr[pnum]._pRSplType == RSPLTYPE_SCROLL) {
if (plr[pnum]._pRSpell != SPL_INVALID) {
// BUGFIX: Cast the literal `1` to `unsigned __int64` to make that bitshift 64bit
// this causes the last 4 skills to not reset correctly after use
// replace with SPELLBIT(plr[pnum]._pRSpell)
if (!(
plr[pnum]._pScrlSpells
& (1 << (plr[pnum]._pRSpell - 1)))) {
plr[pnum]._pRSpell = SPL_INVALID;
}
force_redraw = 255;
}
}
}
#ifdef HELLFIRE
/**
* @brief This destroyes all items except gold
*/
BOOL inv_diablo_to_hellfire(int pnum)
{
ItemStruct tmp;
ItemStruct *item;
int i, old_item_cnt, new_item_index;
if (plr[pnum]._pgfxnum != 0) {
plr[pnum]._pgfxnum = 0;
plr[pnum]._pGFXLoad = 0;
SetPlrAnims(pnum);
}
for (i = 0, item = plr[pnum].InvBody; i < NUM_INVLOC; i++, item++) {
item->_itype = ITYPE_NONE;
}
old_item_cnt = plr[pnum]._pNumInv;
memset(plr[pnum].InvGrid, 0, sizeof(plr[pnum].InvGrid));
plr[pnum]._pNumInv = 0;
for (i = 0; i < old_item_cnt; i++) {
item = &plr[pnum].InvList[i];
if (item->_itype == ITYPE_GOLD) {
new_item_index = plr[pnum]._pNumInv;
// BUGFIX: new_item_index may be greater or equal to NUM_INV_GRID_ELEM
tmp = *item;
item->_itype = ITYPE_NONE;
plr[pnum].InvList[new_item_index] = tmp;
plr[pnum]._pNumInv++;
plr[pnum].InvGrid[i] = plr[pnum]._pNumInv;
} else {
item->_itype = ITYPE_NONE;
}
};
for (i = 0, item = plr[pnum].SpdList; i < MAXBELTITEMS; i++, item++) {
item->_itype = ITYPE_NONE;
}
CalcPlrItemVals(pnum, FALSE);
return FALSE;
}
#endif
void RemoveSpdBarItem(int pnum, int iv)
{
plr[pnum].SpdList[iv]._itype = ITYPE_NONE;
CalcPlrScrolls(pnum);
if (plr[pnum]._pRSplType == RSPLTYPE_SCROLL) {
if (plr[pnum]._pRSpell != SPL_INVALID) {
// BUGFIX: Cast the literal `1` to `unsigned __int64` to make that bitshift 64bit
// this causes the last 4 skills to not reset correctly after use
// replace with SPELLBIT(plr[pnum]._pRSpell)
if (!(
plr[pnum]._pScrlSpells
& (1 << (plr[pnum]._pRSpell - 1)))) {
plr[pnum]._pRSpell = SPL_INVALID;
}
}
}
force_redraw = 255;
}
void CheckInvItem()
{
if (pcurs >= CURSOR_FIRSTITEM) {
CheckInvPaste(myplr, MouseX, MouseY);
} else {
CheckInvCut(myplr, MouseX, MouseY);
}
}
/**
* Check for interactions with belt
*/
void CheckInvScrn()
{
if (MouseX > 190 + PANEL_LEFT && MouseX < 437 + PANEL_LEFT
&& MouseY > PANEL_TOP && MouseY < 33 + PANEL_TOP) {
CheckInvItem();
}
}
void CheckItemStats(int pnum)
{
PlayerStruct *p = &plr[pnum];
p->HoldItem._iStatFlag = FALSE;
if (p->_pStrength >= p->HoldItem._iMinStr
&& p->_pMagic >= p->HoldItem._iMinMag
&& p->_pDexterity >= p->HoldItem._iMinDex) {
p->HoldItem._iStatFlag = TRUE;
}
}
void CheckBookLevel(int pnum)
{
int slvl;
if (plr[pnum].HoldItem._iMiscId == IMISC_BOOK) {
plr[pnum].HoldItem._iMinMag = spelldata[plr[pnum].HoldItem._iSpell].sMinInt;
slvl = plr[pnum]._pSplLvl[plr[pnum].HoldItem._iSpell];
while (slvl != 0) {
plr[pnum].HoldItem._iMinMag += 20 * plr[pnum].HoldItem._iMinMag / 100;
slvl--;
if (plr[pnum].HoldItem._iMinMag + 20 * plr[pnum].HoldItem._iMinMag / 100 > 255) {
plr[pnum].HoldItem._iMinMag = -1;
slvl = 0;
}
}
}
}
void CheckQuestItem(int pnum)
{
if (plr[pnum].HoldItem.IDidx == IDI_OPTAMULET)
quests[Q_BLIND]._qactive = QUEST_DONE;
if (plr[pnum].HoldItem.IDidx == IDI_MUSHROOM && quests[Q_MUSHROOM]._qactive == QUEST_ACTIVE && quests[Q_MUSHROOM]._qvar1 == QS_MUSHSPAWNED) {
#ifndef SPAWN
sfxdelay = 10;
if (plr[pnum]._pClass == PC_WARRIOR) { // BUGFIX: Voice for this quest might be wrong in MP
sfxdnum = PS_WARR95;
} else if (plr[pnum]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE95;
} else if (plr[pnum]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE95;
}
#ifdef HELLFIRE
else if (plr[pnum]._pClass == PC_MONK) {
sfxdnum = PS_MONK95;
} else if (plr[pnum]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE95;
} else if (plr[pnum]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR95;
}
#endif
#endif
quests[Q_MUSHROOM]._qvar1 = QS_MUSHPICKED;
}
if (plr[pnum].HoldItem.IDidx == IDI_ANVIL) {
if (quests[Q_ANVIL]._qactive == QUEST_INIT) {
quests[Q_ANVIL]._qactive = QUEST_ACTIVE;
quests[Q_ANVIL]._qvar1 = 1;
}
#ifndef SPAWN
if (quests[Q_ANVIL]._qlog == TRUE) {
sfxdelay = 10;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR89;
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE89;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE89;
}
#ifdef HELLFIRE
else if (plr[myplr]._pClass == PC_MONK) {
sfxdnum = PS_MONK89;
} else if (plr[myplr]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE89;
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR89;
}
#endif
}
#endif
}
#ifndef SPAWN
if (plr[pnum].HoldItem.IDidx == IDI_GLDNELIX) {
sfxdelay = 30;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR88;
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE88;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE88;
}
#ifdef HELLFIRE
else if (plr[myplr]._pClass == PC_MONK) {
sfxdnum = PS_MONK88;
} else if (plr[myplr]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE88;
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR88;
}
#endif
}
#endif
if (plr[pnum].HoldItem.IDidx == IDI_ROCK) {
if (quests[Q_ROCK]._qactive == QUEST_INIT) {
quests[Q_ROCK]._qactive = QUEST_ACTIVE;
quests[Q_ROCK]._qvar1 = 1;
}
#ifndef SPAWN
if (quests[Q_ROCK]._qlog == TRUE) {
sfxdelay = 10;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR87;
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE87;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE87;
}
#ifdef HELLFIRE
else if (plr[myplr]._pClass == PC_MONK) {
sfxdnum = PS_MONK87;
} else if (plr[myplr]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE87;
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR87;
}
#endif
}
#endif
}
if (plr[pnum].HoldItem.IDidx == IDI_ARMOFVAL) {
quests[Q_BLOOD]._qactive = QUEST_DONE;
#ifndef SPAWN
sfxdelay = 20;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR91;
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE91;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE91;
#ifdef HELLFIRE
} else if (plr[myplr]._pClass == PC_MONK) {
sfxdnum = PS_MONK91;
} else if (plr[myplr]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE91;
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR91;
#endif
}
#endif
}
#ifdef HELLFIRE
if (plr[pnum].HoldItem.IDidx == IDI_MAPOFDOOM) {
quests[Q_GRAVE]._qlog = FALSE;
quests[Q_GRAVE]._qactive = QUEST_ACTIVE;
quests[Q_GRAVE]._qvar1 = 1;
sfxdelay = 10;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR79;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE79;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE79;
#endif
} else if (plr[myplr]._pClass == PC_MONK) {
sfxdnum = PS_MONK79;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE79;
#endif
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR79;
}
}
if (plr[pnum].HoldItem.IDidx == IDI_NOTE1 || plr[pnum].HoldItem.IDidx == IDI_NOTE2 || plr[pnum].HoldItem.IDidx == IDI_NOTE3) {
int mask, idx, item_num;
int n1, n2, n3;
ItemStruct tmp;
mask = 0;
idx = plr[pnum].HoldItem.IDidx;
if (PlrHasItem(pnum, IDI_NOTE1, n1) || idx == IDI_NOTE1)
mask = 1;
if (PlrHasItem(pnum, IDI_NOTE2, n2) || idx == IDI_NOTE2)
mask |= 2;
if (PlrHasItem(pnum, IDI_NOTE3, n3) || idx == IDI_NOTE3)
mask |= 4;
if (mask == 7) {
sfxdelay = 10;
if (plr[myplr]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR46;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE46;
} else if (plr[myplr]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE46;
#endif
} else if (plr[myplr]._pClass == PC_MONK) {
sfxdnum = PS_MONK46;
#ifndef SPAWN
} else if (plr[myplr]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE46;
#endif
} else if (plr[myplr]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR46;
}
switch (idx) {
case IDI_NOTE1:
PlrHasItem(pnum, IDI_NOTE2, n2);
RemoveInvItem(pnum, n2);
PlrHasItem(pnum, IDI_NOTE3, n3);
RemoveInvItem(pnum, n3);
break;
case IDI_NOTE2:
PlrHasItem(pnum, IDI_NOTE1, n1);
RemoveInvItem(pnum, n1);
PlrHasItem(pnum, IDI_NOTE3, n3);
RemoveInvItem(pnum, n3);
break;
case IDI_NOTE3:
PlrHasItem(pnum, IDI_NOTE1, n1);
RemoveInvItem(pnum, n1);
PlrHasItem(pnum, IDI_NOTE2, n2);
RemoveInvItem(pnum, n2);
break;
}
item_num = itemactive[0];
tmp = item[item_num];
GetItemAttrs(item_num, IDI_FULLNOTE, 16);
SetupItem(item_num);
plr[pnum].HoldItem = item[item_num];
item[item_num] = tmp;
}
}
#endif
}
void InvGetItem(int pnum, int ii)
{
int i;
#ifdef HELLFIRE
BOOL cursor_updated;
#endif
if (dropGoldFlag) {
dropGoldFlag = FALSE;
dropGoldValue = 0;
}
if (dItem[item[ii]._ix][item[ii]._iy] != 0) {
if (myplr == pnum && pcurs >= CURSOR_FIRSTITEM)
NetSendCmdPItem(TRUE, CMD_SYNCPUTITEM, plr[myplr]._px, plr[myplr]._py);
#ifdef HELLFIRE
if (item[ii]._iUid != 0)
#endif
item[ii]._iCreateInfo &= ~CF_PREGEN;
plr[pnum].HoldItem = item[ii];
CheckQuestItem(pnum);
CheckBookLevel(pnum);
CheckItemStats(pnum);
#ifdef HELLFIRE
cursor_updated = FALSE;
if (plr[pnum].HoldItem._itype == ITYPE_GOLD && GoldAutoPlace(pnum))
cursor_updated = TRUE;
#endif
dItem[item[ii]._ix][item[ii]._iy] = 0;
#ifdef HELLFIRE
if (currlevel == 21 && item[ii]._ix == CornerStone.x && item[ii]._iy == CornerStone.y) {
CornerStone.item.IDidx = -1;
CornerStone.item._itype = ITYPE_MISC; // BUGFIX should be ITYPE_NONE
CornerStone.item._iSelFlag = FALSE;
CornerStone.item._ix = 0;
CornerStone.item._iy = 0;
CornerStone.item._iAnimFlag = FALSE;
CornerStone.item._iIdentified = FALSE;
CornerStone.item._iPostDraw = FALSE;
}
#endif
i = 0;
while (i < numitems) {
if (itemactive[i] == ii) {
DeleteItem(itemactive[i], i);
i = 0;
} else {
i++;
}
}
pcursitem = -1;
#ifdef HELLFIRE
if (!cursor_updated)
#endif
SetCursor_(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
}
}
void AutoGetItem(int pnum, int ii)
{
int i, idx;
int w, h;
BOOL done;
if (dropGoldFlag) {
dropGoldFlag = FALSE;
dropGoldValue = 0;
}
if (ii != MAXITEMS) {
if (dItem[item[ii]._ix][item[ii]._iy] == 0)
return;
}
#ifdef HELLFIRE
if (item[ii]._iUid != 0)
#endif
item[ii]._iCreateInfo &= ~CF_PREGEN;
plr[pnum].HoldItem = item[ii]; /// BUGFIX: overwrites cursor item, allowing for belt dupe bug
CheckQuestItem(pnum);
CheckBookLevel(pnum);
CheckItemStats(pnum);
SetICursor(plr[pnum].HoldItem._iCurs + CURSOR_FIRSTITEM);
if (plr[pnum].HoldItem._itype == ITYPE_GOLD) {
done = GoldAutoPlace(pnum);
#ifdef HELLFIRE
if (!done)
item[ii]._ivalue = plr[pnum].HoldItem._ivalue;
#endif
} else {
done = FALSE;
if (((plr[pnum]._pgfxnum & 0xF) == ANIM_ID_UNARMED || (plr[pnum]._pgfxnum & 0xF) == ANIM_ID_UNARMED_SHIELD
#ifdef HELLFIRE
|| plr[pnum]._pClass == PC_BARD && ((plr[pnum]._pgfxnum & 0xF) == ANIM_ID_MACE || (plr[pnum]._pgfxnum & 0xF) == ANIM_ID_SWORD)
#endif
)
&& plr[pnum]._pmode <= PM_WALK3) {
if (plr[pnum].HoldItem._iStatFlag) {
if (plr[pnum].HoldItem._iClass == ICLASS_WEAPON) {
done = WeaponAutoPlace(pnum);
if (done)
CalcPlrInv(pnum, TRUE);
}
}
}
if (!done) {
w = icursW28;
h = icursH28;
if (w == 1 && h == 1) {
idx = plr[pnum].HoldItem.IDidx;
if (plr[pnum].HoldItem._iStatFlag && AllItemsList[idx].iUsable) {
for (i = 0; i < MAXBELTITEMS && !done; i++) {
if (plr[pnum].SpdList[i]._itype == ITYPE_NONE) {
plr[pnum].SpdList[i] = plr[pnum].HoldItem;
CalcPlrScrolls(pnum);
drawsbarflag = TRUE;
done = TRUE;
}
}
}
for (i = 30; i <= 39 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 20; i <= 29 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 10; i <= 19 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 0; i <= 9 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
}
if (w == 1 && h == 2) {
for (i = 29; i >= 20 && !done; i--) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 9; i >= 0 && !done; i--) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 19; i >= 10 && !done; i--) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
}
if (w == 1 && h == 3) {
for (i = 0; i < 20 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
}
if (w == 2 && h == 2) {
for (i = 0; i < 10 && !done; i++) {
done = AutoPlace(pnum, AP2x2Tbl[i], w, h, TRUE);
}
for (i = 21; i < 29 && !done; i += 2) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 1; i < 9 && !done; i += 2) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 10; i < 19 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
}
if (w == 2 && h == 3) {
for (i = 0; i < 9 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
for (i = 10; i < 19 && !done; i++) {
done = AutoPlace(pnum, i, w, h, TRUE);
}
}
}
}
if (done) {
dItem[item[ii]._ix][item[ii]._iy] = 0;
#ifdef HELLFIRE
if (currlevel == 21 && item[ii]._ix == CornerStone.x && item[ii]._iy == CornerStone.y) {
CornerStone.item.IDidx = -1;
CornerStone.item._itype = ITYPE_MISC;
CornerStone.item._iSelFlag = FALSE;
CornerStone.item._ix = 0;
CornerStone.item._iy = 0;
CornerStone.item._iAnimFlag = FALSE;
CornerStone.item._iIdentified = FALSE;
CornerStone.item._iPostDraw = FALSE;
}
#endif
i = 0;
while (i < numitems) {
if (itemactive[i] == ii) {
DeleteItem(itemactive[i], i);
i = 0;
} else {
i++;
}
}
} else {
if (pnum == myplr) {
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySFX(random_(0, 3) + PS_WARR14);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySFX(random_(0, 3) + PS_ROGUE14);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySFX(random_(0, 3) + PS_MAGE14);
#endif
#ifdef HELLFIRE
} else if (plr[pnum]._pClass == PC_MONK) {
PlaySFX(random_(0, 3) + PS_MONK14);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_BARD) {
PlaySFX(random_(0, 3) + PS_ROGUE14);
#endif
} else if (plr[pnum]._pClass == PC_BARBARIAN) {
PlaySFX(random_(0, 3) + PS_WARR14);
#endif
}
}
plr[pnum].HoldItem = item[ii];
RespawnItem(ii, TRUE);
NetSendCmdPItem(TRUE, CMD_RESPAWNITEM, item[ii]._ix, item[ii]._iy);
plr[pnum].HoldItem._itype = ITYPE_NONE;
#ifdef HELLFIRE
NewCursor(CURSOR_HAND);
#endif
}
}
int FindGetItem(int idx, WORD ci, int iseed)
{
int i, ii;
i = 0;
if (numitems <= 0)
return -1;
while (1) {
ii = itemactive[i];
if (item[ii].IDidx == idx && item[ii]._iSeed == iseed && item[ii]._iCreateInfo == ci)
break;
i++;
if (i >= numitems)
return -1;
}
return ii;
}
void SyncGetItem(int x, int y, int idx, WORD ci, int iseed)
{
int i, ii;
if (dItem[x][y]) {
ii = dItem[x][y] - 1;
if (item[ii].IDidx == idx
&& item[ii]._iSeed == iseed
&& item[ii]._iCreateInfo == ci) {
FindGetItem(idx, ci, iseed);
} else {
ii = FindGetItem(idx, ci, iseed);
}
} else {
ii = FindGetItem(idx, ci, iseed);
}
if (ii != -1) {
dItem[item[ii]._ix][item[ii]._iy] = 0;
#ifdef HELLFIRE
if (currlevel == 21 && item[ii]._ix == CornerStone.x && item[ii]._iy == CornerStone.y) {
CornerStone.item.IDidx = -1;
CornerStone.item._itype = ITYPE_MISC;
CornerStone.item._iSelFlag = FALSE;
CornerStone.item._ix = 0;
CornerStone.item._iy = 0;
CornerStone.item._iAnimFlag = FALSE;
CornerStone.item._iIdentified = FALSE;
CornerStone.item._iPostDraw = FALSE;
}
#endif
i = 0;
while (i < numitems) {
if (itemactive[i] == ii) {
DeleteItem(itemactive[i], i);
FindGetItem(idx, ci, iseed);
#ifndef HELLFIRE
/// ASSERT: assert(FindGetItem(idx,ci,iseed) == -1);
FindGetItem(idx, ci, iseed); /* todo: replace with above */
#endif
i = 0;
} else {
i++;
}
}
/// ASSERT: assert(FindGetItem(idx, ci, iseed) == -1);
FindGetItem(idx, ci, iseed); /* todo: replace with above */
}
}
BOOL CanPut(int x, int y)
{
char oi, oi2;
if (dItem[x][y])
return FALSE;
if (nSolidTable[dPiece[x][y]])
return FALSE;
if (dObject[x][y] != 0) {
if (object[dObject[x][y] > 0 ? dObject[x][y] - 1 : -1 - dObject[x][y]]._oSolidFlag)
return FALSE;
}
oi = dObject[x + 1][y + 1];
if (oi > 0 && object[oi - 1]._oSelFlag != 0) {
return FALSE;
}
if (oi < 0 && object[-(oi + 1)]._oSelFlag != 0) {
return FALSE;
}
oi = dObject[x + 1][y];
if (oi > 0) {
oi2 = dObject[x][y + 1];
if (oi2 > 0 && object[oi - 1]._oSelFlag != 0 && object[oi2 - 1]._oSelFlag != 0)
return FALSE;
}
if (currlevel == 0 && dMonster[x][y] != 0)
return FALSE;
if (currlevel == 0 && dMonster[x + 1][y + 1] != 0)
return FALSE;
return TRUE;
}
BOOL TryInvPut()
{
int dir;
if (numitems >= MAXITEMS)
return FALSE;
dir = GetDirection(plr[myplr]._px, plr[myplr]._py, cursmx, cursmy);
if (CanPut(plr[myplr]._px + offset_x[dir], plr[myplr]._py + offset_y[dir])) {
return TRUE;
}
dir = (dir - 1) & 7;
if (CanPut(plr[myplr]._px + offset_x[dir], plr[myplr]._py + offset_y[dir])) {
return TRUE;
}
dir = (dir + 2) & 7;
if (CanPut(plr[myplr]._px + offset_x[dir], plr[myplr]._py + offset_y[dir])) {
return TRUE;
}
return CanPut(plr[myplr]._px, plr[myplr]._py);
}
void DrawInvMsg(const char *msg)
{
DWORD dwTicks;
dwTicks = GetTickCount();
if (dwTicks - sgdwLastTime >= 5000) {
sgdwLastTime = dwTicks;
ErrorPlrMsg(msg);
}
}
int InvPutItem(int pnum, int x, int y)
{
BOOL done;
int d, ii;
int i, j, l;
int xx, yy;
int xp, yp;
if (numitems >= MAXITEMS)
return -1;
if (FindGetItem(plr[pnum].HoldItem.IDidx, plr[pnum].HoldItem._iCreateInfo, plr[pnum].HoldItem._iSeed) != -1) {
DrawInvMsg("A duplicate item has been detected. Destroying duplicate...");
SyncGetItem(x, y, plr[pnum].HoldItem.IDidx, plr[pnum].HoldItem._iCreateInfo, plr[pnum].HoldItem._iSeed);
}
d = GetDirection(plr[pnum]._px, plr[pnum]._py, x, y);
xx = x - plr[pnum]._px;
yy = y - plr[pnum]._py;
if (abs(xx) > 1 || abs(yy) > 1) {
x = plr[pnum]._px + offset_x[d];
y = plr[pnum]._py + offset_y[d];
}
if (!CanPut(x, y)) {
d = (d - 1) & 7;
x = plr[pnum]._px + offset_x[d];
y = plr[pnum]._py + offset_y[d];
if (!CanPut(x, y)) {
d = (d + 2) & 7;
x = plr[pnum]._px + offset_x[d];
y = plr[pnum]._py + offset_y[d];
if (!CanPut(x, y)) {
done = FALSE;
for (l = 1; l < 50 && !done; l++) {
for (j = -l; j <= l && !done; j++) {
yp = j + plr[pnum]._py;
for (i = -l; i <= l && !done; i++) {
xp = i + plr[pnum]._px;
if (CanPut(xp, yp)) {
done = TRUE;
x = xp;
y = yp;
}
}
}
}
if (!done)
return -1;
}
}
}
#ifdef HELLFIRE
if (currlevel == 0) {
yp = cursmy;
xp = cursmx;
if (plr[pnum].HoldItem._iCurs == ICURS_RUNE_BOMB && xp >= 79 && xp <= 82 && yp >= 61 && yp <= 64) {
NetSendCmdLocParam2(0, CMD_OPENHIVE, plr[pnum]._px, plr[pnum]._py, xx, yy);
quests[Q_FARMER]._qactive = QUEST_DONE;
if (gbMaxPlayers != 1) {
NetSendCmdQuest(TRUE, Q_FARMER);
return -1;
}
return -1;
}
if (plr[pnum].HoldItem.IDidx == IDI_MAPOFDOOM && xp >= 35 && xp <= 38 && yp >= 20 && yp <= 24) {
NetSendCmd(FALSE, CMD_OPENCRYPT);
quests[Q_GRAVE]._qactive = QUEST_DONE;
if (gbMaxPlayers != 1) {
NetSendCmdQuest(TRUE, Q_GRAVE);
}
return -1;
}
}
#endif
CanPut(x, y); //if (!CanPut(x, y)) {
// assertion_failed(1524, "C:\\Diablo\\Direct\\inv.cpp", "CanPut(x,y)");
//}
ii = itemavail[0];
dItem[x][y] = ii + 1;
itemavail[0] = itemavail[MAXITEMS - (numitems + 1)];
itemactive[numitems] = ii;
item[ii] = plr[pnum].HoldItem;
item[ii]._ix = x;
item[ii]._iy = y;
RespawnItem(ii, TRUE);
numitems++;
#ifdef HELLFIRE
if (currlevel == 21 && x == CornerStone.x && y == CornerStone.y) {
CornerStone.item = item[ii];
InitQTextMsg(296);
quests[Q_CORNSTN]._qlog = FALSE;
quests[Q_CORNSTN]._qactive = QUEST_DONE;
}
#endif
NewCursor(CURSOR_HAND);
return ii;
}
int SyncPutItem(int pnum, int x, int y, int idx, WORD icreateinfo, int iseed, int Id, int dur, int mdur, int ch, int mch, int ivalue, DWORD ibuff
#ifdef HELLFIRE
,
int to_hit, int max_dam, int min_str, int min_mag, int min_dex, int ac
#endif
)
{
BOOL done;
int d, ii;
int i, j, l;
int xx, yy;
int xp, yp;
if (numitems >= MAXITEMS)
return -1;
if (FindGetItem(idx, icreateinfo, iseed) != -1) {
DrawInvMsg("A duplicate item has been detected from another player.");
SyncGetItem(x, y, idx, icreateinfo, iseed);
}
d = GetDirection(plr[pnum]._px, plr[pnum]._py, x, y);
xx = x - plr[pnum]._px;
yy = y - plr[pnum]._py;
if (abs(xx) > 1 || abs(yy) > 1) {
x = plr[pnum]._px + offset_x[d];
y = plr[pnum]._py + offset_y[d];
}
if (!CanPut(x, y)) {
d = (d - 1) & 7;
x = plr[pnum]._px + offset_x[d];
y = plr[pnum]._py + offset_y[d];
if (!CanPut(x, y)) {
d = (d + 2) & 7;
x = plr[pnum]._px + offset_x[d];
y = plr[pnum]._py + offset_y[d];
if (!CanPut(x, y)) {
done = FALSE;
for (l = 1; l < 50 && !done; l++) {
for (j = -l; j <= l && !done; j++) {
yp = j + plr[pnum]._py;
for (i = -l; i <= l && !done; i++) {
xp = i + plr[pnum]._px;
if (CanPut(xp, yp)) {
done = TRUE;
x = xp;
y = yp;
}
}
}
}
if (!done)
return -1;
}
}
}
CanPut(x, y);
ii = itemavail[0];
dItem[x][y] = ii + 1;
itemavail[0] = itemavail[MAXITEMS - (numitems + 1)];
itemactive[numitems] = ii;
if (idx == IDI_EAR) {
RecreateEar(ii, icreateinfo, iseed, Id, dur, mdur, ch, mch, ivalue, ibuff);
} else {
RecreateItem(ii, idx, icreateinfo, iseed, ivalue);
if (Id)
item[ii]._iIdentified = TRUE;
item[ii]._iDurability = dur;
item[ii]._iMaxDur = mdur;
item[ii]._iCharges = ch;
item[ii]._iMaxCharges = mch;
#ifdef HELLFIRE
item[ii]._iPLToHit = to_hit;
item[ii]._iMaxDam = max_dam;
item[ii]._iMinStr = min_str;
item[ii]._iMinMag = min_mag;
item[ii]._iMinDex = min_dex;
item[ii]._iAC = ac;
#endif
}
item[ii]._ix = x;
item[ii]._iy = y;
RespawnItem(ii, TRUE);
numitems++;
#ifdef HELLFIRE
if (currlevel == 21 && x == CornerStone.x && y == CornerStone.y) {
CornerStone.item = item[ii];
InitQTextMsg(296);
quests[Q_CORNSTN]._qlog = FALSE;
quests[Q_CORNSTN]._qactive = QUEST_DONE;
}
#endif
return ii;
}
char CheckInvHLight()
{
int r, ii, nGold;
ItemStruct *pi;
PlayerStruct *p;
char rv;
for (r = 0; (DWORD)r < NUM_XY_SLOTS; r++) {
if (MouseX >= InvRect[r].X
&& MouseX < InvRect[r].X + (INV_SLOT_SIZE_PX + 1)
&& MouseY >= InvRect[r].Y - (INV_SLOT_SIZE_PX + 1)
&& MouseY < InvRect[r].Y) {
break;
}
}
if ((DWORD)r >= NUM_XY_SLOTS)
return -1;
rv = -1;
infoclr = COL_WHITE;
pi = NULL;
p = &plr[myplr];
ClearPanel();
if (r >= SLOTXY_HEAD_FIRST && r <= SLOTXY_HEAD_LAST) {
rv = INVLOC_HEAD;
pi = &p->InvBody[rv];
} else if (r == SLOTXY_RING_LEFT) {
rv = INVLOC_RING_LEFT;
pi = &p->InvBody[rv];
} else if (r == SLOTXY_RING_RIGHT) {
rv = INVLOC_RING_RIGHT;
pi = &p->InvBody[rv];
} else if (r == SLOTXY_AMULET) {
rv = INVLOC_AMULET;
pi = &p->InvBody[rv];
} else if (r >= SLOTXY_HAND_LEFT_FIRST && r <= SLOTXY_HAND_LEFT_LAST) {
rv = INVLOC_HAND_LEFT;
pi = &p->InvBody[rv];
} else if (r >= SLOTXY_HAND_RIGHT_FIRST && r <= SLOTXY_HAND_RIGHT_LAST) {
pi = &p->InvBody[INVLOC_HAND_LEFT];
#ifdef HELLFIRE
if (pi->_itype == ITYPE_NONE || pi->_iLoc != ILOC_TWOHAND
|| (p->_pClass == PC_BARBARIAN && (p->InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_SWORD || p->InvBody[INVLOC_HAND_LEFT]._itype == ITYPE_MACE))) {
#else
if (pi->_itype == ITYPE_NONE || pi->_iLoc != ILOC_TWOHAND) {
#endif
rv = INVLOC_HAND_RIGHT;
pi = &p->InvBody[rv];
} else {
rv = INVLOC_HAND_LEFT;
}
} else if (r >= SLOTXY_CHEST_FIRST && r <= SLOTXY_CHEST_LAST) {
rv = INVLOC_CHEST;
pi = &p->InvBody[rv];
} else if (r >= SLOTXY_INV_FIRST && r <= SLOTXY_INV_LAST) {
r = abs(p->InvGrid[r - SLOTXY_INV_FIRST]);
if (r == 0)
return -1;
ii = r - 1;
rv = ii + INVITEM_INV_FIRST;
pi = &p->InvList[ii];
} else if (r >= SLOTXY_BELT_FIRST) {
r -= SLOTXY_BELT_FIRST;
drawsbarflag = TRUE;
pi = &p->SpdList[r];
if (pi->_itype == ITYPE_NONE)
return -1;
rv = r + INVITEM_BELT_FIRST;
}
if (pi->_itype == ITYPE_NONE)
return -1;
if (pi->_itype == ITYPE_GOLD) {
nGold = pi->_ivalue;
sprintf(infostr, "%i gold %s", nGold, get_pieces_str(nGold));
} else {
if (pi->_iMagical == ITEM_QUALITY_MAGIC) {
infoclr = COL_BLUE;
} else if (pi->_iMagical == ITEM_QUALITY_UNIQUE) {
infoclr = COL_GOLD;
}
strcpy(infostr, pi->_iName);
if (pi->_iIdentified) {
strcpy(infostr, pi->_iIName);
PrintItemDetails(pi);
} else {
PrintItemDur(pi);
}
}
return rv;
}
void RemoveScroll(int pnum)
{
int i;
for (i = 0; i < plr[pnum]._pNumInv; i++) {
if (plr[pnum].InvList[i]._itype != ITYPE_NONE
&& (plr[pnum].InvList[i]._iMiscId == IMISC_SCROLL || plr[pnum].InvList[i]._iMiscId == IMISC_SCROLLT)
#ifndef HELLFIRE
&& plr[pnum].InvList[i]._iSpell == plr[pnum]._pRSpell) {
#else
&& plr[pnum].InvList[i]._iSpell == plr[pnum]._pSpell) {
#endif
RemoveInvItem(pnum, i);
CalcPlrScrolls(pnum);
return;
}
}
for (i = 0; i < MAXBELTITEMS; i++) {
if (plr[pnum].SpdList[i]._itype != ITYPE_NONE
&& (plr[pnum].SpdList[i]._iMiscId == IMISC_SCROLL || plr[pnum].SpdList[i]._iMiscId == IMISC_SCROLLT)
#ifndef HELLFIRE
&& plr[pnum].SpdList[i]._iSpell == plr[pnum]._pRSpell) {
#else
&& plr[pnum].SpdList[i]._iSpell == plr[pnum]._pSpell) {
#endif
RemoveSpdBarItem(pnum, i);
CalcPlrScrolls(pnum);
return;
}
}
}
BOOL UseScroll()
{
int i;
if (pcurs != CURSOR_HAND)
return FALSE;
if (leveltype == DTYPE_TOWN && !spelldata[plr[myplr]._pRSpell].sTownSpell)
return FALSE;
for (i = 0; i < plr[myplr]._pNumInv; i++) {
if (plr[myplr].InvList[i]._itype != ITYPE_NONE
&& (plr[myplr].InvList[i]._iMiscId == IMISC_SCROLL || plr[myplr].InvList[i]._iMiscId == IMISC_SCROLLT)
&& plr[myplr].InvList[i]._iSpell == plr[myplr]._pRSpell) {
return TRUE;
}
}
for (i = 0; i < MAXBELTITEMS; i++) {
if (plr[myplr].SpdList[i]._itype != ITYPE_NONE
&& (plr[myplr].SpdList[i]._iMiscId == IMISC_SCROLL || plr[myplr].SpdList[i]._iMiscId == IMISC_SCROLLT)
&& plr[myplr].SpdList[i]._iSpell == plr[myplr]._pRSpell) {
return TRUE;
}
}
return FALSE;
}
void UseStaffCharge(int pnum)
{
if (plr[pnum].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE
&& (plr[pnum].InvBody[INVLOC_HAND_LEFT]._iMiscId == IMISC_STAFF
#ifdef HELLFIRE
|| plr[myplr].InvBody[INVLOC_HAND_LEFT]._iMiscId == IMISC_UNIQUE // BUGFIX: myplr->pnum
#endif
)
&& plr[pnum].InvBody[INVLOC_HAND_LEFT]._iSpell == plr[pnum]._pRSpell
&& plr[pnum].InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
plr[pnum].InvBody[INVLOC_HAND_LEFT]._iCharges--;
CalcPlrStaff(pnum);
}
}
BOOL UseStaff()
{
if (pcurs == CURSOR_HAND) {
if (plr[myplr].InvBody[INVLOC_HAND_LEFT]._itype != ITYPE_NONE
#ifdef HELLFIRE
&& (plr[myplr].InvBody[INVLOC_HAND_LEFT]._iMiscId == IMISC_STAFF || plr[myplr].InvBody[INVLOC_HAND_LEFT]._iMiscId == IMISC_UNIQUE)
#else
&& plr[myplr].InvBody[INVLOC_HAND_LEFT]._iMiscId == IMISC_STAFF
#endif
&& plr[myplr].InvBody[INVLOC_HAND_LEFT]._iSpell == plr[myplr]._pRSpell
&& plr[myplr].InvBody[INVLOC_HAND_LEFT]._iCharges > 0) {
return TRUE;
}
}
return FALSE;
}
void StartGoldDrop()
{
initialDropGoldIndex = pcursinvitem;
if (pcursinvitem <= INVITEM_INV_LAST)
initialDropGoldValue = plr[myplr].InvList[pcursinvitem - INVITEM_INV_FIRST]._ivalue;
else
initialDropGoldValue = plr[myplr].SpdList[pcursinvitem - INVITEM_BELT_FIRST]._ivalue;
dropGoldFlag = TRUE;
dropGoldValue = 0;
if (talkflag)
control_reset_talk();
}
BOOL UseInvItem(int pnum, int cii)
{
int c, idata;
ItemStruct *Item;
BOOL speedlist;
if (plr[pnum]._pInvincible && plr[pnum]._pHitPoints == 0 && pnum == myplr)
return TRUE;
if (pcurs != CURSOR_HAND)
return TRUE;
if (stextflag != STORE_NONE)
return TRUE;
if (cii <= INVITEM_HAND_RIGHT) // BUGFIX: should be `cii < INVITEM_INV_FIRST`, was `cii <= INVITEM_HAND_RIGHT`.
return FALSE;
if (cii <= INVITEM_INV_LAST) {
c = cii - INVITEM_INV_FIRST;
Item = &plr[pnum].InvList[c];
speedlist = FALSE;
} else {
if (talkflag)
return TRUE;
c = cii - INVITEM_BELT_FIRST;
Item = &plr[pnum].SpdList[c];
speedlist = TRUE;
}
switch (Item->IDidx) {
case IDI_MUSHROOM:
sfxdelay = 10;
#ifndef SPAWN
if (plr[pnum]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR95;
} else if (plr[pnum]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE95;
} else if (plr[pnum]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE95;
}
#ifdef HELLFIRE
else if (plr[pnum]._pClass == PC_MONK) {
sfxdnum = PS_MONK95;
} else if (plr[pnum]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE95;
} else if (plr[pnum]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR95;
}
#endif
#endif
return TRUE;
case IDI_FUNGALTM:
PlaySFX(IS_IBOOK);
sfxdelay = 10;
if (plr[pnum]._pClass == PC_WARRIOR) {
sfxdnum = PS_WARR29;
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
sfxdnum = PS_ROGUE29;
} else if (plr[pnum]._pClass == PC_SORCERER) {
sfxdnum = PS_MAGE29;
#endif
#ifdef HELLFIRE
} else if (plr[pnum]._pClass == PC_MONK) {
sfxdnum = PS_MONK29;
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_BARD) {
sfxdnum = PS_ROGUE29;
#endif
} else if (plr[pnum]._pClass == PC_BARBARIAN) {
sfxdnum = PS_WARR29;
#endif
}
return TRUE;
}
if (!AllItemsList[Item->IDidx].iUsable)
return FALSE;
if (!Item->_iStatFlag) {
if (plr[pnum]._pClass == PC_WARRIOR) {
PlaySFX(PS_WARR13);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_ROGUE) {
PlaySFX(PS_ROGUE13);
} else if (plr[pnum]._pClass == PC_SORCERER) {
PlaySFX(PS_MAGE13);
#endif
#ifdef HELLFIRE
} else if (plr[pnum]._pClass == PC_MONK) {
PlaySFX(PS_MONK13);
#ifndef SPAWN
} else if (plr[pnum]._pClass == PC_BARD) {
PlaySFX(PS_ROGUE13);
#endif
} else if (plr[pnum]._pClass == PC_BARBARIAN) {
PlaySFX(PS_WARR13);
#endif
}
return TRUE;
}
if (Item->_iMiscId == IMISC_NONE && Item->_itype == ITYPE_GOLD) {
StartGoldDrop();
return TRUE;
}
if (dropGoldFlag) {
dropGoldFlag = FALSE;
dropGoldValue = 0;
}
if (Item->_iMiscId == IMISC_SCROLL && currlevel == 0 && !spelldata[Item->_iSpell].sTownSpell) {
return TRUE;
}
if (Item->_iMiscId == IMISC_SCROLLT && currlevel == 0 && !spelldata[Item->_iSpell].sTownSpell) {
return TRUE;
}
#ifdef HELLFIRE
if (Item->_iMiscId > IMISC_RUNEFIRST && Item->_iMiscId < IMISC_RUNELAST && currlevel == 0) {
return TRUE;
}
#endif
idata = ItemCAnimTbl[Item->_iCurs];
if (Item->_iMiscId == IMISC_BOOK)
PlaySFX(IS_RBOOK);
else if (pnum == myplr)
PlaySFX(ItemInvSnds[idata]);
UseItem(pnum, Item->_iMiscId, Item->_iSpell);
if (speedlist) {
#ifdef HELLFIRE
if (plr[pnum].SpdList[c]._iMiscId == IMISC_NOTE) {
InitQTextMsg(322);
invflag = FALSE;
return TRUE;
}
#endif
RemoveSpdBarItem(pnum, c);
return TRUE;
} else {
if (plr[pnum].InvList[c]._iMiscId == IMISC_MAPOFDOOM)
return TRUE;
#ifdef HELLFIRE
if (plr[pnum].InvList[c]._iMiscId == IMISC_NOTE) {
InitQTextMsg(322);
invflag = FALSE;
return TRUE;
}
#endif
RemoveInvItem(pnum, c);
}
return TRUE;
}
void DoTelekinesis()
{
if (pcursobj != -1)
NetSendCmdParam1(TRUE, CMD_OPOBJT, pcursobj);
if (pcursitem != -1)
NetSendCmdGItem(TRUE, CMD_REQUESTAGITEM, myplr, myplr, pcursitem);
if (pcursmonst != -1 && !M_Talker(pcursmonst) && monster[pcursmonst].mtalkmsg == 0)
NetSendCmdParam1(TRUE, CMD_KNOCKBACK, pcursmonst);
NewCursor(CURSOR_HAND);
}
int CalculateGold(int pnum)
{
int i, gold;
gold = 0;
for (i = 0; i < MAXBELTITEMS; i++) {
if (plr[pnum].SpdList[i]._itype == ITYPE_GOLD) {
gold += plr[pnum].SpdList[i]._ivalue;
force_redraw = 255;
}
}
for (i = 0; i < plr[pnum]._pNumInv; i++) {
if (plr[pnum].InvList[i]._itype == ITYPE_GOLD)
gold += plr[pnum].InvList[i]._ivalue;
}
return gold;
}
BOOL DropItemBeforeTrig()
{
if (TryInvPut()) {
NetSendCmdPItem(TRUE, CMD_PUTITEM, cursmx, cursmy);
NewCursor(CURSOR_HAND);
return TRUE;
}
return FALSE;
}