(Solved) Selecting Inventory, how to show item name/tag?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
User avatar
eharper256
Posts: 817
Joined: Sun Feb 25, 2018 2:30 am
Location: UK

(Solved) Selecting Inventory, how to show item name/tag?

Post by eharper256 »

What I'm looking to do:
>> Have is so that when a player is browsing Inventory (i.e. has their selection box over an item), my HUD also prints the Items Name and/or Tag.
>> Have this text switch when the item selected is changed, and fade away quickly when the item is used and/or item select halts so as to not get in the way of the action.

----------
I am using 3sasters base code in my HUD. Looking at the wiki it seems like this kind of thing isn't directly print-able as a string so I'm guessing I need to acquire it first but I have no idea how to proceed at this point. Here's the relevant status-bar code sections for the inventory:

Code: Select all

	// =========================================================
	// Same as DrawInventoryBar, but with transparency for items
	// =========================================================
	void DrawInventoryBarTrans(InventoryBarState parms, Vector2 position, int numfields, int flags = 0, double bgalpha = 1., double fgalpha = 1., double numalpha = 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.
		
		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 / 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())
		{
			for(int j = 0; j < 2; j++)
			{
				if (j ^ !!(flags & DI_DRAWCURSORFIRST))
				{
					if (item == CPlayer.mo.InvSel)
					{
						double flashAlpha = fgalpha;
						if (flags & DI_ARTIFLASH) flashAlpha *= itemflashFade;
						DrawTexture(parms.selector, position + parms.selectofs + (boxsize.X * i, 0), flags | DI_ITEM_LEFT_TOP, flashAlpha);
					}
				}
				else
				{
					DrawInventoryIcon(item, itempos + (boxsize.X * i, 0), flags | DI_ITEM_CENTER, fgalpha );
				}
			}
			
			if (parms.amountfont != null && (item.Amount > 1 || (flags & DI_ALWAYSSHOWCOUNTERS)))
			{
				DrawString(parms.amountfont, FormatNumber(item.Amount, 0, 5), textpos + (boxsize.X * i, 0), flags | DI_TEXT_ALIGN_RIGHT, parms.cr, numalpha);
				DrawString(parms.amountfont, FormatNumber(item.tag, 0, 5), textpos + (boxsize.X * i, 0), flags | DI_TEXT_ALIGN_RIGHT, parms.cr, numalpha);
			}
			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, fgalpha);
		}
		// Is there something to the right?
		if (item != NULL)
		{
			DrawTexture(parms.right, position + parms.arrowoffset + (width, 0), flags | DI_ITEM_LEFT|DI_ITEM_VCENTER, fgalpha);
		}
	}
	
	// ===============================================
	// Same as DrawInventoryBar, but with transparency
	// ===============================================
	void DrawBarTrans(String ongfx, String offgfx, double curval, double maxval, Vector2 position, int border, int vertical, int flags = 0, double trans = 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 = (maxval != 0) ? clamp(curval / maxval, 0, 1) : 0;
		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;
		
		// preserve the active clipping rectangle
		int cx, cy, cw, ch;
		[cx, cy, cw, ch] = screen.GetClipRect();

		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, trans);
			SetClipRect(position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3], flags);
		}
		
		if (offtex.IsValid() && TexMan.GetScaledSize(offtex) == texsize) DrawTexture(offtex, position, flags | DI_ITEM_LEFT_TOP, trans);
		else 
		{
			// Use partial transparency to prevent the foreground from being shown
			int partTrans = int( trans == 0 ? 0 : 255*(0.4 + 0.6*trans) );
			Fill(color(partTrans,0,0,0), position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3], flags);
			Fill(color(partTrans,0,0,0), position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3], flags);
		}
		
		if (border == 0) 
		{
			SetClipRect(position.X + Clip[0], position.Y + Clip[1], texsize.X - Clip[0] - Clip[2], texsize.Y - Clip[1] - Clip[3], flags);
			DrawTexture(ontex, position, flags | DI_ITEM_LEFT_TOP, trans);
		}
		// restore the previous clipping rectangle
		screen.SetClipRect(cx, cy, cw, ch);
	}
}

