From b9485d4edfdac0f0b02c6a4838b1b02d3f5e5fb0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 28 Mar 2017 11:00:05 +0200 Subject: [PATCH] - ported the Hexen status bar to zscript. Note that DrawBar with a background texture does not work yet because the clipping rectangle is not done yet. --- src/am_map.cpp | 2 + src/g_statusbar/sbar.h | 1 + src/g_statusbar/shared_sbar.cpp | 80 ++++++ wadsrc/static/mapinfo/hexen.txt | 3 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/base.txt | 1 + wadsrc/static/zscript/statusbar/doom_sbar.txt | 6 +- .../static/zscript/statusbar/heretic_sbar.txt | 9 +- .../static/zscript/statusbar/hexen_sbar.txt | 258 ++++++++++++++++++ wadsrc/static/zscript/statusbar/statusbar.txt | 81 +++++- 10 files changed, 430 insertions(+), 12 deletions(-) create mode 100644 wadsrc/static/zscript/statusbar/hexen_sbar.txt diff --git a/src/am_map.cpp b/src/am_map.cpp index 1922b967c..f4382f0fd 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -734,6 +734,8 @@ static int grid = 0; bool automapactive = false; +DEFINE_GLOBAL(automapactive); + // location of window on screen static int f_x; static int f_y; diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index e4ad4e69b..d7c771767 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -397,6 +397,7 @@ public: void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY); void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY); + void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0); void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false); void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false); diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index af294f19d..06f5bed40 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -1935,6 +1935,86 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, DrawString) } +//============================================================================ +// +// draw stuff +// +//============================================================================ + +void DBaseStatusBar::Fill(PalEntry color, double x, double y, double w, double h, int flags) +{ + // resolve auto-alignment before making any adjustments to the position values. + if (!(flags & DI_SCREEN_MANUAL_ALIGN)) + { + if (x < 0) flags |= DI_SCREEN_RIGHT; + else flags |= DI_SCREEN_LEFT; + if (y < 0) flags |= DI_SCREEN_BOTTOM; + else flags |= DI_SCREEN_TOP; + } + + double Alpha = color.a * this->Alpha / 255; + if (Alpha <= 0) return; + x += drawOffset.X; + y += drawOffset.Y; + + if (!fullscreenOffsets) + { + x += ST_X; + //y += ST_Y; + + // Todo: Allow other scaling values, too. + if (Scaled) + { + screen->VirtualToRealCoords(x, y, w, h, HorizontalResolution, VerticalResolution, true, true); + } + } + else + { + double orgx, orgy; + + switch (flags & DI_SCREEN_HMASK) + { + default: orgx = 0; break; + case DI_SCREEN_HCENTER: orgx = screen->GetWidth() / 2; break; + case DI_SCREEN_RIGHT: orgx = screen->GetWidth(); break; + } + + switch (flags & DI_SCREEN_VMASK) + { + default: orgy = 0; break; + case DI_SCREEN_VCENTER: orgy = screen->GetHeight() / 2; break; + case DI_SCREEN_BOTTOM: orgy = screen->GetHeight(); break; + } + + // move stuff in the top right corner a bit down if the fps counter is on. + if ((flags & (DI_SCREEN_HMASK | DI_SCREEN_VMASK)) == DI_SCREEN_RIGHT_TOP && vid_fps) y += 10; + + DVector2 Scale = GetHUDScale(); + + x *= Scale.X; + y *= Scale.Y; + w *= Scale.X; + h *= Scale.Y; + x += orgx; + y += orgy; + } + screen->Dim(color, float(Alpha), int(x), int(y), int(w), int(h)); +} + + +DEFINE_ACTION_FUNCTION(DBaseStatusBar, Fill) +{ + PARAM_SELF_PROLOGUE(DBaseStatusBar); + PARAM_COLOR(color); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(w); + PARAM_FLOAT(h); + PARAM_INT_DEF(flags); + self->Fill(color, x, y, w, h); + return 0; +} + //============================================================================ // // CCMD showpop diff --git a/wadsrc/static/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt index 6b17df101..37afe7336 100644 --- a/wadsrc/static/mapinfo/hexen.txt +++ b/wadsrc/static/mapinfo/hexen.txt @@ -27,7 +27,8 @@ gameinfo defaultbloodcolor = "68 00 00" defaultbloodparticlecolor = "ff 00 00" backpacktype = "BagOfHolding" // Hexen doesn't have a backpack so use Heretic's. - statusbar = "sbarinfo/hexen.txt" + //statusbar = "sbarinfo/hexen.txt" + statusbarclass = "HexenStatusBar" intermissionmusic = "hub" intermissioncounter = false weaponslot = 1, "FWeapFist", "CWeapMace", "MWeapWand" diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 367a9156d..99627676d 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -35,6 +35,7 @@ version "2.5" #include "zscript/statusbar/statusbar.txt" #include "zscript/statusbar/doom_sbar.txt" #include "zscript/statusbar/heretic_sbar.txt" +#include "zscript/statusbar/hexen_sbar.txt" #include "zscript/statusbar/strife_sbar.txt" #include "zscript/statusbar/sbarinfowrapper.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index a312c4688..379e660ce 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -14,6 +14,7 @@ struct _ native // These are the global variables, the struct is only here to av native play @PlayerInfo players[MAXPLAYERS]; native readonly bool playeringame[MAXPLAYERS]; + native readonly bool automapactive; native play uint gameaction; native readonly int gamestate; native readonly TextureID skyflatnum; diff --git a/wadsrc/static/zscript/statusbar/doom_sbar.txt b/wadsrc/static/zscript/statusbar/doom_sbar.txt index 7cd2ae461..2382559e5 100644 --- a/wadsrc/static/zscript/statusbar/doom_sbar.txt +++ b/wadsrc/static/zscript/statusbar/doom_sbar.txt @@ -119,7 +119,7 @@ class DoomStatusBar : BaseStatusBar { DrawTexture(GetMugShot(5), (143, 168), DI_ITEM_OFFSETS); } - if (CPlayer.inventorytics != 0 && !level.NoInventoryBar) + if (isInventoryBarVisible()) { DrawInventoryBar(diparms, (48, 169), 7, DI_ITEM_LEFT_TOP); } @@ -155,7 +155,7 @@ class DoomStatusBar : BaseStatusBar DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT); invY -= 20; } - if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null && !level.NoInventoryBar) + if (!isInventoryBarVisible() && !level.NoInventoryBar) { DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17)); DrawString(mHUDFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT); @@ -187,7 +187,7 @@ class DoomStatusBar : BaseStatusBar } } } - if (CPlayer.inventorytics != 0 && !level.NoInventoryBar) + if (isInventoryBarVisible()) { DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW); } diff --git a/wadsrc/static/zscript/statusbar/heretic_sbar.txt b/wadsrc/static/zscript/statusbar/heretic_sbar.txt index d5191b99a..e2f761501 100644 --- a/wadsrc/static/zscript/statusbar/heretic_sbar.txt +++ b/wadsrc/static/zscript/statusbar/heretic_sbar.txt @@ -11,7 +11,7 @@ class HereticStatusBar : BaseStatusBar override void Init() { Super.Init(); - SetSize(48, 320, 200); + SetSize(42, 320, 200); // Create the font used for the fullscreen HUD Font fnt = "HUDFONT_RAVEN"; @@ -75,7 +75,7 @@ class HereticStatusBar : BaseStatusBar DrawShader(SHADER_HORZ, (19, 190), (16, 10)); DrawShader(SHADER_HORZ|SHADER_REVERSE, (278, 190), (16, 10)); - if (CPlayer.inventorytics == 0 || level.NoInventoryBar) + if (!isInventoryBarVisible()) { //statbar if (!deathmatch) @@ -132,7 +132,6 @@ class HereticStatusBar : BaseStatusBar protected void DrawFullScreenStuff () { - //health DrawImage("PTN1A0", (51, -3)); DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT); @@ -190,7 +189,7 @@ class HereticStatusBar : BaseStatusBar y -= 40; } - if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null && !level.NoInventoryBar) + if (!isInventoryBarVisible() && !level.NoInventoryBar) { // This code was changed to always fit the item into the box, regardless of alignment or sprite size. // Heretic's ARTIBOX is 30x30 pixels. @@ -201,7 +200,7 @@ class HereticStatusBar : BaseStatusBar DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-32, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT); } } - if (CPlayer.inventorytics != 0 && !level.NoInventoryBar) + if (isInventoryBarVisible()) { DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW); } diff --git a/wadsrc/static/zscript/statusbar/hexen_sbar.txt b/wadsrc/static/zscript/statusbar/hexen_sbar.txt new file mode 100644 index 000000000..6f8318b27 --- /dev/null +++ b/wadsrc/static/zscript/statusbar/hexen_sbar.txt @@ -0,0 +1,258 @@ +class HexenStatusBar : BaseStatusBar +{ + DynamicValueInterpolator mHealthInterpolator; + DynamicValueInterpolator mHealthInterpolator2; + HUDFont mHUDFont; + HUDFont mIndexFont; + HUDFont mBigFont; + InventoryBarState diparms; + InventoryBarState diparms_sbar; + + + override void Init() + { + Super.Init(); + SetSize(38, 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); + mHealthInterpolator2 = DynamicValueInterpolator.Create(0, 0.25, 1, 6); // the chain uses a maximum of 6, not 8. + } + + override void NewGame () + { + Super.NewGame(); + mHealthInterpolator.Reset (0); + mHealthInterpolator2.Reset (0); + } + + override void Tick() + { + Super.Tick(); + mHealthInterpolator.Update(CPlayer.health); + mHealthInterpolator2.Update(CPlayer.health); + } + + override void Draw (int state, double TicFrac) + { + Super.Draw (state, TicFrac); + + if (state == HUD_StatusBar) + { + BeginStatusBar(320, 200, 38); + DrawMainBar (TicFrac); + } + else if (state == HUD_Fullscreen) + { + BeginHUD(320, 200, 1., false); + DrawFullScreenStuff (); + } + } + + protected void DrawFullScreenStuff () + { + //health + DrawImage("PTN1A0", (51, -3)); + DrawString(mBigFont, FormatNumber(mHealthInterpolator.GetValue()), (41, -21), DI_TEXT_ALIGN_RIGHT); + + //frags/keys + if (deathmatch) + { + DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (70, -16)); + } + + if (!isInventoryBarVisible() && !level.NoInventoryBar) + { + // 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", (-66, -1), 0, HX_SHADOW); + DrawInventoryIcon(CPlayer.mo.InvSel, (-66, -15), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28)); + if (CPlayer.mo.InvSel.Amount > 1) + { + DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-52, -2 - mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT); + } + } + + Ammo ammo1, ammo2; + [ammo1, ammo2] = GetCurrentAmmo(); + if ((ammo1 is "Mana1") || (ammo2 is "Mana1")) DrawImage("MANABRT1", (-17, -30), DI_ITEM_OFFSETS); + else DrawImage("MANADIM1", (-17, -30), DI_ITEM_OFFSETS); + if ((ammo1 is "Mana2") || (ammo2 is "Mana2")) DrawImage("MANABRT2", (-17, -15), DI_ITEM_OFFSETS); + else DrawImage("MANADIM2", (-17, -15), DI_ITEM_OFFSETS); + DrawString(mHUDFont, FormatNumber(GetAmount("Mana1"), 3), (-21, -30), DI_TEXT_ALIGN_RIGHT); + DrawString(mHUDFont, FormatNumber(GetAmount("Mana2"), 3), (-21, -15), DI_TEXT_ALIGN_RIGHT); + + if (isInventoryBarVisible()) + { + DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW); + } + } + + protected void DrawMainBar (double TicFrac) + { + DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS); + if (!automapactive) + { + if (isInventoryBarVisible()) + { + DrawImage("INVBAR", (38, 162), DI_ITEM_OFFSETS); + DrawInventoryBar(diparms_sbar, (52, 163), 7, DI_ITEM_LEFT_TOP, HX_SHADOW); + return; + } + else + { + DrawImage("STATBAR", (38, 162), DI_ITEM_OFFSETS); + + //inventory box + if (CPlayer.mo.InvSel != null) + { + DrawInventoryIcon(CPlayer.mo.InvSel, (159.5, 177), DI_ARTIFLASH|DI_ITEM_CENTER, boxsize:(28, 28)); + if (CPlayer.mo.InvSel.Amount > 1) + { + DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (174, 184), DI_TEXT_ALIGN_RIGHT); + } + } + + if (deathmatch || teamplay) + { + DrawImage("KILLS", (38, 163), DI_ITEM_OFFSETS); + DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (66, 176), DI_TEXT_ALIGN_RIGHT); + } + else + { + DrawImage("ARMCLS", (41, 178), DI_ITEM_OFFSETS); + // Note that this has been changed to use red only if the REAL health is below 25, not when an interpolated value is below 25! + DrawString(mHUDFont, FormatNumber(mHealthInterpolator.GetValue(), 3), (66, 176), DI_TEXT_ALIGN_RIGHT, CPlayer.Health < 25? Font.CR_RED : Font.CR_UNTRANSLATED); + } + + //armor + DrawImage("ARMCLS", (255, 178), DI_ITEM_OFFSETS); + DrawString(mHUDFont, FormatNumber(GetArmorSavePercent() / 5, 2), (276, 176), DI_TEXT_ALIGN_RIGHT); + + Ammo ammo1, ammo2; + [ammo1, ammo2] = GetCurrentAmmo(); + + if (ammo1 != null && !(ammo1 is "Mana1") && !(ammo1 is "Mana2")) + { + DrawImage("HAMOBACK", (77, 164), DI_ITEM_OFFSETS); + if (ammo2 != null) + { + DrawTexture(ammo1.icon, (89, 172), DI_ITEM_CENTER); + DrawTexture(ammo2.icon, (113, 172), DI_ITEM_CENTER); + DrawString(mIndexFont, FormatNumber(ammo1.amount, 3), ( 98, 182), DI_TEXT_ALIGN_RIGHT); + DrawString(mIndexFont, FormatNumber(ammo2.amount, 3), (122, 182), DI_TEXT_ALIGN_RIGHT); + } + else + { + DrawTexture(ammo1.icon, (100, 172), DI_ITEM_CENTER); + DrawString(mIndexFont, FormatNumber(ammo1.amount, 3), (109, 182), DI_TEXT_ALIGN_RIGHT); + } + } + else + { + int amt1, maxamt1, amt2, maxamt2; + [amt1, maxamt1] = GetAmount("Mana1"); + [amt2, maxamt2] = GetAmount("Mana2"); + if ((ammo1 is "Mana1") || (ammo2 is "Mana1")) + { + DrawImage("MANABRT1", (77, 164), DI_ITEM_OFFSETS); + DrawBar("MANAVL1", "", amt1, maxamt1, (94, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS); + } + else + { + DrawImage("MANADIM1", (77, 164), DI_ITEM_OFFSETS); + DrawBar("MANAVL1D", "", amt1, maxamt1, (94, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS); + } + if ((ammo1 is "Mana2") || (ammo2 is "Mana2")) + { + DrawImage("MANABRT2", (110, 164), DI_ITEM_OFFSETS); + DrawBar("MANAVL2", "", amt2, maxamt2, (102, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS); + } + else + { + DrawImage("MANADIM2", (110, 164), DI_ITEM_OFFSETS); + DrawBar("MANAVL2D", "", amt2, maxamt2, (102, 164), 1, SHADER_VERT, DI_ITEM_OFFSETS); + } + DrawString(mIndexFont, FormatNumber(amt1, 3), ( 92, 181), DI_TEXT_ALIGN_RIGHT); + DrawString(mIndexFont, FormatNumber(amt2, 3), (124, 181), DI_TEXT_ALIGN_RIGHT); + } + if (CPlayer.mo is "ClericPlayer") + { + DrawImage("WPSLOT1", (190, 162), DI_ITEM_OFFSETS); + if (CheckInventory("CWeapWraithverge")) DrawImage("WPFULL1", (190, 162), DI_ITEM_OFFSETS); + else + { + int pieces = GetWeaponPieceMask("CWeapWraithverge"); + if (pieces & 1) DrawImage("WPIECEC1", (190, 162), DI_ITEM_OFFSETS); + if (pieces & 2) DrawImage("WPIECEC2", (212, 162), DI_ITEM_OFFSETS); + if (pieces & 4) DrawImage("WPIECEC3", (225, 162), DI_ITEM_OFFSETS); + } + } + else if (CPlayer.mo is "MagePlayer") + { + DrawImage("WPSLOT2", (190, 162), DI_ITEM_OFFSETS); + if (CheckInventory("MWeapBloodscourge")) DrawImage("WPFULL2", (190, 162), DI_ITEM_OFFSETS); + else + { + int pieces = GetWeaponPieceMask("MWeapBloodscourge"); + if (pieces & 1) DrawImage("WPIECEM1", (190, 162), DI_ITEM_OFFSETS); + if (pieces & 2) DrawImage("WPIECEM2", (205, 162), DI_ITEM_OFFSETS); + if (pieces & 4) DrawImage("WPIECEM3", (224, 162), DI_ITEM_OFFSETS); + } + } + else + { + DrawImage("WPSLOT0", (190, 162), DI_ITEM_OFFSETS); + if (CheckInventory("FWeapQuietus")) DrawImage("WPFULL0", (190, 162), DI_ITEM_OFFSETS); + else + { + int pieces = GetWeaponPieceMask("FWeapQuietus"); + if (pieces & 1) DrawImage("WPIECEF1", (190, 162), DI_ITEM_OFFSETS); + if (pieces & 2) DrawImage("WPIECEF2", (225, 162), DI_ITEM_OFFSETS); + if (pieces & 4) DrawImage("WPIECEF3", (234, 162), DI_ITEM_OFFSETS); + } + } + } + } + else // automap + { + DrawImage("H2BAR", (0, 134), DI_ITEM_OFFSETS); + DrawImage("KEYBAR", (38, 162), DI_ITEM_OFFSETS); + int cnt = 0; + Vector2 keypos = (46, 164); + for(let i = CPlayer.mo.Inv; i != null; i = i.Inv) + { + if (i is "Key" && i.Icon.IsValid()) + { + DrawTexture(i.Icon, keypos, DI_ITEM_OFFSETS); + keypos.X += 20; + if (++cnt >= 5) break; + } + } + DrawHexenArmor(HEXENARMOR_ARMOR, "ARMSLOT1", (150, 164), DI_ITEM_OFFSETS); + DrawHexenArmor(HEXENARMOR_SHIELD, "ARMSLOT2", (181, 164), DI_ITEM_OFFSETS); + DrawHexenArmor(HEXENARMOR_HELM, "ARMSLOT3", (212, 164), DI_ITEM_OFFSETS); + DrawHexenArmor(HEXENARMOR_AMULET, "ARMSLOT4", (243, 164), DI_ITEM_OFFSETS); + } + + String Gem; + if (CPlayer.mo is "ClericPlayer") Gem = "LIFEGMC2"; + else if (CPlayer.mo is "MagePlayer") Gem = "LIFEGMM2"; + else Gem = "LIFEGMF2"; + + int inthealth = mHealthInterpolator2.GetValue(); + DrawGem("CHAIN", "LIFEGMF2", inthealth, CPlayer.mo.GetMaxHealth(true), (30, 193), -23, 49, 15, (multiplayer? DI_TRANSLATABLE : 0) | DI_ITEM_LEFT_TOP); + + DrawImage("LFEDGE", (0, 193), DI_ITEM_OFFSETS); + DrawImage("RTEDGE", (277, 193), DI_ITEM_OFFSETS); + } +} + diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 7219d7d55..01fbcc7ae 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -27,6 +27,7 @@ class InventoryBarState ui TextureID selector; Vector2 boxsize; Vector2 boxofs; + Vector2 selectofs; Vector2 innersize; TextureID left; @@ -52,6 +53,11 @@ class InventoryBarState ui me.innersize = innersize; me.boxofs = (me.boxsize - me.innersize) / 2; } + if (me.selector.IsValid()) + { + Vector2 sel = TexMan.GetScaledSize(me.selector); + me.selectofs = (me.boxsize - sel) / 2; + } me.left = TexMan.CheckForTexture(leftgfx, TexMan.TYPE_MiscPatch); me.right = TexMan.CheckForTexture(rightgfx, TexMan.TYPE_MiscPatch); me.arrowoffset = arrowoffs; @@ -316,6 +322,7 @@ class BaseStatusBar native ui native void DrawTexture(TextureID texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1)); native void DrawImage(String texture, Vector2 pos, int flags = 0, double Alpha = 1., Vector2 box = (-1, -1), Vector2 scale = (1, 1)); native void DrawString(HUDFont font, String string, Vector2 pos, int flags = 0, int translation = Font.CR_UNTRANSLATED, double Alpha = 1., int wrapwidth = -1, int linespacing = 4); + native void Fill(Color col, double x, double y, double w, double h, int flags = 0); native static String FormatNumber(int number, int minsize = 0, int maxsize = 0, int format = 0, String prefix = ""); @@ -513,7 +520,7 @@ class BaseStatusBar native ui bool isInventoryBarVisible() { if (CPlayer == null) return false; - return (CPlayer.inventorytics <= 0 || level.NoInventoryBar); + return (CPlayer.inventorytics > 0 && !level.NoInventoryBar); } //============================================================================ @@ -563,7 +570,7 @@ class BaseStatusBar native ui // //============================================================================ - bool CheckWeaponPiece(class weap, int piecenum) + int CheckWeaponPiece(class weap, int piecenum) { if (CPlayer == null) return false; for(let inv = CPlayer.mo.Inv; inv != NULL; inv = inv.Inv) @@ -583,6 +590,26 @@ class BaseStatusBar native ui // //============================================================================ + int GetWeaponPieceMask(class weap) + { + if (CPlayer == null) return false; + for(let inv = CPlayer.mo.Inv; inv != NULL; inv = inv.Inv) + { + let wh = WeaponHolder(inv); + if (wh != null && wh.PieceWeapon == weap) + { + return wh.PieceMask; + } + } + return 0; + } + + //============================================================================ + // + // checks if player has the given weapon piece + // + //============================================================================ + bool WeaponUsesAmmoType(class ammotype) { if (CPlayer == null) return false; @@ -794,6 +821,54 @@ class BaseStatusBar native ui DrawImage(gem, pos + (offset + leftPadding, 0), flags | DI_ITEM_LEFT_TOP); } + //============================================================================ + // + // DrawBar + // + //============================================================================ + + void DrawBar(String ongfx, String offgfx, double curval, double maxval, Vector2 position, int border, int vertical, int flags = 0, double alpha = 1.) + { + let ontex = TexMan.CheckForTexture(ongfx, TexMan.TYPE_MiscPatch); + if (!ontex.IsValid()) return; + let offtex = TexMan.CheckForTexture(offgfx, TexMan.TYPE_MiscPatch); + + Vector2 texsize = TexMan.GetScaledSize(ontex); + [position, flags] = AdjustPosition(position, flags, texsize.X, texsize.Y); + + double value = clamp(curval / maxval, 0, 1); + if(border != 0) value = 1. - value; //invert since the new drawing method requires drawing the bg on the fg. + + + // {cx, cb, cr, cy} + double Clip[4]; + Clip[0] = Clip[1] = Clip[2] = Clip[3] = 0; + + bool horizontal = !(vertical & SHADER_VERT); + bool reverse = !!(vertical & SHADER_REVERSE); + double sizeOfImage = (horizontal ? texsize.X - border*2 : texsize.Y - border*2); + Clip[(!horizontal) | ((!reverse)<<1)] = sizeOfImage - sizeOfImage *value; + + if(border != 0) + { + for(int i = 0; i < 4; i++) Clip[i] += border; + + //Draw the whole foreground + DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP); + // SetClip + } + + if (offtex.IsValid() && TexMan.GetScaledSize(offtex) == texsize) DrawTexture(offtex, position, flags | DI_ITEM_LEFT_TOP); + else Fill(color(255,0,0,0), position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3]); + + if (border == 0) + { + // SetClip + DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP); + } + // UnsetClip + } + //============================================================================ // // DrawInventoryBar @@ -837,7 +912,7 @@ class BaseStatusBar native ui { double flashAlpha = bgalpha; if (flags & DI_ARTIFLASH) flashAlpha *= itemflashFade; - DrawTexture(parms.selector, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha); + DrawTexture(parms.selector, position + parms.selectofs + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha); } } else