.qc (dot qc) - the group for quake c coders of all denominations. If you make quake one mods and write code in quake c, join our group! I'll try to answer any quake c questions - please post your inquiry in the forums...

Report article RSS Feed 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 numbersix on Sep 30th, 2012
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() weapon_lightning =
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() weapon_bfg =
void() weapon_plasmagun =
void() weapon_machinegun =
void() weapon_shotgun =
void() weapon_gauntlet =
void() weapon_grapplinghook =
void() weapon_railgun =
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() weapon_rocketlauncher =
//void() weapon_grenadelauncher =
//void() weapon_lightning =
//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() weapon_bfg =
self.classname = "weapon_lightning"; // for touch function

// 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
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
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
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
click to sign in

You are not logged in, your comment will be anonymous unless you join the community today (totally free - or sign in with your social account on the right) which we encourage all contributors to do.

2000 characters limit; HTML formatting and smileys are not supported - text only

Aug 18, 2011
Open to all members
Send Message
Members Only
Join this group
Group Watch
Track this group
Report Abuse
Report article
Related Mods
Chaos Archon (Quake)
Chaos Archon Quake - Single & Multiplayer First Person Shooter
Painkeep v2.2 (Quake)
Painkeep v2.2 Quake - Multiplayer First Person Shooter
Related Games
Quake Single & Multiplayer First Person Shooter
Related Engines
DarkPlaces engine
DarkPlaces engine GPL Released Mar 30, 2000
Related Groups
Dark Places engine team
Dark Places engine team Developer with 15 members
qc Hardware & Tech group with 27 members
QuakeDB Fans & Clans group with 141 members