raze/wadsrc/static/zscript/games/sw/ui/sbar.zs
Christoph Oelckers 562c1a18c8 - integrate hud_althud into hud_size
This makes it easier to use and avoids rendering a fullscreen hud on a screen size with view border.
2022-10-30 16:51:39 +01:00

1051 lines
27 KiB
Text

//-------------------------------------------------------------------------
/*
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
*/
//-------------------------------------------------------------------------
class SWStatusBar : RazeStatusBar
{
static const String icons[] = {
"PanelMedkit",
"PanelRepairKit",
"PanelCloak",
"PanelNightVision",
"PanelChemBomb",
"PanelFlashBomb",
"PanelCaltrops"
};
static const String StatusKeyPics[] =
{
"PANEL_KEY_RED",
"PANEL_KEY_BLUE",
"PANEL_KEY_GREEN",
"PANEL_KEY_YELLOW",
"PANEL_SKELKEY_GOLD",
"PANEL_SKELKEY_SILVER",
"PANEL_SKELKEY_BRONZE",
"PANEL_SKELKEY_RED"
};
static const String ammo_sprites[] = { "", "ICON_STAR", "ICON_LG_SHOTSHELL", "ICON_LG_UZI_AMMO", "ICON_MICRO_BATTERY", "ICON_LG_GRENADE", "ICON_LG_MINE", "ICON_RAIL_AMMO",
//"ICON_FIREBALL_LG_AMMO", "ICON_HEART_LG_AMMO", "ICON_FIREBALL_LG_AMMO", "ICON_FIREBALL_LG_AMMO", "ICON_MICRO_BATTERY", "" }; fireball and heart ammo are empty.
"ICON_GUARD_HEAD", "ICON_HEART", "ICON_GUARD_HEAD", "ICON_GUARD_HEAD", "ICON_MICRO_BATTERY", "" };
enum EConstants
{
PANEL_HEALTH_BOX_X = 20,
PANEL_BOX_Y = (174 - 6),
PANEL_HEALTH_XOFF = 2,
PANEL_HEALTH_YOFF = 4,
PANEL_AMMO_BOX_X = 197,
PANEL_AMMO_XOFF = 1,
PANEL_AMMO_YOFF = 4,
WSUM_X = 93,
WSUM_Y = PANEL_BOX_Y + 1,
WSUM_XOFF = 25,
WSUM_YOFF = 6,
PANEL_KEYS_BOX_X = 276,
PANEL_KEYS_XOFF = 0,
PANEL_KEYS_YOFF = 2,
PANEL_ARMOR_BOX_X = 56,
PANEL_ARMOR_XOFF = 2,
PANEL_ARMOR_YOFF = 4,
FRAG_YOFF = 2,
INVENTORY_BOX_X = 231,
INVENTORY_BOX_Y = (176 - 8),
INVENTORY_PIC_XOFF = 1,
INVENTORY_PIC_YOFF = 1,
INVENTORY_PERCENT_XOFF = 19,
INVENTORY_PERCENT_YOFF = 13,
INVENTORY_STATE_XOFF = 19,
INVENTORY_STATE_YOFF = 1,
MINI_BAR_Y = 174,
MINI_BAR_HEALTH_BOX_X = 4,
MINI_BAR_AMMO_BOX_X = 32,
MINI_BAR_INVENTORY_BOX_X = 64,
MINI_BAR_INVENTORY_BOX_Y = MINI_BAR_Y,
}
TextureID PanelFont[10];
TextureID SmallSBFont[3][12];
HUDFont numberFont, miniFont;
override void Init()
{
numberFont = HudFont.Create(BigFont, 0, Mono_Off, 1, 1);
miniFont = HudFont.Create(SmallFont2, 0, Mono_Off, 1, 1);
for (int i = 0; i < 10; i++) PanelFont[i] = TexMan.CheckForTexture(String.Format("PANEL_FONT_G%d", i), TexMan.Type_Any);
for (int i = 0; i < 12; i++)
{
SmallSBFont[0][i] = TexMan.CheckForTexture(String.Format("PANEL_SM_FONT_G%d", i), TexMan.Type_Any);
SmallSBFont[1][i] = TexMan.CheckForTexture(String.Format("PANEL_SM_FONT_Y%d", i), TexMan.Type_Any);
SmallSBFont[2][i] = TexMan.CheckForTexture(String.Format("PANEL_SM_FONT_R%d", i), TexMan.Type_Any);
}
}
int tileHeight(String tex)
{
let img = TexMan.CheckForTexture(tex, TexMan.TYPE_Any);
let siz = TexMan.GetScaledSize(img);
return int(siz.Y);
}
int tileWidth(String tex)
{
let img = TexMan.CheckForTexture(tex, TexMan.TYPE_Any);
let siz = TexMan.GetScaledSize(img);
return int(siz.X);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayPanelNumber(double x, double y, int number)
{
String buffer;
buffer = String.Format("%03d", number);
for (uint i = 0; i < buffer.length(); i++)
{
let c = buffer.ByteAt(i);
if (c < "0" || c > "9")
{
continue;
}
let tex = PanelFont[c - 48];
DrawTexture(tex, (x, y), DI_ITEM_LEFT_TOP);
let siz = TexMan.GetScaledSize(tex);
x += siz.X + 1;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplaySummaryString(double x, double y, int color, int shade, String buffer)
{
for (uint i = 0; i < buffer.length(); i++)
{
let ch = buffer.ByteAt(i);
if (ch == "/") ch = 10;
else if (ch == ":") ch = 11;
else if (ch >= "0" && ch <= "9") ch -= 48;
else
{
if (ch != " ") Console.Printf("Invalid char %c", ch);
x += 4;
continue;
}
let font_pic = SmallSBFont[color][ch];
DrawTexture(font_pic, (x, y), DI_ITEM_LEFT_TOP, col:Raze.shadeToLight(shade));
let siz = TexMan.GetScaledSize(font_pic);
x += siz.X + 1;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayTimeLimit(SWPlayer pp)
{
int seconds = 0;// gNet.TimeLimitClock / 120;
let ds = String.Format("%03d:%02d", seconds / 60, seconds % 60);
DisplaySummaryString(PANEL_KEYS_BOX_X + 1, PANEL_BOX_Y + 6, 0, 0, ds);
}
//---------------------------------------------------------------------------
//
// todo: migrate to FFont to support localization
//
//---------------------------------------------------------------------------
void DisplayTinyString(double xs, double ys, String buffer, int pal)
{
DrawString(miniFont, buffer, (xs, ys), DI_ITEM_LEFT_TOP);
}
void DisplayFragString(SWPlayer pp, double xs, double ys, String buffer)
{
DisplayTinyString(xs, ys, buffer, 0/*pp.DisplayColor()*/);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayFragNumbers()
{
for (int pnum = 0; pnum < 4; pnum++)
{
String buffer;
int xs, ys;
int frag_bar;
static const int xoffs[] =
{
69, 147, 225, 303
};
ys = FRAG_YOFF;
// frag bar 0 or 1
frag_bar = ((pnum) / 4);
// move y down according to frag bar number
ys = ys + (tileHeight("FRAG_BAR") - 2) * frag_bar;
// move x over according to the number of players
xs = xoffs[pnum];
buffer.Format("%03d", Raze.PlayerFrags(pnum, -1));
DisplayFragString(null/*&Player[pnum]*/, xs, ys, buffer);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayFragNames()
{
for (int pnum = 0; pnum < 4; pnum++)
{
int xs, ys;
int frag_bar;
static const int xoffs[] =
{
7, 85, 163, 241
};
ys = FRAG_YOFF;
// frag bar 0 or 1
frag_bar = ((pnum) / 4);
// move y down according to frag bar number
ys = ys + (tileHeight("FRAG_BAR") - 2) * frag_bar;
// move x over according to the number of players
xs = xoffs[pnum];
DisplayFragString(null/*&Player[pnum]*/, xs, ys, Raze.PlayerName(pnum));
}
}
//---------------------------------------------------------------------------
//
// This cannot remain as it is.
//
//---------------------------------------------------------------------------
void DisplayFragBar(SWPlayer pp)
{
// must draw this in HUD mode and align to the top center
int i, num_frag_bars;
int y;
int numplayers = 1;
if (numplayers <= 1) return;
//if (gNet.MultiGameType == MULTI_GAME_COOPERATIVE) return;
num_frag_bars = ((numplayers-1)/4)+1;
for (i = 0, y = 0; i < num_frag_bars; i++)
{
DrawImage("FRAG_BAR", (0, y), DI_ITEM_LEFT_TOP);
y += tileHeight("FRAG_BAR") - 2;
}
DisplayFragNames();
DisplayFragNumbers();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void PlayerUpdateWeaponSummary(SWPlayer pp, int UpdateWeaponNum)
{
int x, y;
int pos;
int column;
int WeaponNum, wpntmp;
int colr, shade;
String ds;
WeaponNum = SW.RealWeapon(UpdateWeaponNum);
static const int wsum_xoff[] = { 0,36,66 };
static const String wsum_fmt2[] = { "%3d/%-3d", "%2d/%-2d", "%2d/%-2d" };
pos = WeaponNum - 1;
column = pos / 3;
if (column > 2) column = 2;
x = WSUM_X + wsum_xoff[column];
y = WSUM_Y + (WSUM_YOFF * (pos % 3));
if (UpdateWeaponNum == pp.WeaponNum())
{
shade = 0;
colr = 0;
}
else
{
shade = 11;
colr = 0;
}
wpntmp = WeaponNum + 1;
if (wpntmp > 9)
wpntmp = 0;
ds = String.Format("%d:", wpntmp);
if (pp.WpnFlags & (1 << WeaponNum))
DisplaySummaryString(x, y, 1, shade, ds);
else
DisplaySummaryString(x, y, 2, shade + 6, ds);
ds = String.Format(wsum_fmt2[column], pp.WpnAmmo[WeaponNum], SW.WeaponMaxAmmo(WeaponNum));
DisplaySummaryString(x + 6, y, colr, shade, ds);
}
void PlayerUpdateWeaponSummaryAll(SWPlayer pp)
{
for (int i = SW.WPN_STAR; i <= SW.WPN_HEART; i++)
{
PlayerUpdateWeaponSummary(pp, i);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayKeys(SWPlayer pp, double xs, double ys, double scalex = 1, double scaley = 1)
{
double x, y;
int row, col;
int i;
let tex = TexMan.CheckForTexture("PANEL_KEY_RED", TexMan.Type_Any);
let size = TexMan.GetScaledSize(tex) + (1, 2);
i = 0;
for (row = 0; row < 2; row++)
{
for (col = 0; col < 2; col++)
{
if (pp.HasKey[i])
{
x = xs + PANEL_KEYS_XOFF + (row * size.X);
y = ys + PANEL_KEYS_YOFF + (col * size.Y);
DrawImage(StatusKeyPics[i], (x, y), DI_ITEM_LEFT_TOP, scale:(scalex, scaley));
}
i++;
}
}
// Check for skeleton keys
i = 0;
for (row = 0; row < 2; row++)
{
for (col = 0; col < 2; col++)
{
if (pp.HasKey[i + 4])
{
x = xs + PANEL_KEYS_XOFF + (row * size.X);
y = ys + PANEL_KEYS_YOFF + (col * size.Y);
DrawImage(StatusKeyPics[i + 4], (x, y), DI_ITEM_LEFT_TOP, scale:(scalex, scaley));
}
i++;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayAllKeys(SWPlayer pp, double xs, double ys, double scalex = 1, double scaley = 1)
{
double x, y;
int i;
let tex = TexMan.CheckForTexture("PANEL_KEY_RED", TexMan.Type_Any);
let size = TexMan.GetScaledSize(tex) + (1, 2);
i = 0;
int row = 0;
for (int key = 0; key < 8; key++)
{
if (pp.HasKey[key])
{
DrawImage(StatusKeyPics[key], (xs, ys), DI_ITEM_LEFT_TOP, scale:(scalex, scaley));
if (row == 0) ys += PANEL_KEYS_YOFF + size.Y;
else
{
ys -= PANEL_KEYS_YOFF + size.Y;
xs -= PANEL_KEYS_XOFF + size.X;
}
row ^= 1;
}
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void PlayerUpdateInventoryPercent(SWPlayer pp, double InventoryBoxX, double InventoryBoxY, double InventoryXoff, double InventoryYoff)
{
String ds;
double x = InventoryBoxX + INVENTORY_PERCENT_XOFF + InventoryXoff;
double y = InventoryBoxY + INVENTORY_PERCENT_YOFF + InventoryYoff;
if (SW.InventoryFlags(pp.InventoryNum) & SW.INVF_COUNT)
{
ds = String.Format("%d", pp.InventoryAmount[pp.InventoryNum]);
}
else
{
ds = String.Format("%d%%", pp.InventoryPercent[pp.InventoryNum]);
}
DisplayTinyString(x, y, ds, 0);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void PlayerUpdateInventoryPic(SWPlayer pp, int InventoryBoxX, int InventoryBoxY, int InventoryXoff, int InventoryYoff)
{
int x = InventoryBoxX + INVENTORY_PIC_XOFF + InventoryXoff;
int y = InventoryBoxY + INVENTORY_PIC_YOFF + InventoryYoff;
DrawImage(icons[pp.InventoryNum], (x, y), DI_ITEM_LEFT_TOP);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void PlayerUpdateInventoryState(SWPlayer pp, double InventoryBoxX, double InventoryBoxY, int InventoryXoff, int InventoryYoff)
{
double x = InventoryBoxX + INVENTORY_STATE_XOFF + InventoryXoff;
double y = InventoryBoxY + INVENTORY_STATE_YOFF + InventoryYoff;
let flags = SW.InventoryFlags(pp.InventoryNum);
if (flags & SW.INVF_AUTO_USE)
{
DisplayTinyString(x, y, "AUTO", 0);
}
else if (flags & SW.INVF_TIMED)
{
DisplayTinyString(x, y, pp.InventoryActive[pp.InventoryNum] ? "ON" : "OFF", 0);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayBarInventory(SWPlayer pp)
{
int InventoryBoxX = INVENTORY_BOX_X;
int InventoryBoxY = INVENTORY_BOX_Y;
int InventoryXoff = -1;
int InventoryYoff = 0;
// put pic
if (pp.InventoryAmount[pp.InventoryNum])
{
PlayerUpdateInventoryPic(pp, InventoryBoxX, InventoryBoxY, 0, InventoryYoff);
// Auto/On/Off
PlayerUpdateInventoryState(pp, InventoryBoxX, InventoryBoxY, InventoryXoff, InventoryYoff);
// Percent count/Item count
PlayerUpdateInventoryPercent(pp, InventoryBoxX, InventoryBoxY, InventoryXoff, InventoryYoff);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
int NORM_CANG(int ang)
{
return (((ang)+32) & 31);
}
enum EXY
{
COMPASS_X = 140,
COMPASS_Y = (162 - 5),
};
void DrawCompass(SWPlayer pp)
{
int start_ang, ang;
int x_size = tileWidth("COMPASS_NORTH");
int x;
int i;
static const String CompassPic[] =
{
"COMPASS_EAST", "COMPASS_EAST2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_MID_TIC", "COMPASS_MID_TIC2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_SOUTH", "COMPASS_SOUTH2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_MID_TIC", "COMPASS_MID_TIC2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_WEST", "COMPASS_WEST2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_MID_TIC", "COMPASS_MID_TIC2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_NORTH", "COMPASS_NORTH2",
"COMPASS_TIC", "COMPASS_TIC2",
"COMPASS_MID_TIC", "COMPASS_MID_TIC2",
"COMPASS_TIC", "COMPASS_TIC2"
};
static const int CompassShade[] =
{
//20, 16, 11, 6, 1, 1, 6, 11, 16, 20
25, 19, 15, 9, 1, 1, 9, 15, 19, 25
};
ang = pp.GetBuildAngle();
if (pp.sop_remote)
ang = 0;
start_ang = (ang + 32) >> 6;
start_ang = NORM_CANG(start_ang - 4);
for (i = 0, x = COMPASS_X; i < 10; i++)
{
DrawImage(CompassPic[NORM_CANG(start_ang + i)], (x, COMPASS_Y), DI_ITEM_LEFT_TOP, col:Raze.shadeToLight(CompassShade[i]));
x += x_size;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawStatusBar(SWPlayer pp)
{
let wnum = pp.WeaponNum();
BeginStatusBar(false, 320, 200, tileHeight("STATUS_BAR"));
if (hud_size == Hud_StbarOverlay) Set43ClipRect();
DrawImage("STATUS_BAR", (160, 200), DI_ITEM_CENTER_BOTTOM);
screen.ClearClipRect();
DisplayPanelNumber(PANEL_HEALTH_BOX_X + PANEL_HEALTH_XOFF, PANEL_BOX_Y + PANEL_HEALTH_YOFF, pp.Health());
DisplayPanelNumber(PANEL_ARMOR_BOX_X + PANEL_ARMOR_XOFF, PANEL_BOX_Y + PANEL_ARMOR_YOFF, pp.Armor);
if (wnum != SW.WPN_FIST && wnum != SW.WPN_SWORD) DisplayPanelNumber(PANEL_AMMO_BOX_X + PANEL_AMMO_XOFF, PANEL_BOX_Y + PANEL_AMMO_YOFF, pp.WpnAmmo[wnum]);
PlayerUpdateWeaponSummaryAll(pp);
/*
if (gNet.MultiGameType != MULTI_GAME_COMMBAT)
DisplayKeys(pp, PANEL_KEYS_BOX_X, PANEL_BOX_Y);
else if (gNet.TimeLimit)
DisplayTimeLimit(pp);
*/
DisplayKeys(pp, PANEL_KEYS_BOX_X, PANEL_BOX_Y);
DisplayBarInventory(pp);
DrawCompass(pp);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DisplayMinibarInventory(SWPlayer pp)
{
int InventoryBoxX = MINI_BAR_INVENTORY_BOX_X;
int InventoryBoxY = MINI_BAR_INVENTORY_BOX_Y - 200;
int InventoryXoff = 0;
int InventoryYoff = 1;
if (pp.InventoryAmount[pp.InventoryNum])
{
PlayerUpdateInventoryPic(pp, InventoryBoxX, InventoryBoxY, InventoryXoff + 1, InventoryYoff);
// Auto/On/Off
PlayerUpdateInventoryState(pp, InventoryBoxX, InventoryBoxY, InventoryXoff, InventoryYoff);
// Percent count/Item count
PlayerUpdateInventoryPercent(pp, InventoryBoxX, InventoryBoxY, InventoryXoff, InventoryYoff);
}
}
//---------------------------------------------------------------------------
//
// Used in DrawHUD2() for determining whether a reloadable weapon is reloading.
//
//---------------------------------------------------------------------------
bool, int DoReloadStatus(int reloadstate, int ammo)
{
bool reloading = ammo == 0 && reloadstate != 2;
if (ammo == 0 && reloadstate == 0)
{
reloadstate = 1;
}
else if (ammo)
{
reloadstate = 0;
}
return reloading, reloadstate;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawHUD1(SWPlayer pp)
{
BeginHUD(1, false, 320, 200);
int x = MINI_BAR_HEALTH_BOX_X;
int y = -26;
DrawImage("MINI_BAR_HEALTH_BOX_PIC", (x, y), DI_ITEM_LEFT_TOP);
x = MINI_BAR_HEALTH_BOX_X + 3;
DisplayPanelNumber(x, y + 5, pp.Health());
let wnum = pp.WeaponNum();
if (wnum != SW.WPN_SWORD && wnum != SW.WPN_FIST)
{
x = MINI_BAR_AMMO_BOX_X;
DrawImage("MINI_BAR_AMMO_BOX_PIC", (x, y), DI_ITEM_LEFT_TOP);
x = MINI_BAR_AMMO_BOX_X + 3;
DisplayPanelNumber(x, y + 5, pp.WpnAmmo[wnum]);
}
if (!pp.InventoryAmount[pp.InventoryNum])
return;
// Inventory Box
x = MINI_BAR_INVENTORY_BOX_X;
DrawImage("MINI_BAR_INVENTORY_BOX_PIC", (x, y), DI_ITEM_LEFT_TOP);
DisplayMinibarInventory(pp);
}
//==========================================================================
//
// Fullscreen HUD variant #1
//
//==========================================================================
void DrawHUD2(SWPlayer pp, SummaryInfo info)
{
BeginHUD(1, false, 320, 200);
String format;
double imgScale;
double baseScale = numberFont.mFont.GetHeight();
//
// Health
//
let img = TexMan.CheckForTexture("ICON_SM_MEDKIT", TexMan.Type_Any);
let siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (1.5, -1), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
let Health = pp.Health();
let MaxHealth = pp.MaxUserHealth();
if (!althud_flashing || Health > (MaxHealth >> 2) || (PlayClock & 32))
{
int s = -8;
if (althud_flashing && Health > MaxHealth)
s += Raze.bsin(PlayClock << 5) >> 10;
int intens = clamp(255 - 4 * s, 0, 255);
let pe = Color(255, intens, intens, intens);
format = String.Format("%d", Health);
DrawString(numberFont, format, (24.25, -numberFont.mFont.GetHeight() - 0.5), DI_TEXT_ALIGN_LEFT);
}
//
// Armor
//
img = TexMan.CheckForTexture("ICON_ARMOR", TexMan.Type_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
DrawTexture(img, (80.75, -1), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
format = String.Format("%d", pp.Armor);
DrawString(numberFont, format, (108.5, -numberFont.mFont.GetHeight() - 0.5), DI_TEXT_ALIGN_LEFT);
//
// Weapon
//
int weapon = pp.WeaponNum();
String wicon = ammo_sprites[weapon];
if (wicon.length() > 0)
{
int ammo = pp.WpnAmmo[weapon];
bool reloadableWeapon = weapon == SW.WPN_SHOTGUN || weapon == SW.WPN_UZI;
if (!reloadableWeapon || (reloadableWeapon && !cl_showmagamt))
{
format = String.Format("%d", ammo);
}
else
{
int capacity;
switch (weapon)
{
case SW.WPN_SHOTGUN:
capacity = 4;
break;
case SW.WPN_UZI:
capacity = pp.WpnUziType ? 50 : 100;
break;
}
bool reload;
[reload, pp.WpnReloadState] = DoReloadStatus(pp.WpnReloadState, ammo % capacity);
int clip = CalcMagazineAmount(ammo, capacity, reload);
format = String.Format("%d/%d", clip, ammo - clip);
}
img = TexMan.CheckForTexture(wicon, TexMan.Type_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
let imgX = 21.125;
let strlen = format.Length();
if (strlen > 1)
{
imgX += (imgX * 0.855) * (strlen - 1);
}
if ((!althud_flashing || PlayClock & 32 || ammo > (SW.WeaponMaxAmmo(weapon) / 10)))
{
DrawString(numberFont, format, (-1.5, -numberFont.mFont.GetHeight() - 0.5), DI_TEXT_ALIGN_RIGHT);
}
DrawTexture(img, (-imgX, -1), DI_ITEM_RIGHT_BOTTOM, scale:(imgScale, imgScale));
}
//
// Selected inventory item
//
img = TexMan.CheckForTexture(icons[pp.InventoryNum], TexMan.Type_Any);
siz = TexMan.GetScaledSize(img);
imgScale = baseScale / siz.Y;
int x = 165;
DrawTexture(img, (x, -1), DI_ITEM_LEFT_BOTTOM, scale:(imgScale, imgScale));
PlayerUpdateInventoryState(pp, x + 3.0, -18.0, 1, 1);
PlayerUpdateInventoryPercent(pp, x + 3.5, -20.5, 1, 1);
//
// keys
//
DisplayAllKeys(pp, -12, -38, 0.8625, 0.8625);
DoLevelStats(baseScale + 4, info);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void DrawInventoryIcon(double xs, double ys, int align, int InventoryNum, int amount, bool selected)
{
double x, y;
int INVENTORY_ICON_WIDTH = 28;
x = xs + (InventoryNum * INVENTORY_ICON_WIDTH);
y = ys;
let tex = icons[InventoryNum];
DrawImage(tex, (x, y), align | DI_ITEM_LEFT_TOP, amount ? 1. : 0.333);
if (selected)
{
DrawImage("SelectionBox", (x - 5, y - 5), align | DI_ITEM_LEFT_TOP);
}
}
//////////////////////////////////////////////////////////////////////
//
// INVENTORY BAR
//
//////////////////////////////////////////////////////////////////////
void DrawInventory(SWPlayer pp, double xs, double ys, int align)
{
if (!pp.InventoryBarTics)
{
return;
}
for (int i = 0; i < pp.InventoryAmount.size(); i++)
{
DrawInventoryIcon(xs, ys, align, i, pp.InventoryAmount[i], i == pp.InventoryNum);
}
}
//==========================================================================
//
// Statistics output
//
//==========================================================================
void DoLevelStats(int bottomy, SummaryInfo info)
{
StatsPrintInfo stats;
stats.fontscale = 1;
stats.screenbottomspace = bottomy;
int y = -1;
int mask = 1;
if (automapMode == am_full)
{
stats.letterColor = Font.TEXTCOLOR_SAPPHIRE;
stats.standardColor = Font.TEXTCOLOR_UNTRANSLATED;
stats.statfont = SmallFont2;
stats.spacing = 6;
stats.altspacing = SmallFont.GetHeight() + 1;
y = PrintAutomapInfo(stats, info, false);
mask = 2;
}
if (hud_stats & mask)
{
stats.statfont = SmallFont;
stats.spacing = 7;
stats.letterColor = Font.TEXTCOLOR_RED;
stats.standardColor = Font.TEXTCOLOR_TAN;
stats.completeColor = Font.TEXTCOLOR_FIRE;
PrintLevelStats(stats, info, y);
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
override void UpdateStatusBar(SummaryInfo info)
{
let pp = SW.GetViewPlayer();
int nPalette = 0;
double inv_x, inv_y;
int align;
if (hud_size == Hud_Nothing)
{
align = DI_SCREEN_RIGHT_BOTTOM;
inv_x = -210;
inv_y = -28;
DoLevelStats(2, info);
}
else if (hud_size == Hud_Full)
{
align = DI_SCREEN_CENTER_BOTTOM;
inv_x = -80;
inv_y = -40;
DrawHUD2(pp, info);
}
else if (hud_size == Hud_Mini)
{
align = DI_SCREEN_RIGHT_BOTTOM;
inv_x = -210;
inv_y = -28;
DrawHUD1(pp);
DoLevelStats(30, info);
}
else
{
align = 0;
inv_x = 80;
inv_y = 130;
DrawStatusBar(pp);
DoLevelStats(-3, info);
}
DrawInventory(pp, inv_x, inv_y, align);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
override void GetAllStats(HudStats stats)
{
stats.Clear();
stats.info.fontscale = 1;
stats.info.spacing = 7;
stats.info.letterColor = Font.TEXTCOLOR_RED;
stats.info.standardColor = Font.TEXTCOLOR_TAN;
stats.info.completeColor = Font.TEXTCOLOR_FIRE;
stats.info.statfont = SmallFont;
let pp = SW.GetViewPlayer();
stats.healthicon = "ICON_SM_MEDKIT";
stats.healthvalue = pp.Health();
if (pp.Armor > 0)
{
stats.armoricons.Push("ICON_ARMOR");
stats.armorvalues.Push(pp.Armor);
}
for (int i = 0; i < 8; i++)
{
if (pp.hasKey[i])
{
stats.keyicons.Push(StatusKeyPics[i]);
}
}
// omits all weapons where ammo == weapon or secondary fire mode.
static const String weaponIcons[] = { "", "" /* shuriken*/, "ICON_SHOTGUN", "ICON_UZI", "ICON_MICRO_GUN", "ICON_GRENADE_LAUNCHER", "" /* mine */, "ICON_RAIL_GUN", "ICON_GUARD_HEAD", "ICON_HEART" };
let weap = pp.WeaponNum();
for(int i = 0; i < weaponIcons.Size(); i++)
{
if ((pp.WpnFlags & (1 << i)) && weaponIcons[i] != "")
{
if (weap == i ||
((weap == SW.WPN_NAPALM || weap == SW.WPN_RING) && i == SW.WPN_HOTHEAD) ||
(weap == SW.WPN_ROCKET && i == SW.WPN_MICRO))
{
stats.weaponselect = stats.weaponicons.Size();
}
stats.weaponicons.Push(weaponIcons[i]);
}
}
static const int ammoOrder[] = { SW.WPN_STAR, SW.WPN_SHOTGUN, SW.WPN_UZI, SW.WPN_MICRO, SW.WPN_GRENADE, SW.WPN_MINE, SW.WPN_RAIL, SW.WPN_HOTHEAD, SW.WPN_HEART };
for(int i = 0; i < ammoOrder.Size(); i++)
{
int ammonum = ammoorder[i];
if (weap == ammonum ||
((weap == SW.WPN_NAPALM || weap == SW.WPN_RING) && ammonum == SW.WPN_HOTHEAD) ||
(weap == SW.WPN_ROCKET && ammonum == SW.WPN_MICRO))
{
stats.ammoselect = stats.ammoicons.Size();
}
stats.ammoicons.Push(ammo_sprites[ammonum]);
int num = pp.WpnAmmo[ammonum];
stats.ammovalues.Push(num);
stats.ammomaxvalues.Push(SW.WeaponMaxAmmo(ammonum));
}
for (int i = 0; i < pp.InventoryAmount.size(); i++)
{
if (pp.InventoryAmount[i] > 0)
{
if (i == pp.InventoryNum) stats.inventoryselect = stats.inventoryicons.Size();
stats.inventoryicons.Push(icons[i]);
if (SW.InventoryFlags(i) & SW.INVF_COUNT)
{
stats.inventoryamounts.Push(pp.InventoryAmount[i]);
}
else
{
stats.inventoryamounts.Push(pp.InventoryPercent[i]);
}
}
}
}
}