- implemented the Heretic status bar.

This commit is contained in:
Christoph Oelckers 2017-03-27 21:01:40 +02:00
parent 0fdd118906
commit a6bf93c624
11 changed files with 396 additions and 119 deletions

View file

@ -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__ */

View file

@ -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);

View file

@ -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();
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -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);

View file

@ -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);

View file

@ -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"

View file

@ -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"

View file

@ -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);
}
}
}

View file

@ -8,7 +8,6 @@ struct SBarInfo native ui
native void NewGame();
native bool MustDrawLog(int state);
native void Tick();
native void FlashItem(class<Inventory> 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<Inventory> itemtype)
{
core.FlashItem(itemtype);
}
override void ShowPop(int popnum)
{
Super.ShowPop(popnum);

View file

@ -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<Inventory> itemtype) {}
virtual void FlashItem (class<Inventory> 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)

View file

@ -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<Inventory> 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));
}