[SOLVED] [ZS] How do I draw a number from a weapon?

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!)
yum13241
Posts: 853
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support

[SOLVED] [ZS] How do I draw a number from a weapon?

Post by yum13241 »

I want to draw a string (from LANGUAGE) concatenated to a number a weapon based on a weapon's upgrade level, and this is an int called upgradelevel.

I want to draw this in the middle of the weapon (so 0,16 I believe), so the user can easily tell what upgrade they have on. HudMessage is ACS only, and I don't want to use dummy inventory items to display the upgrades in SBARINFO, which defeats the point of using variables. (ZScript HUDs are hard)

How would I go about doing this?
Spoiler: My Weapon
Spoiler: MWSWeapon
Last edited by yum13241 on Tue May 23, 2023 5:09 am, edited 1 time in total.
Jarewill
 
 
Posts: 1822
Joined: Sun Jul 21, 2019 8:54 am

Re: How do I draw a number from a weapon?

Post by Jarewill »

Without overriding the HUD, the only way I am aware of is to use RenderUnderlay/Overlay event handler.
Admittedly I am not good at this, so I am sure someone else could do this way better, but here's a working example:

Code: Select all

Class TestEventHandler : EventHandler{
	Override void RenderUnderlay(RenderEvent e){
		If(players[consoleplayer].readyweapon is "PlasmaRifle"){ //If the currently selected weapon is a plasma rifle
			int offset;
			If(CVar.FindCVar("screenblocks").GetInt()==10){offset=32;} //Set the offset to 32 if the statusbar is enabled
			Vector2 pos = Screen.VirtualToRealCoords((160,180-offset),(320,200),(320,200)); //Get real coordinates where to draw, in this case we want to draw in position 160,180
			double scale = Screen.GetHeight()/200.0; //Get the scale so the string isn't drawn small
			Screen.DrawText("bigfont",0,pos.x,pos.y,"A",DTA_ScaleX,scale,DTA_ScaleY,scale); //Draw an "A" in specified location with the BIGFONT
		}
	}
}
yum13241
Posts: 853
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support

Re: How do I draw a number from a weapon?

Post by yum13241 »

Thanks, but the "A" is off center. Also, I'm trying to display:
1. An int called upgradelevelchosen.
2. A "/" character.
3. An int called upgradelevel.

EX: 1/2

I only want to display these if upgradelevel > 1.
The problem is I cannot access the variable at all. I've tried player[consoleplayer].readyweapon.upgradelevel to no avail.
The weapon is called MWSPlasmaGun. These ints are public. If you need the weapon code I'll give it to you but I don't think that's the case.
Jarewill
 
 
Posts: 1822
Joined: Sun Jul 21, 2019 8:54 am

Re: How do I draw a number from a weapon?

Post by Jarewill »

You still need to cast a pointer to the weapon to access its variables.
And to fix the A being off center, use StringWidth.

Code: Select all

	Override void RenderUnderlay(RenderEvent e){
		let playe = players[consoleplayer];
		If(playe.readyweapon is "MWSPlasmaGun"){
			let weap = MWSPlasmaGun(playe.mo.FindInventory("MWSPlasmaGun")); //Cast the weapon to this variable
			If(!weap||weap.upgradelevel<=1){Return;} //Break the function if the weapon wasn't found or if the variable is lower than needed
			string toprint = String.Format("%i/%i",weap.upgradelevelchosen,weap.upgradelevel); //This is where you can access your weapon's variables to set what you want to draw
			double half = Font.GetFont("bigfont").StringWidth(toprint)/2; //This gets half the width of the string to center it, the rest is as before.
			int offset;
			If(CVar.FindCVar("screenblocks").GetInt()==10){offset=32;}
			Vector2 pos = Screen.VirtualToRealCoords((160-half,180-offset),(320,200),(320,200));
			double scale = Screen.GetHeight()/200.0;
			Screen.DrawText("bigfont",0,pos.x,pos.y,toprint,DTA_ScaleX,scale,DTA_ScaleY,scale);
		}
	}
