mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-30 15:52:09 +00:00
b4d3715345
Made ZScript implementation of chain wiggling in Heretic status bar as close as possible to C++ SBARINFO one https://forum.zdoom.org/viewtopic.php?t=59840
219 lines
6.4 KiB
Text
219 lines
6.4 KiB
Text
class HereticStatusBar : BaseStatusBar
|
|
{
|
|
DynamicValueInterpolator mHealthInterpolator;
|
|
HUDFont mHUDFont;
|
|
HUDFont mIndexFont;
|
|
HUDFont mBigFont;
|
|
InventoryBarState diparms;
|
|
InventoryBarState diparms_sbar;
|
|
private int wiggle;
|
|
|
|
|
|
override void Init()
|
|
{
|
|
Super.Init();
|
|
SetSize(42, 320, 200);
|
|
|
|
// Create the font used for the fullscreen HUD
|
|
Font fnt = "HUDFONT_RAVEN";
|
|
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0") + 1, true, 1, 1);
|
|
fnt = "INDEXFONT_RAVEN";
|
|
mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true);
|
|
fnt = "BIGFONT";
|
|
mBigFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 2, 2);
|
|
diparms = InventoryBarState.Create(mIndexFont);
|
|
diparms_sbar = InventoryBarState.CreateNoBox(mIndexFont, boxsize:(31, 31), arrowoffs:(0,-10));
|
|
mHealthInterpolator = DynamicValueInterpolator.Create(0, 0.25, 1, 8);
|
|
}
|
|
|
|
override int GetProtrusion(double scaleratio) const
|
|
{
|
|
return scaleratio > 0.7? 8 : 0;
|
|
}
|
|
|
|
override void NewGame ()
|
|
{
|
|
Super.NewGame();
|
|
mHealthInterpolator.Reset (0);
|
|
}
|
|
|
|
override void Tick()
|
|
{
|
|
Super.Tick();
|
|
mHealthInterpolator.Update(CPlayer.health);
|
|
|
|
// wiggle the chain if it moves
|
|
if (level.time & 1)
|
|
{
|
|
wiggle = (mHealthInterpolator.GetValue() != CPlayer.health) && Random[ChainWiggle](0, 1);
|
|
}
|
|
}
|
|
|
|
override void Draw (int state, double TicFrac)
|
|
{
|
|
Super.Draw (state, TicFrac);
|
|
|
|
if (state == HUD_StatusBar)
|
|
{
|
|
BeginStatusBar();
|
|
DrawMainBar (TicFrac);
|
|
}
|
|
else if (state == HUD_Fullscreen)
|
|
{
|
|
BeginHUD();
|
|
DrawFullScreenStuff ();
|
|
}
|
|
}
|
|
|
|
protected void DrawMainBar (double TicFrac)
|
|
{
|
|
DrawImage("BARBACK", (0, 158), DI_ITEM_OFFSETS);
|
|
DrawImage("LTFCTOP", (0, 148), DI_ITEM_OFFSETS);
|
|
DrawImage("RTFCTOP", (290, 148), DI_ITEM_OFFSETS);
|
|
if (isInvulnerable())
|
|
{
|
|
//god mode
|
|
DrawImage("GOD1", (16, 167), DI_ITEM_OFFSETS);
|
|
DrawImage("GOD2", (287, 167), DI_ITEM_OFFSETS);
|
|
}
|
|
//health
|
|
DrawImage("CHAINCAC", (0, 190), DI_ITEM_OFFSETS);
|
|
// wiggle the chain if it moves
|
|
int inthealth = mHealthInterpolator.GetValue();
|
|
DrawGem("CHAIN", "LIFEGEM2",inthealth, CPlayer.mo.GetMaxHealth(true), (2, 191 + wiggle), 15, 25, 16, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP);
|
|
DrawImage("LTFACE", (0, 190), DI_ITEM_OFFSETS);
|
|
DrawImage("RTFACE", (276, 190), DI_ITEM_OFFSETS);
|
|
DrawShader(SHADER_HORZ, (19, 190), (16, 10));
|
|
DrawShader(SHADER_HORZ|SHADER_REVERSE, (278, 190), (16, 10));
|
|
|
|
if (!isInventoryBarVisible())
|
|
{
|
|
//statbar
|
|
if (!deathmatch)
|
|
{
|
|
DrawImage("LIFEBAR", (34, 160), DI_ITEM_OFFSETS);
|
|
DrawImage("ARMCLEAR", (57, 171), DI_ITEM_OFFSETS);
|
|
DrawString(mHUDFont, FormatNumber(mHealthInterpolator.GetValue(), 3), (88, 170), DI_TEXT_ALIGN_RIGHT);
|
|
}
|
|
else
|
|
{
|
|
DrawImage("STATBAR", (34, 160), DI_ITEM_OFFSETS);
|
|
DrawImage("ARMCLEAR", (57, 171), DI_ITEM_OFFSETS);
|
|
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (88, 170), DI_TEXT_ALIGN_RIGHT);
|
|
}
|
|
DrawString(mHUDFont, FormatNumber(GetArmorAmount(), 3), (255, 170), DI_TEXT_ALIGN_RIGHT);
|
|
|
|
//ammo
|
|
Ammo ammo1, ammo2;
|
|
[ammo1, ammo2] = GetCurrentAmmo();
|
|
if (ammo1 != null && ammo2 == null)
|
|
{
|
|
DrawString(mHUDFont, FormatNumber(ammo1.Amount, 3), (136, 162), DI_TEXT_ALIGN_RIGHT);
|
|
DrawTexture(ammo1.icon, (123, 180), DI_ITEM_CENTER);
|
|
}
|
|
else if (ammo2 != null)
|
|
{
|
|
DrawString(mIndexFont, FormatNumber(ammo1.Amount, 3), (137, 165), DI_TEXT_ALIGN_RIGHT);
|
|
DrawString(mIndexFont, FormatNumber(ammo2.Amount, 3), (137, 177), DI_TEXT_ALIGN_RIGHT);
|
|
DrawTexture(ammo1.icon, (115, 169), DI_ITEM_CENTER);
|
|
DrawTexture(ammo2.icon, (115, 180), DI_ITEM_CENTER);
|
|
}
|
|
|
|
//keys
|
|
if (CPlayer.mo.CheckKeys(3, false, true)) DrawImage("YKEYICON", (153, 164), DI_ITEM_OFFSETS);
|
|
if (CPlayer.mo.CheckKeys(1, false, true)) DrawImage("GKEYICON", (153, 172), DI_ITEM_OFFSETS);
|
|
if (CPlayer.mo.CheckKeys(2, false, true)) DrawImage("BKEYICON", (153, 180), DI_ITEM_OFFSETS);
|
|
|
|
//inventory box
|
|
if (CPlayer.mo.InvSel != null)
|
|
{
|
|
DrawInventoryIcon(CPlayer.mo.InvSel, (194, 175), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
|
|
if (CPlayer.mo.InvSel.Amount > 1)
|
|
{
|
|
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (209, 182), DI_TEXT_ALIGN_RIGHT);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DrawImage("INVBAR", (34, 160), DI_ITEM_OFFSETS);
|
|
DrawInventoryBar(diparms_sbar, (49, 160), 7, DI_ITEM_LEFT_TOP, HX_SHADOW);
|
|
}
|
|
}
|
|
|
|
protected void DrawFullScreenStuff ()
|
|
{
|
|
//health
|
|
DrawImage("PTN1A0", (51, -3));
|
|
DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT);
|
|
|
|
//armor
|
|
let armor = CPlayer.mo.FindInventory("BasicArmor");
|
|
if (armor != null && armor.Amount > 0)
|
|
{
|
|
DrawInventoryIcon(armor, (58, -24));
|
|
DrawString(mBigFont, FormatNumber(armor.Amount, 3), (41, -43), DI_TEXT_ALIGN_RIGHT);
|
|
}
|
|
//frags/keys
|
|
if (deathmatch)
|
|
{
|
|
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (70, -16));
|
|
}
|
|
else
|
|
{
|
|
Vector2 keypos = (60, -1);
|
|
int rowc = 0;
|
|
double roww = 0;
|
|
for(let i = CPlayer.mo.Inv; i != null; i = i.Inv)
|
|
{
|
|
if (i is "Key" && i.Icon.IsValid())
|
|
{
|
|
DrawTexture(i.Icon, keypos, DI_ITEM_LEFT_BOTTOM);
|
|
Vector2 size = TexMan.GetScaledSize(i.Icon);
|
|
keypos.Y -= size.Y + 2;
|
|
roww = max(roww, size.X);
|
|
if (++rowc == 3)
|
|
{
|
|
keypos.Y = -1;
|
|
keypos.X += roww + 2;
|
|
roww = 0;
|
|
rowc = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//ammo
|
|
Ammo ammo1, ammo2;
|
|
[ammo1, ammo2] = GetCurrentAmmo();
|
|
int y = -22;
|
|
if (ammo1 != null)
|
|
{
|
|
DrawTexture(ammo1.Icon, (-17, y));
|
|
DrawString(mHUDFont, FormatNumber(ammo1.Amount, 3), (-3, y+7), DI_TEXT_ALIGN_RIGHT);
|
|
y -= 40;
|
|
}
|
|
if (ammo2 != null)
|
|
{
|
|
DrawTexture(ammo2.Icon, (-14, y));
|
|
DrawString(mHUDFont, FormatNumber(ammo2.Amount, 3), (-3, y+7), DI_TEXT_ALIGN_RIGHT);
|
|
y -= 40;
|
|
}
|
|
|
|
if (!isInventoryBarVisible() && !level.NoInventoryBar && CPlayer.mo.InvSel != null)
|
|
{
|
|
// This code was changed to always fit the item into the box, regardless of alignment or sprite size.
|
|
// Heretic's ARTIBOX is 30x30 pixels.
|
|
DrawImage("ARTIBOX", (-46, -1), 0, HX_SHADOW);
|
|
DrawInventoryIcon(CPlayer.mo.InvSel, (-46, -15), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28));
|
|
if (CPlayer.mo.InvSel.Amount > 1)
|
|
{
|
|
DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-32, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT);
|
|
}
|
|
}
|
|
if (isInventoryBarVisible())
|
|
{
|
|
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
|
|
}
|
|
}
|
|
}
|