Snippet
Moderator: InsideQC Admins
25 posts
• Page 1 of 2 • 1, 2
Snippet
I'm willing to try to restart a snippet forum. Hopefully people will post their small qc codes. Any contribution is helpful. If no one wants to contribute, I'll just keep posting stuff.
Anywho, my first contribution. This code lets you draw an empty box of any thickness for use in menuqc or csqc. making inorout 0 makes the box drawn inside where you want it. make it 1 for it to be drawn outside and 2 to make it draw around the center of where you want it. any of you who use photoshop will know what I'm talking about
Anywho, my first contribution. This code lets you draw an empty box of any thickness for use in menuqc or csqc. making inorout 0 makes the box drawn inside where you want it. make it 1 for it to be drawn outside and 2 to make it draw around the center of where you want it. any of you who use photoshop will know what I'm talking about
- Code: Select all
void(vector pos, vector length, float thickness, vector boxcolor, float boxalpha, float boxflag, float inorout) drawemptybox =
{
local vector thickv;
local vector top, left, posdown, posright, poss;
if (!inorout)
thickv_x = 0;
else if (inorout == 1)
thickv_x = thickness;
else if (inorout == 2)
thickv_x = thickness / 2;
thickv_y = thickv_x;
pos = pos - thickv;
length = length + thickv;
top_x = thickness;
top_y = length_y - thickness;
left_x = length_x + thickness;
left_y = thickness;
posright_x = pos_x + length_x;
posright_y = pos_y + thickness;
posdown_x = pos_x;
posdown_y = pos_y + length_y;
poss_x = pos_x;
poss_y = pos_y + thickness;
drawfill(poss, top, boxcolor, boxalpha, boxflag); //|
drawfill(posright, top, boxcolor, boxalpha, boxflag); // |
drawfill(pos, left, boxcolor, boxalpha, boxflag); // -
drawfill(posdown, left, boxcolor, boxalpha, boxflag); // _
};
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
Ok, this code makes a traceline. that traceline will hit the wall in front of you, and change your angles to the wall's angles. AKA do this, then when you fire your weapon, the bullet will travel parallel to the wall. I'm using this code for AI navigation, but it can be put to other uses as well.
- Code: Select all
vector(vector which) positivevec = //finds any negative numbers in the vector and makes it positive
{
if (which_x < 0)
which_x = which_x * -1;
if (which_y < 0)
which_y = which_y * -1;
if (which_z < 0)
which_z = which_z * -1;
return which;
};
void() wallangles =
{
local vector tpn, anglechange, endpos;
local float walldist, opt1dist, opt2dist;
traceline (self.origin, self.origin + v_forward * 10000, TRUE, self);//find the wall you are looking at
endpos = trace_endpos;//save this trace_endpos, since the other tracelines that will be made will overwrite it
walldist = vlen(endpos - self.origin);//distance between you and wall, needed later
tpn = positivevec(trace_plane_normal * 180);//gets the wall angle (out of 1) and multiplies it by 180(also makes sure no values are negative)
tpn_x = tpn_x / 2;//divides x value b 2
tpn_y = tpn_y * - 1;//changes sign of y value from positive to negative (or vice versa)
// I really do not know why the above 2 lines are needed. i got them through trial and error :P.
anglechange_y = tpn_x + tpn_y;//adds the x and y values of wall (this will translate to whatever angle the player will have
makevectors(anglechange);//figures out the forward, up and right directions relative to the wall's angles
traceline(self.origin + v_forward * walldist, self.origin + v_forward * walldist, MOVE_WORLDONLY, world);//don't interact
opt1dist = vlen(trace_endpos - endpos);
traceline(self.origin - v_forward * walldist, self.origin - v_forward * walldist, MOVE_WORLDONLY, world);//don't interact
opt2dist = vlen(trace_endpos - endpos);
//the 4 above lines creates 2 points. then it subtracts the distance of the points by the original point that was made with the first traceline (endpos). this is a hacky way to turn your angle to the nearest available option.
if (opt1dist > opt2dist)
anglechange_y = anglechange_y - 180;//if the way you plan on turning is bigger than the other way, use the other way instead by subtracting the desired angle by 180
self.angles_y = anglechange_y;//you now face the same angles as the wall
self.fixangle = TRUE;//set your angles, needed
};
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
This is a simple code that lets you look directly at an entity:
- Code: Select all
void(entity lookingat) faceentity =
{
local vector result, dir;
result = lookingat.origin - self.origin;//subtract the entity origin you want to look at from your origin
dir = normalize (result);//normalize the above: which means you figure out the direction of it
self.v_angle = vectoangles (dir);//set your v_angle to face it
self.angles_y = self.v_angle_y;
self.angles_x = self.v_angle_x;//set your x and y angles to the result. don't do z angle because it will tilt your screen and you will end up with a dead quake angle effect :P
self.fixangle = TRUE;//sets the angle, you look at entity :D
};
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
With csqc, you can make your own HUD. This is a small noob explanation on how you can draw a string that represents your health. A bonus: Whenever your health reaches 25, it will pulse a red color! Neat, huh?
As usual, my code is heavily commented for your learning:
Then in the View.qc file, in the function CSQC_UpdateView (maybe called something else in FTE), add this to the bottom of it:
explaining how to drawstring:
look at this example: drawstring(where, what, howbig, whatcolor, howopaque, flag);
where: this is the position of the text(vector)
what: this is the text to write(string)
howbig: this is the size of text(vector)(example: '10 10 0', which is width x height). never mess with the last value and keep it a zero since this is the z value (depth). it is invalid here since the text is 2d.
whatcolor: this is the color of text(vector). in my code: if health is above 0, it's white. otherwise, it pulses red.
howopaque: alpha of text(float). AKA how transparent the text is. lower values = more transparent.
flag: this is a boolean flag(float). if its set to a number besides 0, your text's transparency will be affected by it's color vector. basically a text with it's color '0.4 0.1 0.2' will be more transparent than a text with it's color '1 0.7 0.5'
Enjoy! More posts coming soon!
As usual, my code is heavily commented for your learning:
- Code: Select all
//=================
vector healthcolor;
float healthtoggle;
//=================
//above is for pulsing health (a boolean float and the gradually changing vector(every pulsing item needs a separate set)
vector hpos;//position health text
float(float ccolor, float colortoggle, float minc, float maxc, float pulsespeed) valuepulse = //my nifty pulsing code (can be used to pulse anything, not just colors. can be used with alpha as well!)
{
if (ccolor >= maxc)//if your color reaches the max allowed
colortoggle = FALSE;//make the toggle false
else if (ccolor <= minc)//if your color reaches the minimum allowed
colortoggle = TRUE;//make toggle true
if (colortoggle == TRUE)//if toggle is true
ccolor = ccolor + pulsespeed;//increase color by desired speed
else
ccolor = ccolor - pulsespeed;//otherwise, decrease color by desired speed
return ccolor;//give color value
}
void() DrawHealth =
{
float currenthealth;
string healthstring;
currenthealth = getstati(STAT_HEALTH);//gets your health value
hpos_x = vid_size_x * 0.0150;
hpos_y = vid_size_y * 0.8500;//positions health string
healthcolor_x = 1;//set this to the color you want to pulse it to (x = red, y = green, z = blue). if you change, be sure you adjust the other healthcolor_'s ac
if (currenthealth > 25)//if your health is above 25
healthcolor_y = 1;//don't pulse
else
healthcolor_y = valuepulse(healthcolor_y, healthtoggle, 0.25, 1, 0.05);//else start pulsing. explanation on how to use:
/*
healthcolor_y: which float to pulse
healthtoggle: which float to use as boolean(switch)
0.25: lowest allowed number for float to reach before pulsing up
1: highest allowed number for float to reach before pulsing down
0.05: speed of pulse (higher number = faster pulse)
*/
healthcolor_z = healthcolor_y;//make sure the other value (z in this case) equals the pulsing value
healthstring = ftos(currenthealth);//makes your health a string so you can print it.
if (currenthealth > 0)//if you are alive
drawstring(hpos, healthstring, '10 10 0', healthcolor, 0.75, 0);//draw your health string
}
Then in the View.qc file, in the function CSQC_UpdateView (maybe called something else in FTE), add this to the bottom of it:
- Code: Select all
DrawHealth();
explaining how to drawstring:
look at this example: drawstring(where, what, howbig, whatcolor, howopaque, flag);
where: this is the position of the text(vector)
what: this is the text to write(string)
howbig: this is the size of text(vector)(example: '10 10 0', which is width x height). never mess with the last value and keep it a zero since this is the z value (depth). it is invalid here since the text is 2d.
whatcolor: this is the color of text(vector). in my code: if health is above 0, it's white. otherwise, it pulses red.
howopaque: alpha of text(float). AKA how transparent the text is. lower values = more transparent.
flag: this is a boolean flag(float). if its set to a number besides 0, your text's transparency will be affected by it's color vector. basically a text with it's color '0.4 0.1 0.2' will be more transparent than a text with it's color '1 0.7 0.5'
Enjoy! More posts coming soon!
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
This small addition allows the character to walk slower whenever a certain button is held.
This is all in PlayerPreThink in client.qc:
In config.cfg, add this line:
Enjoy!
This is all in PlayerPreThink in client.qc:
- Code: Select all
local float maxspeed;
maxspeed = cvar("sv_maxspeed");//find out your current speed
if (self.button3)//if you are holding down the button (change this to any button you want)
{
if (maxspeed != 80)//if your speed is not equal to walking speed
cvar_set ("sv_maxspeed", "80");//make it equal to walking speed
}
else //if you are not touching the button
{
if (maxspeed != 200)//if your speed is not equal to normal speed
cvar_set ("sv_maxspeed", "200");//make it equal to normal speed
}
In config.cfg, add this line:
- Code: Select all
bind SHIFT "+button3"
Enjoy!
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
Ok,
Let's say you have a number. You want to only get one digit from the number. The following function allows you to do this.
Note: If you are using vanilla QuakeC, you will need a qc file called mathlib.qc by FrikaC. Here it is
So, anywho here's the code (heavily commented for your learning):
To use this:
numsegment(number, numberpos);
number = the number you are using
numberpos = the position of the number you want
Example:
Let's say 'number' you are using is '5986'
If you use 1 as 'numberpos', the function will return '6'
If you use 2 as 'numberpos', the function will return '8'
If you use 3 as 'numberpos', the function will return '9'
If you use 4 as 'numberpos', the function will return '5'
If you use a number smaller than 1 as 'numberpos', the function will return '6' (AKA same as using 1)
If you use a number larger than the total amount of digits in the number as 'numberpos', the function will return '0'
Alright! Now here's my second contribution for the day:
Let's say you divide 2 floats. Sometimes it is useful to know if the two floats divide into each other evenly AKA no decimal point in answer. This function returns TRUE or FALSE depending on if the two numbers provided divide into each other evenly:
And there you have it!
Let's say you have a number. You want to only get one digit from the number. The following function allows you to do this.
Note: If you are using vanilla QuakeC, you will need a qc file called mathlib.qc by FrikaC. Here it is
So, anywho here's the code (heavily commented for your learning):
- Code: Select all
float(float num, float numpos) numsegment =
{
local float factornum;
if (numpos <= 0)
numpos = 1;
numpos = floor(numpos);
//above lines to correct any mistakes made when you use the function
factornum = 1 / pow(10, numpos); //if using mathlib.qc, rename pow to mathlib_pow
//divide 1 by 10 to the power of whatever number position you want to find. (ie numpos = 1 gets a factornum = 0.1, numpos = 2 factornum = 0.01, etc.)
num = num * factornum;//multiply the number by factornum found above(the number in the number pos you want should fall right of decimal point after this line)
num = floor((floor(num) - num) * 10);//subtract a rounded version of above from regular version. this leaves you with only your desired number right after decimal point. then, multiply it by 10 to get your desired number in the ones position and round it to get rid of excess
return num;//phew! Return the number for use.
};
To use this:
numsegment(number, numberpos);
number = the number you are using
numberpos = the position of the number you want
Example:
Let's say 'number' you are using is '5986'
If you use 1 as 'numberpos', the function will return '6'
If you use 2 as 'numberpos', the function will return '8'
If you use 3 as 'numberpos', the function will return '9'
If you use 4 as 'numberpos', the function will return '5'
If you use a number smaller than 1 as 'numberpos', the function will return '6' (AKA same as using 1)
If you use a number larger than the total amount of digits in the number as 'numberpos', the function will return '0'
Alright! Now here's my second contribution for the day:
Let's say you divide 2 floats. Sometimes it is useful to know if the two floats divide into each other evenly AKA no decimal point in answer. This function returns TRUE or FALSE depending on if the two numbers provided divide into each other evenly:
- Code: Select all
float(float num1, float num2) evendivide =
{
local float calc;
calc = num1 / num2;//divide the numbers
calc = (floor(calc) - calc) * 1000;//this basically checks if numbers exist after decimal point (ie looking for a number like 76.6785 or 82.0001 or 55.025 etc)
if (calc)//if there is numbers after decimal point (AKA if the two numbers do not divide into each other evenly)
return FALSE;//it's false
return TRUE;//otherwise the numbers divide into each other evenly and it is true
};
And there you have it!
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
Thank you, toneddu2000 for being the first person, besides me to reply to this topic!
Two more snippets
Today we will figure out whether any file you specify in qc exists or not. This is done by using the search functions which AFAIK, are supported in DP and probably FTE.
Here's the code:
To use it, assign the value of a float to this:
fileexists(NAMEHERE);
Note that you have to include the path to the file as well as the filename.
Example:
If you want to check if a certain picture called 'overhere.tga' exists in the folder 'gfx/thisway', you must supply the following in place of NAMEHERE:
"gfx/thisway/overhere.tga"
This is the only way it will work.
===
The simple function here will round a number to either of the two numbers provided, depending on the which of the 2 numbers it's closest to.
To use:
Assign a float to this: roundto(number, value1, value2);
Number is the number that is rounding
Value1 and value2 are the values that the number will be rounding to.
Enjoy!
Two more snippets
Today we will figure out whether any file you specify in qc exists or not. This is done by using the search functions which AFAIK, are supported in DP and probably FTE.
Here's the code:
- Code: Select all
float(string nameandloc) fileexists =//returns TRUE if specified file exists
{
local float findtext;
local string foundtext;
findtext = search_begin(nameandloc, FALSE, FALSE);//start searching for file. The first FALSE is for case-insensitivity. Make it true and all matching results will yield regardless of capital letters
foundtext = search_getfilename(findtext, 0);//find the file name of the first file you find
search_end(findtext);//end the search. No longer needed
if (foundtext == nameandloc)
return TRUE;//if file with same name found, return true
return FALSE;//otherwise, return false (file not found)
};
To use it, assign the value of a float to this:
fileexists(NAMEHERE);
Note that you have to include the path to the file as well as the filename.
Example:
If you want to check if a certain picture called 'overhere.tga' exists in the folder 'gfx/thisway', you must supply the following in place of NAMEHERE:
"gfx/thisway/overhere.tga"
This is the only way it will work.
===
The simple function here will round a number to either of the two numbers provided, depending on the which of the 2 numbers it's closest to.
- Code: Select all
float(float num, float small, float big) roundto =
{
local float smalldist, bigdist;
smalldist = num - small;
if (smalldist < 0)
smalldist = smalldist * -1;//subtract the number from the first possible value and make sure answer is positive
bigdist = big - num;
if (bigdist < 0)
bigdist = bigdist * -1;//subtract the number from the second possible value and make sure answer is positive
if (bigdist > smalldist)
return smalldist;
else if (smalldist > bigdist)
return bigdist;//these lines check which of the saved numbers earlier is bigger. AKA which number is closest to the number you are rounding. It returns the value that is closest
else
return num;//if both values are the same distance from the number, return the unmodified number (some may want to do something else in this case)
};
To use:
Assign a float to this: roundto(number, value1, value2);
Number is the number that is rounding
Value1 and value2 are the values that the number will be rounding to.
Enjoy!
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
This function reads and returns the specified line of text from the specified file. Note that the file you want to read must be located inside a folder (in your gamefolder) called 'data' (without quotes).
Here's the code:
The code is heavily commented (as usual) for your learning.
To use this, assign a string to this value:
readtextline (FILENAME, LINE);
Replace FILENAME with the name of the file (must be inside 'data' folder).
Replace LINE with the line of text you want to return (AKA '3' will return the 3rd line of text in the file).
Enjoy!
Here's the code:
- Code: Select all
string (string filename, float line) readtextline =
{
local float file_read, readcount;
file_read = fopen(filename, FILE_READ);//Open the file in read mode
while(readcount < line)//loop until condition met
{
filename = fgets(file_read);//everytime you use fgets, it gets a line of the file. if you use it repeatedly, you will get every next line of text. Do it the specific amount of times and you will get the line of text on the line you wanted
readcount = readcount + 1;//simple counter that ends the loop when needed
}
fclose(file_read);//closes the file (important)
return filename;//return the line of text!
};
The code is heavily commented (as usual) for your learning.
To use this, assign a string to this value:
readtextline (FILENAME, LINE);
Replace FILENAME with the name of the file (must be inside 'data' folder).
Replace LINE with the line of text you want to return (AKA '3' will return the 3rd line of text in the file).
Enjoy!
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
Could this last function be used to read some ingame text? Example: you're walinkg in a room and you find a book, as you collect it a message appears on the screen and displays the content of the book(read by a text file in the data folder).
It would be awesome! Thanks behind_you for this very interesting new section!
It would be awesome! Thanks behind_you for this very interesting new section!
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
toneddu2000 wrote:Could this last function be used to read some ingame text? Example: you're walinkg in a room and you find a book, as you collect it a message appears on the screen and displays the content of the book(read by a text file in the data folder).
It would be awesome! Thanks behind_you for this very interesting new section!
i believe that you have a good idea for the use of the FRIK_FILE!
For example, I was using texts already declared in qc or in the map, but using the frik file it is possible to "personalize" the text according to what the player does. It is an excellent idea!
hi, I am nahuel, I love quake and qc.
-