yum13241
Posts: 853
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support

Re: How do I draw a number from a weapon?

Post by yum13241 »

Thanks, but the following produces zero visible results. It doesn't crash, but does not display anything at all.

Code: Select all

Class MWSRenderUpgrades : EventHandler
{
	override void RenderUnderlay(RenderEvent e)
	{
		let playe = players[consoleplayer];
		if(playe.readyweapon is "MWSPlasmaGun")
			{
				let weap = MWSPlasmaGun(playe.mo.FindInventory("MWSPlasmaGun"));
				if(!weap || weap.upgradelevel <= 1) return;
				string toprint = String.Format("%i/%i", weap.upgradelevelchosen, weap.upgradelevel);
				double half = Font.GetFont("bigfont").StringWidth(toprint)/2;
				int offset;
				if(CVar.FindCVar("screenblocks").GetInt()==10) offset=32; 
				Vector2 pos = Screen.VirtualToRealCoords((160-half,180-offset),(320,200),(320,20));
				double scale = Screen.GetHeight()/200.0;
				Screen.DrawText("bigfont", 0, pos.x, pos.y, toprint, DTA_ScaleX, scale, DTA_ScaleY, scale);
			}
	}
}
No matter how many times it gets upgraded it does nothing.
Jarewill
 
 
Posts: 1822
Joined: Sun Jul 21, 2019 8:54 am

Re: How do I draw a number from a weapon?

Post by Jarewill »

Make sure the class names are correct and if you added your event handler to MAPINFO.
If it still doesn't work, please upload your weapon code.
yum13241
Posts: 853
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support

Re: How do I draw a number from a weapon?

Post by yum13241 »

The class names are correct.
Spoiler: The upgradeable weapon
Spoiler: Base Weapon Class
Jarewill
 
 
Posts: 1822
Joined: Sun Jul 21, 2019 8:54 am

Re: How do I draw a number from a weapon?

Post by Jarewill »

The first issue is that the upgradelevel variable will never go above 1, meaning it will always pass the first check and return.
This is the correct logic for the check: if(!weap || weap.upgradelevel < 1) return;
And the second issue is that you forgot one 0 in the third set of coordinates, you had (320,20) instead of (320,200):
Vector2 pos = Screen.VirtualToRealCoords((160-half,180-offset),(320,200),(320,200));

Those two changes make the text render for me.
yum13241
Posts: 853
Joined: Mon May 10, 2021 8:08 pm
Preferred Pronouns: He/Him
Operating System Version (Optional): EndeavorOS (basically Arch)
Graphics Processor: Intel with Vulkan/Metal Support

Re: How do I draw a number from a weapon?

Post by yum13241 »

Thanks!

Code: Select all

Class MWSRenderUpgrades : EventHandler
{
	override void RenderUnderlay(RenderEvent e)
	{
		let playe = players[consoleplayer];
		if(playe.readyweapon is "MWSPlasmaGun")
			{
				let weap = MWSPlasmaGun(playe.mo.FindInventory("MWSPlasmaGun"));
				if(!weap || weap.upgradelevel < 1) return;
				string toprint = String.Format("%i/%i", weap.upgradelevelchosen, weap.upgradelevel);
				double half = Font.GetFont("bigfont").StringWidth(toprint)/2;
				int offset;
				if(CVar.FindCVar("screenblocks").GetInt()==10) offset=32; 
				Vector2 pos = Screen.VirtualToRealCoords((160-half,180-offset),(320,200),(320,200));
				double scale = Screen.GetHeight()/200.0;
				Screen.DrawText("bigfont", 0, pos.x, pos.y, toprint, DTA_ScaleX, scale, DTA_ScaleY, scale);
			}
	}
}
is the solution.

Return to “Scripting”