Code: Select all

		// Compute how much space we have for the inventory bar
		Vector2 scale = GetHUDScale();
		int VirtualWidth  = int(Screen.GetWidth()/scale.x);
		
		let left =  TexMan.CheckForTexture(barLeft,    TexMan.Type_MiscPatch);
		let right = TexMan.CheckForTexture("BAR_RGHT", TexMan.Type_MiscPatch);
		double textureWidth = 2*max(getTextureWidth(left),getTextureWidth(right))+2 + getTextureWidth(diparms_sbar.left) + getTextureWidth(diparms_sbar.right);
		
		int maxInv = int( (VirtualWidth - textureWidth)/diparms_sbar.boxsize.X );
		
		// Draw Inventory Bar
		if (isInventoryBarVisible())
		{
			int itemCount = 0;
			for(Inventory item = CPlayer.mo.FirstInv(); item != NULL && itemCount < maxInv; item = item.NextInv())
				itemCount++;
			DrawInventoryBarTrans(diparms_sbar, (0, -1), max(itemCount,1), DI_SCREEN_CENTER_BOTTOM, bgalpha:alphaFloat, fgalpha:alphaFloatGraph, numalpha: alphaFloatNum);
		}

		// Draw Inventory
		else if (CPlayer.mo.InvSel != null)
		{
			DrawInventoryIcon(CPlayer.mo.InvSel, (-111.5, -16), DI_ARTIFLASH|DI_ITEM_CENTER|DI_SCREEN_RIGHT_BOTTOM,alpha:alphaFloatGraph, boxsize:(28, 28));
			if (CPlayer.mo.InvSel.Amount > 1)
			{
				DrawString(mIndexFont, FormatNumber(CPlayer.mo.InvSel.Amount, 3), (-97, -7), DI_SCREEN_RIGHT_BOTTOM|DI_TEXT_ALIGN_RIGHT, Font.CR_UNTRANSLATED, alpha:alphaFloatNum);
			}
		}
I'm highly assuming I simply need to pop an extra DrawString under the lowest one shown above, but I have no idea how to obtain the current items name and tag and just keep causing hilarious crashes with my attempts.

Any help will be much appreciated and of course credited in the mod.
Last edited by eharper256 on Tue Feb 01, 2022 6:10 am, edited 1 time in total.
User avatar
Blue Shadow
Posts: 4903
Joined: Sun Nov 14, 2010 12:59 am
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD (Modern GZDoom)

Re: ZScrpt] When selecting Inventory, how to show item name/

Post by Blue Shadow »

There's GetSelectedInventoryTag function.
User avatar
eharper256
Posts: 817
Joined: Sun Feb 25, 2018 2:30 am
Location: UK

Re: ZScrpt] When selecting Inventory, how to show item name/

Post by eharper256 »

Blue Shadow wrote:There's GetSelectedInventoryTag function.
How do I add this to the code? I have tried stuff like this; but If I just add a Drawstring with GetSelectedInventoryTag() or inventorytag replacing the usual number, I just get Unknown Identifier Tag errors when booting in GZDoom, even if expressing it exactly as the wiki page indicates.

Which I notice, must be kinda off, since it specifies:

Code: Select all

DrawString <font>, <translation>, <string>, <x>, <y> [, <spacing> [, <flags>]]
But none of the current code puts it in this order (It skips by Translation and puts it later in the ordering).

Keep in mind I'm used to working purely with decorate, and I'm not much of a programmer, all current changes to ZScript I've done have been of the hammering square pegs into round holes variety, so you'll likely have to do an "explain it like I'm 5 deal", I'm afraid. :(
User avatar
Blue Shadow
Posts: 4903
Joined: Sun Nov 14, 2010 12:59 am
Operating System: Windows 10/8.1/8/201x 64-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: ATI/AMD (Modern GZDoom)

Re: ZScrpt] When selecting Inventory, how to show item name/

Post by Blue Shadow »

That DrawString is for SBARINFO, not ZScript, which what you're dealing with here. This is the function you want to use.

Code: Select all

DrawString(<font>, GetSelectedInventoryTag(), (<x>, <y>)); 
Replace <font> with whatever HUDFont the HUD is made available to you. <x> and <y> set the position of the text. You can further customize things by using the function's optional arguments, like flags* and translation (font color).


* Note that not all the flags you see are usable by DrawString. Some are for the graphic-drawing functions.
User avatar
eharper256
Posts: 817
Joined: Sun Feb 25, 2018 2:30 am
Location: UK

Re: ZScrpt] When selecting Inventory, how to show item name/

Post by eharper256 »

Blue Shadow wrote:That DrawString is for SBARINFO, not ZScript, which what you're dealing with here. This is the function you want to use.

Code: Select all

DrawString(<font>, GetSelectedInventoryTag(), (<x>, <y>)); 
Replace <font> with whatever HUDFont the HUD is made available to you. <x> and <y> set the position of the text. You can further customize things by using the function's optional arguments, like flags* and translation (font color).


* Note that not all the flags you see are usable by DrawString. Some are for the graphic-drawing functions.

It required some surgery from the resources you gave me and adding in a new HUD font, but I got it working! Thanks for the pointers!

This sort of thing will be really helpful for newer users of the mod or those that have no idea what Hexen items do by default (as was fed back to me from some streamers doing tests).

Return to “Scripting”