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
Wait 
is it always on the same line? 
 
interesting that savegames store lightstyles though. one would think that's easily gettable from the progs.

The current string for each style needs to be saved because there's no post-loadgame callback for entities to set the lightstyle strings again. 
Looks Like It's The 20th Line 
save game version, description, 16 parameters, skill and then the bsp name. 
Qc/engine Question 
if a coder specifies a file "tORch.Mdl" would the engine usually look for tORch.Mdl or torch.mdl or what? 
Different Cases? 
From what I can glean from a quick browse through the source:

Models in pak files must match capitalisation exactly or they will not be loaded.

Models in the filesystem depend on the operating system's implementation of fopen in the standard c library. I believe this means that unix type OSs will fail to find the file but DOS and windows will succeed, but I can't find any documentation which confirms this for 'fopen'. So where possible make sure the exact case is used. 
 
i have had problems with upper/lower case before.
i found it best to avoid uppercase altogether.
for example, ne_tower had a bunch of custom sounds.

when i was developing it, i had all the files loose in folders and setting keys like 'noise' 'necros/someSound.wav' worked fine. when i packed everything into a pak file, someSound could not be found, even though the filename hadn't changed. 
Preach 
i know you've posted about this before, but i can't find it again :S

basically, there was a faster way to compare distances without using vlen.

was it something like vec1*vec2 > distance*distance ?? 
Necros: 
if (vec_x * vec_x + vec_y * vec_y + vec_z * vec_z > distance * distance) {
//temp is longer than distance
 
er ...

//vec is longer than distance 
Yup 
It's almost like that. You can compare the length of a vector v to a distance d with:

v * v > d * d (notice that on both sides of the equation we have the same variable twice)

If you're testing the distance between two positions p1 and p2, you need to take the difference in positions first:
v = p2 - p1;
v * v > d * d;

It works exactly as metl says, but v * v is a single QC instruction which computes the dot product he has expanded out. 
Very Cool 
thank you!

when you say it's one instruction, i guess doing it as vec * vec is faster then? 
 
It works exactly as metl says, but v * v is a single QC instruction which computes the dot product he has expanded out.

Ah, good to know. 
Monster_boss Glitch In Progs 1.06? 
On skill 2, Chthon's aim prediction fails if the player moves towards him when he's about to throw a lavaball. The result is that he throws it backwards instead (or possibly towards worldspawn). It doesn't occur on 1.01.
Is this a known issue - why wasn't it fixed? 
 
it's just to do with the math involved to calculate the throwing vector.

because the lavaball moves so slowly (300u/s), if you jump toward chthon, you'd be behind him by the time the projectile would hit you.

i would assume that v1.01 of the progs didn't have chthon's forward projection targetting code. 
Iterative AI And Tracking 
The algorithm is:

1) work out the time it would take to hit the current player position
2) predict where the player will be at that time
3) set the target position to be that spot

There's a logical flaw in this scheme. The time it will take the projectile to reach the new spot will be different to the time it takes to reach the current spot, so there's no guarantee that the new aiming vector will be any better. This would not be significant with a fast projectile, as the two travel times would likely be very similar, and the size of the player's hitbox is a large enough margin of error.

However, the slower the projectile moves the worse the situation gets, compounding the problem necros describes. Moving towards the origin of the shot combines these two problems, and I'll try to give an example of the worst case. The player is moving towards chthon from 600 units away (2 seconds of flight time). We imagine that the player is moving at just over 300 u/s (the player's top speed is somewhere around 400 u/s). This means that in two seconds time, the player would be just behind the knuckle that the rock is thrown from. The projectile is then thrown directly backwards and misses completely.

We realise that this target point is stupid for a few reasons:
� The player will likely not run straight at chthon for two seconds
� More importantly, the player cannot run through the solid body
� Even more importantly, the rock will sail past the target point before even a fraction of a second passes. Even if the player could and did continue exactly to the predicted spot the shot would still miss!

This last problem is something we can fix with iteration! The idea is that we want to calculate a point where the time the rock will take to reach it roughly matches the time the player would take to reach it. If the player is running towards Chthon then this point will be roughly halfway between the two. The iteration is based on
� Taking the current target point
� Calculating the time to strike that
� Calculating a new target point from the predicted position the player would be in at that time
� Feeding the new target point into the top.

In our worst case scenario we described, we'd start with a target point of the player himself. Then we'd get the point right next to the knuckle with a very short flight time, so our third point would be very near to the player, but a bit closer to Chthon than point 1. After a bit of ping-pong of points that are too near to each end, we should work into the middle.

This is quite nice, and I like iteration in AI because you can do one iteration in each animation frame leading up to the shot. It creats an interesting, slightly unpredictable thought process which keeps taking on updates as the world changes. It's worth noting that this actually offers better prediction in other cases as well.

An alternate method for a more reliable forwards-travelling shot would be this: Take the offset of the new target point from the player, a vector called o.

Apply the following equation:

o = o - (o * v_forward)* v_forward;

This removes the component of o in the direction Chthon is facing. Finally, make the target point equal to the player's origin + o. Not as elegant, but perhaps slightly easier. 
<-- Chthon Lavaball 
that is... fucking cool, man. 
Heh 
I wondered why, when I go to hit the button that if I moved a step backwards and then over and than towards him as I stepped on the button I was almost always ensured not to be hit, perhaps I should have looked at him once or twice. 
 
if the original chthon fight hadn't been so gimmicky, it would have been a cool trick akin to shambler dancing or nails + fiends.
it's sad that you barely even have to look at chthon to defeat him. :\

yes, i am bitter. it's a great model and texture. yet, so poorly used. :(
the same could be said for shub. 
 
killable Chthons are en vogue lately. 
Probably A Silly Question... 
when multiple entities a touching another entity with a .touch function, each entity runs the .touch with itself as other right? 
Touching 
Yeah, although you have to be careful with entities that aren't moving. For example, monsters at rest inside a trigger don't generate touch events, since the monster only checks for collision when moving, and the trigger never does. This is where force_retouch is required. All entities use the same code for checking collisions though, and it is a combination of descending recursively down the tree of nodes intersecting the 'self' entity, along with a for loop to test all the entities within the current node. 
 
thanks yet again, preach :)

i was thinking maybe i should go through all your posts in this thread and make like a 'preach's guide to arcane quake facts' :P 
Well 
I do have a fun fact about that fun fact: it implies that in a multiple collision, the order that the collisions are resolved is essentially unpredictable - they depend on the location of the entities within the bsp tree that comprises the level.

Speculation: it might be possible to exploit this to glean some information about the bsp tree from QC - using force_retouch with a trigger and some point entities spawned in a region. Knowing that one point is in a leaf higher up the tree(or further left) than another may not be incredibly useful though... 
Path_corner Weirdness... 
void() movetarget_f =
{
if (!self.targetname)
objerror ("monster_movetarget: no targetname");

self.solid = SOLID_TRIGGER;
self.touch = t_movetarget;
setsize (self, '-8 -8 -8', '8 8 8');

};

void() path_corner =
{
movetarget_f();
};


quoted is the path_corner entity. unlike every other entity, path_corner defer's it's setup code in another function.
as i'm passing by, i frown at it, comment out movetarget_f and just paste the code into the path_corner function and grin at my cleverness.

suddenly, none of the path_corners work anymore. so i o_O and put it back the way it was. of course, i'm left with the question of why? it's just an entity with a touch function. 
Path_corner 
I couldn't reproduce this - the monsters seemed to follow their usual paths when this was the only change made to the vanilla source code. Any chance that something else changed at the same time? 
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.