yet another CSQC HUD tutorial

Discuss CSQC related programming.
Post Reply
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

yet another CSQC HUD tutorial

Post by gnounc »

https://dl.dropboxusercontent.com/u/177 ... orials.zip

Start here. It has the shell of the mod, all you have to do is fill in updateStats(), drawHud(), and add the apropriate
clientstat() and globalstat() to worldspawn.

The following tutorials should explain pretty well just how to do that.

View.qc:
the weaponFrame() of csqc.
that is, its the function I abuse to get shit done every single frame.

I call all of my hud drawing functions at the ass end of csqc_updateview()

also has options to turn off crosshairs and the default hud (very useful)
and drawmasks for people who know what they're doing.

main.qc
most of the things I dare not touch are here!
If you just want a hud, you can leave this file alone completely.
If you want to intercept te_effects, events, print messages, input events
and console commands though, this is your shangri la.
#DEFINES are needed for some of those functions. I forget which ones, I'll
try to answer that later.

csplat.qc
This file can be regenerated by issuing the following command:
pr_dumpplatform -fdefines -tcs -o csplat

contains tons of function prototypes for engine builtins and the like.

a trove of information.
Read it, it'll give you ideas fo sho.
Last edited by gnounc on Sat May 11, 2013 8:41 pm, edited 4 times in total.
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: yet another CSQC HUD tutorial

Post by gnounc »

-This tutorial assumes you know a little somethin somethin about qc to begin with-

Use fteqcc as your compiler or expect breakage.
Your csqc's progs.dat needs to be next to your ssqc's progs.
Set it up so that it is, and lets begin.

we have to tell serverside qc about the csqc builtins we are going to use.
so place these lines in your defs.

////these lines right here

Code: Select all

	void(float num, float type, .__variant fld) clientstat = #232;
	void(float num, float type, string name) globalstat = #233;
	float AS_STRING          = 1;
	float AS_FLOAT_TRUNCATED = 2; // int value
	float AS_FLOAT           = 8;

Now head to world.qc serverside and find worldspawn() to register a variable from the engine.
For entity fields use clientstat, for globals use globalstat.

Code: Select all

	clientstat(36,AS_FLOAT_TRUNCATED, armortype);
the first argument to clientstat() is the number you're registering, known as the globalnum or fieldnum.
you will need to start registering new fields after number 34,
because every number before that is already in use (and therefore available to getstat)
the first 21 registered numbers are listed here:

(from csplat.qc)

#define STAT_HEALTH 0
#define STAT_WEAPON 2
#define STAT_AMMO 3
#define STAT_ARMOR 4
#define STAT_WEAPONFRAME 5
#define STAT_SHELLS 6
#define STAT_NAILS 7
#define STAT_ROCKETS 8
#define STAT_CELLS 9
#define STAT_ACTIVEWEAPON 10
#define STAT_TOTALSECRETS 11
#define STAT_TOTALMONSTERS 12
#define STAT_SECRETS 13
#define STAT_MONSTERS 14
#define STAT_ITEMS 15
#define STAT_VIEWHEIGHT 16
#define STAT_VIEW2 20
#define STAT_VIEWZOOM 21

the second argument is what type of data youre sending,
we added the available options to your defs
a moment ago:

float AS_STRING = 1;
float AS_FLOAT_TRUNCATED = 2; // int value
float AS_FLOAT = 8;

the third argument is the name of the field.
in this case, armortype.

That bit is the same for globalstat except you use quotes around the globalname.
had you added a global named score to track player stats, you might add
a line like this:

Code: Select all

	globalstat(34,AS_FLOAT_TRUNCATED, "score");
Now that the clientstat CAN request the newly registered stat...it probably SHOULD,
so head back over to csqc and make a new function for updating stats.
Once again, call it from the bottom of CSQC_updateView() in view.qc

you have 3 functions one for floats, one for integers and one for strings

getstatf
getstati
and getstats respectively.
their only argument is the globalnum you used when registering it in worldspawn.

centerprinting in csqc is mostly the same as in ssqc, except that
the local client is assumed for the entity argument, and its called cprint instead.
go ahead and put a cprint() in for health to make sure its working.

because health is already available as a built in stat, its not necessary to register it with ssqc.
you can add it immediately using its globalnum of 0, as stated in csplat and the above list.
update stats should now look like this

