News | Forum | People | FAQ | Links | Search | Register | Log in
Coding Help
This is a counterpart to the "Mapping Help" thread. If you need help with QuakeC coding, or questions about how to do some engine modification, this is the place for you! We've got a few coders here on the forum and hopefully someone knows the answer.
First | Previous | Next | Last
Model Flags 
There are flags you can set on models which select which (if any) effect that applies. If you open one with QMe it gives you a nice tickbox interface if you bring up the model properties box. 
Flags 
Thanks Preach 
Just To Clarify 
This is distinct from the QC .flags field - you can't change the particle effects from QC (other than having multiple models and switching between them). 
Flags 
Understood: I found the flag on the model immediately and was able to change them as required.

Is there any effect on performance if I suddenly add lots of these 'particle' effects? 
 
i don't think you'll feel it on an engine with the original particles (or even fitz' circular ones) but DP and other engines with 'fancy' particles can start to chug. i know some players using DP found the lava splash effects in ne_ruins would just kill their framerate, for example but i wouldn't even notice it in quakespasm. 
 
I think older engines have a maximum number of particles they will show. 
 
even glquake had -particles though and i always used to use -particles 20000. these days, i use -200000, but i think modern engines don't even use that anymore? i just leave it because it's in a batch file. :P 
Five Particles 
A hell knight fires 5 projectiles with trails in a single attack. Launching 1 projectile with five trail should be within scope. 
I Forget... 
is:

val = random();
val = val + random();
val = val + random();
val = val + random();

the same as:

val = random() + random() + random() + random();

Should Be 
as long as assigning the result of random() to val doesn't lose any information.

e.g. for the first case, if the language was C, val was an int variable, and random() returned a float between 0.0 and 1.0, the right hand side of each statement would be truncated to an integer before being stored in val, so in most cases you'd end up with val as 0, unless one of the random()'s returned exactly 1.0. In the second case the floats would be added up before being truncated to an int.

I think in QuakeC they are equivalent because random returns a float and the only numeric type is float. 
 
this is purely for quakec.

my question was along the lines of ftos() vs random() and if random() has the same problem ftos does.
my head tells me it shouldn't, since floats are primitives, but my gut tells me qc may do things in a weird way. 
 
Ah. here's the implementation of random: (pr_cmds.c)


static void PF_random (void)
{
float num;

num = (rand() & 0x7fff) / ((float)0x7fff);

G_FLOAT(OFS_RETURN) = num;
}


it looks fine.. I think the "G_FLOAT(OFS_RETURN) = num;" just stores the result in the vm global for return values. so it's not using any shared buffer like ftos.

... but I'm a qc noob so maybe someone more experienced should chime in :-) 
 
i'd totally test this, except it's random. XD 
Return Value 
Yeah, it's basically about return values in C. A return value of a float is passed by value - i.e. copied to the return value and therefore to the QC. So subsequent calls to rand get different values.

The problem with ftos is that strings in C aren't primitives. Instead what gets returned is a pointer, and passing a pointer by value is effectively passing the string by reference. In the case of ftos there is only a single buffer used, so the pointer which is returned always has the same value: the address for the start of the buffer. 
 
in a way, qc is a lot like java...

thanks, preach. 
Interesting Micro-optimisation 
The idea that the pointer doesn't change means you can save valuable QC operations by not assigning the return value of subsequent calls to ftos or vtos!

local string a;
a = ftos(self.health); //store pr_string_temp in a
dprint (a);
ftos(self.max_health); //a already stores the pointer to pr_string_temp
dprint(a); //so no need for an assignment
vtos(self.origin);
dprint(a); //vtos uses the same string buffer

Remember: saving 3 QC commands in your debugging routines should be your top priority when coding.


To make it even more efficient, why not just use a global!

string pr_string_temp;

void() worldspawn
{
...
pr_string_temp = ftos(0);
...
}

Never assign to the variable again, and just use the following pattern in all ftos code:

ftos(self.health);
dprint(pr_string_temp);

Although it was born from a daft optimisation idea, there is one nice thing about this coding structure. It makes explicit the gotcha with using ftos - that internally it uses a single temporary buffer. Consequently you'd be much less likely to use it incorrectly by calling ftos twice without writing the buffer to screen or console first. 
Multiple Replies 
#653:
In theory, yes.

In practice, the original QCC has a bug where only the last of the return values is actually used if they appear in a single statement, so it becomes random()*4. Spike claims to have fixed this in FTEQCC, but I remain slightly skeptical.

#660:
Note that some engines will likely break this behaviour... 
 
In practice, the original QCC has a bug where only the last of the return values is actually used if they appear in a single statement, so it becomes random()*4. Spike claims to have fixed this in FTEQCC, but I remain slightly skeptical.

So we're back to it not working then? :( 
Depends 
Some compilers will do this wrong thing:

� call random once - store the return value
� call random again - overwrite the return
� call random yet again - overwrite the return
� call random finally - overwrite the return
� add the final return value to itself four time

The difference between this and the ftos problem is that ftos overwrites the result on the engine side, but this bug occurs on the QC side so better compilers can fix it. I'm pretty confident that FTEQCC compiles this correctly but you could test it with the following code:


float counter;

float() increment_counter =
{
counter = counter + 1;
return counter;
}

void() test_compiler =
{
local float total;
total = increment_counter() + increment_counter() + increment_counter() + increment_counter();
dprint( ftos (total));
}

Compilers with the fix should output 1 + 2 + 3 + 4 = 10, the original qcc compiler will output 16. There's no difference here between a builtin returning a float and a compiled QC function which does the same. 
 
excellent! everything is peachy, preachy! 
Wow 
you are a poet! 
 
OK, some basic QuakeC questions here...

1. I know if I set the velocity on an entity, it will start moving in that direction. I read that avelocity is a force acting on that. Does that degrade over time or something? Like, is it a temp force or is it always there?

2. Velocity moves an entity regardless of it's angles, correct?

3. Is there a quick and dirty way to tell an entity to face the direction that it's moving in? Like, say I fire a rocket from a point in space -- I want it to face the direction that it's moving in. This is escaping me for whatever reason.

Thanks! :) Hopefully these aren't too rudimentary. 
 
To expand on the rocket things, say the rocket fires from EntityA towards EntityB. So the direction is:

normalize( EntityB.origin - EntityA.origin ); (or vice versa, I can never remember that)

That gives me a unit vector I can use to calc a velocity for flying but how do I make it point at EntityB while it's doing that? 
 
1. avelocity is angular velocity and has no bearing on velocity. it does not degrade either. the engine just increments .angles by this much every second.

2. velocity moves an entity IF it's .flags does NOT contain the ON_GROUND flag.
yes, it does move it regardless of angles. to move in the direction of angles, you need to do makevectors(self.angles)
self.velocity = v_forward * someSpeed

3. yes: self.angles = vectoangles(self.velocity) turns the velocity into an angle. 
 
Excellent, thank you! Yes, what you said in #3 fixed my rockets as well. Woot! 
First | Previous | Next | Last
You must be logged in to post in this thread.
Website copyright © 2002-2024 John Fitzgibbons. All posts are copyright their respective authors.