mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 13:01:47 +00:00
- implemented the inventory bar. This object is a bit special because it requires a lot of parameters, most of which are easily set to defaults. To make handling easier, most are passed through a container object which does some processing up front.
- finished work on the Doom status bar. I also took the opportunity to fix the layout of the inventory bar which is a bit broken in SBARINFO. - tuned the selection rules for deciding what creates the status bar, so that the most recent definition that can be found is chosen.
This commit is contained in:
parent
e791c957d9
commit
a112b29c43
7 changed files with 181 additions and 34 deletions
|
@ -115,7 +115,7 @@ static FFont * IndexFont; // The font for the inventory indices
|
|||
static FTexture * healthpic; // Health icon
|
||||
static FTexture * berserkpic; // Berserk icon (Doom only)
|
||||
static FTexture * fragpic; // Frags icon
|
||||
static FTexture * invgems[4]; // Inventory arrows
|
||||
static FTexture * invgems[2]; // Inventory arrows
|
||||
|
||||
static int hudwidth, hudheight; // current width/height for HUD display
|
||||
static int statspace;
|
||||
|
@ -816,7 +816,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
|
|||
{
|
||||
if(rover->PrevInv())
|
||||
{
|
||||
screen->DrawTexture(invgems[!!(level.time&4)], x-10, y,
|
||||
screen->DrawTexture(invgems[0], x-10, y,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE);
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ static void DrawInventory(player_t * CPlayer, int x,int y)
|
|||
}
|
||||
if(rover)
|
||||
{
|
||||
screen->DrawTexture(invgems[2 + !!(level.time&4)], x-10, y,
|
||||
screen->DrawTexture(invgems[1], x-10, y,
|
||||
DTA_KeepRatio, true,
|
||||
DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_Alpha, 0.4, TAG_DONE);
|
||||
}
|
||||
|
@ -1279,9 +1279,7 @@ void HUD_InitHud()
|
|||
if (IndexFont == NULL) IndexFont = ConFont; // Emergency fallback
|
||||
|
||||
invgems[0] = TexMan.FindTexture("INVGEML1");
|
||||
invgems[1] = TexMan.FindTexture("INVGEML2");
|
||||
invgems[2] = TexMan.FindTexture("INVGEMR1");
|
||||
invgems[3] = TexMan.FindTexture("INVGEMR2");
|
||||
invgems[1] = TexMan.FindTexture("INVGEMR1");
|
||||
|
||||
fragpic = TexMan.FindTexture("HU_FRAGS"); // Sadly, I don't have anything usable for this. :(
|
||||
|
||||
|
|
|
@ -984,13 +984,13 @@ public:
|
|||
"USEARTIA", "USEARTIB", "USEARTIC", "USEARTID",
|
||||
};
|
||||
TArray<const char *> patchnames;
|
||||
patchnames.Resize(script->Images.Size()+10);
|
||||
patchnames.Resize(script->Images.Size()+9);
|
||||
unsigned int i = 0;
|
||||
for(i = 0;i < script->Images.Size();i++)
|
||||
{
|
||||
patchnames[i] = script->Images[i];
|
||||
}
|
||||
for(i = 0;i < 10;i++)
|
||||
for(i = 0;i < 9;i++)
|
||||
{
|
||||
patchnames[i+script->Images.Size()] = InventoryBarLumps[i];
|
||||
}
|
||||
|
|
|
@ -243,16 +243,24 @@ void ST_CreateStatusBar(bool bTitleLevel)
|
|||
StatusBar = new DBaseStatusBar();
|
||||
StatusBar->SetSize(0);
|
||||
}
|
||||
else if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile)
|
||||
else
|
||||
{
|
||||
auto cls = PClass::FindClass(gameinfo.statusbarclass);
|
||||
if (cls != nullptr)
|
||||
// The old rule of 'what came last wins' goes here, as well.
|
||||
// If the most recent SBARINFO definition comes before a status bar class definition it will be picked,
|
||||
// if the class is defined later, this will be picked. If both come from the same file, the class definition will win.
|
||||
int sbarinfolump = Wads.CheckNumForName("SBARINFO");
|
||||
int sbarinfofile = Wads.GetLumpFile(sbarinfolump);
|
||||
if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile && gameinfo.statusbarclassfile >= sbarinfofile)
|
||||
{
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
auto cls = PClass::FindClass(gameinfo.statusbarclass);
|
||||
if (cls != nullptr)
|
||||
{
|
||||
VMValue params[] = { StatusBar };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
{
|
||||
VMValue params[] = { StatusBar };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +291,6 @@ void ST_CreateStatusBar(bool bTitleLevel)
|
|||
auto cls = PClass::FindClass(defname);
|
||||
if (cls != nullptr)
|
||||
{
|
||||
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
{
|
||||
|
@ -1605,8 +1612,8 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla
|
|||
|
||||
switch (flags & DI_ITEM_VMASK)
|
||||
{
|
||||
case DI_ITEM_VCENTER: y -= texheight / 2; break;
|
||||
case DI_ITEM_BOTTOM: y -= texheight; break;
|
||||
case DI_ITEM_VCENTER: y -= boxheight / 2; break;
|
||||
case DI_ITEM_BOTTOM: y -= boxheight; break;
|
||||
case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble() * boxheight / texheight; break;
|
||||
}
|
||||
|
||||
|
@ -1732,6 +1739,8 @@ DEFINE_ACTION_FUNCTION(DHUDFont, Create)
|
|||
ACTION_RETURN_POINTER(new DHUDFont(fnt, spac, mono, sy, sy));
|
||||
}
|
||||
|
||||
DEFINE_FIELD(DHUDFont, mFont);
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// draw a string
|
||||
|
@ -2039,3 +2048,4 @@ DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetMugshot)
|
|||
auto tex = self->mugshot.GetFace(self->CPlayer, def_face, accuracy, (FMugShot::StateFlags)stateflags);
|
||||
ACTION_RETURN_INT(tex ? tex->id.GetIndex() : -1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1045,6 +1045,12 @@ AInventory *AActor::FirstInv ()
|
|||
return Inventory->NextInv ();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, FirstInv)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
ACTION_RETURN_OBJECT(self->FirstInv());
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// AActor :: UseInventory
|
||||
|
|
|
@ -502,6 +502,7 @@ class Actor : Thinker native
|
|||
native void SetShade(color col);
|
||||
native clearscope int GetRenderStyle() const;
|
||||
native clearscope bool CheckKeys(int locknum, bool remote, bool quiet = false);
|
||||
native clearscope Inventory FirstInv() const;
|
||||
|
||||
native clearscope string GetTag(string defstr = "") const;
|
||||
native void SetTag(string defstr = "");
|
||||
|
|
|
@ -2,7 +2,8 @@ class DoomStatusBar : BaseStatusBar
|
|||
{
|
||||
HUDFont mHUDFont;
|
||||
HUDFont mIndexFont;
|
||||
//DrawInventoryBarParms diparms;
|
||||
HUDFont mAmountFont;
|
||||
InventoryBarState diparms;
|
||||
|
||||
|
||||
override void Init()
|
||||
|
@ -10,19 +11,13 @@ class DoomStatusBar : BaseStatusBar
|
|||
Super.Init();
|
||||
SetSize(32, 320, 200);
|
||||
|
||||
// set up the inventory bar drawer.
|
||||
/*
|
||||
diparms.SetDefaults(HX_SHADOW);
|
||||
diparms.SetTextures("SELECTBO", "ARTIBOX", "INVGEML1", "INVGEMR1");
|
||||
diparms.SetLeftArrow("INVGEML1");
|
||||
diparms.SetRightArrow("INVGEMR1");
|
||||
*/
|
||||
|
||||
// Create the font used for the fullscreen HUD
|
||||
Font fnt = "HUDFONT_DOOM";
|
||||
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 1, 1);
|
||||
fnt = "INDEXFONT_DOOM";
|
||||
mIndexFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true);
|
||||
mAmountFont = HUDFont.Create("INDEXFONT");
|
||||
diparms = InventoryBarState.Create();
|
||||
}
|
||||
|
||||
override void NewGame ()
|
||||
|
@ -120,14 +115,23 @@ class DoomStatusBar : BaseStatusBar
|
|||
DrawImage("STFBANY", (143, 0), DI_ITEM_OFFSETS|DI_TRANSLATABLE);
|
||||
}
|
||||
|
||||
if (CPlayer.mo.InvSel != null)
|
||||
if (CPlayer.mo.InvSel != null && !level.NoInventoryBar)
|
||||
{
|
||||
//drawinventorybar Doom, 7, INDEXFONT, 50, 170;
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (160, 30));
|
||||
if (CPlayer.mo.InvSel.Amount > 0)
|
||||
{
|
||||
DrawString(mAmountFont, FormatNumber(CPlayer.mo.InvSel.Amount), (175, 30-mIndexFont.mFont.GetHeight()), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture(GetMugShot(5), (143, 0), DI_ITEM_OFFSETS);
|
||||
}
|
||||
if (CPlayer.inventorytics != 0 && !level.NoInventoryBar)
|
||||
{
|
||||
DrawInventoryBar(diparms, (48, 1), 7, DI_ITEM_LEFT_TOP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void DrawFullScreenStuff ()
|
||||
|
@ -159,14 +163,14 @@ 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)
|
||||
if (CPlayer.inventorytics == 0 && CPlayer.mo.InvSel != null && !level.NoInventoryBar)
|
||||
{
|
||||
DrawInventoryIcon(CPlayer.mo.InvSel, (-14, invY + 17));
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT);
|
||||
}
|
||||
if (deathmatch)
|
||||
{
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (-3, 1), DI_TEXT_ALIGN_RIGHT);
|
||||
DrawString(mHUDFont, FormatNumber(CPlayer.FragCount, 3), (-3, 1), DI_TEXT_ALIGN_RIGHT, Font.CR_GOLD);
|
||||
}
|
||||
|
||||
// Draw the keys. This does not use a special draw function like SBARINFO because the specifics will be different for each mod
|
||||
|
@ -191,9 +195,9 @@ class DoomStatusBar : BaseStatusBar
|
|||
}
|
||||
}
|
||||
}
|
||||
if (CPlayer.inventorytics != 0)
|
||||
if (CPlayer.inventorytics != 0 && !level.NoInventoryBar)
|
||||
{
|
||||
//DrawInventoryBar(diparms, (0, 0), 7, ALIGN_CENTER_BOTTOM, ALIGN_CENTER_BOTTOM);
|
||||
DrawInventoryBar(diparms, (0, 0), 7, DI_SCREEN_CENTER_BOTTOM, HX_SHADOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,10 +17,57 @@ struct MugShot
|
|||
|
||||
class HUDFont native ui
|
||||
{
|
||||
// This is intentionally opaque to the script side.
|
||||
native Font mFont;
|
||||
native static HUDFont Create(Font fnt, int spacing = 0, bool monospaced = false, int shadowx = 0, int shadowy = 0);
|
||||
}
|
||||
|
||||
class InventoryBarState ui
|
||||
{
|
||||
TextureID box;
|
||||
TextureID selector;
|
||||
Vector2 boxsize;
|
||||
Vector2 innersize;
|
||||
int boxframesize;
|
||||
|
||||
TextureID left;
|
||||
TextureID right;
|
||||
Vector2 arrowoffset;
|
||||
|
||||
double itemalpha;
|
||||
|
||||
HUDFont amountfont;
|
||||
int cr;
|
||||
int flags;
|
||||
|
||||
// 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 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);
|
||||
me.left = TexMan.CheckForTexture(leftgfx, TexMan.TYPE_MiscPatch);
|
||||
me.right = TexMan.CheckForTexture(rightgfx, TexMan.TYPE_MiscPatch);
|
||||
me.arrowoffset = arrowoffs;
|
||||
me.arrowoffset.Y += me.boxsize.Y/2; // default is centered to the side of the box.
|
||||
if (indexfont == null)
|
||||
{
|
||||
me.amountfont = HUDFont.Create("INDEXFONT");
|
||||
if (cr == Font.CR_UNTRANSLATED) cr = Font.CR_GOLD;
|
||||
}
|
||||
else me.amountfont = indexfont;
|
||||
me.cr = cr;
|
||||
me.flags = flags;
|
||||
return me;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class BaseStatusBar native ui
|
||||
{
|
||||
|
@ -130,6 +177,7 @@ class BaseStatusBar native ui
|
|||
|
||||
DI_ALPHAMAPPED = 0x2000000,
|
||||
DI_NOSHADOW = 0x4000000,
|
||||
DI_ALWAYSSHOWCOUNTERS = 0x8000000,
|
||||
};
|
||||
|
||||
enum IconType
|
||||
|
@ -630,6 +678,86 @@ 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.)
|
||||
{
|
||||
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))
|
||||
{
|
||||
if (position.x < 0) flags |= DI_SCREEN_RIGHT;
|
||||
else flags |= DI_SCREEN_LEFT;
|
||||
if (position.y < 0) flags |= DI_SCREEN_BOTTOM;
|
||||
else flags |= DI_SCREEN_TOP;
|
||||
}
|
||||
|
||||
// placement by offset is not supported because the inventory bar is a composite.
|
||||
switch (flags & DI_ITEM_HMASK)
|
||||
{
|
||||
case DI_ITEM_HCENTER: position.x -= width / 2; break;
|
||||
case DI_ITEM_RIGHT: position.x -= width; break;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// clear all alignment flags so that the following code only passed on the rest
|
||||
flags &= ~(DI_ITEM_VMASK|DI_ITEM_HMASK);
|
||||
|
||||
CPlayer.mo.InvFirst = ValidateInvFirst(numfields);
|
||||
if (CPlayer.mo.InvFirst == null) return; // Player has no listed inventory items.
|
||||
|
||||
Vector2 boxsize = parms.boxsize;
|
||||
// First draw all the boxes
|
||||
for(int i = 0; i < numfields; i++)
|
||||
{
|
||||
DrawTexture(parms.box, position + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, bgalpha);
|
||||
}
|
||||
|
||||
// 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());
|
||||
|
||||
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);
|
||||
|
||||
if (parms.amountfont != null && (item.Amount > 1 || (parms.flags & DI_ALWAYSSHOWCOUNTERS)))
|
||||
{
|
||||
DrawString(parms.amountfont, FormatNumber(item.Amount, 0, 5), textpos + (boxsize.X * i, 0), flags | DI_TEXT_ALIGN_RIGHT, parms.cr, parms.itemalpha);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// Is there something to the left?
|
||||
if (CPlayer.mo.FirstInv() != CPlayer.mo.InvFirst)
|
||||
{
|
||||
DrawTexture(parms.left, position + (-parms.arrowoffset.X, parms.arrowoffset.Y), flags | DI_ITEM_RIGHT|DI_ITEM_VCENTER);
|
||||
}
|
||||
// Is there something to the right?
|
||||
if (item != NULL)
|
||||
{
|
||||
DrawTexture(parms.right, position + parms.arrowoffset + (width, 0), flags | DI_ITEM_LEFT|DI_ITEM_VCENTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
Loading…
Reference in a new issue