Code: Select all

	updateStats()
	{
		armortype = getstatf(36);
		health = getstatf(0);
		cprint(strHealth);
	}
dont forget to put armortype and any other new variables in your csqc defs.

recast your health float as a string

Code: Select all

	strHealth = ftos(health);
and remove the hardset 100 value we previously set strHealth to,
et voila, you should have a string printing somewhere on your screen that
tells you what your health is at.

you can now do the same for armor, ammo, weaponnum, or even things you add
like lives, or accuracy.
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: yet another CSQC HUD tutorial

Post by gnounc »

Looking at csplat.qc we find
float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #326;

we're going to replace the cprint we did last tut, with this.

I'm not sure what the flags do exactly, so for now throw a zero in there, and fill in the other arguments.

You should be able to figure this part out, remembering that the floats are
numbers between 0 and 1, not 0 and 100.

Code: Select all

	drawHealth()
	{
	//	drawstring(vecPos, strText, vecScale, vecRGB, flAlpha, flFlags);
		drawstring('0 0', strHealth, 1, '1 1 1', 1, 0);
	}
'0 0' is top left, x y. go from there.
you have screen_center, screen_center_x and screen_center_y
available to help you position your text.
any vector can be referenced with an _x _y or _z attribute

You can also check how much space your string takes up (relatively)
by multiplying the vector scale by the length of the string

vecScale*strlen(mystring);

and position your string relative to that.

you can change the color of your health string using the rgb vector weve called
vecRGB.

remember to check against the float health, not the string.

Code: Select all

	if(health <= 20)
		vecRGB = '1 0 0';

	drawHealth()
	{
		string strHealth;
		strHealth = "100";
	//	drawstring(vecPos, strText, vecScale, vecRGB, flAlpha, flFlags);
		drawstring('0 0', strHealth, 1, '1 1 1', 1, 0);
	}
and now your health will be red when very low.
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: yet another CSQC HUD tutorial

Post by gnounc »

drawpic is mostly the same as drawstring.
So read that tutorial first.

Code: Select all

	float(vector position, string pic, vector size, vector rgb, float alpha, optional float flag) drawpic = #322;
here (aside from flags) the only argument that is not in the previous tutorial, is string pic.

its just the path to the desired graphic. No extension neccesary.
that is, dont put .jpg, .png, .gif after it, just health0.

the way I use drawpic for hud elements like health, is I place it in a folder according to what it is
(health, armor, ammo)

and i make the filename a framenumber (0, 1, 2 etc)

then i use string concatenation via "strcat()" to paste them into a filename based on health or armor value
i get from getstat.
if you have 100 health pics, you would do this

Code: Select all

	health = getstati(0,2, health);
	string imgPath
	imgPath = strcat("gfx/health/",health);
resulting in a path something like

gfx/health/25

so if you had in gfx/health a graphic named 25, it would show up.

and in this way, you can have an image that changes to reflect your health status.

use some simple math so you dont need 100 frames.
also remember to use ceil() or floor() so you get nice round integers.
you can also scale, reposition or color your images based on stats, so have fun!
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: yet another CSQC HUD tutorial

Post by gnounc »

a more up to date, and more permanant place to find the csqc files for this tutorial
...and for anything really. its a nice stub based on dresks.

https://gitorious.org/clean_csqc/cleanc ... rce/master:

if you know how to use git, you can do that
otherwise you can click the download button on the top right
Last edited by gnounc on Sat Jan 18, 2014 4:47 pm, edited 1 time in total.
Dr. Shadowborg
InsideQC Staff
Posts: 1120
Joined: Sat Oct 16, 2004 3:34 pm

Re: yet another CSQC HUD tutorial

Post by Dr. Shadowborg »

Thanks also for calling my attention to this. I'd already been messing around with CSQC using the source from the FTEQW svn, this probably will be more useful for my needs though...
gnounc
Posts: 428
Joined: Mon Apr 06, 2009 6:26 am

Re: yet another CSQC HUD tutorial

Post by gnounc »

No problem : ) It had recently come to my attention that the files provided were not as useful as I remembered them being.
So it was a happy coincidence. But this tutorial should be piss easy and there should be very little left fo leave you scratching your head.
Let me know how helpful you found it!
Post Reply