Nahuel - Posts: 492
- Joined: Wed Jan 12, 2011 8:42 pm
- Location: mar del plata
Hi Nahuel, can you post some link to the documentation of FRIK_FILE?
Is it the same of this?
Is it the same of this?
- toneddu2000
- Posts: 1352
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Today I will show you how to centerprint one letter at a time instead of the entire thing at once. I thought about this while playing Half-Life. The text that prints in HL prints in this kind of style.
This is the code:
Make sure you add this in defs.qc
There you have it! To use this, stick this line of code somewhere where it will be triggered (MAKE SURE IT IS ONLY TRIGGERED ONCE PER USE):
initcharprint(THETEXT);
Obviously, replace 'THETEXT' with the string you want to print (ie "I would like to print the following").
Enjoy!
EDIT: toneddu2000 to do what you want, create a .string called booktext and a float called .nextpage, then every time you create a book in the map assign it's self.booktext to a file inside the 'data' folder which will contain the text to read. Then whenever you go and read the book, do this line:
readtextline (self.booktext, self.nextpage);
Then make it so that whenever you click a button, increase the book's nextpage by one, to read the next line of text. Centerprint each text! That's a simple way of doing it.
This is the code:
- Code: Select all
void() charprint =
{
local float howmany, blankcount;
local string text, blanks;
howmany = strlen(toprint);//count how many letters to print
if (howmany >= textpos)//if your printing position is smaller than or equal to the amount of letters in your text
{
textpos = textpos + 1;//add one to your textposition
text = substring (toprint, 0, textpos);//this substrings your text by the value of textpos. So if textpos equaled 2 and the text to print was "PRINTING", you would print "PR". If it were 3, you would print "PRI" and so on. Since textpos goes up every time by 1, you would get a letter by letter printing effect
while(blankcount < (howmany - textpos))//while loop: whenever the blankcount is smaller than the difference between the character count and the typing text position
{
blanks = strcat(blanks, " ");//add a blank to the blanks string
blankcount = blankcount + 1;//add to the blankcount(prevents runaway loop and tempstring errors)
}
text = strcat(text, blanks);//combine the text and the blanks. The point of this is to get rid of the constant centering the engine does with centerprints. Without the constant centering, it looks better IMO. If you want the constant centering, then remove this strcat line and the while loop.
//Optional: Add a sound code here. This sound will be played every time an extra character is printed (A typewriter or keystroke sound is best)
}
else//otherwise
{
text = toprint;//print the whole text
return;//End the loop which would cause the text to disappear in a few seconds
}
centerprint(self, text);//print the current text
self.nextthink = time + 0.02;//loop in 0.02 seconds. Higher value = slower print
};
void(string whattowrite) initcharprint =
{
toprint = whattowrite;
textpos = 0;
//Resets all the globals once for use again
self.think = charprint;
self.nextthink = time + 0.1;//start printing!
};
Make sure you add this in defs.qc
- Code: Select all
float textpos;
string toprint;
There you have it! To use this, stick this line of code somewhere where it will be triggered (MAKE SURE IT IS ONLY TRIGGERED ONCE PER USE):
initcharprint(THETEXT);
Obviously, replace 'THETEXT' with the string you want to print (ie "I would like to print the following").
Enjoy!
EDIT: toneddu2000 to do what you want, create a .string called booktext and a float called .nextpage, then every time you create a book in the map assign it's self.booktext to a file inside the 'data' folder which will contain the text to read. Then whenever you go and read the book, do this line:
readtextline (self.booktext, self.nextpage);
Then make it so that whenever you click a button, increase the book's nextpage by one, to read the next line of text. Centerprint each text! That's a simple way of doing it.
-

behind_you - Posts: 237
- Joined: Sat Feb 05, 2011 6:57 am
- Location: Tripoli, Libya
25 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 1 guest