Pointer To World
Most things tend to use world as the "NULL pointer". find() and variants usually return world if nothing is found, or end a linked list with world. I believe traceline() sets the hit entity to world if nothing is hit (the general way to detect no hit is if(trace_fraction == 1) although sometimes testing for hitting world is acceptable).
Usually, world is entity 0 (maybe eprint() might be able to tell you), although the compiler probably doesn't accept the implicit cast from float to entity.
Other NULL values are 0, "", and '0 0 0'.
Just to add that
if( !myEntity )
is valid qc and equivalent to
if(myEntity == world)
If world can be a valid return type you need to deal with that as a seperate case somehow.
Removing Entities And It's Effects On Other Things
so, say i have ent1.owner = ent2
and ent2 is removed. what happens to my pointer on ent1.owner? is it set to world or is it now corrupted junk?
can i do a check if (!ent1.owner) now and it'll pass?
The entity field continues to point to the same "slot" that the original entity occupied. Worse, after two seconds that entity slot can be reallocated when a new spawn() request is received, so the field now points to a valid entity, but an entirely unrelated one.
It's also worth noting that most of the fields on the removed entity will still be readable, and contain the same values they did before the entity was removed. The engine resets a few fields on removal, like solid, model and origin, but doesn't zero all of them until it's reused by the spawn() command. You can observe a side effect in fitzquake if you turn r_showbboxes on; a removed entity creates a bbox of that entity's size at the origin.
You could exploit the above fact to write code which can tell if an entity is removed or not:
Before removing an entity, set a float .isremoved on that entity to TRUE. The value can still be read, and will be reset when the entity is respawned as something else. You have to pinkie-swear never to modify that value outside the remove() function for it to be reliable.
I wouldn't recommend actually doing that though, because it's kinda relying on "undefined" behaviour in the engine - that removed entities can still be read. Engines which had more advanced entity management might not enforce that.
It's probably better to have a destructor function for the entity which is being removed which knows which entities will refer to it and sets them to WORLD. This would be practical if it's a master-slave kind of thing, not so much if you're worried about a monster getting removed and other monsters suddenly having an invalid .enemy...
"You can observe a side effect in fitzquake if you turn r_showbboxes on; a removed entity creates a bbox of that entity's size at the origin. "
Hahaha, so THAT'S what that is. I wondered what that box at the origin of the world was. Thanks! I thought my code was doing something wacky...
Mind Melting Code
Ok, I dug out the monster I wrote a few months back, here's some code which actually tracks all of your removed entities in a linked list. The file is pretty thoroughly commented, with a big block of text at the start describing how you might use it, and how to integrate it into a standard qc source.
The main application is a new field on entities you can read called .reused.
Positive/zero values of .reused
mean the entity is currently spawned, negative values mean it's currently removed. The absolute value of .reused
gives you the number of times the entity has been removed previously. This gives you an index you can compare to see if a stored entity differs in number of removals from the value it used to have - i.e. it has been removed and
I've tested it with fitz, bjp and dp, and it seems to function correctly in all 3. If anyone wants to know how it works, I can post that up too...
I was trying to add some doombirds to my map, and couldn't find the right movement for the thing. If I use a func_train it worked, only the sight of a plane flying backwards is a little queer.
So I took the custents and saw the map with the falling wall. It has a four way movement train that uses func_rotate. I integrated the doombird in it and it worked out fine again.
One thing I can't get is
why can I jump on the func_train in custents,
and why do I drop through it in my own version?
you mean func_rotate_train and not func_train?
in which case, you need the oft-posted czg rotation tutorial which, ironicall, i don't have the link to. :P
that's to say, the tutorial explains how to get collision on your rotaters. it's kind of wierd and annoying.
necros, the turning goes al right.
it is just that funny behaviour that when I play the map falendoor of custents I can stand on the func_train and I rotate in eyesight.
when I transponse the map coordinates of that func_rotate_train to my own the train isn't solid anymore. (?!)
forgot to include func_movewall. Now it's solid.
There's an odd point where the func_rotate suddenly behaves like a counter-turn in the opposite. Can't fly the thing without Doom patents.
To throw a spanner in the works -
Would it be possible to have the plane as a model, with all it's takeoff animation (turning etc.) done in Qme?
Or would the size of the animation break the model - look in the wrong direction and the game assumes you can't see it because it's in a different visleaf.
There's Something Worse That What You Mentioned
about doing it that way.
the way that vertex coordinate info is stored is completely relative.
this means that no matter how big or small your model is, the only thing important is how far from the origin all the vertices are.
this has an impact on the resolution of the model.
in quake, you could make a miniscule model of a bolt and it'll look completely fine.
but if you made a huge wall with the same bolt in the middle, the bolt would be messed up.
this is because the huge wall caused the scale of the vertex 'snap' to be larger.
if you made a plane model that was fully animated to fly around in, say an area of 1024x1024, your plane's vertices would probably be so low resolution as to not even be able to make out what it was.
as an example, look at the amount of vertex dancing on the vermis model. compare it to something like the fish model (which hardly moves) to get a good idea of how it impacts vertex position.
Another Way To Look At It.
imagine that a vertex in a model can only be on a grid of 256x256 units. it can rest on any even number from 0 to 255.
but that this grid can be stretched in all directions.
so if your model was 1024 units tall, it's vertices could, internally, only snap to a 256 tall grid.
that is to say that in the game world, the model's vertices would fit on every 4 grid units, instead of every 1.
Ahh right. I was going to call you out on that resolution thing but then I remembered Carmack's 256x256x256 cube compression stuff. Yes, quite the ugly issue.
this is aa far as I have come with the the doombird and custents.
Coding a mechtech is somewhat harder, but would be better.
That's pretty fun. The collision seems to go a bit nuts and just do its own thing, but even so.
Maybe some Qc to add grenade style smoke to the jets?
As To The Model Thing
So to do it with a model would require a func_modeltrain of some sort then, so it wouldn't just dissolve into a mess.
That explains why all the monsters seem to have Parkinsons in their idle animations though.
The larger ones anyway. The Shambler has way more error in his verts than, say, a soldier. The rest of the jittering comes from the fact that, I believe, Quake only supports integer locations for vertices.
Used to engine side vertex interpolation so don't usually notice it so much, except when looking at the models in raw state, as it were.
custents support the func_rotation and the func_rotate_train.
I'm trying to understand these options to get a better flyer.
that strange swing don't seem related to the func triggers.
Haven't found out where it comes from.
Reason that in custents a part of the func_rotate is hided.
I succeeded to create a health bowl and give it a health strength , by adding a health function in the qc.
I thought giving it armor points would be that easy. But it isn't.
There are only three IT_ARMOR types.
By substituring one I get my extra powerup object of ten armor points.
But not as alike the health paks I can only take one at the time,
the rest stays non solid as if I have taken a full armor .
I want to check what you're trying to do here. You would like an item which gives a boost of, 10 points of armour to a player who picks it up. So far, you've managed to make an item which gives the player 10 points of armour if they pick one up, but then subsequent ones will only top the player back up to 10, and if they are already at 10, then it doesn't increase.
To me, that sounds exactly like what would happen if you rewrote the green armour to have 10 armour points rather that 100. Have I read your aim and current result right?