/*-----------------------------------------------------------------------** ** Diablo ** ** Invetory file ** ** (C)1995 Condor, Inc. All rights reserved. ** **-----------------------------------------------------------------------** ** $Header: /Diablo/INV.CPP 11 2/24/97 7:53p Jmcreynolds $ **-----------------------------------------------------------------------** ** ** File Routines **-----------------------------------------------------------------------*/ #include "diablo.h" #pragma hdrstop #include "sound.h" #include "gendung.h" //required for player.h #include "items.h" #include "itemdat.h" #include "player.h" #include "inv.h" #include "engine.h" #include "lighting.h" #include "cursor.h" #include "scrollrt.h" #include "control.h" #include "monster.h" #include "effects.h" #include "spelldat.h" #include "spells.h" #include "objects.h" #include "quests.h" #include "doom.h" #include "msg.h" #include "stores.h" #include "missiles.h" #include "minitext.h" #include "textdat.h" #include "multi.h" ItemStruct *PlrHasItem(int pnum, int item, int &i); void SetupItem(int); void CheckItemStats(int pnum); void DeleteItem(int ii, int i); void OpenNest(); void OpenCrypt(); void InitTownTriggers(); // JMM.PATCH1.2.22.97 void sysmsg_add_string(const char * pszMsg); // END.JMM.PATCH1.2.22.97 /*-----------------------------------------------------------------------** ** Global variables **-----------------------------------------------------------------------*/ BOOL invflag; BOOL drawsbarflag; /*-----------------------------------------------------------------------** ** private **-----------------------------------------------------------------------*/ // Offscreen control panel buffer static BYTE *pInvCels; int AP2x2Tbl[10] = { 8, 28, 6, 26, 4, 24, 2, 22, 0, 20 }; // InvRect defines lower-left corners of inventory screen rectangles static const POINT InvRect[] = { { 452, 31 },{ 480, 31 }, // Head (0-3) { 452, 59 },{ 480, 59 }, { 365,205 }, // Ring 1 (4) { 567,205 }, // Ring 2 (5) { 524, 59 }, // Neck (6) { 337,104 },{ 366,104 }, // Left Hand (7-12) { 337,132 },{ 366,132 }, { 337,160 },{ 366,160 }, { 567,104 },{ 596,104 }, // Right Hand (13-18) { 567,132 },{ 596,132 }, { 567,160 },{ 596,160 }, { 452,104 },{ 480,104 }, // Body (19-24) { 452,132 },{ 480,132 }, { 452,160 },{ 480,160 }, // Inv (25-64) { 337,250 },{ 366,250 },{ 394,250 },{ 423,250 },{ 451,250 },{ 480,250 },{ 509,250 },{ 538,250 },{ 567,250 },{ 596,250 }, { 337,279 },{ 366,279 },{ 394,279 },{ 423,279 },{ 451,279 },{ 480,279 },{ 509,279 },{ 538,279 },{ 567,279 },{ 596,279 }, { 337,308 },{ 366,308 },{ 394,308 },{ 423,308 },{ 451,308 },{ 480,308 },{ 509,308 },{ 538,308 },{ 567,308 },{ 596,308 }, { 337,336 },{ 366,336 },{ 394,336 },{ 423,336 },{ 451,336 },{ 480,336 },{ 509,336 },{ 538,336 },{ 567,336 },{ 596,336 }, // Speed Bar(65-72) { 205,385 },{ 234,385 },{ 263,385 },{ 292,385 },{ 321,385 },{ 350,385 },{ 379,385 },{ 408,385 } }; #define INVRECTS (sizeof(InvRect) / sizeof(InvRect[0])) /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ void FreeInvGFX() { DiabloFreePtr (pInvCels); } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ void InitInv() { app_assert(! pInvCels); if (plr[myplr]._pClass == CLASS_WARRIOR) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv.CEL",NULL,'INVC'); #if !IS_VERSION(SHAREWARE) else if (plr[myplr]._pClass == CLASS_ROGUE) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_rog.CEL",NULL,'INVC'); else if (plr[myplr]._pClass == CLASS_SORCEROR) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_Sor.CEL",NULL,'INVC'); else if (plr[myplr]._pClass == CLASS_MONK) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_Sor.CEL",NULL,'INVC'); // GWP Fix this else if (plr[myplr]._pClass == CLASS_BARD) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv_rog.CEL",NULL,'INVC'); // GWP Fix this else if (plr[myplr]._pClass == CLASS_BARBARIAN) pInvCels = LoadFileInMemSig("Data\\Inv\\Inv.CEL",NULL,'INVC'); // GWP Fix this #endif invflag = FALSE; drawsbarflag = FALSE; } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ void ChangeBackground(int x, int y, int w, int h) { BYTE *p; app_assert(gpBuffer); p = gpBuffer + nBuffWTbl[y] + x; __asm { mov edi,dword ptr [p] xor edx,edx xor ebx,ebx mov dx,word ptr [h] mov bx,word ptr [w] _YLp: mov ecx,ebx _XLp: mov al,byte ptr [edi] cmp al,176 jb _Skip2 cmp al,191 ja _Try2 sub al,16 jmp _Save _Try2: cmp al,240 jb _Skip2 sub al,80 _Save: mov byte ptr [edi],al _Skip2: inc edi loop _XLp sub edi,768 sub edi,ebx dec edx jnz _YLp } } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ #define INVOCLR 197 #define INVOMCLR 181 #define INVOICLR 229 extern "C" { extern BYTE gbHudAnimateActive; extern BYTE gbHudPotionHealthTable[4][256]; extern BYTE gbHudPotionManaTable[4][256]; extern BYTE gbHudPotionRejuvTable[4][256]; } #define HUDPOT_NONE 0 #define HUDPOT_HEALTH 1 #define HUDPOT_MANA 2 #define HUDPOT_REJUV 3 /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ static int HudPotionKind(ItemStruct *item) { switch (item->_iMiscId) { case IMID_PHEAL: case IMID_PLHEAL: case IMID_PSHEAL: case IMID_PDHEAL: return HUDPOT_HEALTH; case IMID_PMANA: case IMID_PFMANA: return HUDPOT_MANA; case IMID_REJUV: case IMID_FREJUV: return HUDPOT_REJUV; default: return HUDPOT_NONE; } } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ static BYTE *HudPotionTable(int kind, int phase) { phase &= 3; if (kind == HUDPOT_HEALTH) return gbHudPotionHealthTable[phase]; if (kind == HUDPOT_MANA) return gbHudPotionManaTable[phase]; return gbHudPotionRejuvTable[phase]; } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ static void HudAnimatePotionIcon(int x, int y, int w, int h, int kind, int salt) { int row, col; int xclip, wclip; int yy; BYTE *p; BYTE *table; if (kind == HUDPOT_NONE || !gbHudAnimateActive || gpBuffer == NULL) return; xclip = x; wclip = w; if (xclip < 0) { wclip += xclip; xclip = 0; } if (xclip + wclip > BUFFERX) wclip = BUFFERX - xclip; if (wclip <= 0) return; table = HudPotionTable(kind, (GetTickCount() / 115) + salt); for (row = 0; row < h; row++) { yy = y - row; if (yy < 0 || yy >= BUFFERY) continue; p = gpBuffer + nBuffWTbl[yy] + xclip; for (col = 0; col < wclip; col++) p[col] = table[p[col]]; } } void DrawInv() { int i, f, w, ii, xx, yy, oc; BYTE *pB; BOOL invtest[MAXINV]; // @@@@ Dave test app_assert(gpBuffer); DrawCel(384, 511, pInvCels, 1, 320); if (plr[myplr].HeadItem._itype != -1) { ChangeBackground(517, 219, 56, 56); f = plr[myplr].HeadItem._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == INVLOC_HEAD) { oc = INVOCLR; if (plr[myplr].HeadItem._iMagical) oc = INVOMCLR; if (!plr[myplr].HeadItem._iStatFlag) oc = INVOICLR; if (f <= ICLAST ) OutlineSlabCel(oc, 517, 219, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, 517, 219, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].HeadItem._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(517, 219, pCursCels, f, w, 0, 8); else DrawSlabCel(517, 219, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(517, 219, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(517, 219, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } } if (plr[myplr].Ring1Item._itype != -1) { ChangeBackground(432, 365, 28, 28); f = plr[myplr].Ring1Item._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == INVLOC_RING1) { oc = INVOCLR; if (plr[myplr].Ring1Item._iMagical) oc = INVOMCLR; if (!plr[myplr].Ring1Item._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, 432, 365, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, 432, 365, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].Ring1Item._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(432, 365, pCursCels, f, w, 0, 8); else DrawSlabCel(432, 365, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(432, 365, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(432, 365, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } } if (plr[myplr].Ring2Item._itype != -1) { ChangeBackground(633, 365, 28, 28); f = plr[myplr].Ring2Item._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == INVLOC_RING2) { oc = INVOCLR; if (plr[myplr].Ring2Item._iMagical) oc = INVOMCLR; if (!plr[myplr].Ring2Item._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, 633, 365, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, 633, 365, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].Ring2Item._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(633, 365, pCursCels, f, w, 0, 8); else DrawSlabCel(633, 365, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(633, 365, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(633, 365, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } } if (plr[myplr].NeckItem._itype != -1) { ChangeBackground(589, 220, 28, 28); f = plr[myplr].NeckItem._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == INVLOC_NECK) { oc = INVOCLR; if (plr[myplr].NeckItem._iMagical) oc = INVOMCLR; if (!plr[myplr].NeckItem._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, 589, 220, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, 589, 220, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].NeckItem._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(589, 220, pCursCels, f, w, 0, 8); else DrawSlabCel(589, 220, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(589, 220, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(589, 220, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } } if (plr[myplr].Hand1Item._itype != -1) { ChangeBackground(401, 320, 56, 84); f = plr[myplr].Hand1Item._iCurs + ICSTART; w = CursorWidth[f]; if (w == 28) xx = 415; else xx = 401; if (CursorHeight[f] == 84) yy = 320; else yy = 306; if (cursinvitem == INVLOC_HAND1) { oc = INVOCLR; if (plr[myplr].Hand1Item._iMagical) oc = INVOMCLR; if (!plr[myplr].Hand1Item._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, xx, yy, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, xx, yy, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].Hand1Item._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(xx, yy, pCursCels, f, w, 0, 8); else DrawSlabCel(xx, yy, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(xx, yy, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(xx, yy, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } if (plr[myplr].Hand1Item._iLoc == IL_2HAND && !(plr[myplr]._pClass == CLASS_BARBARIAN && (plr[myplr].Hand1Item._itype == IT_SWORD || plr[myplr].Hand1Item._itype == IT_MACE) ) ) { ChangeBackground(631, 320, 56, 84); nLVal = 0; nTrans = TRUE; if (w == 28) pB = gpBuffer + 246405; else pB = gpBuffer + 246391; if (f <= ICLAST) TDrawSlabCelPL (pB, pCursCels, f, w, 0, 8); else TDrawSlabCelPL (pB, pCursCels2, f - ICLAST, w, 0, 8); nTrans = FALSE; } } if (plr[myplr].Hand2Item._itype != -1) { ChangeBackground(631, 320, 56, 84); f = plr[myplr].Hand2Item._iCurs + ICSTART; w = CursorWidth[f]; if (w == 28) xx = 645; else xx = 633; if (CursorHeight[f] == 84) yy = 320; else yy = 306; if (cursinvitem == INVLOC_HAND2) { oc = INVOCLR; if (plr[myplr].Hand2Item._iMagical) oc = INVOMCLR; if (!plr[myplr].Hand2Item._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, xx, yy, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, xx, yy, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].Hand2Item._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(xx, yy, pCursCels, f, w, 0, 8); else DrawSlabCel(xx, yy, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(xx, yy, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(xx, yy, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } } if (plr[myplr].BodyItem._itype != -1) { ChangeBackground(517, 320, 56, 84); f = plr[myplr].BodyItem._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == INVLOC_BODY) { oc = INVOCLR; if (plr[myplr].BodyItem._iMagical) oc = INVOMCLR; if (!plr[myplr].BodyItem._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, 517, 320, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, 517, 320, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].BodyItem._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(517, 320, pCursCels, f, w, 0, 8); else DrawSlabCel(517, 320, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(517, 320, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(517, 320, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } } for (i = 0; i < MAXINV; i++) { invtest[i] = FALSE; if (plr[myplr].InvGrid[i] != 0) ChangeBackground(InvRect[i+25].x + 64, InvRect[i+25].y + 159, 28, 28); } for (i = 0; i < MAXINV; i++) { if (plr[myplr].InvGrid[i] > 0) { app_assert(!invtest[i]); invtest[i] = TRUE; app_assert(plr[myplr].InvGrid[i] <= plr[myplr]._pNumInv); ii = plr[myplr].InvGrid[i] - 1; f = plr[myplr].InvList[ii]._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == (ii + NUM_INVLOC)) { oc = INVOCLR; if (plr[myplr].InvList[ii]._iMagical) oc = INVOMCLR; if (!plr[myplr].InvList[ii]._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].InvList[ii]._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels, f, w, 0, 8); else DrawSlabCel(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(InvRect[i+25].x + 64, InvRect[i+25].y + 159, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } HudAnimatePotionIcon(InvRect[i+25].x + 64, InvRect[i+25].y + 159, w, CursorHeight[f], HudPotionKind(&plr[myplr].InvList[ii]), i); } } } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ void DrawSpdBar() { int i, f, w, oc, idata; long poffset; if (talkflag) return; CopyCtrlPan(205, 21, 232, 28, 269, 517); for (i = 0; i < MAXSPD; i++) { if (plr[myplr].SpdList[i]._itype != -1) { ChangeBackground(InvRect[i+65].x + 64, InvRect[i+65].y + 159, 28, 28); f = plr[myplr].SpdList[i]._iCurs + ICSTART; w = CursorWidth[f]; if (cursinvitem == (i + 47)) { oc = INVOCLR; if (plr[myplr].SpdList[i]._iMagical) oc = INVOMCLR; if (!plr[myplr].SpdList[i]._iStatFlag) oc = INVOICLR; if (f <= ICLAST) OutlineSlabCel(oc, InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels, f, w, 0, 8); else OutlineSlabCel(oc, InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels2, f - ICLAST, w, 0, 8); } if (plr[myplr].SpdList[i]._iStatFlag) { app_assert(pCursCels); if (f <= ICLAST) DrawSlabCel(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels, f, w, 0, 8); else DrawSlabCel(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels2, f - ICLAST, w, 0, 8); } else { if (f <= ICLAST) DrawSlabCelI(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels, f, w, 0, 8, LIGHT_INFRA); else DrawSlabCelI(InvRect[i+65].x + 64, InvRect[i+65].y + 159, pCursCels2, f - ICLAST, w, 0, 8, LIGHT_INFRA); } HudAnimatePotionIcon(InvRect[i+65].x + 64, InvRect[i+65].y + 159, w, CursorHeight[f], HudPotionKind(&plr[myplr].SpdList[i]), i + 8); idata = plr[myplr].SpdList[i].IDidx; if (AllItemsList[idata].iUsable && plr[myplr].SpdList[i]._iStatFlag && (plr[myplr].SpdList[i]._itype != IT_GOLD)) { BYTE c = char2print(i + '1'); c = fonttrans[c]; poffset = nBuffWTbl[InvRect[i+65].y + 159] + InvRect[i+65].x + 92 - fontkern[c]; DrawPanelFont(poffset, c, ICOLOR_WHITE); } } } } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL AutoPlace(int pnum, int ii, int sx, int sy, BOOL saveflag) { int i, j, xx, yy; BOOL done; done = TRUE; yy = (ii / 10) * 10; if (yy < 0) yy = 0; for (j = 0; (j < sy) && done; j++) { if (yy >= 40) 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)) { i = plr[pnum]._pNumInv; plr[pnum].InvList[i] = plr[pnum].HoldItem; plr[pnum]._pNumInv++; yy = (ii / 10) * 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; //Check InvList done = TRUE; yy = (ii / 10) * 10; if (yy < 0) yy = 0; for (j = 0; (j < sy) && done; j++) { if (yy >= 40) 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; } //Inventory is full so check SpdList if (!done) { if (sx > 1 || sy > 1) done = FALSE; else { for (i = 0; i < MAXSPD; i++) { if (plr[pnum].SpdList[i]._itype == -1) { done = TRUE; break; } } } } if ((done) && (saveflag)) { i = plr[pnum]._pNumInv; plr[pnum].InvList[i] = plr[pnum].HoldItem; plr[pnum]._pNumInv++; yy = (ii / 10) * 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 i, ii, xx, yy; long gt; BOOL done; // Check if it can be added on to a gold location done = FALSE; for (i = 0; (i < plr[pnum]._pNumInv) && (!done); i++) { if (plr[pnum].InvList[i]._itype == IT_GOLD) { gt = plr[pnum].HoldItem._ivalue + plr[pnum].InvList[i]._ivalue; if (gt <= GOLD_VMAX) { plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; if (gt >= GOLD_VT2) { plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; } else { if (gt <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; } plr[pnum]._pGold = CalculateGold(pnum); plr[pnum].HoldItem._ivalue = 0; done = TRUE; } else if (plr[pnum].InvList[i]._ivalue < GOLD_VMAX) { // There's room, add to existing gold. int const depositGold = GOLD_VMAX - plr[pnum].InvList[i]._ivalue; plr[pnum].InvList[i]._ivalue = GOLD_VMAX; plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; plr[pnum].HoldItem._ivalue -= depositGold; // Just in case. if (plr[pnum].HoldItem._ivalue < 0) { plr[pnum].HoldItem._ivalue = 0; done = TRUE; } GetPlrHandSeed(&plr[pnum].HoldItem); SetDropGoldCursor(pnum); plr[pnum]._pGold = CalculateGold(pnum); } } } #if 0 // If there's still gold in my hand, try to place it in more empty slots if (!done) { for (i = 0; (i < plr[pnum]._pNumInv) && (!done); i++) { if (plr[pnum].InvList[i]._itype == IT_GOLD) { if (plr[pnum].InvList[i]._ivalue < GOLD_VMAX) { gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; if (gt <= GOLD_VMAX) { plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; if (gt >= GOLD_VT2) { plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; } else { if (gt <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; } plr[pnum]._pGold = CalculateGold(pnum); done = TRUE; } } } } } #endif // Lastly check for any empty space to drop put gold into if (!done) { for (ii = MAXINV-1; (ii >= 0) && (!done); --ii) { yy = (ii / 10) * 10; xx = ii % 10; if (plr[pnum].InvGrid[xx+yy] == 0) { i = plr[pnum]._pNumInv; plr[pnum].InvList[i] = plr[pnum].HoldItem; // struct copy. plr[pnum]._pNumInv++; plr[pnum].InvGrid[xx+yy] = plr[pnum]._pNumInv; if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) { plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; } else { if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; } if (plr[pnum].HoldItem._ivalue > GOLD_VMAX) { plr[pnum].HoldItem._ivalue -= GOLD_VMAX; GetPlrHandSeed(&plr[pnum].HoldItem); // We have to set the inventory value because we did a struct copy above. plr[pnum].InvList[i]._ivalue = GOLD_VMAX; } else { done = TRUE; plr[pnum].HoldItem._ivalue = 0; plr[pnum]._pGold = CalculateGold(pnum); SetCursor(GLOVE_CURS); } } } } return(done); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL WeaponAutoPlace(int pnum) { if (plr[pnum]._pClass == CLASS_MONK) // Monks don't autoequip weapons return FALSE; // (open-hand is often better) if (plr[pnum].HoldItem._iLoc == IL_2HAND && !(plr[pnum]._pClass == CLASS_BARBARIAN && (plr[pnum].HoldItem._itype == IT_SWORD || plr[pnum].HoldItem._itype == IT_MACE) ) ) { if ((plr[pnum].Hand1Item._itype != -1) || (plr[pnum].Hand2Item._itype != -1)) return(FALSE); NetSendCmdChItem(TRUE, INVLOC_HAND1); plr[pnum].Hand1Item = plr[pnum].HoldItem; return(TRUE); } else { if (plr[pnum]._pClass != CLASS_BARD) { if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iClass == IC_WEAP)) return(FALSE); if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._iClass == IC_WEAP)) return(FALSE); } if (plr[pnum].Hand1Item._itype == -1) { NetSendCmdChItem(TRUE, INVLOC_HAND1); plr[pnum].Hand1Item = plr[pnum].HoldItem; } else { if ((plr[pnum].Hand2Item._itype == -1) && (plr[pnum].Hand1Item._iLoc != IL_2HAND)) { NetSendCmdChItem(TRUE, INVLOC_HAND2); plr[pnum].Hand2Item = plr[pnum].HoldItem; } else return(FALSE); } return(TRUE); } } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ int SwapItem(ItemStruct *a, ItemStruct *b) { ItemStruct h; h = *a; *a = *b; *b = h; return(h._iCurs + ICSTART); } /*-----------------------------------------------------------------------* ** Place cursor item into inventory window **-----------------------------------------------------------------------*/ void CheckInvPaste(int pnum, int mx, int my) { int r; int i, j, xx, yy, ii; int il, cn, it, iv, ig; long gt; ItemStruct tempitem; SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); int cx = mx + (icursW>>1); // center of cursor graphic int cy = my + (icursH>>1); int const sx = icursW28; // size of cursor, in 28x28 blocks int const sy = icursH28; BOOL done = FALSE; for (r = 0; (r < INVRECTS) && (!done); r++) { if ((cx >= InvRect[r].x) && (cx < InvRect[r].x + 28) && (cy >= InvRect[r].y - 29) && (cy < InvRect[r].y)) { done = TRUE; r--; } // shift for inv grid if (r == 24) { if (!(sx & 1)) cx -= 14; if (!(sy & 1)) cy -= 14; } // shift back y for spd bar if (r == 64) { if (!(sy & 1)) cy += 14; } } if (done) { // Check if correct item location type il = IL_INV; if ((r >= 0) && (r <= 3)) il = IL_HEAD; if ((r >= 4) && (r <= 5)) il = IL_RING; if (r == 6) il = IL_NECK; if ((r >= 7) && (r <= 18)) il = IL_HAND; if ((r >= 19) && (r <= 24)) il = IL_BODY; if ((r >= 65) && (r <= 72)) il = IL_SPD; done = FALSE; if (plr[pnum].HoldItem._iLoc == il) done = TRUE; if ((il == IL_HAND) && (plr[pnum].HoldItem._iLoc == IL_2HAND)) { // Hack so placement will work for a two handed weapon. if (plr[pnum]._pClass == CLASS_BARBARIAN && (plr[pnum].HoldItem._itype == IT_SWORD || plr[pnum].HoldItem._itype == IT_MACE) ) { il = IL_HAND; } else { il = IL_2HAND; } done = TRUE; } if ((plr[pnum].HoldItem._iLoc == IL_INV) && (il == IL_SPD) && (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 == IT_GOLD) done = FALSE; } if (il == IL_INV) { ii = r - 25; iv = 0; done = TRUE; if (plr[pnum].HoldItem._itype == IT_GOLD) { yy = (ii / 10) * 10; xx = ii % 10; if (plr[pnum].InvGrid[xx+yy] != 0) { ig = plr[pnum].InvGrid[xx+yy]; if (ig > 0) { if (plr[pnum].InvList[ig-1]._itype != IT_GOLD) iv = ig; } else iv = -ig; } } else { yy = ((ii / 10) - ((sy - 1) >> 1)) * 10; if (yy < 0) yy = 0; for (j = 0; (j < sy) && done; j++) { if (yy >= 40) 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) { ig = plr[pnum].InvGrid[xx+yy]; if (ig < 0) ig = -ig; if (iv != 0) { if (iv != ig) done = FALSE; } else iv = ig; } } xx++; } yy+=10; } } } // Do I have the min stats to place this item? if ((done) && (il != IL_INV) && (il != IL_SPD) && (!plr[pnum].HoldItem._iStatFlag)) { done = FALSE; if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR13); #if !IS_VERSION(SHAREWARE) else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE13); else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE13); else if (plr[pnum]._pClass == CLASS_MONK) PlaySFX(PS_MONK13); else if (plr[pnum]._pClass == CLASS_BARD) PlaySFX(PS_BARD13); else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN13); #endif } if (done) { it = ItemCAnimTbl[plr[pnum].HoldItem._iCurs]; if(pnum == myplr) PlaySFX(ItemInvSnds[it]); cn = GLOVE_CURS; // Go back to gaunts unless something else there switch (il) { case IL_HEAD : NetSendCmdChItem(FALSE, INVLOC_HEAD); if (plr[pnum].HeadItem._itype == -1) plr[pnum].HeadItem = plr[pnum].HoldItem; else cn = SwapItem(&plr[pnum].HeadItem, &plr[pnum].HoldItem); break; case IL_RING : if (r == 4) { NetSendCmdChItem(FALSE, INVLOC_RING1); if (plr[pnum].Ring1Item._itype == -1) plr[pnum].Ring1Item = plr[pnum].HoldItem; else cn = SwapItem(&plr[pnum].Ring1Item, &plr[pnum].HoldItem); } else { NetSendCmdChItem(FALSE, INVLOC_RING2); if (plr[pnum].Ring2Item._itype == -1) plr[pnum].Ring2Item = plr[pnum].HoldItem; else cn = SwapItem(&plr[pnum].Ring2Item, &plr[pnum].HoldItem); } break; case IL_NECK: NetSendCmdChItem(FALSE, INVLOC_NECK); if (plr[pnum].NeckItem._itype == -1) plr[pnum].NeckItem = plr[pnum].HoldItem; else cn = SwapItem(&plr[pnum].NeckItem, &plr[pnum].HoldItem); break; case IL_HAND : if (r <= 12) { if (plr[pnum].Hand1Item._itype == -1) { if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._iClass == plr[pnum].HoldItem._iClass) && !(plr[pnum]._pClass == CLASS_BARD && plr[pnum].Hand2Item._iClass == IC_WEAP && plr[pnum].HoldItem._iClass == IC_WEAP) ) { NetSendCmdChItem(FALSE, INVLOC_HAND2); cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); } else { NetSendCmdChItem(FALSE, INVLOC_HAND1); plr[pnum].Hand1Item = plr[pnum].HoldItem; } } else { if ((plr[pnum].Hand2Item._itype != -1) && (plr[pnum].Hand2Item._iClass == plr[pnum].HoldItem._iClass) && !(plr[pnum]._pClass == CLASS_BARD && plr[pnum].Hand2Item._iClass == IC_WEAP && plr[pnum].HoldItem._iClass == IC_WEAP) ) { NetSendCmdChItem(FALSE, INVLOC_HAND2); cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); } else { NetSendCmdChItem(FALSE, INVLOC_HAND1); cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); } } } else { if (plr[pnum].Hand2Item._itype == -1) { if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iLoc == IL_2HAND && !(plr[pnum]._pClass == CLASS_BARBARIAN && (plr[pnum].Hand1Item._itype == IT_SWORD || plr[pnum].Hand1Item._itype == IT_MACE ) ) ) ) { NetSendCmdChItem(FALSE, INVLOC_HAND1); SwapItem(&plr[pnum].Hand2Item, &plr[pnum].Hand1Item); cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); } else { if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iClass == plr[pnum].HoldItem._iClass) && !(plr[pnum]._pClass == CLASS_BARD && plr[pnum].Hand1Item._iClass == IC_WEAP && plr[pnum].HoldItem._iClass == IC_WEAP) ) { NetSendCmdChItem(FALSE, INVLOC_HAND1); cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); } else { NetSendCmdChItem(FALSE, INVLOC_HAND2); plr[pnum].Hand2Item = plr[pnum].HoldItem; } } } else { if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iClass == plr[pnum].HoldItem._iClass && !(plr[pnum]._pClass == CLASS_BARD && plr[pnum].Hand1Item._iClass == IC_WEAP && plr[pnum].HoldItem._iClass == IC_WEAP) ) ) { NetSendCmdChItem(FALSE, INVLOC_HAND1); cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); } else { NetSendCmdChItem(FALSE, INVLOC_HAND2); cn = SwapItem(&plr[pnum].Hand2Item, &plr[pnum].HoldItem); } } } break; case IL_2HAND : NetSendCmdDelItem(FALSE, INVLOC_HAND2); if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand2Item._itype != -1)) { tempitem = plr[pnum].HoldItem; if (plr[pnum].Hand2Item._itype == IT_SHIELD) { plr[pnum].HoldItem = plr[pnum].Hand2Item; } else { plr[pnum].HoldItem = plr[pnum].Hand1Item; } if (pnum == myplr) { SetCursor(plr[pnum].HoldItem._iCurs + ICSTART); } else { SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); } BOOL done2h(FALSE); for (i = 0; (i < MAXINV) && (!done2h); ++i) { done2h = AutoPlace(pnum, i, icursW28, icursH28, TRUE); } plr[pnum].HoldItem = tempitem; if (pnum == myplr) SetCursor(plr[pnum].HoldItem._iCurs + ICSTART); else SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); if (done2h) { if (plr[pnum].Hand2Item._itype == IT_SHIELD) { plr[pnum].Hand2Item._itype = -1; } else { plr[pnum].Hand1Item._itype = -1; } } else return; } if ((plr[pnum].Hand1Item._itype == -1) && (plr[pnum].Hand2Item._itype == -1)) { NetSendCmdChItem(FALSE, INVLOC_HAND1); plr[pnum].Hand1Item = plr[pnum].HoldItem; } else { NetSendCmdChItem(FALSE, INVLOC_HAND1); if (plr[pnum].Hand1Item._itype == -1) SwapItem(&plr[pnum].Hand1Item, &plr[pnum].Hand2Item); cn = SwapItem(&plr[pnum].Hand1Item, &plr[pnum].HoldItem); } if (plr[pnum].Hand1Item._itype == IT_STAFF) { if ((plr[pnum].Hand1Item._iSpell) && (plr[pnum].Hand1Item._iCharges > 0)) { plr[pnum]._pRSpell = plr[pnum].Hand1Item._iSpell; plr[pnum]._pRSplType = SPT_ITEM; force_redraw = FULLDRAW; } } break; case IL_BODY : NetSendCmdChItem(FALSE, INVLOC_BODY); if (plr[pnum].BodyItem._itype == -1) plr[pnum].BodyItem = plr[pnum].HoldItem; else cn = SwapItem(&plr[pnum].BodyItem, &plr[pnum].HoldItem); break; case IL_INV : // Gold is stackable if ((plr[pnum].HoldItem._itype == IT_GOLD) && (iv == 0)) { ii = r - 25; yy = (ii / 10) * 10; xx = ii % 10; // Empty (== 0) or gold (> 0) if (plr[pnum].InvGrid[xx+yy] > 0) { i = plr[pnum].InvGrid[xx+yy] - 1; gt = plr[pnum].InvList[i]._ivalue + plr[pnum].HoldItem._ivalue; // Gold total <= GOLD_VMAX then all done if (gt <= GOLD_VMAX) { plr[pnum].InvList[i]._ivalue += plr[pnum].HoldItem._ivalue; plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; if (gt >= GOLD_VT2) { plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; } else { if (gt <= GOLD_VT1) plr[pnum].InvList[i]._iCurs = ITEM_1GOLD; else plr[pnum].InvList[i]._iCurs = ITEM_3GOLD; } } else { // Fill as much as possible and keep holding extra gt = GOLD_VMAX - plr[pnum].InvList[i]._ivalue; plr[pnum]._pGold += gt; plr[pnum].HoldItem._ivalue -= gt; plr[pnum].InvList[i]._ivalue = GOLD_VMAX; plr[pnum].InvList[i]._iCurs = ITEM_5GOLD; if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) cn = ITEM_5GOLD + ICSTART; else { if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) cn = ITEM_1GOLD + ICSTART; else cn = ITEM_3GOLD + ICSTART; } } } else { // Place gold in empty spot ii = plr[pnum]._pNumInv; plr[pnum].InvList[ii] = plr[pnum].HoldItem; plr[pnum]._pNumInv++; plr[pnum].InvGrid[xx+yy] = plr[pnum]._pNumInv; plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; //Choose correct gold cursor gt = plr[pnum].HoldItem._ivalue; if (gt <= GOLD_VMAX) { if (gt >= GOLD_VT2) { plr[pnum].InvList[ii]._iCurs = ITEM_5GOLD; } else { if (gt <= GOLD_VT1) plr[pnum].InvList[ii]._iCurs = ITEM_1GOLD; else plr[pnum].InvList[ii]._iCurs = ITEM_3GOLD; } } else { plr[pnum].InvList[ii]._iCurs = ITEM_5GOLD; } } } else { // Item not gold if (iv == 0) { // No swaping item ii = plr[pnum]._pNumInv; plr[pnum].InvList[ii] = plr[pnum].HoldItem; plr[pnum]._pNumInv++; iv = plr[pnum]._pNumInv; } else { ii = iv-1; if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; cn = SwapItem(&plr[pnum].InvList[ii], &plr[pnum].HoldItem); if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold = CalculateGold(pnum); for (i = 0; i < MAXINV; i++) { if (plr[pnum].InvGrid[i] == iv) plr[pnum].InvGrid[i] = 0; if (plr[pnum].InvGrid[i] == -iv) plr[pnum].InvGrid[i] = 0; } } ii = r - 25; yy = ((ii / 10) - ((sy - 1) >> 1)) * 10; 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] = iv; else plr[pnum].InvGrid[xx+yy] = -iv; xx++; } yy+=10; } } break; case IL_SPD: ii = r - 65; // Gold is stackable if (plr[pnum].HoldItem._itype == IT_GOLD) { // Check if something is already there if (plr[pnum].SpdList[ii]._itype != -1) { if (plr[pnum].SpdList[ii]._itype == IT_GOLD) { gt = plr[pnum].SpdList[ii]._ivalue + plr[pnum].HoldItem._ivalue; // Gold total <= GOLD_VMAX then all done if (gt <= GOLD_VMAX) { plr[pnum].SpdList[ii]._ivalue += plr[pnum].HoldItem._ivalue; plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; if (gt >= GOLD_VT2) { plr[pnum].SpdList[ii]._iCurs = ITEM_5GOLD; } else { if (gt <= GOLD_VT1) plr[pnum].SpdList[ii]._iCurs = ITEM_1GOLD; else plr[pnum].SpdList[ii]._iCurs = ITEM_3GOLD; } } else { // Fill as much as possible and keep holding extra gt = GOLD_VMAX - plr[pnum].SpdList[ii]._ivalue; plr[pnum]._pGold += gt; plr[pnum].HoldItem._ivalue -= gt; plr[pnum].SpdList[ii]._ivalue = GOLD_VMAX; plr[pnum].SpdList[ii]._iCurs = ITEM_5GOLD; if (plr[pnum].HoldItem._ivalue >= GOLD_VT2) cn = ITEM_5GOLD + ICSTART; else { if (plr[pnum].HoldItem._ivalue <= GOLD_VT1) cn = ITEM_1GOLD + ICSTART; else cn = ITEM_3GOLD + ICSTART; } } } else { // Swap with non gold plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem); } } else { // Place gold in empty spot plr[pnum].SpdList[ii] = plr[pnum].HoldItem; plr[pnum]._pGold += plr[pnum].HoldItem._ivalue; } } else { // Not gold. Place or swap if (plr[pnum].SpdList[ii]._itype == -1) plr[pnum].SpdList[ii] = plr[pnum].HoldItem; else { cn = SwapItem(&plr[pnum].SpdList[ii], &plr[pnum].HoldItem); if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold = CalculateGold(pnum); } } drawsbarflag = TRUE; break; } CalcPlrInv(pnum,TRUE); if (pnum == myplr) { if (cn == GLOVE_CURS) SetCursorPos(MouseX + (cursW>>1),MouseY + (cursH>>1)); SetCursor(cn); } } } } /*-----------------------------------------------------------------------** ** Change items for another player **-----------------------------------------------------------------------*/ // drb.patch1.start.02/10/97 //void SyncInvPaste(int pnum, BYTE bLoc, int idx, WORD icreateinfo, int iseed) void SyncInvPaste(int pnum, BYTE bLoc, int idx, WORD icreateinfo, int iseed, BOOL Id) // drb.patch1.end.02/10/97 { // temp use the first slot to grab an item RecreateItem(TEMPAVAIL, idx, icreateinfo, iseed, 0); PlayerStruct * p = &plr[pnum]; p->HoldItem = item[TEMPAVAIL]; // drb.patch1.start.02/10/97 if (Id) p->HoldItem._iIdentified = TRUE; // drb.patch1.end.02/10/97 if (bLoc < NUM_INVLOC) { p->InvBody[bLoc] = p->HoldItem; if (bLoc == INVLOC_HAND1) { if (p->HoldItem._iLoc == IL_2HAND) p->Hand2Item._itype = -1; } else if (bLoc == INVLOC_HAND2) { if (p->HoldItem._iLoc == IL_2HAND) p->Hand1Item._itype = -1; } } CalcPlrInv(pnum,TRUE); } /*-----------------------------------------------------------------------** ** Pick up items from inventory window and set cursor appropriately **-----------------------------------------------------------------------*/ void CheckInvCut(int pnum, int mx, int my) { int r; BOOL done; int ii,iv,i; if (plr[pnum]._pmode > PM_WALK3) return; if (dropGoldFlag) { dropGoldFlag = FALSE; dropGoldValue = 0; } done = FALSE; for (r = 0; (r < INVRECTS) && (!done); r++) { if ((mx >= InvRect[r].x) && (mx < InvRect[r].x + 29) && (my >= InvRect[r].y - 29) && (my < InvRect[r].y)) { done = TRUE; r--; } } if (done) { plr[pnum].HoldItem._itype = -1; if ((r >= 0) && (r <= 3) && (plr[pnum].HeadItem._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_HEAD); plr[pnum].HoldItem = plr[pnum].HeadItem; plr[pnum].HeadItem._itype = -1; } if ((r == 4) && (plr[pnum].Ring1Item._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_RING1); plr[pnum].HoldItem = plr[pnum].Ring1Item; plr[pnum].Ring1Item._itype = -1; } if ((r == 5) && (plr[pnum].Ring2Item._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_RING2); plr[pnum].HoldItem = plr[pnum].Ring2Item; plr[pnum].Ring2Item._itype = -1; } if ((r == 6) && (plr[pnum].NeckItem._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_NECK); plr[pnum].HoldItem = plr[pnum].NeckItem; plr[pnum].NeckItem._itype = -1; } if ((r >= 7) && (r <= 12) && (plr[pnum].Hand1Item._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_HAND1); plr[pnum].HoldItem = plr[pnum].Hand1Item; plr[pnum].Hand1Item._itype = -1; } if ((r >= 13) && (r <= 18) && (plr[pnum].Hand2Item._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_HAND2); plr[pnum].HoldItem = plr[pnum].Hand2Item; plr[pnum].Hand2Item._itype = -1; } if ((r >= 19) && (r <= 24) && (plr[pnum].BodyItem._itype != -1)) { NetSendCmdDelItem(FALSE, INVLOC_BODY); plr[pnum].HoldItem = plr[pnum].BodyItem; plr[pnum].BodyItem._itype = -1; } if ((r >= 25) && (r <= 64)) { ii = r - 25; if (plr[pnum].InvGrid[ii] != 0) { if (plr[pnum].InvGrid[ii] > 0) iv = plr[pnum].InvGrid[ii]; else iv = -plr[pnum].InvGrid[ii]; for (i = 0; i < MAXINV; 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 (i = 0; i < MAXINV; i++) { if (plr[pnum].InvGrid[i] == plr[pnum]._pNumInv+1) plr[pnum].InvGrid[i] = iv+1; if (plr[pnum].InvGrid[i] == -(plr[pnum]._pNumInv+1)) plr[pnum].InvGrid[i] = -(iv+1); } } } } if (r >= 65) { ii = r - 65; if (plr[pnum].SpdList[ii]._itype != -1) { plr[pnum].HoldItem = plr[pnum].SpdList[ii]; plr[pnum].SpdList[ii]._itype = -1; drawsbarflag = TRUE; } } if (plr[pnum].HoldItem._itype != -1) { if (plr[pnum].HoldItem._itype == IT_GOLD) plr[pnum]._pGold = CalculateGold(pnum); CalcPlrInv(pnum,TRUE); CheckItemStats(pnum); if (pnum == myplr) { PlaySFX(IS_IGRAB); SetCursor(plr[pnum].HoldItem._iCurs + ICSTART); SetCursorPos(mx - (cursW>>1),MouseY - (cursH>>1)); } } } } /*-----------------------------------------------------------------------* ** Remove an item from another player **-----------------------------------------------------------------------*/ void SyncInvCut(int pnum, BYTE bLoc) { if (bLoc < NUM_INVLOC) plr[pnum].InvBody[bLoc]._itype = -1; if (plr[pnum]._pmode != PM_DEATH) CalcPlrInv(pnum,TRUE); else CalcPlrInv(pnum,FALSE); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void RemoveInvItem(int pnum, int iv) { int i; iv++; for (i = 0; i < MAXINV; 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 (i = 0; i < MAXINV; i++) { if (plr[pnum].InvGrid[i] == plr[pnum]._pNumInv+1) plr[pnum].InvGrid[i] = iv+1; if (plr[pnum].InvGrid[i] == -(plr[pnum]._pNumInv+1)) plr[pnum].InvGrid[i] = -(iv+1); } } CalcPlrScrolls(pnum); if ((plr[pnum]._pRSplType == SPT_SCROLL) && (plr[pnum]._pRSpell != -1)) { if (!(plr[pnum]._pScrlSpells & (1 << plr[pnum]._pRSpell-1))) plr[pnum]._pRSpell = -1; force_redraw = FULLDRAW; } } BOOL StripPlayer(int pnum) { int i; // Give the plr no items in hands gfx if (plr[pnum]._pgfxnum != PGFX_NGUY) { plr[pnum]._pgfxnum = PGFX_NGUY; plr[pnum]._pGFXLoad = 0; SetPlrAnims(pnum); } ItemStruct *pi = &plr[pnum].InvBody[0]; for (i = NUM_INVLOC; i--; pi++) pi->_itype = -1; int oldnum = plr[pnum]._pNumInv; ZeroMemory(plr[pnum].InvGrid,sizeof(plr[pnum].InvGrid)); plr[pnum]._pNumInv = 0; for (i = 0; i < oldnum; ++i) { pi = &plr[pnum].InvList[i]; if (pi->_itype == IT_GOLD) { int num = plr[pnum]._pNumInv; ItemStruct tmp = *pi; pi->_itype = -1; plr[pnum].InvList[num] = tmp; plr[pnum]._pNumInv++; plr[pnum].InvGrid[i] = plr[pnum]._pNumInv; } else pi->_itype = -1; } // zero speedbar pi = &plr[pnum].SpdList[0]; for (i = MAXSPD; i--; pi++) pi->_itype = -1; CalcPlrItemVals(pnum,FALSE); return FALSE; } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void RemoveSpdBarItem(int pnum, int iv) { plr[pnum].SpdList[iv]._itype = -1; CalcPlrScrolls(pnum); if ((plr[pnum]._pRSplType == SPT_SCROLL) && (plr[pnum]._pRSpell != -1)) { if (!(plr[pnum]._pScrlSpells & (1 << plr[pnum]._pRSpell-1))) plr[pnum]._pRSpell = -1; } force_redraw = FULLDRAW; } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void CheckInvScrn() { if (curs >= ICSTART) CheckInvPaste(myplr, MouseX, MouseY); else CheckInvCut(myplr, MouseX, MouseY); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void CheckSpdBar() { if ((MouseX > 190) && (MouseX < 437) && (MouseY > 352) && (MouseY < 385)) CheckInvScrn(); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void CheckItemStats(int pnum) { PlayerStruct * p = &plr[pnum]; ItemStruct * pi = &p->HoldItem; pi->_iStatFlag = FALSE; if (p->_pStrength < pi->_iMinStr) return; if (p->_pMagic < (byte)pi->_iMinMag) return; if (p->_pDexterity < pi->_iMinDex) return; pi->_iStatFlag = TRUE; } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void CheckBookLevel(int pnum) { if (plr[pnum].HoldItem._iMiscId != IMID_BOOK) return; plr[pnum].HoldItem._iMinMag = spelldata[plr[pnum].HoldItem._iSpell].sMinInt; int slvl = plr[pnum]._pSplLvl[plr[pnum].HoldItem._iSpell]; while (slvl != 0) { plr[pnum].HoldItem._iMinMag += ((plr[pnum].HoldItem._iMinMag * 20) / 100); slvl--; if ((plr[pnum].HoldItem._iMinMag + ((plr[pnum].HoldItem._iMinMag * 20) / 100)) > 255) { plr[pnum].HoldItem._iMinMag = 255; 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_BKMUSHRM]._qactive == QUEST_NOTDONE && quests[Q_BKMUSHRM]._qvar1 == QS_MUSHSPAWNED) { // say "That is a big mushroom" #if !IS_VERSION(SHAREWARE) sfxdelay = 10; if (plr[pnum]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR95; else if (plr[pnum]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE95; else if (plr[pnum]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE95; else if (plr[pnum]._pClass == CLASS_MONK) sfxdnum = PS_MONK95; else if (plr[pnum]._pClass == CLASS_BARD) sfxdnum = PS_BARD95; else if (plr[pnum]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN95; #endif quests[Q_BKMUSHRM]._qvar1 = QS_MUSHPICKED; } if (plr[pnum].HoldItem.IDidx == IDI_ANVIL) { if (quests[Q_ANVIL]._qactive == QUEST_NOTACTIVE) { quests[Q_ANVIL]._qactive = QUEST_NOTDONE; quests[Q_ANVIL]._qvar1 = 1; } if (quests[Q_ANVIL]._qlog == TRUE) { #if !IS_VERSION(SHAREWARE) sfxdelay = 10; if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR89; else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE89; else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE89; else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK89; else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD89; else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN89; #endif } } if (plr[pnum].HoldItem.IDidx == IDI_GLDNELIX) { #if !IS_VERSION(SHAREWARE) sfxdelay = 30; if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR88; else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE88; else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE88; else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK88; else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD88; else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN88; #endif } if (plr[pnum].HoldItem.IDidx == IDI_ROCK) { if (quests[Q_ROCK]._qactive == QUEST_NOTACTIVE) { quests[Q_ROCK]._qactive = QUEST_NOTDONE; quests[Q_ROCK]._qvar1 = 1; } if (quests[Q_ROCK]._qlog == TRUE) { #if !IS_VERSION(SHAREWARE) sfxdelay = 10; if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR87; else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE87; else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE87; else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK87; else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD87; else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN87; #endif } } if (plr[pnum].HoldItem.IDidx == IDI_ARMOFVAL) { quests[Q_BLOOD]._qactive = QUEST_DONE; #if !IS_VERSION(SHAREWARE) sfxdelay = 20; if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR91; else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE91; else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE91; else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK91; else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD91; else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN91; #endif } // Add pick up item triggers here. JKE if (plr[pnum].HoldItem.IDidx == IDI_MAPOFDOOM) { quests[Q_CRYPTMAP]._qactive = QUEST_NOTDONE; quests[Q_CRYPTMAP]._qvar1 = 1; quests[Q_CRYPTMAP]._qlog = FALSE; #if !IS_VERSION(SHAREWARE) sfxdelay = 10; if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR79; else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE79; else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE79; else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK79; else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD79; else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN79; #endif } if ((plr[pnum].HoldItem.IDidx == IDI_NOTE1) || (plr[pnum].HoldItem.IDidx == IDI_NOTE2) || (plr[pnum].HoldItem.IDidx == IDI_NOTE3)) { #if !IS_VERSION(SHAREWARE) int noteflag = 0; int idi = plr[pnum].HoldItem.IDidx; int x1, x2, x3; if (PlrHasItem(pnum, IDI_NOTE1, x1) || idi == IDI_NOTE1) noteflag |= 0x01; if (PlrHasItem(pnum, IDI_NOTE2, x2) || idi == IDI_NOTE2) noteflag |= 0x02; if (PlrHasItem(pnum, IDI_NOTE3, x3) || idi == IDI_NOTE3) noteflag |= 0x04; if (noteflag == 0x07) { // "Just what I was looking for" sfxdelay = 10; if (plr[myplr]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR46; else if (plr[myplr]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE46; else if (plr[myplr]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE46; else if (plr[myplr]._pClass == CLASS_MONK) sfxdnum = PS_MONK46; else if (plr[myplr]._pClass == CLASS_BARD) sfxdnum = PS_BARD46; else if (plr[myplr]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN46; // Put the items together switch(idi) { case IDI_NOTE1: PlrHasItem(pnum, IDI_NOTE2, x2); RemoveInvItem(pnum, x2); PlrHasItem(pnum, IDI_NOTE3, x3); RemoveInvItem(pnum, x3); break; case IDI_NOTE2: PlrHasItem(pnum, IDI_NOTE1, x1); RemoveInvItem(pnum, x1); PlrHasItem(pnum, IDI_NOTE3, x3); RemoveInvItem(pnum, x3); break; case IDI_NOTE3: PlrHasItem(pnum, IDI_NOTE1, x1); RemoveInvItem(pnum, x1); PlrHasItem(pnum, IDI_NOTE2, x2); RemoveInvItem(pnum, x2); break; } int ii = itemavail[0]; // use this item slot temporarily ItemStruct tmp = item[ii]; GetItemAttrs(ii, IDI_FULLNOTE, 16); SetupItem(ii); plr[pnum].HoldItem = item[ii]; item[ii] = tmp; } #endif } } /*-----------------------------------------------------------------------* ** Processes CMD_GETITEM player command **-----------------------------------------------------------------------*/ void InvGetItem(int pnum, int ii) { if (dropGoldFlag) { dropGoldFlag = FALSE; dropGoldValue = 0; } if (dItem[item[ii]._ix][item[ii]._iy] == 0) return; // Already picked up? // Next line can happen in mulitplayer due to latecency if ((myplr == pnum) && (curs >= ICSTART)) { NetSendCmdPItem(TRUE,CMD_SYNCPUTITEM,plr[myplr]._px,plr[myplr]._py); //InvPutItem(myplr,plr[myplr]._px,plr[myplr]._py); } // once an item is picked up it is no longer a pregen item if (item[ii]._iUid != 0) item[ii]._iCreateInfo &= ICI_PREGENMASK; plr[pnum].HoldItem = item[ii]; CheckQuestItem(pnum); CheckBookLevel(pnum); CheckItemStats(pnum); // added 970911 by DKT BOOL done = FALSE; if (plr[pnum].HoldItem._itype == IT_GOLD) { if (GoldAutoPlace(pnum)) done = TRUE; } // PATCH1.JMM DROPLOG(" InvGetItem: deleting item %d.\n",ii); // item[ii]._iDelFlag = TRUE; // ENDPATCH1.JMM dItem[item[ii]._ix][item[ii]._iy] = 0; if (currlevel == CRYPTSTART) { if (item[ii]._ix == CornerStone.x && item[ii]._iy == CornerStone.y) { CornerStone.item.IDidx = -1; CornerStone.item._itype = 0; CornerStone.item._ix = 0; CornerStone.item._iy = 0; CornerStone.item._iAnimFlag = FALSE; CornerStone.item._iSelFlag = ISEL_NONE; CornerStone.item._iIdentified = FALSE; CornerStone.item._iPostDraw = FALSE; } } // PATCH1.JMM int j; int jj; #if _DEBUG for(j = 0; j < numitems; j++) { DROPLOG(" InvGetItem: itemactive[%2.2d]: %2.2d\n",j,itemactive[j]); } #endif j = 0; while (j < numitems) { jj = itemactive[j]; if (jj == ii) { DROPLOG(" InvGetItem: Removing item index %d (struct %d,numitems %d) from item list!\n",j,jj,numitems); DeleteItem(jj, j); j = 0; } else { j++; } } // ENDPATCH1.JMM cursitem = -1; if (!done) NewCursor(plr[pnum].HoldItem._iCurs + ICSTART); } /*-----------------------------------------------------------------------* ** Processes CMD_AGETITEM player command **-----------------------------------------------------------------------*/ void AutoGetItem(int pnum, int ii) { int i, g, w, h, idx; BOOL done; if (dropGoldFlag) { dropGoldFlag = FALSE; dropGoldValue = 0; } // drb.patch1.start.02/15/97 if (ii != TEMPAVAIL) { // drb.patch1.end.02/15/97 if (dItem[item[ii]._ix][item[ii]._iy] == 0) return; // Already picked up? } done = FALSE; // once an item is picked up it is no longer a pregen item if (item[ii]._iUid != 0) item[ii]._iCreateInfo &= ICI_PREGENMASK; // Pick it up to get params for placing UID_OPTAMULET plr[pnum].HoldItem = item[ii]; CheckQuestItem(pnum); CheckBookLevel(pnum); CheckItemStats(pnum); SetICursor(plr[pnum].HoldItem._iCurs + ICSTART); // Try and fit it in if (plr[pnum].HoldItem._itype == IT_GOLD) { done = GoldAutoPlace(pnum); if (!done) { // If we only particially filled our inventory with gold. // reduce the temp value by to the new amount we are holding. item[ii]._ivalue = plr[pnum].HoldItem._ivalue; } } else { done = FALSE; g = plr[pnum]._pgfxnum & PGFX_MASK; if (((g == PGFX_NGUY) || (g == PGFX_SGUY) || (plr[pnum]._pClass == CLASS_BARD && (g == PGFX_ZGUY || g == PGFX_XGUY))) && (plr[pnum]._pmode <= PM_WALK3) && ((plr[pnum].HoldItem._iStatFlag) && (plr[pnum].HoldItem._iClass == IC_WEAP))) { done = WeaponAutoPlace(pnum); if (done) CalcPlrInv(pnum,TRUE); } if (!done) { // all items are either 1x1, 1x2, 1x3, 2x2, or 2x3 // the inv is 10x4 w = icursW28; h = icursH28; if ((w == 1) && (h == 1)) { // Check to see if speed bar available first idx = plr[pnum].HoldItem.IDidx; if ((plr[pnum].HoldItem._iStatFlag) && (AllItemsList[idx].iUsable)) { for (i = 0; (i < MAXSPD) && (!done); i++) { if (plr[pnum].SpdList[i]._itype == -1) { plr[pnum].SpdList[i] = plr[pnum].HoldItem; CalcPlrScrolls(pnum); drawsbarflag = TRUE; done = TRUE; } } } // Start in lower left and continue trying right then up a line 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)) { // Try 3rd row, 1st row, and then 2nd row 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)) { // Try 1st row then 2nd row for (i = 0; (i < 20) && (!done); i++) done = AutoPlace(pnum, i, w, h, TRUE); } if ((w == 2) && (h == 2)) { // Try 1st and 3rd row starting right and moving left for (i = 0; (i < 10) && (!done); i++) done = AutoPlace(pnum, AP2x2Tbl[i], w, h, TRUE); // Try 3rd row, 1st row, and then 2nd row 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)) { // Try 1st row then 2nd row 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) { // PATCH1.JMM DROPLOG(" AutoGetItem: set item[%d].iDelFlag = TRUE",ii); //item[ii]._iDelFlag = TRUE; dItem[item[ii]._ix][item[ii]._iy] = 0; if (currlevel == CRYPTSTART) { if (item[ii]._ix == CornerStone.x && item[ii]._iy == CornerStone.y) { CornerStone.item.IDidx = -1; CornerStone.item._itype = 0; CornerStone.item._ix = 0; CornerStone.item._iy = 0; CornerStone.item._iAnimFlag = FALSE; CornerStone.item._iSelFlag = ISEL_NONE; CornerStone.item._iIdentified = FALSE; CornerStone.item._iPostDraw = FALSE; } } int j; int jj; j = 0; while (j < numitems) { jj = itemactive[j]; if (jj == ii) { DROPLOG(" AutogetItem: Removing item index %d (struct %d,numitems %d) from item list!\n",j,jj,numitems); DeleteItem(jj, j); j = 0; } else { j++; } } // ENDPATCH1.JMM } else { if (pnum == myplr) { if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR14+random(0,3)); #if !IS_VERSION(SHAREWARE) else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE14+random(0,3)); else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE14+random(0,3)); else if (plr[pnum]._pClass == CLASS_MONK) PlaySFX(PS_MONK14+random(0,3)); else if (plr[pnum]._pClass == CLASS_BARD) PlaySFX(PS_BARD14+random(0,3)); else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN14+random(0,3)); #endif } plr[pnum].HoldItem = item[ii]; DROPLOG("AutogetItem\n"); RespawnItem(ii, TRUE); NetSendCmdPItem(TRUE,CMD_RESPAWNITEM,item[ii]._ix,item[ii]._iy); plr[pnum].HoldItem._itype = -1; // we're going to drop the item so change the cursor back to a glove. NewCursor(GLOVE_CURS); } } // PATCH1.JMM /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ #if _DEBUG void VerifyItemActiveList( void ) { int i, j; UINT nItemIndex; int nCurrIndex; WORD wCurrCI; int dwCurrSeed; BYTE x, y; for( i = 0; i < numitems; i++ ) { nItemIndex = itemactive[i]; nCurrIndex = item[nItemIndex].IDidx; wCurrCI = item[nItemIndex]._iCreateInfo; dwCurrSeed = item[nItemIndex]._iSeed; x = item[nItemIndex]._ix; y = item[nItemIndex]._iy; for( j = i+1; j < numitems; j++ ) { nItemIndex = itemactive[j]; if((item[nItemIndex].IDidx == nCurrIndex) && (item[nItemIndex]._iSeed == dwCurrSeed) && (item[nItemIndex]._iCreateInfo == wCurrCI)) DROPLOG(" VerifyItemActiveList: Duplicate item detected: itemactive[%d] = %d (%d %8.8x %4.4x)\n",j, nItemIndex, nCurrIndex, dwCurrSeed, wCurrCI); // app_assert(!((item[nItemIndex].IDidx == nCurrIndex) && (item[nItemIndex]._iSeed == dwCurrSeed) && (item[nItemIndex]._iCreateInfo == wCurrCI))); // app_assert(!((item[nItemIndex]._ix == x) && (item[nItemIndex]._iy == y))); } } } #else #define VerifyItemActiveList() #endif // ENDPATCH1.JMM /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ int FindGetItem(int idx, WORD ci, int iseed) { int i, ii; // PATCH1.JMM VerifyItemActiveList(); for (i = 0; i < numitems; i++) { ii = itemactive[i]; if ((item[ii].IDidx == idx) && (item[ii]._iSeed == iseed) && (item[ii]._iCreateInfo == ci)) { return (ii); } } // ENDPATCH1.JMM return (-1); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void SyncGetItem(int x, int y, int idx, WORD ci, int iseed) { int ii; // PATCH1.JMM VerifyItemActiveList(); DROPLOG(" Doing SyncGetItem...\n"); // try optimal location first if (dItem[x][y] != 0) { DROPLOG(" Attempting to find item by (x,y)\n"); ii = dItem[x][y] - 1; if ((item[ii].IDidx != idx) || (item[ii]._iSeed != iseed) || (item[ii]._iCreateInfo != ci)) { ii = FindGetItem(idx, ci, iseed); DROPLOG(" Bad (x,y). Did FindGetItem->%d.\n"); } else { DROPLOG(" (x,y) said ii == %d, FindGetItem says ii == %d\n",ii,FindGetItem(idx,ci,iseed)); } } else { DROPLOG(" Nongood (x,y)\n"); ii = FindGetItem(idx, ci, iseed); } DROPLOG(" FindGetItem returned %d\n",ii); if (ii != -1) { DROPLOG(" Removing item from map!\n"); // remove from map dItem[item[ii]._ix][item[ii]._iy] = 0; if (currlevel == CRYPTSTART) { if (item[ii]._ix == CornerStone.x && item[ii]._iy == CornerStone.y) { CornerStone.item.IDidx = -1; CornerStone.item._itype = 0; CornerStone.item._ix = 0; CornerStone.item._iy = 0; CornerStone.item._iAnimFlag = FALSE; CornerStone.item._iSelFlag = ISEL_NONE; CornerStone.item._iIdentified = FALSE; CornerStone.item._iPostDraw = FALSE; } } // remove from list int j = 0; while (j < numitems) { int jj = itemactive[j]; if (jj == ii) { DROPLOG(" Removing item index %d (struct %d,numitems %d) from item list!\n",j,jj,numitems); DeleteItem(jj, j); jj = FindGetItem(idx,ci,iseed); DROPLOG(" Item removed. FindGetItem->%d, numitems->%d\n", jj, numitems); j = 0; } else { j++; } } app_assert(FindGetItem(idx, ci, iseed) == -1); DROPLOG(" Item is definitely removed!\n"); } // ENDPATCH1.JMM } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL CanPut(int i, int j) { int oi; if (dItem[i][j]) return FALSE; if (nSolidTable[dPiece[i][j]]) return FALSE; if (dObject[i][j] != 0) { if (dObject[i][j] > 0) oi = dObject[i][j]-1; else oi = -(dObject[i][j]+1); if (object[oi]._oSolidFlag) return FALSE; } if (dObject[i+1][j+1] > 0) { oi = dObject[i+1][j+1]-1; if (object[oi]._oSelFlag != OSEL_NONE) return FALSE; } if (dObject[i+1][j+1] < 0) { oi = -(dObject[i+1][j+1]+1); if (object[oi]._oSelFlag != OSEL_NONE) return FALSE; } if ((dObject[i+1][j] > 0) && (dObject[i][j+1] > 0)) { oi = dObject[i+1][j]-1; if (object[oi]._oSelFlag != OSEL_NONE) { oi = dObject[i][j+1]-1; if (object[oi]._oSelFlag != OSEL_NONE) return FALSE; } } if (((currlevel == 0) && (dMonster[i][j] != 0)) || ((currlevel == 0) && (dMonster[i+1][j+1] != 0))) return FALSE; return TRUE; } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL TryInvPut() { // can't drop if too many items on floor already if (numitems >= MAXITEMS) return FALSE; int d = GetDirection(plr[myplr]._px, plr[myplr]._py, cursmx, cursmy); int x = plr[myplr]._px + offset_x[d]; int y = plr[myplr]._py + offset_y[d]; if (CanPut(x,y)) return TRUE; d = (d - 1) & 0x7; x = plr[myplr]._px + offset_x[d]; y = plr[myplr]._py + offset_y[d]; if (CanPut(x,y)) return TRUE; d = (d + 2) & 0x7; x = plr[myplr]._px + offset_x[d]; y = plr[myplr]._py + offset_y[d]; if (CanPut(x,y)) return TRUE; return(CanPut(plr[myplr]._px, plr[myplr]._py)); } // PATCH1.JMM.2/24/97 /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ #define DUP_DISP_INTERVAL 5 static DWORD sgdwLastTime = 0; void ShowDupString( LPCSTR lpszMessage ) { DWORD dwCurrTime; dwCurrTime = GetTickCount( ); if((dwCurrTime - sgdwLastTime) < (DUP_DISP_INTERVAL*1000)) return; sgdwLastTime = dwCurrTime; sysmsg_add_string( lpszMessage ); } // ENDPATCH1.JMM.2/24/97 /*-----------------------------------------------------------------------* ** Processes CMD_PUTITEM player command from myself **-----------------------------------------------------------------------*/ int InvPutItem(int pnum, int x, int y) { // can't drop if too many items on floor already if (numitems >= MAXITEMS) { DROPLOG("numitems >= MAXITEMS\n"); return -1; } // drb.patch1.start.02/18/97 // already in list? int ii = FindGetItem(plr[pnum].HoldItem.IDidx, plr[pnum].HoldItem._iCreateInfo, plr[pnum].HoldItem._iSeed); if (ii != -1) { DROPLOG(" Duplicate item detected!\n"); // JMM.PATCH1.2.22.97 // NetSendString(1 << myplr, "A duplicate item has been detected. Unable to drop."); ShowDupString("A duplicate item has been detected. Destroying duplicate..."); SyncGetItem(x,y,plr[pnum].HoldItem.IDidx,plr[pnum].HoldItem._iCreateInfo,plr[pnum].HoldItem._iSeed); // END.JMM.PATCH1.2.22.97 } // drb.patch1.end.02/18/97 VerifyItemActiveList(); // if square is too far away, then drop on adjacent square int d = GetDirection(plr[pnum]._px, plr[pnum]._py, x, y); int dx = x - plr[pnum]._px; int dy = y - plr[pnum]._py; if (abs(dx) > 1 || abs(dy) > 1) { x = plr[pnum]._px + offset_x[d]; y = plr[pnum]._py + offset_y[d]; } if (!CanPut(x,y)) { d = (d - 1) & 0x7; x = plr[pnum]._px + offset_x[d]; y = plr[pnum]._py + offset_y[d]; if (!CanPut(x,y)) { d = (d + 2) & 0x7; x = plr[pnum]._px + offset_x[d]; y = plr[pnum]._py + offset_y[d]; if (!CanPut(x,y)) { // radial search outward until a space is found BOOL done = FALSE; for (int l = 1; (l < 50) && !done; l++) { for (int j = -l; (j <= l) && !done; j++) { int yy = plr[pnum]._py + j; for (int i = -l; (i <= l) && !done; i++) { int xx = plr[pnum]._px + i; if (!CanPut(xx,yy)) continue; done = TRUE; x = xx; y = yy; } } } if (! done) return -1; } } } // JKEQUESTS Dropping stuff if (currlevel == 0) { if (plr[pnum].HoldItem._iCurs == ITEM_RUNEBOMB) { if(((cursmx >= 79) && (cursmx <= 82)) && ((cursmy >= 61) && (cursmy <= 64))) { NetSendCmdLocParam2(FALSE, CMD_OPEN_NEST, plr[pnum]._px, plr[pnum]._py, dx, dy ); quests[Q_FARMER]._qactive = QUEST_DONE; if (gbMaxPlayers != 1) NetSendCmdQuest(TRUE, Q_FARMER); return -1; } } if (plr[pnum].HoldItem.IDidx == IDI_MAPOFDOOM) { if(((cursmx >= 35) && (cursmx <= 38)) && ((cursmy >= 20) && (cursmy <= 24))) { NetSendCmd(FALSE, CMD_OPEN_CRYPT); quests[Q_CRYPTMAP]._qactive = QUEST_DONE; if (gbMaxPlayers != 1) NetSendCmdQuest(TRUE, Q_CRYPTMAP); return -1; } } } app_assert(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; DROPLOG(" InvPutItem\n"); RespawnItem(ii, TRUE); numitems++; if (currlevel == CRYPTSTART) { if (x == CornerStone.x && y == CornerStone.y) { // memcpy(&(CornerStone.item), &(item[ii]), SAVE_ITEM_SIZE); CornerStone.item = item[ii]; // Jims stuff InitQTextMsg(TXT_CORNERSTONE1); quests[Q_CORNERSTONE]._qlog = FALSE; quests[Q_CORNERSTONE]._qactive = QUEST_DONE; } } NewCursor(GLOVE_CURS); return ii; } /*-----------------------------------------------------------------------* ** Processes CMD_PUTITEM player command from another person **-----------------------------------------------------------------------*/ #if CHEATS BOOL syncdebug = FALSE; #endif int SyncPutItem( int pnum, int x, int y, int idx, WORD icreateinfo, int iseed, BOOL Id, int dur, int mdur, int ch, int mch, int ivalue, DWORD ibuff, int PLToHit, int MaxDam, int MinStr, int MinMag, int MinDex, int AC) { #if CHEATS if (syncdebug) { sprintf(tempstr, "Player %i dropping item.", pnum); NetSendString((1 << myplr), tempstr); } #endif // can't drop if too many items on floor already if (numitems >= MAXITEMS) { DROPLOG("numitems >= MAXITEMS\n"); return -1; } // drb.patch1.start.02/18/97 // already in list? int ii = FindGetItem(idx, icreateinfo, iseed); if (ii != -1) { DROPLOG(" Duplicate item detected!\n"); // JMM.PATCH1.2.22.97 //NetSendString(1 << myplr, "A duplicate item has been detected from another player."); ShowDupString("A duplicate item has been detected from another player."); SyncGetItem(x,y,idx,icreateinfo,iseed); // END.JMM.PATCH1.2.22.97 // return(-1); } // drb.patch1.end.02/18/97 // if square is too far away, then drop on adjacent square int d = GetDirection(plr[pnum]._px, plr[pnum]._py, x, y); int dx = x - plr[pnum]._px; int dy = y - plr[pnum]._py; if (abs(dx) > 1 || abs(dy) > 1) { x = plr[pnum]._px + offset_x[d]; y = plr[pnum]._py + offset_y[d]; } if (!CanPut(x,y)) { d = (d - 1) & 0x7; x = plr[pnum]._px + offset_x[d]; y = plr[pnum]._py + offset_y[d]; if (!CanPut(x,y)) { d = (d + 2) & 0x7; x = plr[pnum]._px + offset_x[d]; y = plr[pnum]._py + offset_y[d]; if (!CanPut(x,y)) { BOOL done = FALSE; // radial search outward until a space is found for (int l = 1; (l < 50) && !done; l++) { for (int j = -l; (j <= l) && !done; j++) { int yy = plr[pnum]._py + j; for (int i = -l; (i <= l) && !done; i++) { int xx = plr[pnum]._px + i; if (!CanPut(xx,yy)) continue; done = TRUE; x = xx; y = yy; } } } if (! done) { DROPLOG("Failed to find a good square to drop in!\n"); return -1; } } } } app_assert(CanPut(x,y)); ii = itemavail[0]; dItem[x][y] = ii+1; itemavail[0] = itemavail[MAXITEMS - numitems - 1]; itemactive[numitems] = ii; app_assert(ii >= 0); 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; item[ii]._iPLToHit = PLToHit; item[ii]._iMaxDam = MaxDam; item[ii]._iMinStr = MinStr; item[ii]._iMinMag = MinMag; item[ii]._iMinDex = MinDex; item[ii]._iAC = AC; } item[ii]._ix = x; item[ii]._iy = y; DROPLOG("SyncPutItem: respawning object %d!\n",ii); RespawnItem(ii, TRUE); numitems++; if (currlevel == CRYPTSTART) { if (x == CornerStone.x && y == CornerStone.y) { // memcpy(&(CornerStone.item), &(item[ii]), SAVE_ITEM_SIZE); CornerStone.item = item[ii]; // Jims stuff InitQTextMsg(TXT_CORNERSTONE1); quests[Q_CORNERSTONE]._qlog = FALSE; quests[Q_CORNERSTONE]._qactive = QUEST_DONE; } } return(ii); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ char CheckInvHLight() { // find box for (int r = 0; r < INVRECTS; r++) { if ((MouseX >= InvRect[r].x) && (MouseX < InvRect[r].x + 29) && (MouseY >= InvRect[r].y - 29) && (MouseY < InvRect[r].y)) break; } if (r >= INVRECTS) return -1; char rv = -1; infoclr = ICOLOR_WHITE; ItemStruct * pi = NULL; PlayerStruct * p = &plr[myplr]; ClearPanel(); if (r >= 0 && r <= 3) { rv = INVLOC_HEAD; pi = &p->HeadItem; } else if (r == 4) { rv = INVLOC_RING1; pi = &p->Ring1Item; } else if (r == 5) { rv = INVLOC_RING2; pi = &p->Ring2Item; } else if (r == 6) { rv = INVLOC_NECK; pi = &p->NeckItem; } else if (r >= 7 && r <= 12) { rv = INVLOC_HAND1; pi = &p->Hand1Item; } else if (r >= 13 && r <= 18) { // check for two handed item pi = &p->Hand1Item; if (pi->_itype != -1 && pi->_iLoc == IL_2HAND && !(p->_pClass == CLASS_BARBARIAN && ( p->Hand1Item._itype == IT_SWORD || p->Hand1Item._itype == IT_MACE ) ) ) { rv = INVLOC_HAND1; } else { rv = INVLOC_HAND2; pi = &p->Hand2Item; } } else if (r >= 19 && r <= 24) { rv = INVLOC_BODY; pi = &p->BodyItem; } else if (r >= 25 && r <= 64) { // is there an inventory item in this slot? if (0 == (r = abs(p->InvGrid[r - 25]))) return -1; // make zero based r--; // convert to global inventory slot number rv = r + NUM_INVLOC; // get item pi = &p->InvList[r]; } else if (r >= 65) { drawsbarflag = TRUE; r -= 65; pi = &p->SpdList[r]; if (pi->_itype == -1) return -1; // convert to global inventory slot number rv = r + MAXINV + NUM_INVLOC; } // Do I have an item (I should) app_assert(pi); // Is it still there? if (pi->_itype == -1) return -1; if (pi->_itype == IT_GOLD) { int nGold = pi->_ivalue; const char * get_pieces_str(int nGold); sprintf(infostr,"%i gold %s",nGold,get_pieces_str(nGold)); } else { if (pi->_iMagical == IMAGIC_MAGIC) infoclr = ICOLOR_BLUE; else if (pi->_iMagical == IMAGIC_UNIQUE) infoclr = ICOLOR_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 != -1) && ((plr[pnum].InvList[i]._iMiscId == IMID_SCROLL) || (plr[pnum].InvList[i]._iMiscId == IMID_TSCROLL)) && (plr[pnum].InvList[i]._iSpell == plr[pnum]._pSpell)) { RemoveInvItem(pnum, i); CalcPlrScrolls(pnum); return; } } for (i = 0; i < MAXSPD; i++) { if ((plr[pnum].SpdList[i]._itype != -1) && ((plr[pnum].SpdList[i]._iMiscId == IMID_SCROLL) || (plr[pnum].SpdList[i]._iMiscId == IMID_TSCROLL)) && (plr[pnum].SpdList[i]._iSpell == plr[pnum]._pSpell)) { RemoveSpdBarItem(pnum, i); CalcPlrScrolls(pnum); return; } } } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL UseScroll() { int i; if (curs != GLOVE_CURS) return(FALSE); // rjs if (leveltype == 0) return(FALSE); if (leveltype == 0 && spelldata[plr[myplr]._pRSpell].sTownSpell == FALSE) return(FALSE); for (i = 0; i < plr[myplr]._pNumInv; i++) { if ((plr[myplr].InvList[i]._itype != -1) && ((plr[myplr].InvList[i]._iMiscId == IMID_SCROLL) || (plr[myplr].InvList[i]._iMiscId == IMID_TSCROLL)) && (plr[myplr].InvList[i]._iSpell == plr[myplr]._pRSpell)) { return(TRUE); } } for (i = 0; i < MAXSPD; i++) { if ((plr[myplr].SpdList[i]._itype != -1) && ((plr[myplr].SpdList[i]._iMiscId == IMID_SCROLL) || (plr[myplr].SpdList[i]._iMiscId == IMID_TSCROLL)) && (plr[myplr].SpdList[i]._iSpell == plr[myplr]._pRSpell)) { return(TRUE); } } return(FALSE); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void UseStaffCharge(int pnum) { if ((plr[pnum].Hand1Item._itype != -1) && (plr[pnum].Hand1Item._iMiscId == IMID_STAFF || plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE) && (plr[pnum].Hand1Item._iSpell == plr[pnum]._pRSpell) && (plr[pnum].Hand1Item._iCharges > 0)) { plr[pnum].Hand1Item._iCharges--; CalcPlrStaff(pnum); return; } } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL UseStaff() { if (curs != GLOVE_CURS) return(FALSE); if ((plr[myplr].Hand1Item._itype != -1) && (plr[myplr].Hand1Item._iMiscId == IMID_STAFF || plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE) && (plr[myplr].Hand1Item._iSpell == plr[myplr]._pRSpell) && (plr[myplr].Hand1Item._iCharges > 0)) { return(TRUE); } return(FALSE); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL UseStaffSBook(int spl) { if (curs != GLOVE_CURS) return(FALSE); if ((plr[myplr].Hand1Item._itype != -1) && (plr[myplr].Hand1Item._iMiscId == IMID_STAFF || plr[myplr].Hand1Item._iMiscId == IMID_UNIQUE) && (plr[myplr].Hand1Item._iSpell == spl) && (plr[myplr].Hand1Item._iCharges > 0)) { return(TRUE); } return(FALSE); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL CheckUsable(int pnum, int cii) { int c, idata; BOOL rv; // Can't use items on my body, just in my inv rv = FALSE; if (cii <= 5) return(rv); if (cii <= 46) { c = cii - 7; idata = plr[pnum].InvList[c].IDidx; if (AllItemsList[idata].iUsable) rv = TRUE; } else { c = cii - 47; idata = plr[pnum].SpdList[c].IDidx; if (AllItemsList[idata].iUsable) rv = TRUE; } return(rv); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ extern int dropGoldValue; void StartGoldDrop() { // Save the index of the gold pile initialDropGoldIndex = cursinvitem; if (cursinvitem <= 46) // Gold item is in InvList // Save the value of the gold pile initialDropGoldValue = plr[myplr].InvList[cursinvitem-7]._ivalue; else // Gold item is in SpdList // Save the value of the gold pile initialDropGoldValue = plr[myplr].SpdList[cursinvitem-47]._ivalue; // Set flag so drop gold functionality is enabled dropGoldFlag = TRUE; // Initialize the drop gold value when right click gold pile dropGoldValue = 0; if (talkflag) TalkEnd(); } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ BOOL UseInvItem(int pnum, int cii) { int c, idata, it; ItemStruct *Item; BOOL speedlist; // Don't use while dead if ((plr[pnum]._pInvincible) && (plr[pnum]._pHitPoints == 0) && (pnum == myplr)) return TRUE; // Don't use unless glove curs if (curs != GLOVE_CURS) return TRUE; // Don't use during stores if (stextflag != STORE_NONE) return TRUE; // Can't use items on my body, just in my inv if (cii <= 5) return FALSE; if (cii <= 46) { c = cii - 7; Item = &plr[pnum].InvList[c]; speedlist = FALSE; } else { if (talkflag) return TRUE; c = cii - 47; Item = &plr[pnum].SpdList[c]; speedlist = TRUE; } idata = Item->IDidx; switch (idata) { case IDI_MUSHROOM: sfxdelay = 10; #if !IS_VERSION(SHAREWARE) if (plr[pnum]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR95; else if (plr[pnum]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE95; else if (plr[pnum]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE95; else if (plr[pnum]._pClass == CLASS_MONK) sfxdnum = PS_MONK95; else if (plr[pnum]._pClass == CLASS_BARD) sfxdnum = PS_BARD95; else if (plr[pnum]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN95; #endif return TRUE; case IDI_FUNGALTM: PlaySFX(IS_IBOOK); sfxdelay = 10; if (plr[pnum]._pClass == CLASS_WARRIOR) sfxdnum = PS_WARR29; #if !IS_VERSION(SHAREWARE) else if (plr[pnum]._pClass == CLASS_ROGUE) sfxdnum = PS_ROGUE29; else if (plr[pnum]._pClass == CLASS_SORCEROR) sfxdnum = PS_MAGE29; else if (plr[pnum]._pClass == CLASS_MONK) sfxdnum = PS_MONK29; else if (plr[pnum]._pClass == CLASS_BARD) sfxdnum = PS_BARD29; else if (plr[pnum]._pClass == CLASS_BARBARIAN) sfxdnum = PS_BARBARIAN29; #endif return TRUE; } if (!AllItemsList[idata].iUsable) return FALSE; if (!Item->_iStatFlag) { if (plr[pnum]._pClass == CLASS_WARRIOR) PlaySFX(PS_WARR13); #if !IS_VERSION(SHAREWARE) else if (plr[pnum]._pClass == CLASS_ROGUE) PlaySFX(PS_ROGUE13); else if (plr[pnum]._pClass == CLASS_SORCEROR) PlaySFX(PS_MAGE13); else if (plr[pnum]._pClass == CLASS_MONK) PlaySFX(PS_MONK13); else if (plr[pnum]._pClass == CLASS_BARD) PlaySFX(PS_BARD13); else if (plr[pnum]._pClass == CLASS_BARBARIAN) PlaySFX(PS_BARBARIAN13); #endif return TRUE; } else { // Was the item chosen a pile of gold if ((Item->_iMiscId == IMID_NONE) && (Item->_itype == IT_GOLD)) { StartGoldDrop(); return TRUE;; } if (dropGoldFlag) { dropGoldFlag = FALSE; dropGoldValue = 0; } if ((Item->_iMiscId == IMID_SCROLL) && (currlevel == 0) && (spelldata[Item->_iSpell].sTownSpell == FALSE)) return TRUE; if ((Item->_iMiscId == IMID_TSCROLL) && (currlevel == 0) && (spelldata[Item->_iSpell].sTownSpell == FALSE)) return TRUE; if ((Item->_iMiscId > IMID_FIRSTRUNE) && (Item->_iMiscId < IMID_LASTRUNE) && (currlevel == 0)) return TRUE; it = ItemCAnimTbl[Item->_iCurs]; if (Item->_iMiscId == IMID_BOOK) PlaySFX(IS_RBOOK); else if (pnum == myplr) PlaySFX(ItemInvSnds[it]); UseItem(pnum, Item->_iMiscId, Item->_iSpell); if (speedlist) { if (plr[pnum].SpdList[c]._iMiscId == IMID_FULLNOTE) { InitQTextMsg(TXT_SKULLJRNL7); invflag = FALSE; // PlaySFX(HSFX_SKULLJRNL7); return TRUE; } RemoveSpdBarItem(pnum, c); } else { // Don't delete map of doom when used if (plr[pnum].InvList[c]._iMiscId == IMID_MAPOFDOOM) return TRUE; if (plr[pnum].InvList[c]._iMiscId == IMID_FULLNOTE) { InitQTextMsg(TXT_SKULLJRNL7); invflag = FALSE; // PlaySFX(HSFX_SKULLJRNL7); return TRUE; } RemoveInvItem(pnum, c); } } return TRUE; } /*-----------------------------------------------------------------------* **-----------------------------------------------------------------------*/ void DoTelekinesis() { if (cursobj != -1) { NetSendCmdParam1(TRUE, CMD_OPOBJT, cursobj); } if (cursitem != -1) { NetSendCmdGItem(TRUE, CMD_REQUESTAGITEM, myplr, myplr, cursitem); } BOOL M_Talker (int); if ((cursmonst != -1) && (!M_Talker(cursmonst)) && (monster[cursmonst].mtalkmsg == 0)) { NetSendCmdParam1(TRUE, CMD_KNOCKBACK, cursmonst); } NewCursor(GLOVE_CURS); } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ long CalculateGold(int pnum) { int i; long gold; // Initialize gold gold = 0; // Find the gold in the speedbar list for (i = 0; i < MAXSPD; i++) { if (plr[pnum].SpdList[i]._itype == IT_GOLD) { gold += plr[pnum].SpdList[i]._ivalue; force_redraw = FULLDRAW; } } // Find the gold in the inventory list for (i = 0; i < plr[pnum]._pNumInv; i++) { if (plr[pnum].InvList[i]._itype == IT_GOLD) gold += plr[pnum].InvList[i]._ivalue; } return(gold); } /*-----------------------------------------------------------------------** **-----------------------------------------------------------------------*/ BOOL DropItemBeforeTrig() /*-----------------------------------------------------------------------** ** DESCRIPTION: Drops the item the player has in hand before talking to a ** towner or entering a level. ** INPUT: None ** RETURN: TRUE = The item was dropped successfully ** FALSE = The item could not be dropped. /*-----------------------------------------------------------------------*/ { if (TryInvPut()) { NetSendCmdPItem(TRUE,CMD_PUTITEM,cursmx,cursmy); NewCursor(GLOVE_CURS); return TRUE; } return FALSE; } int GetHighRingValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_RING && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_RING && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighBowValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_BOW && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_BOW && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighStaffValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_STAFF && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_STAFF && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighSwordValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_SWORD && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_SWORD && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighHelmValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_HELM && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_HELM && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighShieldValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_SHIELD && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_SHIELD && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighArmorValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && (plr[myPlr].InvBody[i]._itype == IT_ARMOR || plr[myPlr].InvBody[i]._itype == IT_MARMOR || plr[myPlr].InvBody[i]._itype == IT_HARMOR ) && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && (plr[myPlr].InvList[i]._itype == IT_ARMOR || plr[myPlr].InvList[i]._itype == IT_MARMOR || plr[myPlr].InvList[i]._itype == IT_HARMOR) && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighMaceValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_MACE && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_MACE && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighAmuletValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_AMULET && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_AMULET && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; } int GetHighAxeValue(int myPlr) { int itemValue = 0; int i; for (i =0; i < NUM_INVLOC; ++i) { if (plr[myPlr].InvBody[i]._iClass != -1 && plr[myPlr].InvBody[i]._itype == IT_AXE && itemValue < plr[myPlr].InvBody[i]._iIvalue) { itemValue = plr[myPlr].InvBody[i]._iIvalue; } } for (i =0; i < MAXINV; ++i) { if (plr[myPlr].InvList[i]._iClass != -1 && plr[myPlr].InvList[i]._itype == IT_AXE && itemValue < plr[myPlr].InvList[i]._iIvalue) { itemValue = plr[myPlr].InvList[i]._iIvalue; } } return itemValue; }