Rage through 32 single player levels and 6 deathmatch levels of sheer terror and fully immersive sound and lighting. Arm yourself against the cannibalistic Ogre, fiendish Vore and indestructible Schambler using lethal nails, fierce Thunderbolts and abominable Rocket and Grenade Launchers.

Post tutorial Report RSS Dynamically-Sized Bodyque

In Quake, there is a limit of four player corpses being displayed at once, but what if you want to be able to easily change that?

Posted by on - Basic Server Side Coding

If you've played Quake online, you may have noticed that while you do see player corpses occasionally, the level never seems to get cluttered with them no matter how many times people die. This is because in the code there is a bodyque, a list of four entities that are used as a 'queue' for corpses. It will hold the four most recently killed corpses.

Perhaps you don't want only four corpses. The way the bodyque list is hardcoded makes it ugly and hard to change. This is why we are going to change it to simply construct its own bodyque based on a constant value you give it.

Open up world.qc. Scroll down near the bottom until you find the function InitBodyQue. It looks like this:

void() InitBodyQue =
{
 local entity    e;
 
 bodyque_head = spawn();
 bodyque_head.classname = "bodyque";
 bodyque_head.owner = spawn();
 bodyque_head.owner.classname = "bodyque";
 bodyque_head.owner.owner = spawn();
 bodyque_head.owner.owner.classname = "bodyque";
 bodyque_head.owner.owner.owner = spawn();
 bodyque_head.owner.owner.owner.classname = "bodyque";
 bodyque_head.owner.owner.owner.owner = bodyque_head;
};

To be honest, this is rather ugly. It works, but we are going to replace it with something much better :)

Simply replace that function with this new one:

void() InitBodyQue
{
 local entity e;
 local float i;

 e = spawn ();
 e.classname = "bodyque";
 bodyque_head = e;

 i = 0;
 while (i < (BODYQUE_SIZE - 1))
 {
  e.owner = spawn ();
  e.classname = "bodyque";
  e = e.owner;

  i = i + 1;
 }

 e.owner = bodyque_head;
}

Now add the following constant definition anywhere in your code before this function (I recommend defs.qc):

float BODYQUE_SIZE = 4;

You can change the size to anything you want. Be reasonable, however ;)

It was that simple! You now can dynamically change the size of your bodyque.

[page=Explanation & Conclusion]
You now can dynamically change the size of your bodyque. But this wouldn't be a tutorial if it was just that. Let's examine what we changed.

Explanatian
First of all, the bodyque is a linked list. A linked list contains items that contain pointers to the next item in the list. The main advantage of using a linked list is that it is not statically sized: you can add, remove or modify items from the list whenever you want.

In QuakeC the items in a linked list are entities, and the pointers are just that: entity pointers in the form of QuakeC fields (in this case we use 'owner').

Linked lists must have a head, which is either the first item in the list or a pointer to it. Without this, the linked list would be lost and you wouldn't be able to reach it! The bodyque linked list is a looping linked list. This means that the last item in the list points back to the first (You can observe this by the 'e.owner = bodyque_head;' line in the code).

The bodyque is created at the start of the level, with empty spaces to put corpses in. Each time someone dies, the CopyToBodyQue function (under InitBodyQue) is called, which changes the bodyque_head entity to look like the player's corpse. It then changes bodyque_head to point to bodyque_head.owner, the next in the list. Eventually, bodyque_head.owner will equal the first corpse entered, and that one will be replaced! Simple, is it not? Even if not, you still got the job done ;)

Conclusion
Whether you simple cut-and-pasted the code, or actually read through my poor explanation, you have hopefully gotten something from this tutorial. Linked lists are an essential programming tool, and it's best off to start simple. Before you know it, you'll be getting into dually-linked lists that have to be modified on the fly!

Good luck with your programming, and please create Quake mods for the community :)

Post comment Comments
bart2o
bart2o - - 1,863 comments

hehe. that's nice, i think that it's a bad thing to get the bodyque variable over 10, because the map would be spammed with corpses :)

Reply Good karma Bad karma+1 vote
VonGimli
VonGimli - - 37 comments

How would I do it in call of duty or half-life? Do you know?

Reply Good karma Bad karma+1 vote
Sajt Author
Sajt - - 1,641 comments

I don't. Half-Life is based off Quake and uses a lot of its old game code, so it might have a bodyque (but I'm not familiar with the HL code at all, I've only glanced at it), but I'm sure Call of Duty is completely different. So sorry :(

Reply Good karma+1 vote
San-J
San-J - - 662 comments

Well, CoD uses the Quake 3 engine, so it is definately possible that it would be similiar.

Reply Good karma Bad karma+1 vote
Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: