diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index cdb191354..be8b7bb00 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -426,6 +426,8 @@ public: double CrosshairSize; double Displacement; bool ShowLog; + int artiflashTick = 0; + double itemflashFade = 0.75; player_t *CPlayer; @@ -475,9 +477,6 @@ enum DI_Flags DI_ALWAYSSHOWCOUNT = 0x200, // only for DrawInventoryBar. DI_DIMDEPLETED = 0x400, DI_DONTANIMATE = 0x800, // do not animate the texture - // These 2 flags are only used by SBARINFO - DI_DRAWINBOX = 0x1000, // Set when either width or height is not zero - DI_ALTERNATEONFAIL = 0x2000, DI_SCREEN_AUTO = 0, // decide based on given offsets. DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect @@ -531,6 +530,14 @@ enum DI_Flags DI_ALPHAMAPPED = 0x2000000, DI_NOSHADOW = 0x4000000, + DI_ALWAYSSHOWCOUNTERS = 0x8000000, + DI_ARTIFLASH = 0x10000000, + DI_FORCEFILL = 0x20000000, + + // These 2 flags are only used by SBARINFO so these duplicate other flags not used by SBARINFO + DI_DRAWINBOX = DI_TEXT_ALIGN_RIGHT, + DI_ALTERNATEONFAIL = DI_TEXT_ALIGN_CENTER, + }; #endif /* __SBAR_H__ */ diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index b7f859442..c64dbef65 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1161,9 +1161,6 @@ public: lastInventoryBar->Tick(NULL, this, false); } - // void DSBarInfo::FlashItem(const PClass *itemtype) - Is defined with CommandDrawSelectedInventory - void _FlashItem(const PClass *itemtype); - void _ShowPop(int popnum) { if(popnum != currentPopup) @@ -1604,14 +1601,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, Tick) return 0; } -DEFINE_ACTION_FUNCTION(DSBarInfo, FlashItem) -{ - PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); - PARAM_CLASS(w, AInventory); - self->_FlashItem(w); - return 0; -} - DEFINE_ACTION_FUNCTION(DSBarInfo, ShowPop) { PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo); diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index 64da7a7d5..458208b96 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -1691,16 +1691,16 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra if(statusBar->CPlayer->mo->InvSel != NULL && !(level.flags & LEVEL_NOINVENTORYBAR)) { - if(artiflash && artiflashTick) + if(artiflash && statusBar->wrapper->artiflashTick) { - statusBar->DrawGraphic(statusBar->Images[ARTIFLASH_OFFSET+(4-artiflashTick)], imgx, imgy, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), + statusBar->DrawGraphic(statusBar->Images[ARTIFLASH_OFFSET+(4- statusBar->wrapper->artiflashTick)], imgx, imgy, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), translatable, false, offset); } else { - if(itemflash && itemflashFade != 0) + if(itemflash && statusBar->wrapper->itemflashFade != 0) { - double flashAlpha = block->Alpha() * itemflashFade; + double flashAlpha = block->Alpha() * statusBar->wrapper->itemflashFade; statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgCURSOR], imgx-4, imgy+2, block->XOffset(), block->YOffset(), flashAlpha, block->FullScreenOffsets(), translatable, false, offset); } @@ -1789,38 +1789,18 @@ class CommandDrawSelectedInventory : public CommandDrawImage, private CommandDra { SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged); - if(artiflashTick > 0) - artiflashTick--; - if(itemflashFade > 0) - { - itemflashFade -= 1./14; - if(itemflashFade < 0) - itemflashFade = 0; - } - SetTruth(statusBar->CPlayer->mo->InvSel == NULL || (level.flags & LEVEL_NOINVENTORYBAR), block, statusBar); CommandDrawImage::Tick(block, statusBar, hudChanged); CommandDrawNumber::Tick(block, statusBar, hudChanged); } - static void Flash() { artiflashTick = 4; itemflashFade = 0.75; } protected: bool alternateOnEmpty; bool artiflash; bool alwaysShowCounter; bool itemflash; - - static int artiflashTick; - static double itemflashFade; }; -int CommandDrawSelectedInventory::artiflashTick = 0; -double CommandDrawSelectedInventory::itemflashFade = 0.75; - -void DSBarInfo::_FlashItem(const PClass *itemtype) -{ - CommandDrawSelectedInventory::Flash(); -} //////////////////////////////////////////////////////////////////////////////// diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 919d67848..af294f19d 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -593,6 +593,19 @@ void DBaseStatusBar::Tick () } } } + + if (artiflashTick > 0) + artiflashTick--; + + if (itemflashFade > 0) + { + itemflashFade -= 1 / 14.; + if (itemflashFade < 0) + { + itemflashFade = 0; + } + } + } DEFINE_ACTION_FUNCTION(DBaseStatusBar, Tick) @@ -1562,26 +1575,29 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla if (boxwidth > 0 || boxheight > 0) { - double scale1 = 1., scale2 = 1.; - - if (boxwidth > 0 && (boxwidth < texwidth || (flags & DI_FORCESCALE))) + if (!(flags & DI_FORCEFILL)) { - scale1 = boxwidth / texwidth; - } - if (boxheight != -1 && (boxheight < texheight || (flags & DI_FORCESCALE))) - { - scale2 = boxheight / texheight; - } + double scale1 = 1., scale2 = 1.; - if (flags & DI_FORCESCALE) - { - if (boxwidth <= 0 || (boxheight > 0 && scale2 < scale1)) - scale1 = scale2; - } - else scale1 = MIN(scale1, scale2); + if (boxwidth > 0 && (boxwidth < texwidth || (flags & DI_FORCESCALE))) + { + scale1 = boxwidth / texwidth; + } + if (boxheight != -1 && (boxheight < texheight || (flags & DI_FORCESCALE))) + { + scale2 = boxheight / texheight; + } - boxwidth = texwidth * scale1; - boxheight = texheight * scale1; + if (flags & DI_FORCESCALE) + { + if (boxwidth <= 0 || (boxheight > 0 && scale2 < scale1)) + scale1 = scale2; + } + else scale1 = MIN(scale1, scale2); + + boxwidth = texwidth * scale1; + boxheight = texheight * scale1; + } } else { @@ -1962,6 +1978,8 @@ DEFINE_FIELD(DBaseStatusBar, drawOffset); DEFINE_FIELD(DBaseStatusBar, drawClip); DEFINE_FIELD(DBaseStatusBar, fullscreenOffsets); DEFINE_FIELD(DBaseStatusBar, defaultScale); +DEFINE_FIELD(DBaseStatusBar, artiflashTick); +DEFINE_FIELD(DBaseStatusBar, itemflashFade); DEFINE_GLOBAL(StatusBar); diff --git a/src/scripting/backend/codegen.h b/src/scripting/backend/codegen.h index 084ff52d7..2974866ca 100644 --- a/src/scripting/backend/codegen.h +++ b/src/scripting/backend/codegen.h @@ -508,7 +508,6 @@ public: FxConstant(PType *type, VMValue &vmval, const FScriptPosition &pos) : FxExpression(EFX_Constant, pos) { - ValueType = value.Type = type; isresolved = true; switch (vmval.Type) { @@ -522,13 +521,14 @@ public: break; case REGT_STRING: - value = ExpVal(vmval.s()); + new(&value) ExpVal(vmval.s()); break; case REGT_POINTER: value.pointer = vmval.a; break; } + ValueType = value.Type = type; } static FxExpression *MakeConstant(PSymbol *sym, const FScriptPosition &pos); diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 361bf5cde..af0295ef3 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -25,7 +25,8 @@ gameinfo defaultbloodparticlecolor = "ff 00 00" backpacktype = "BagOfHolding" armoricons = "SHLDA0", 0.75, "SHD2A0" - statusbar = "sbarinfo/heretic.txt" + //statusbar = "sbarinfo/heretic.txt" + statusbarclass = "HereticStatusBar" intermissionmusic = "mus_intr" intermissioncounter = false weaponslot = 1, "Staff", "Gauntlets" diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index a8a1d2586..367a9156d 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -34,6 +34,7 @@ version "2.5" #include "zscript/statusbar/statusbar.txt" #include "zscript/statusbar/doom_sbar.txt" +#include "zscript/statusbar/heretic_sbar.txt" #include "zscript/statusbar/strife_sbar.txt" #include "zscript/statusbar/sbarinfowrapper.txt" diff --git a/wadsrc/static/zscript/statusbar/heretic_sbar.txt b/wadsrc/static/zscript/statusbar/heretic_sbar.txt new file mode 100644 index 000000000..4c97a16be --- /dev/null +++ b/wadsrc/static/zscript/statusbar/heretic_sbar.txt @@ -0,0 +1,208 @@ +class HereticStatusBar : BaseStatusBar +{ + DynamicValueInterpolator mHealthInterpolator; + HUDFont mHUDFont; + HUDFont mIndexFont; + HUDFont mBigFont; + InventoryBarState diparms; + + + override void Init() + { + Super.Init(); + SetSize(48, 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); + mHealthInterpolator = DynamicValueInterpolator.Create(0, 0.25, 1, 8); + } + + override void NewGame () + { + Super.NewGame(); + mHealthInterpolator.Reset (0); + } + + override void Tick() + { + Super.Tick(); + mHealthInterpolator.Update(CPlayer.health); + } + + override void Draw (int state, double TicFrac) + { + Super.Draw (state, TicFrac); + + if (state == HUD_StatusBar) + { + BeginStatusBar(320, 200, 42); + DrawMainBar (TicFrac); + } + else if (state == HUD_Fullscreen) + { + BeginHUD(320, 200, 1., false); + 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(); + int wiggle = (inthealth != CPlayer.health) && Random[ChainWiggle](0, 1); + 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 (CPlayer.inventorytics == 0 || level.NoInventoryBar) + { + //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 Heretic, noartibox, 7, INDEXFONT_RAVEN, 50, 160, 77, 182, untranslated; + } + } + + 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) + { + 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 (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null && !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", (-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 (CPlayer.inventorytics != 0 && !level.NoInventoryBar) + { + DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW); + } + } +} diff --git a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt index d58e175d1..8c8c6bf53 100644 --- a/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt +++ b/wadsrc/static/zscript/statusbar/sbarinfowrapper.txt @@ -8,7 +8,6 @@ struct SBarInfo native ui native void NewGame(); native bool MustDrawLog(int state); native void Tick(); - native void FlashItem(class itemtype); native void ShowPop(int popnum); } @@ -49,7 +48,6 @@ class SBarInfoWrapper : BaseStatusBar Super.NewGame(); if (CPlayer != NULL) { - AttachToPlayer(CPlayer); core.NewGame(); } } @@ -65,11 +63,6 @@ class SBarInfoWrapper : BaseStatusBar core.Tick(); } - override void FlashItem(class itemtype) - { - core.FlashItem(itemtype); - } - override void ShowPop(int popnum) { Super.ShowPop(popnum); diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index e1bdf4d63..3d6c4fe86 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -26,9 +26,9 @@ class InventoryBarState ui TextureID box; TextureID selector; Vector2 boxsize; + Vector2 boxofs; Vector2 innersize; - int boxframesize; - + TextureID left; TextureID right; Vector2 arrowoffset; @@ -41,17 +41,25 @@ class InventoryBarState ui // The default settings here are what SBARINFO is using. static InventoryBarState Create(HUDFont indexfont = null, int cr = Font.CR_UNTRANSLATED, double itemalpha = 1., - String boxgfx = "ARTIBOX", String selgfx = "SELECTBO", int fsize = 2, + String boxgfx = "ARTIBOX", String selgfx = "SELECTBO", Vector2 innersize = (0, 0), String leftgfx = "INVGEML1", String rightgfx = "INVGEMR1", Vector2 arrowoffs = (0, 0), int flags = 0) { let me = new ("InventoryBarState"); me.itemalpha = itemalpha; me.box = TexMan.CheckForTexture(boxgfx, TexMan.TYPE_MiscPatch); me.selector = TexMan.CheckForTexture(selgfx, TexMan.TYPE_MiscPatch); - me.boxframesize = fsize; if (me.box.IsValid() || me.selector.IsValid()) me.boxsize = TexMan.GetScaledSize(me.box.IsValid()? me.box : me.selector); else me.boxsize = (32., 32.); - me.innersize = me.boxsize - (2.*fsize, 2.*fsize); + if (innersize == (0, 0)) + { + me.boxofs = (2, 2); + me.innersize = me.boxsize - (4, 4); // Default is based on Heretic's and Hexens icons. + } + else + { + me.innersize = innersize; + me.boxofs = (me.boxsize - me.innersize) / 2; + } me.left = TexMan.CheckForTexture(leftgfx, TexMan.TYPE_MiscPatch); me.right = TexMan.CheckForTexture(rightgfx, TexMan.TYPE_MiscPatch); me.arrowoffset = arrowoffs; @@ -122,25 +130,22 @@ class BaseStatusBar native ui DI_ALWAYSSHOWCOUNT = 0x200, // only for DrawInventoryBar. DI_DIMDEPLETED = 0x400, DI_DONTANIMATE = 0x800, // do not animate the texture - // These 2 flags are only used by SBARINFO - DI_DRAWINBOX = 0x1000, // Set when either width or height is not zero - DI_ALTERNATEONFAIL = 0x2000, - + DI_SCREEN_AUTO = 0, // decide based on given offsets. DI_SCREEN_MANUAL_ALIGN = 0x4000, // If this is on, the following flags will have an effect - + DI_SCREEN_TOP = DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_VCENTER = 0x8000 | DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_BOTTOM = 0x10000 | DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_VOFFSET = 0x18000 | DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_VMASK = 0x18000 | DI_SCREEN_MANUAL_ALIGN, - + DI_SCREEN_LEFT = DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_HCENTER = 0x20000 | DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_RIGHT = 0x40000 | DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_HOFFSET = 0x60000 | DI_SCREEN_MANUAL_ALIGN, DI_SCREEN_HMASK = 0x60000 | DI_SCREEN_MANUAL_ALIGN, - + DI_SCREEN_LEFT_TOP = DI_SCREEN_TOP|DI_SCREEN_LEFT, DI_SCREEN_RIGHT_TOP = DI_SCREEN_TOP|DI_SCREEN_RIGHT, DI_SCREEN_LEFT_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_LEFT, @@ -148,21 +153,21 @@ class BaseStatusBar native ui DI_SCREEN_CENTER = DI_SCREEN_VCENTER|DI_SCREEN_HCENTER, DI_SCREEN_CENTER_BOTTOM = DI_SCREEN_BOTTOM|DI_SCREEN_HCENTER, DI_SCREEN_OFFSETS = DI_SCREEN_HOFFSET|DI_SCREEN_VOFFSET, - + DI_ITEM_AUTO = 0, // equivalent with bottom center, which is the default alignment. - + DI_ITEM_TOP = 0x80000, DI_ITEM_VCENTER = 0x100000, DI_ITEM_BOTTOM = 0, // this is the default vertical alignment DI_ITEM_VOFFSET = 0x180000, DI_ITEM_VMASK = 0x180000, - + DI_ITEM_LEFT = 0x200000, DI_ITEM_HCENTER = 0, // this is the deafault horizontal alignment DI_ITEM_RIGHT = 0x400000, DI_ITEM_HOFFSET = 0x600000, DI_ITEM_HMASK = 0x600000, - + DI_ITEM_LEFT_TOP = DI_ITEM_TOP|DI_ITEM_LEFT, DI_ITEM_RIGHT_TOP = DI_ITEM_TOP|DI_ITEM_RIGHT, DI_ITEM_LEFT_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_LEFT, @@ -170,14 +175,22 @@ class BaseStatusBar native ui DI_ITEM_CENTER = DI_ITEM_VCENTER|DI_ITEM_HCENTER, DI_ITEM_CENTER_BOTTOM = DI_ITEM_BOTTOM|DI_ITEM_HCENTER, DI_ITEM_OFFSETS = DI_ITEM_HOFFSET|DI_ITEM_VOFFSET, - + DI_TEXT_ALIGN_LEFT = 0, DI_TEXT_ALIGN_RIGHT = 0x800000, DI_TEXT_ALIGN_CENTER = 0x1000000, + DI_TEXT_ALIGN = 0x1800000, DI_ALPHAMAPPED = 0x2000000, DI_NOSHADOW = 0x4000000, DI_ALWAYSSHOWCOUNTERS = 0x8000000, + DI_ARTIFLASH = 0x10000000, + DI_FORCEFILL = 0x20000000, + + // These 2 flags are only used by SBARINFO so these duplicate other flags not used by SBARINFO + DI_DRAWINBOX = DI_TEXT_ALIGN_RIGHT, + DI_ALTERNATEONFAIL = DI_TEXT_ALIGN_CENTER, + }; enum IconType @@ -220,6 +233,13 @@ class BaseStatusBar native ui FNF_WHENNOTZERO, } + enum EShade + { + SHADER_HORZ = 0, + SHADER_VERT = 2, + SHADER_REVERSE = 1 + } + const XHAIRSHRINKSIZE =(1./18); const XHAIRPICKUPSIZE = (2+XHAIRSHRINKSIZE); const POWERUPICONSIZE = 32; @@ -237,6 +257,8 @@ class BaseStatusBar native ui native PlayerInfo CPlayer; native bool ShowLog; native Vector2 defaultScale; // factor for fully scaled fullscreen display. + native int artiflashTick; + native double itemflashFade; // These are block properties for the drawers. A child class can set them to have a block of items use the same settings. native double Alpha; @@ -259,7 +281,7 @@ class BaseStatusBar native ui native virtual clearscope void ReceivedWeapon (Weapon weapn); native virtual clearscope void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false); - virtual void FlashItem (class itemtype) {} + virtual void FlashItem (class itemtype) { artiflashTick = 4; itemflashFade = 0.75; } virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; } virtual void FlashCrosshair () { CrosshairSize = XHAIRPICKUPSIZE; } virtual void NewGame () { if (CPlayer != null) AttachToPlayer(CPlayer); } @@ -287,7 +309,7 @@ class BaseStatusBar native ui // //============================================================================ - Inventory, Inventory, int, int GetCurrentAmmo () const + Ammo, Ammo, int, int GetCurrentAmmo () const { Ammo ammo1, ammo2; if (CPlayer.ReadyWeapon != NULL) @@ -666,10 +688,16 @@ class BaseStatusBar native ui void DrawInventoryIcon(Inventory item, Vector2 pos, int flags = 0, double alpha = 1.0, Vector2 boxsize = (-1, -1), Vector2 scale = (1.,1.)) { + static const String flashimgs[]= { "USEARTID", "USEARTIC", "USEARTIB", "USEARTIA" }; TextureID texture; Vector2 applyscale; [texture, applyscale] = GetIcon(item, flags, false); - if (texture.IsValid()) + + if((flags & DI_ARTIFLASH) && artiflashTick > 0) + { + DrawImage(flashimgs[artiflashTick-1], pos, flags | DI_TRANSLATABLE, alpha, boxsize); + } + else if (texture.IsValid()) { if ((flags & DI_DIMDEPLETED) && item.Amount <= 0) flags |= DI_DIM; applyscale.X *= scale.X; @@ -680,19 +708,24 @@ class BaseStatusBar native ui //============================================================================ // - // DrawInventoryBar // - // This function needs too many parameters, so most have been offloaded to - // a struct to keep code readable and allow initialization somewhere outside - // the actual drawing code. // //============================================================================ - // Except for the placement information this gets all info from the struct that gets passed in. - void DrawInventoryBar(InventoryBarState parms, Vector2 position, int numfields, int flags = 0, double bgalpha = 1.) + void DrawShader(int which, Vector2 pos, Vector2 size, int flags = 0, double alpha = 1.) + { + static const String texnames[] = {"BarShaderHF", "BarShaderHR", "BarShaderVF", "BarShaderVR" }; + DrawImage(texnames[which], pos, DI_ITEM_LEFT_TOP|DI_ALPHAMAPPED|DI_FORCEFILL | (flags & ~(DI_ITEM_HMASK|DI_ITEM_VMASK)), alpha, size); + } + + //============================================================================ + // + // + // + //============================================================================ + + Vector2, int AdjustPosition(Vector2 position, int flags, double width, double height) { - double width = parms.boxsize.X * numfields; - // This must be done here, before altered coordinates get sent to the draw functions. if (!(flags & DI_SCREEN_MANUAL_ALIGN)) { @@ -711,12 +744,52 @@ class BaseStatusBar native ui switch (flags & DI_ITEM_VMASK) { - case DI_ITEM_VCENTER: position.y -= parms.boxsize.Y / 2; break; - case DI_ITEM_BOTTOM: position.y -= parms.boxsize.Y; break; + case DI_ITEM_VCENTER: position.y -= height / 2; break; + case DI_ITEM_BOTTOM: position.y -= height; break; } - // clear all alignment flags so that the following code only passed on the rest + // clear all alignment flags so that the following code only passes on the rest flags &= ~(DI_ITEM_VMASK|DI_ITEM_HMASK); + return position, flags; + } + + //============================================================================ + // + // note that this does not implement chain wiggling, this is because + // it would severely complicate the parameter list. The calling code is + // normally in a better position to do the needed calculations anyway. + // + //============================================================================ + + void DrawGem(String chain, String gem, int displayvalue, int maxrange, Vector2 pos, int leftpadding, int rightpadding, int chainmod, int flags = 0) + { + TextureID chaintex = TexMan.CheckForTexture(chain, TexMan.TYPE_MiscPatch); + if (!chaintex.IsValid()) return; + Vector2 chainsize = TexMan.GetScaledSize(chaintex); + [pos, flags] = AdjustPosition(pos, flags, chainsize.X, chainsize.Y); + + displayvalue = clamp(displayvalue, 0, maxrange); + int offset = int(double(chainsize.X - leftpadding - rightpadding) * displayvalue / maxrange); + + DrawTexture(chaintex, pos + (offset % chainmod, 0), flags | DI_ITEM_LEFT_TOP); + DrawImage(gem, pos + (offset + leftPadding, 0), flags | DI_ITEM_LEFT_TOP); + } + + //============================================================================ + // + // DrawInventoryBar + // + // This function needs too many parameters, so most have been offloaded to + // a struct to keep code readable and allow initialization somewhere outside + // the actual drawing code. + // + //============================================================================ + + // Except for the placement information this gets all info from the struct that gets passed in. + void DrawInventoryBar(InventoryBarState parms, Vector2 position, int numfields, int flags = 0, double bgalpha = 1.) + { + double width = parms.boxsize.X * numfields; + [position, flags] = AdjustPosition(position, flags, width, parms.boxsize.Y); CPlayer.mo.InvFirst = ValidateInvFirst(numfields); if (CPlayer.mo.InvFirst == null) return; // Player has no listed inventory items. @@ -730,16 +803,29 @@ class BaseStatusBar native ui // now the items and the rest - Vector2 itempos = position + (boxsize.X / 2, boxsize.Y - parms.boxframesize); - Vector2 textpos = position + boxsize - (parms.boxframesize*2, parms.boxframesize + parms.amountfont.mFont.GetHeight()); + Vector2 itempos = position + boxsize / 2; + Vector2 textpos = position + boxsize - (1, 1 + parms.amountfont.mFont.GetHeight()); int i = 0; Inventory item; for(item = CPlayer.mo.InvFirst; item != NULL && i < numfields; item = item.NextInv()) { - if ((parms.flags & DI_DRAWCURSORFIRST) && item == CPlayer.mo.InvSel) DrawTexture(parms.selector, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP); - DrawInventoryIcon(item, itempos + (boxsize.X * i, 0), flags | DI_ITEM_CENTER_BOTTOM ); - if (!(parms.flags & DI_DRAWCURSORFIRST) && item == CPlayer.mo.InvSel) DrawTexture(parms.selector, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP); + for(int j = 0; j < 2; j++) + { + if (j ^ !!(parms.flags & DI_DRAWCURSORFIRST)) + { + if (item == CPlayer.mo.InvSel) + { + double flashAlpha = bgalpha; + if (flags & DI_ARTIFLASH) flashAlpha *= itemflashFade; + DrawTexture(parms.selector, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha); + } + } + else + { + DrawInventoryIcon(item, itempos + (boxsize.X * i, 0), flags | DI_ITEM_CENTER ); + } + } if (parms.amountfont != null && (item.Amount > 1 || (parms.flags & DI_ALWAYSSHOWCOUNTERS))) { @@ -780,6 +866,11 @@ class LinearValueInterpolator : Object return v; } + void Reset(int value) + { + mCurrentValue = value; + } + // This must be called peroiodically in the status bar's Tick function. // Do not call this in the Draw function because that may skip some frames! void Update(int destvalue) @@ -819,6 +910,11 @@ class DynamicValueInterpolator : Object return v; } + void Reset(int value) + { + mCurrentValue = value; + } + // This must be called peroiodically in the status bar's Tick function. // Do not call this in the Draw function because that may skip some frames! void Update(int destvalue) diff --git a/wadsrc/static/zscript/statusbar/strife_sbar.txt b/wadsrc/static/zscript/statusbar/strife_sbar.txt index 889842cc3..fc1862698 100644 --- a/wadsrc/static/zscript/statusbar/strife_sbar.txt +++ b/wadsrc/static/zscript/statusbar/strife_sbar.txt @@ -37,7 +37,6 @@ class StrifeStatusBar : BaseStatusBar int CursorImage; int CurrentPop, PendingPop, PopHeight, PopHeightChange; int KeyPopPos, KeyPopScroll; - double ItemFlash; HUDFont mYelFont, mGrnFont, mBigFont; @@ -152,22 +151,12 @@ class StrifeStatusBar : BaseStatusBar PopHeight = 0; KeyPopPos = 0; KeyPopScroll = 0; - ItemFlash = 0; } override void Tick () { Super.Tick (); - if (ItemFlash > 0) - { - ItemFlash -= 1/14.; - if (ItemFlash < 0) - { - ItemFlash = 0; - } - } - PopHeightChange = 0; if (PendingPop != POP_NoChange) { @@ -211,11 +200,6 @@ class StrifeStatusBar : BaseStatusBar } } - override void FlashItem (Class itemtype) - { - ItemFlash = 0.75; - } - private void FillBar(double x, double y, double start, double stopp, Color color1, Color color2) { Vector2 virt = Scaled? (320., 200.) : (screen.GetWidth(), screen.GetHeight()); @@ -336,7 +320,7 @@ class StrifeStatusBar : BaseStatusBar int flags = item.Amount <= 0? DI_ITEM_OFFSETS|DI_DIM : DI_ITEM_OFFSETS; if (item == CPlayer.mo.InvSel) { - DrawTexture (Images[CursorImage], (42 + 35*i, 180), flags, 1. - ItemFlash); + DrawTexture (Images[CursorImage], (42 + 35*i, 180), flags, 1. - itemflashFade); } DrawInventoryIcon (item, (48 + 35*i, 182), flags); DrawString(mYelFont, FormatNumber(item.Amount, 3, 5), (75 + 35*i, 191), DI_TEXT_ALIGN_RIGHT); @@ -386,7 +370,7 @@ class StrifeStatusBar : BaseStatusBar { if (CPlayer.mo.InvSel != null) { - if (ItemFlash > 0) + if (itemflashFade > 0) { DrawTexture(Images[CursorImage], (-42, -15)); }