View previous topic :: View next topic |
Author |
Message |
Orion

Joined: 12 Jan 2007 Posts: 413 Location: Brazil
|
Posted: Wed Jul 18, 2007 4:02 pm Post subject: Doubt |
|
|
Hi there.
Sometimes when I compile I get this warning: "Equation may require intermediate variable".
Most of them I've fixed, but of the my bots to shoot an entity I haven't fixed!
Code: |
if (visible(self.enemy) && infront(self.enemy))
self.button0 = 1;
else
{
self.button0 = 0;
self.angles_x = 0;
}
|
But if I comment out the visible(), the bot will see the enemy through walls, and aim at the wall!
So what's that "intermediate variable"?
The ones I've fixed looks like this in dog_bite():
Original
Code: |
ldmg = (random() + random() + random()) * 8;
|
Fixed
Code: |
ldmg = (random()*3) * 8;
|
Thanks... _________________ There's no signature here. Stop looking for one. |
|
Back to top |
|
 |
Teiman
Joined: 03 Jun 2007 Posts: 309
|
Posted: Wed Jul 18, 2007 4:17 pm Post subject: Re: Doubt |
|
|
Orion wrote: | Hi there.
Sometimes when I compile I get this warning: "Equation may require intermediate variable".
|
The warning message is self-explanatory.
QC is not your rich and modern programming language, with flexible string handling, and infinite deep support for re-entry.
I have forget about, but I think It mean that theres only ONE return area for functions, so the return value from infront(self.enemy) will overwrite the return value for visible(self.enemy). Hence.. to solve this, you don't stack more than one funtion in a expresion at equal deep.
something(something(something()); will not overwrite
something()+something()+something() may overwrite
Code: |
//Using a intermediate var
isVisible = visible(self.enemy)
if ( isVisible && infront(self.enemy))
self.button0 = 1;
else
{
self.button0 = 0;
self.angles_x = 0;
}
|
I have forget If that problem has already been resolved on quake engines. I don't think so. |
|
Back to top |
|
 |
Orion

Joined: 12 Jan 2007 Posts: 413 Location: Brazil
|
Posted: Wed Jul 18, 2007 4:33 pm Post subject: |
|
|
Ah, I see.
So, if I fix the dog_bite() in this way, it won't overwrite, right?
Code: |
local float r;
r = random();
ldmg = (r + r + r) * 8;
|
_________________ There's no signature here. Stop looking for one. |
|
Back to top |
|
 |
FrikaC Site Admin

Joined: 08 Oct 2004 Posts: 947
|
Posted: Wed Jul 18, 2007 4:37 pm Post subject: |
|
|
Or just use a newer version of frikqcc that has this problem fixed. |
|
Back to top |
|
 |
Entar

Joined: 05 Nov 2004 Posts: 422 Location: At my computer
|
Posted: Wed Jul 18, 2007 8:48 pm Post subject: |
|
|
Orion wrote: | Ah, I see.
So, if I fix the dog_bite() in this way, it won't overwrite, right?
Code: |
local float r;
r = random();
ldmg = (r + r + r) * 8;
|
|
You realize that will just give you a single random number, multiplied by 3 and then by 8? Your original code would give you three random numbers. _________________ woh... feelin woozy... too much cider...
http://entar.quakedev.com
games fascination - My Game Development Blog/Journal
 |
|
Back to top |
|
 |
FrikaC Site Admin

Joined: 08 Oct 2004 Posts: 947
|
Posted: Thu Jul 19, 2007 1:05 am Post subject: |
|
|
Depending on the compiler. Original qcc and other compilers that do not have this fixed will produce a kind of messed up result with the original code, as Tei pointed out there's only one return space in the QuakeC vm. So..
Code: |
ldmg = (random() + random() + random()) * 8;
|
Will compile to (under qcc):
Code: |
CALL0 random
CALL0 random
ADD_F OFS_RETURN OFS_RETURN -> temp0
CALL0 random
ADD_F temp0 OFS_RETURN -> temp1
MUL_F temp1 IMMEDIATE(8) -> temp2
STORE_F temp2 -> ldmg
|
So to be perfectly functionally accurate it would be r = random(); ldmg = (r * 2 + random()) * 8;
Maybe that's not very clear but basically what it will do is call random twice and then try to add the return values, but since the second call overwrote the first, it's really just doubling the result of the first call. Then it calls again, fortunately the result of the first add was saved off in temp space so it's still accurate (accurate in that it's still the wrong value it computed).
FrikQCC 2.3 - 2.5 warned about this problem, 2.6 onward solved the problem by just saving off the return value in temp space whenever it detected the problem will occur (using more robust logic than the warning did - actually the warning just warned about any operation where both operands were OFS_RETURN (thus by that point there was nothing it could do to fix it, only complain), the newer frikqccs save off the return space if it's still in use when a function call is encountered) |
|
Back to top |
|
 |
|