Highly evolved engine based on id Software technology, available under dual license (GPL, proprietary licensing for commercial use available).

Post tutorial Report RSS Quake c - using map entity spawn functions to load Quake III maps in Darkplaces

Darkplaces can load Quake III maps. This tutorial will demonstrate how to get the most of those maps by using quake-c to populate them with quake one entities.

Posted by on - Intermediate Server Side Coding

When you load a map in quake, all the objects that move (monsters and other objects) or a player can interact with (weapons, ammo, armor, etc.) are loaded by a special quake-c function called an entity spawn.

This will be a two part tutorial.

1. Demonstrate how to manage a quake map entity spawn function.
2. Demonstrate how to develop the code to load quake 1 entities on a Quake III map loaded in Darkplaces.

Part 1:

The Quake map entity spawn functions.

When the engine is loading a map and sees a set of brackets { } with "classname" in it it tries to call a quake-c function named by the classname field. Any fields specified that match entity fields ("origin", "name", etc.) are loaded into the new entity before the spawn function is called.

If you want to put a weapon in a quake map, you place this code in a map, usually with a map editor:
(The reason you want to use a map editor, is that the editor calculates the origin for you.)

// entity 24
{
"classname" "weapon_lightning"
"origin" "48 16 0"
}

This will cause the engine to spawn a lightning gun at that origin when the map is loaded. This is done with a quake-c spawn function:

/*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
*/
void() weap /> {
precache_model ("progs/g_light.mdl");
setmodel (self, "progs/g_light.mdl");
self.weapon = 3;
self.netname = "Thunderbolt";
self.touch = weapon_touch;
setsize (self, '-16 -16 0', '16 16 56');
StartItem ();
};

This quake-c code called from the map load section of the engine loads a lightning gun on the map. The origin is set from the data supplied in the map file as shown above.

So if you want to put custom entities in a map, you need the { } code for the map (including origin, brush blocks and other stats) and the corresponding quake-c spawn function. This system is very flexible and makes customization of maps contents very easy. What appears on a map is controlled dynamically from quake-c. This eliminates the necessity of recompiling maps or the quake engine to change entity appearance.

If you wanted a Quake mod to change the base weapons around in deathmatch you could simply rename the weapon spawn functions (found in items.qc):

void () weapon_supershotgun
void () weapon_nailgun
void () weapon_supernailgun
void () weapon_grenadelauncher
void () weapon_rocketlauncher
void () weapon_lightning

You could move those around to change nailguns into lightnings, supershotguns into rocket launchers, and so on. Note that this would radically affect single player / coop and might not have decent ammo balance.

Part 2:

Darkplaces (a Quake one game Engine) can load Quake III maps. (It DOES NOT run Quake III the game - there is a large difference!)

Why do you want to?
Because there are loads of awesome Quake III maps. Example: Moddb.com

Download the complete source file q3items.qc and mod here: Moddb.com

There is one issue - the entity definitions used by Quake III are different from those in Quake.
That means Quake III maps under darkplaces will have few weapons, no ammo, and almost none of the other entities.

Unless you follow this tutorial to create spawn functions to translate the Quake III items to Quake.

Quake III has the following item spawn functions:

// these functions can be defined just like this in quake-c
void() weap /> void ) weap /> void ) weap /> void ) weap /> void ) weap /> void ) weap /> void ) weap /> void() ammo_bullets =
void() ammo_grenades =
void() ammo_lightning =
void() ammo_bfg =
void() ammo_slugs =
void() item_armor_combat =
void() item_armor_body =
void() item_armor_shard =
void() item_health_small =
void() item_health_large =
void() item_health_mega =
void() item_quad =
void() item_regen =
void() item_invis =
void() item_enviro =
void() item_haste =
void() item_flight =
void() holdable_medkit =
void() holdable_teleporter =
void() info_player_intermission =
void() target_position =
void() trigger_push =
void() misc_teleporter_dest =
void() target_teleporter =
void() misc_teleporter =
void() play_sound =
void() target_speaker =
void() trap_shooter =
void() shooter_grenade =
void() shooter_plasma =
void() shooter_rocket =

// these function can not be defined - they already exist in quake 1
// this is good, these weapons will load on any quake 3 map darkplaces loads
//void() weap /> /void() weap /> /void() weap /> //void() item_health =

// these functions can not be defined because they are quake-c variables!
// Lord Havoc has solved this problem with the method below
//void() ammo_shells =
//void() ammo_rockets =
//void() ammo_cells =

// use these for spawn functions that quake-c blocks because they are variables
// just append spawnfunc_ to them - darkplaces will try spawnfunc_ammo_cells() if ammo_cells() fails
void() spawnfunc_ammo_cells =
void() spawnfunc_ammo_rockets =
void() spawnfunc_ammo_shells =

Now it is simply a matter of copying the code from the spawn functions you wish to substitute.
Or you could try this:

// make this a quake lightning gun
void() weap /> {
self.classname = "weapon_lightning"; // for touch function
weapon_lightning();
};

// spawn cell boxes
void() spawnfunc_ammo_cells =
{
// call to prevent suspended items from falling - defined seperately
// if (self.spawnflags & SUSPENDED) q3_suspend();

self.spawnflags = self.spawnflags | 1; // make it a big box - note conflicts with suspend
item_cells();
self.aflag = 50; // q3 ammo boxes contain more ammo
};

void() ammo_bfg =
{
// call to prevent suspended items from falling - defined seperately
// if (self.spawnflags & SUSPENDED) q3_suspend();

self.spawnflags = self.spawnflags | 1; // make it a big box - note conflicts with suspend
item_cells();
self.aflag = 100; // q3 ammo boxes contain more ammo
};

void() ammo_lightning =
{
// call to prevent suspended items from falling - defined seperately
// if (self.spawnflags & SUSPENDED) q3_suspend();

self.spawnflags = self.spawnflags | 1; // make it a big box - note conflicts with suspend
item_cells();
self.aflag = 50; // q3 ammo boxes contain more ammo
};

Download the complete source file and mod here: Moddb.com

Painkeep v2.x includes this code tweaked for the painkeep mod.

When Chaos Archon: Moddb.com is released Quake III maps will be supported at a high level of detail where entities are concerned.

Post a comment

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