raze/source/sw/src/inv.cpp
Christoph Oelckers 75c76ccf66 - changed SW's PlaySound interface to take pointers to objects instead of pointers to coordinates.
With pointers to coordinates the sound engine cannot work, so this had to be changed globally.
2019-12-18 11:09:01 +01:00

1097 lines
29 KiB
C++

//-------------------------------------------------------------------------
/*
Copyright (C) 1997, 2005 - 3D Realms Entertainment
This file is part of Shadow Warrior version 1.2
Shadow Warrior is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Original Source: 1997 - Frank Maddin and Jim Norwood
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include "ns.h"
#undef MAIN
#include "build.h"
#include "keys.h"
#include "names2.h"
#include "panel.h"
#include "game.h"
#include "pal.h"
#include "text.h"
#include "colormap.h"
#include "player.h"
BEGIN_SW_NS
//#define SAVE_EXTERN
//#include "_save.h"
//#undef SAVE_EXTERN
extern short NormalVisibility;
// indexed by gs.BorderNum 130,172
short InventoryBarXpos[] = {110, 110, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80};
short InventoryBarYpos[] = {172, 172, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130};
void PlayerUpdateInventory(PLAYERp pp, short InventoryNum);
void SpawnInventoryBar(PLAYERp pp);
void InventoryBarUpdatePosition(PLAYERp pp);
void InvBorderRefresh(PLAYERp pp);
void InventoryUse(PLAYERp pp);
void InventoryStop(PLAYERp pp, short InventoryNum);
void KillInventoryBar(PLAYERp pp);
void PlayerUpdateInventoryPercent(PLAYERp pp);
void PlayerUpdateInventoryPic(PLAYERp pp);
void PlayerUpdateInventoryState(PLAYERp pp);
//#define INVENTORY_ICON_WIDTH 32
#define INVENTORY_ICON_WIDTH 28
void UseInventoryRepairKit(PLAYERp pp);
void UseInventoryMedkit(PLAYERp pp);
void UseInventoryRepairKit(PLAYERp pp);
void UseInventoryCloak(PLAYERp pp);
void UseInventoryEnvironSuit(PLAYERp pp);
void UseInventoryNightVision(PLAYERp pp);
void UseInventoryChemBomb(PLAYERp pp);
void UseInventoryFlashBomb(PLAYERp pp);
void UseInventoryCaltrops(PLAYERp pp);
void StopInventoryRepairKit(PLAYERp pp, short);
void StopInventoryMedkit(PLAYERp pp, short);
void StopInventoryRepairKit(PLAYERp pp, short);
void StopInventoryCloak(PLAYERp pp, short);
void StopInventoryEnvironSuit(PLAYERp pp, short);
void StopInventoryNightVision(PLAYERp pp, short);
extern PANEL_STATE ps_PanelEnvironSuit[];
extern PANEL_STATE ps_PanelCloak[];
extern PANEL_STATE ps_PanelMedkit[];
extern PANEL_STATE ps_PanelRepairKit[];
extern PANEL_STATE ps_PanelSelectionBox[];
extern PANEL_STATE ps_PanelNightVision[];
extern PANEL_STATE ps_PanelChemBomb[];
extern PANEL_STATE ps_PanelFlashBomb[];
extern PANEL_STATE ps_PanelCaltrops[];
INVENTORY_DATA InventoryData[MAX_INVENTORY+1] =
{
{"PORTABLE MEDKIT", UseInventoryMedkit, NULL, ps_PanelMedkit, 0, 1, (1<<16), 0},
{"REPAIR KIT", NULL, NULL, ps_PanelRepairKit, 100, 1, (1<<16), INVF_AUTO_USE},
{"SMOKE BOMB", UseInventoryCloak, StopInventoryCloak, ps_PanelCloak, 4, 1, (1<<16), INVF_TIMED},
{"NIGHT VISION", UseInventoryNightVision, StopInventoryNightVision, ps_PanelNightVision,3, 1, (1<<16), INVF_TIMED},
{"GAS BOMB", UseInventoryChemBomb, NULL, ps_PanelChemBomb, 0, 1, (1<<16), INVF_COUNT},
{"FLASH BOMB", UseInventoryFlashBomb, NULL, ps_PanelFlashBomb, 0, 2, (1<<16), INVF_COUNT},
{"CALTROPS", UseInventoryCaltrops, NULL, ps_PanelCaltrops, 0, 3, (1<<16), INVF_COUNT},
{NULL, NULL, NULL, NULL, 0, 0, 0, 0}
};
void PanelInvTestSuicide(PANEL_SPRITEp psp);
void UpdateMiniBar(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short i;
int x,y;
SWBOOL found;
INVENTORY_DATAp id;
extern SWBOOL PanelUpdateMode;
#define MINI_BAR_Y 174
#define MINI_BAR_HEALTH_BOX_PIC 2437
#define MINI_BAR_AMMO_BOX_PIC 2437
#define MINI_BAR_INVENTORY_BOX_PIC 2438
#define MINI_BAR_HEALTH_BOX_X 4
#define MINI_BAR_AMMO_BOX_X 32
#define MINI_BAR_INVENTORY_BOX_X 64
#define MINI_BAR_INVENTORY_BOX_Y MINI_BAR_Y
if (!PanelUpdateMode)
return;
if (gs.BorderNum != BORDER_MINI_BAR)
return;
x = MINI_BAR_HEALTH_BOX_X;
y = 200 - 26;
rotatesprite(x << 16, y << 16, (1 << 16), 0,
MINI_BAR_HEALTH_BOX_PIC, 0, 0,
ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L,
0, 0, xdim - 1, ydim - 1);
x = MINI_BAR_HEALTH_BOX_X+3;
DisplayMiniBarNumber(pp, x, y+5, u->Health);
if (u->WeaponNum != WPN_SWORD && u->WeaponNum != WPN_FIST)
{
x = MINI_BAR_AMMO_BOX_X;
rotatesprite(x << 16, y << 16, (1 << 16), 0,
MINI_BAR_AMMO_BOX_PIC, 0, 0,
ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L,
0, 0, xdim - 1, ydim - 1);
x = MINI_BAR_AMMO_BOX_X+3;
DisplayMiniBarNumber(pp, x, y+5, pp->WpnAmmo[u->WeaponNum]);
}
if (!pp->InventoryAmount[pp->InventoryNum])
return;
// Inventory Box
x = MINI_BAR_INVENTORY_BOX_X;
rotatesprite(x << 16, y << 16, (1 << 16), 0,
MINI_BAR_INVENTORY_BOX_PIC, 0, 0,
ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L,
0, 0, xdim - 1, ydim - 1);
id = &InventoryData[pp->InventoryNum];
// Inventory pic
x = MINI_BAR_INVENTORY_BOX_X + 2;
y += 2;
rotatesprite(x << 16, y << 16, (1 << 16), 0,
id->State->picndx, 0, 0,
ROTATE_SPRITE_SCREEN_CLIP | ROTATE_SPRITE_CORNER | RS_ALIGN_L,
0, 0, xdim - 1, ydim - 1);
// will update the AUTO and % inventory values
PlayerUpdateInventory(pp, pp->InventoryNum);
}
void PanelInvTestSuicide(PANEL_SPRITEp psp)
{
if (TEST(psp->flags, PANF_SUICIDE))
{
pKillSprite(psp);
}
}
PANEL_SPRITEp SpawnInventoryIcon(PLAYERp pp, short InventoryNum)
{
PANEL_SPRITEp psp;
short x,y;
// check invalid value
ASSERT(InventoryNum < MAX_INVENTORY);
// check to see if its already spawned
if (pp->InventorySprite[InventoryNum])
return NULL;
// check for Icon panel state
if (!InventoryData[InventoryNum].State)
return NULL;
x = InventoryBarXpos[gs.BorderNum] + (InventoryNum*INVENTORY_ICON_WIDTH);
y = InventoryBarYpos[gs.BorderNum];
psp = pSpawnSprite(pp, InventoryData[InventoryNum].State, PRI_FRONT, x, y);
pp->InventorySprite[InventoryNum] = psp;
psp->x1 = 0;
psp->y1 = 0;
psp->x2 = xdim - 1;
psp->y2 = ydim - 1;
psp->scale = InventoryData[InventoryNum].Scale;
SET(psp->flags, PANF_STATUS_AREA | PANF_SCREEN_CLIP);
return psp;
}
void KillPanelInv(PLAYERp pp, short InventoryNum)
{
ASSERT(pp->InventorySprite[InventoryNum]);
ASSERT(InventoryNum < MAX_INVENTORY);
pp->InventoryTics[InventoryNum] = 0;
SET(pp->InventorySprite[InventoryNum]->flags, PANF_SUICIDE);
pp->InventorySprite[InventoryNum] = NULL;
}
void KillPlayerIcon(PLAYERp pp, PANEL_SPRITEp *pspp)
{
SET((*pspp)->flags, PANF_SUICIDE);
(*pspp) = NULL;
}
void KillAllPanelInv(PLAYERp pp)
{
short i;
for (i = 0; i < MAX_INVENTORY; i++)
{
if (!pp->InventorySprite[i])
continue;
pp->InventoryTics[i] = 0;
SET(pp->InventorySprite[i]->flags, PANF_SUICIDE);
pp->InventorySprite[i]->numpages = 0;
pp->InventorySprite[i] = NULL;
}
}
PANEL_SPRITEp SpawnIcon(PLAYERp pp, PANEL_STATEp state)
{
PANEL_SPRITEp psp;
short i;
psp = pSpawnSprite(pp, state, PRI_FRONT, 0, 0);
psp->x1 = 0;
psp->y1 = 0;
psp->x2 = xdim - 1;
psp->y2 = ydim - 1;
SET(psp->flags, PANF_STATUS_AREA | PANF_SCREEN_CLIP);
return psp;
}
//////////////////////////////////////////////////////////////////////
//
// MEDKIT
//
//////////////////////////////////////////////////////////////////////
void AutoPickInventory(PLAYERp pp)
{
int i;
// auto pick only if run out of currently selected one
if (pp->InventoryAmount[pp->InventoryNum] <= 0)
{
for (i = 0; i < MAX_INVENTORY; i++)
{
if (i == INVENTORY_REPAIR_KIT)
continue;
if (pp->InventoryAmount[i])
{
pp->InventoryNum = i;
return;
}
}
// only take this if there is nothing else
if (pp->InventoryAmount[INVENTORY_REPAIR_KIT])
pp->InventoryNum = INVENTORY_REPAIR_KIT;
}
}
void UseInventoryMedkit(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short diff;
short inv = INVENTORY_MEDKIT;
short amt;
if (!pp->InventoryAmount[inv])
return;
diff = 100 - u->Health;
if (diff <= 0)
return;
if (diff > pp->InventoryPercent[inv]) // If not enough to get to 100, use what's left
amt = pp->InventoryPercent[inv];
else
amt = diff;
PlayerUpdateHealth(pp, amt);
pp->InventoryPercent[inv] -= diff;
if (pp->InventoryPercent[inv] < 0)
{
pp->InventoryPercent[inv] = 0;
pp->InventoryAmount[inv]--;
}
AutoPickInventory(pp);
//percent
PlayerUpdateInventory(pp, pp->InventoryNum);
if (pp == Player+myconnectindex)
{
if (amt >= 30)
PlayerSound(DIGI_GETMEDKIT, v3df_follow|v3df_dontpan,pp);
else
PlayerSound(DIGI_AHH, v3df_follow|v3df_dontpan,pp);
}
}
//////////////////////////////////////////////////////////////////////
//
// CHEMICAL WARFARE CANISTERS
//
//////////////////////////////////////////////////////////////////////
void UseInventoryChemBomb(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short diff;
short inv = INVENTORY_CHEMBOMB;
if (!pp->InventoryAmount[inv])
return;
PlayerInitChemBomb(pp); // Throw a chemical bomb out there
pp->InventoryPercent[inv] = 0;
if (--pp->InventoryAmount[inv] < 0)
pp->InventoryAmount[inv] = 0;
AutoPickInventory(pp);
PlayerUpdateInventory(pp, pp->InventoryNum);
}
//////////////////////////////////////////////////////////////////////
//
// FLASH BOMBS
//
//////////////////////////////////////////////////////////////////////
void UseInventoryFlashBomb(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short diff;
short inv = INVENTORY_FLASHBOMB;
if (!pp->InventoryAmount[inv])
return;
PlayerInitFlashBomb(pp);
pp->InventoryPercent[inv] = 0;
if (--pp->InventoryAmount[inv] < 0)
pp->InventoryAmount[inv] = 0;
AutoPickInventory(pp);
PlayerUpdateInventory(pp, pp->InventoryNum);
}
//////////////////////////////////////////////////////////////////////
//
// CALTROPS
//
//////////////////////////////////////////////////////////////////////
void UseInventoryCaltrops(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short diff;
short inv = INVENTORY_CALTROPS;
if (!pp->InventoryAmount[inv])
return;
PlayerInitCaltrops(pp);
pp->InventoryPercent[inv] = 0;
if (--pp->InventoryAmount[inv] < 0)
pp->InventoryAmount[inv] = 0;
AutoPickInventory(pp);
PlayerUpdateInventory(pp, pp->InventoryNum);
}
//////////////////////////////////////////////////////////////////////
//
// REPAIR KIT
//
//////////////////////////////////////////////////////////////////////
void UseInventoryRepairKit(PLAYERp pp)
{
SPRITEp sp = pp->SpriteP;
short inv = INVENTORY_REPAIR_KIT;
//PlaySound(DIGI_TOOLBOX, pp, v3df_none);
if (pp == Player + myconnectindex)
{
if (STD_RANDOM_RANGE(1000) > 500)
PlayerSound(DIGI_NOREPAIRMAN, v3df_follow|v3df_dontpan,pp);
else
PlayerSound(DIGI_NOREPAIRMAN2, v3df_follow|v3df_dontpan,pp);
}
pp->InventoryPercent[inv] = 0;
pp->InventoryAmount[inv] = 0;
AutoPickInventory(pp);
//percent
PlayerUpdateInventory(pp, pp->InventoryNum);
}
//////////////////////////////////////////////////////////////////////
//
// CLOAK
//
//////////////////////////////////////////////////////////////////////
void UseInventoryCloak(PLAYERp pp)
{
SPRITEp sp = pp->SpriteP;
if (pp->InventoryActive[pp->InventoryNum])
{
// StopInventoryCloak(pp, pp->InventoryNum);
return;
}
pp->InventoryActive[pp->InventoryNum] = TRUE;
AutoPickInventory(pp);
// on/off
PlayerUpdateInventory(pp, pp->InventoryNum);
SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
sp->shade = 100;
PlaySound(DIGI_GASPOP, pp, v3df_none);
//if(RANDOM_RANGE(1000) > 950)
if (pp == Player+myconnectindex)
PlayerSound(DIGI_IAMSHADOW, v3df_follow|v3df_dontpan,pp);
}
void StopInventoryCloak(PLAYERp pp, short InventoryNum)
{
SPRITEp sp = pp->SpriteP;
pp->InventoryActive[InventoryNum] = FALSE;
if (pp->InventoryPercent[InventoryNum] <= 0)
{
pp->InventoryPercent[InventoryNum] = 0;
if (--pp->InventoryAmount[InventoryNum] < 0)
pp->InventoryAmount[InventoryNum] = 0;
}
// on/off
PlayerUpdateInventory(pp, InventoryNum);
RESET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT);
sp->shade = 0;
PlaySound(DIGI_GASPOP, pp, v3df_none);
}
//////////////////////////////////////////////////////////////////////
//
// ENVIRONMENT SUIT
//
//////////////////////////////////////////////////////////////////////
#if 0
void UseInventoryEnvironSuit(PLAYERp pp)
{
SPRITEp sp = pp->SpriteP;
short inv = INVENTORY_ENVIRON_SUIT;
// only activate if you have one
if (pp->InventoryAmount[inv])
{
pp->InventoryActive[inv] = TRUE;
// on/off
PlayerUpdateInventory(pp, inv);
}
}
void StopInventoryEnvironSuit(PLAYERp pp, short InventoryNum)
{
SPRITEp sp = pp->SpriteP;
short inv = INVENTORY_ENVIRON_SUIT;
pp->InventoryActive[InventoryNum] = FALSE;
if (pp->InventoryPercent[InventoryNum] <= 0)
{
pp->InventoryPercent[InventoryNum] = 0;
if (--pp->InventoryAmount[InventoryNum] < 0)
pp->InventoryAmount[InventoryNum] = 0;
}
// on/off
PlayerUpdateInventory(pp, InventoryNum);
PlaySound(DIGI_SWCLOAKUNCLOAK, pp, v3df_none);
}
#endif
//////////////////////////////////////////////////////////////////////
//
// NIGHT VISION
//
//////////////////////////////////////////////////////////////////////
static char sectorfloorpals[MAXSECTORS], sectorceilingpals[MAXSECTORS], wallpals[MAXWALLS];
void
DoPlayerNightVisionPalette(PLAYERp pp)
{
if (pp != Player + screenpeek) return;
if (pp->InventoryActive[INVENTORY_NIGHT_VISION])
{
// if (pp->NightVision && pp->StartColor == 148)
// return;
SetFadeAmt(pp,-1005,148); // Night vision green tint
pp->NightVision = TRUE;
}
else
{
// Put it all back to normal
if (pp->StartColor == 148)
{
memcpy(pp->temp_pal, palette_data, sizeof(palette_data));
memcpy(palookup[PALETTE_DEFAULT], DefaultPalette, 256 * 32);
pp->FadeAmt = 0;
if (videoGetRenderMode() < REND_POLYMOST)
COVERsetbrightness(0, &palette_data[0][0]);
else
videoFadePalette(0,0,0,0);
}
pp->NightVision = FALSE;
}
}
void
UseInventoryNightVision(PLAYERp pp)
{
SPRITEp sp = pp->SpriteP;
#define NIGHT_INVENTORY_TIME 30
if (pp->InventoryActive[pp->InventoryNum])
{
StopInventoryNightVision(pp, pp->InventoryNum);
return;
}
pp->InventoryActive[pp->InventoryNum] = TRUE;
// on/off
PlayerUpdateInventory(pp, pp->InventoryNum);
DoPlayerNightVisionPalette(pp);
PlaySound(DIGI_NIGHTON, pp, v3df_dontpan|v3df_follow);
}
void
StopInventoryNightVision(PLAYERp pp, short InventoryNum)
{
SPRITEp sp = pp->SpriteP;
pp->InventoryActive[InventoryNum] = FALSE;
if (pp->InventoryPercent[InventoryNum] <= 0)
{
pp->InventoryPercent[InventoryNum] = 0;
if (--pp->InventoryAmount[InventoryNum] < 0)
pp->InventoryAmount[InventoryNum] = 0;
}
AutoPickInventory(pp);
// on/off
PlayerUpdateInventory(pp, pp->InventoryNum);
DoPlayerNightVisionPalette(pp);
DoPlayerDivePalette(pp);
PlaySound(DIGI_NIGHTOFF, pp, v3df_dontpan|v3df_follow);
}
//////////////////////////////////////////////////////////////////////
//
// INVENTORY KEYS
//
//////////////////////////////////////////////////////////////////////
void InventoryKeys(PLAYERp pp)
{
short inv_hotkey;
// scroll SPELLs left
if (TEST_SYNC_KEY(pp, SK_INV_LEFT))
{
if (FLAG_KEY_PRESSED(pp, SK_INV_LEFT))
{
FLAG_KEY_RELEASE(pp, SK_INV_LEFT);
SpawnInventoryBar(pp);
PlayerUpdateInventory(pp, pp->InventoryNum - 1);
PutStringInfo(pp, InventoryData[pp->InventoryNum].Name);
InventoryBarUpdatePosition(pp);
InvBorderRefresh(pp);
}
}
else
{
FLAG_KEY_RESET(pp, SK_INV_LEFT);
}
// scroll SPELLs right
if (TEST_SYNC_KEY(pp, SK_INV_RIGHT))
{
if (FLAG_KEY_PRESSED(pp, SK_INV_RIGHT))
{
FLAG_KEY_RELEASE(pp, SK_INV_RIGHT);
SpawnInventoryBar(pp);
PlayerUpdateInventory(pp, pp->InventoryNum + 1);
PutStringInfo(pp, InventoryData[pp->InventoryNum].Name);
InventoryBarUpdatePosition(pp);
InvBorderRefresh(pp);
}
}
else
{
FLAG_KEY_RESET(pp, SK_INV_RIGHT);
}
if (TEST_SYNC_KEY(pp, SK_INV_USE))
{
if (FLAG_KEY_PRESSED(pp, SK_INV_USE))
{
FLAG_KEY_RELEASE(pp, SK_INV_USE);
if (InventoryData[pp->InventoryNum].Init)
{
if (pp->InventoryAmount[pp->InventoryNum])
{
InventoryUse(pp);
}
else
{
sprintf(ds,"No %s",InventoryData[pp->InventoryNum].Name);
PutStringInfo(pp,ds); // DONT have message
}
}
}
}
else
{
FLAG_KEY_RESET(pp, SK_INV_USE);
}
// get hotkey number out of input bits
inv_hotkey = TEST(pp->input.bits, SK_INV_HOTKEY_MASK) >> SK_INV_HOTKEY_BIT0;
if (inv_hotkey)
{
if (FLAG_KEY_PRESSED(pp, SK_INV_HOTKEY_BIT0))
{
FLAG_KEY_RELEASE(pp, SK_INV_HOTKEY_BIT0);
inv_hotkey -= 1;
////DSPRINTF(ds,"inv_hotkey %d",inv_hotkey);
//MONO_PRINT(ds);
// switches you to this inventory item
//PlayerUpdateInventory(pp, inv_hotkey);
pp->InventoryNum = inv_hotkey;
if (InventoryData[pp->InventoryNum].Init && !TEST(pp->Flags, PF_CLIMBING))
{
if (pp->InventoryAmount[pp->InventoryNum])
{
InventoryUse(pp);
}
#if 0
else
{
sprintf(ds,"No %s",InventoryData[pp->InventoryNum].Name);
PutStringInfo(pp,ds); // DONT have message
}
#endif
}
//PlayerUpdateInventory(pp, pp->InventoryNum);
}
}
else
{
FLAG_KEY_RESET(pp, SK_INV_HOTKEY_BIT0);
}
}
void InvBorderRefresh(PLAYERp pp)
{
int x,y;
if (pp != Player + myconnectindex)
return;
x = InventoryBarXpos[gs.BorderNum];
y = InventoryBarYpos[gs.BorderNum];
SetRedrawScreen(pp);
//BorderRefreshClip(pp, x-5, y-5, x + (MAX_INVENTORY * INVENTORY_ICON_WIDTH), y + 24);
}
void InventoryTimer(PLAYERp pp)
{
// called every time through loop
short inv = 0;
INVENTORY_DATAp id;
// if bar is up
if (pp->InventoryBarTics)
{
InventoryBarUpdatePosition(pp);
pp->InventoryBarTics -= synctics;
// if bar time has elapsed
if (pp->InventoryBarTics <= 0)
{
// get rid of the bar
KillInventoryBar(pp);
// don't update bar anymore
pp->InventoryBarTics = 0;
InvBorderRefresh(pp);
//BorderRefresh(pp);
}
}
for (id = InventoryData; id->Name; id++, inv++)
{
// if timed and active
if (TEST(id->Flags, INVF_TIMED) && pp->InventoryActive[inv])
{
// dec tics
pp->InventoryTics[inv] -= synctics;
if (pp->InventoryTics[inv] <= 0)
{
// take off a percentage
pp->InventoryPercent[inv] -= id->DecPerSec;
if (pp->InventoryPercent[inv] <= 0)
{
// ALL USED UP
pp->InventoryPercent[inv] = 0;
InventoryStop(pp, inv);
pp->InventoryActive[inv] = FALSE;
}
else
{
// reset 1 sec tic clock
pp->InventoryTics[inv] = SEC(1);
}
//PlayerUpdateInventoryPercent(pp);
PlayerUpdateInventory(pp, pp->InventoryNum);
}
}
else
// the idea behind this is that the USE function will get called
// every time the player is in an AUTO_USE situation.
// This code will decrement the timer and set the Item to InActive
// EVERY SINGLE TIME. Relies on the USE function getting called!
if (TEST(id->Flags, INVF_AUTO_USE) && pp->InventoryActive[inv])
{
pp->InventoryTics[inv] -= synctics;
if (pp->InventoryTics[inv] <= 0)
{
// take off a percentage
pp->InventoryPercent[inv] -= id->DecPerSec;
if (pp->InventoryPercent[inv] <= 0)
{
// ALL USED UP
pp->InventoryPercent[inv] = 0;
// should get rid if Amount - stop it for good
InventoryStop(pp, inv);
}
else
{
// reset 1 sec tic clock
pp->InventoryTics[inv] = SEC(1);
// set to InActive EVERY TIME THROUGH THE LOOP!
pp->InventoryActive[inv] = FALSE;
}
//PlayerUpdateInventoryPercent(pp);
PlayerUpdateInventory(pp, pp->InventoryNum);
}
}
}
}
//////////////////////////////////////////////////////////////////////
//
// INVENTORY BAR
//
//////////////////////////////////////////////////////////////////////
void SpawnInventoryBar(PLAYERp pp)
{
short inv = 0;
INVENTORY_DATAp id;
PANEL_SPRITEp psp;
// its already up
if (pp->InventoryBarTics)
{
pp->InventoryBarTics = SEC(2);
return;
}
pp->InventorySelectionBox = SpawnIcon(pp, ps_PanelSelectionBox);
for (id = InventoryData; id->Name; id++, inv++)
{
psp = SpawnInventoryIcon(pp, inv);
if (!pp->InventoryAmount[inv])
{
//SET(psp->flags, PANF_TRANSLUCENT);
//SET(psp->flags, PANF_TRANS_FLIP);
psp->shade = 100; //Darken it
}
}
pp->InventoryBarTics = SEC(2);
}
void KillInventoryBar(PLAYERp pp)
{
KillAllPanelInv(pp);
KillPlayerIcon(pp, &pp->InventorySelectionBox);
}
// In case the BorderNum changes - move the postions
void InventoryBarUpdatePosition(PLAYERp pp)
{
short inv = 0;
short x,y;
INVENTORY_DATAp id;
x = InventoryBarXpos[gs.BorderNum] + (pp->InventoryNum * INVENTORY_ICON_WIDTH);
y = InventoryBarYpos[gs.BorderNum];
pp->InventorySelectionBox->x = x - 5;
pp->InventorySelectionBox->y = y - 5;
for (id = InventoryData; id->Name && inv < MAX_INVENTORY; id++, inv++)
{
x = InventoryBarXpos[gs.BorderNum] + (inv * INVENTORY_ICON_WIDTH);
y = InventoryBarYpos[gs.BorderNum];
pp->InventorySprite[inv]->x = x;
pp->InventorySprite[inv]->y = y;
}
}
void InventoryUse(PLAYERp pp)
{
INVENTORY_DATAp id = &InventoryData[pp->InventoryNum];
if (id->Init)
(*id->Init)(pp);
}
void InventoryStop(PLAYERp pp, short InventoryNum)
{
INVENTORY_DATAp id = &InventoryData[InventoryNum];
if (id->Stop)
(*id->Stop)(pp, InventoryNum);
}
/////////////////////////////////////////////////////////////////
//
// Inventory Console Area
//
/////////////////////////////////////////////////////////////////
#define INVENTORY_BOX_X 231
#define INVENTORY_BOX_Y (176-8)
#define INVENTORY_BOX_ERASE 2403
short InventoryBoxX;
short InventoryBoxY;
short InventoryXoff;
short InventoryYoff;
void (*InventoryDisplayString)(PLAYERp, short, short, short, const char *);
#define INVENTORY_PIC_XOFF 1
#define INVENTORY_PIC_YOFF 1
#define INVENTORY_PERCENT_XOFF 19
#define INVENTORY_PERCENT_YOFF 13
#define INVENTORY_STATE_XOFF 19
#define INVENTORY_STATE_YOFF 1
void PlayerUpdateInventory(PLAYERp pp, short InventoryNum)
{
USERp u = User[pp->PlayerSprite];
short w,h;
// Check for items that need to go translucent from use
if (pp->InventoryBarTics)
{
short inv = 0;
INVENTORY_DATAp id;
PANEL_SPRITEp psp;
// Go translucent if used
for (id = InventoryData; id->Name && inv < MAX_INVENTORY; id++, inv++)
{
psp = pp->InventorySprite[inv];
if (!psp)
continue;
if (!pp->InventoryAmount[inv])
{
//SET(psp->flags, PANF_TRANSLUCENT);
//SET(psp->flags, PANF_TRANS_FLIP);
psp->shade = 100; // Darken it
}
else
{
//RESET(psp->flags, PANF_TRANSLUCENT);
//RESET(psp->flags, PANF_TRANS_FLIP);
psp->shade = 0;
}
}
}
pp->InventoryNum = InventoryNum;
if (pp->InventoryNum < 0)
pp->InventoryNum = MAX_INVENTORY-1;
if (pp->InventoryNum >= MAX_INVENTORY)
pp->InventoryNum = 0;
if (pp - Player != screenpeek)
return;
if (gs.BorderNum == BORDER_MINI_BAR)
{
InventoryBoxX = MINI_BAR_INVENTORY_BOX_X;
InventoryBoxY = MINI_BAR_INVENTORY_BOX_Y;
InventoryXoff = 1;
InventoryYoff = 1;
InventoryDisplayString = DisplayMiniBarSmString;
}
else
{
if (gs.BorderNum < BORDER_BAR)
return;
InventoryBoxX = INVENTORY_BOX_X;
InventoryBoxY = INVENTORY_BOX_Y;
InventoryXoff = 0;
InventoryYoff = 0;
InventoryDisplayString = DisplaySmString;
// erase old info
pSpawnFullScreenSprite(pp, INVENTORY_BOX_ERASE, PRI_MID, INVENTORY_BOX_X, INVENTORY_BOX_Y);
// put pic
if (pp->InventoryAmount[pp->InventoryNum])
PlayerUpdateInventoryPic(pp);
}
if (pp->InventoryAmount[pp->InventoryNum])
{
// Auto/On/Off
PlayerUpdateInventoryState(pp);
// Percent count/Item count
PlayerUpdateInventoryPercent(pp);
}
}
void PlayerUpdateInventoryPercent(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short x,y;
INVENTORY_DATAp id = &InventoryData[pp->InventoryNum];
x = InventoryBoxX + INVENTORY_PERCENT_XOFF + InventoryXoff;
y = InventoryBoxY + INVENTORY_PERCENT_YOFF + InventoryYoff;
if (TEST(id->Flags, INVF_COUNT))
{
sprintf(ds,"%d", pp->InventoryAmount[pp->InventoryNum]);
InventoryDisplayString(pp, x, y, 0, ds);
}
else
{
sprintf(ds,"%d%c", pp->InventoryPercent[pp->InventoryNum],'%');
InventoryDisplayString(pp, x, y, 0, ds);
}
}
void PlayerUpdateInventoryPic(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
PANEL_SPRITEp psp;
short pic;
short x,y;
INVENTORY_DATAp id = &InventoryData[pp->InventoryNum];
x = InventoryBoxX + INVENTORY_PIC_XOFF + InventoryXoff;
y = InventoryBoxY + INVENTORY_PIC_YOFF + InventoryYoff;
pic = id->State->picndx;
psp = pSpawnFullScreenSprite(pp, pic, PRI_FRONT_MAX, x, y);
psp->scale = id->Scale;
}
void PlayerUpdateInventoryState(PLAYERp pp)
{
USERp u = User[pp->PlayerSprite];
short x,y;
INVENTORY_DATAp id = &InventoryData[pp->InventoryNum];
x = InventoryBoxX + INVENTORY_STATE_XOFF + InventoryXoff;
y = InventoryBoxY + INVENTORY_STATE_YOFF + InventoryYoff;
if (TEST(id->Flags, INVF_AUTO_USE))
{
sprintf(ds,"%s", "AUTO");
InventoryDisplayString(pp, x, y, 0, ds);
}
else if (TEST(id->Flags, INVF_TIMED))
{
sprintf(ds,"%s", pp->InventoryActive[pp->InventoryNum] ? "ON" : "OFF");
InventoryDisplayString(pp, x, y, 0, ds);
}
}
END_SW_NS