Changing Levels

With the player correctly placed at the start of the level, the next thing we need for a single player game is some way of changing levels. In this type of game the player must travel through a level and, when he reaches a predetermined location, be advanced to the next level. To accomplish this we need a new entity that, when triggered will end the current level and load the next level. We must also save the player's health, weapons, ammo and item data so it can be reloaded at the start of the new level.

The new entity we will create here is called target_level_end and you must add the following to the entity definitions file of your map editor :

/*QUAKED target_level_end (1 0 0) (-16 -16 -24) (16 16 32)
when triggered, the level ends
"message" use it to set the name of the next level
targetname: To trigger the level end.
*/

The source code changes to implement this entity are :

In g_local.h about line 628 add :

void QDECL G_Printf( const char *fmt, ... );
void QDECL G_Error( const char *fmt, ... );
#ifdef SINGLEPLAYER
void ExitLevel (void);
#endif

In g_spawn.c about line 165 add :

void SP_target_location (gentity_t *ent);
void SP_target_push (gentity_t *ent);
#ifdef SINGLEPLAYER
void SP_target_level_end (gentity_t *ent);
#endif

In g_spawn.c about line 244 add :

	{"target_location", SP_target_location},
{"target_push", SP_target_push},
#ifdef SINGLEPLAYER
{"target_level_end", SP_target_level_end},
#endif

In g_target.c at the end of the file add :

#ifdef SINGLEPLAYER
/*QUAKED target_level_end (1 0 0) (-16 -16 -24) (16 16 32)
when triggered, the level ends
"message" use it to set the name of the next level without any extension
targetname: To trigger the level end.
*/ char next_level[10][MAX_QPATH]; // max of 10 level change entities per level
int num_next_levels=0;
void target_use_end_level( gentity_t *self, gentity_t *other, gentity_t *activator ) {
char buf[MAX_QPATH] char *nx= next_level[self->health];;
trap_Cvar_Set("Save_Loading", "2");
trap_Cvar_Set("ui_LoadGame", "");
G_SavePersistant(nx);
Com_sprintf(buf,MAX_QPATH,"map %s",nx);;
trap_Cvar_Set( "nextmap", buf );
ExitLevel();
}
void SP_target_level_end( gentity_t *self ) { char *buf;
char *nx=next_level[num_next_levels];
self->health=num_next_levels;
G_SpawnString( "message", "missinglevel", &buf);
G_Printf("nextmap (%d): %s\n",num_next_levels,buf);
Com_sprintf(nx,sizeof(next_level[0]),"%s",buf);
self->use = target_use_end_level;
num_next_levels++;
}
#endif

This entity uses the UI cvars Save_Loading and ui_Loading to tell the code we added to place the player in the game that a level change has occured and to reload the persistant attributes.

Notes :

  1. The name of the level placed in message should not have any .bsp extension added to it.
  2. A level can have multiple target_level_end entities in it, each pointing to the different new levels, up to a maximum of 10 per level.


Return to Home Page