636 lines
15 KiB
C++
636 lines
15 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Logfile:: /Quake 2 Engine/Sin/code/game/worldspawn.cpp $
|
|
// $Revision:: 97 $
|
|
// $Author:: Jimdose $
|
|
// $Date:: 11/08/98 10:49p $
|
|
//
|
|
// Copyright (C) 1997 by Ritual Entertainment, Inc.
|
|
// All rights reserved.
|
|
//
|
|
// This source is may not be distributed and/or modified without
|
|
// expressly written permission by Ritual Entertainment, Inc.
|
|
//
|
|
// $Log:: /Quake 2 Engine/Sin/code/game/worldspawn.cpp $
|
|
//
|
|
// 97 11/08/98 10:49p Jimdose
|
|
// moved earthquake to level struct
|
|
//
|
|
// 96 10/27/98 9:46p Aldie
|
|
// Changed training cvar to level.training
|
|
//
|
|
// 95 10/27/98 6:28a Jimdose
|
|
// set model to "*1"
|
|
//
|
|
// 94 10/27/98 5:43a Jimdose
|
|
// World wasn't calling Entity::Archive or Unarchive!
|
|
// Added FreeTargetList
|
|
//
|
|
// 93 10/27/98 4:36a Markd
|
|
// reset the earthquake in worldspawn
|
|
//
|
|
// 92 10/26/98 2:16p Aldie
|
|
// Added AirClamp
|
|
//
|
|
// 91 10/21/98 2:17a Jimdose
|
|
// Fixed bug where world wiped out configstrings during loadgame
|
|
//
|
|
// 90 10/19/98 9:53p Jimdose
|
|
// changed slime variables to lightvolume
|
|
//
|
|
// 89 10/10/98 1:31a Jimdose
|
|
// moved precache scripts to G_Precache in G_Utils
|
|
// some things are no longer initialized during loadgames
|
|
//
|
|
// 88 10/08/98 12:37a Jimdose
|
|
// Made savegames work
|
|
//
|
|
// 87 9/30/98 4:36p Aldie
|
|
// Reset gravpaths when worldspawn is destroyed
|
|
//
|
|
// 86 9/27/98 6:27p Aldie
|
|
// Added water, slime, and lava colors to worldspawn
|
|
//
|
|
// 85 9/17/98 5:53p Jimdose
|
|
// create level.total_secrets and level.found_secrets on startup
|
|
//
|
|
// 84 9/02/98 7:48p Aldie
|
|
// Added support for multiple global scripts
|
|
//
|
|
// 83 8/29/98 9:48p Jimdose
|
|
// included deadbody.h
|
|
//
|
|
// 82 8/24/98 11:32a Markd
|
|
// Added Start method to threads, repladed all ProcessEvent(
|
|
// EV_ScriptThread_execute) with thread->Start( -1 )
|
|
//
|
|
// 81 8/22/98 6:34p Markd
|
|
// Revamped player readiness for scripting
|
|
//
|
|
// 80 8/21/98 5:26p Markd
|
|
// Added sv_precache and cl_precache
|
|
//
|
|
// 79 8/17/98 7:33p Jimdose
|
|
// skipthread is now initialized with G_GetStringArg since G_GetSpawnArg can
|
|
// return NULL, which the str class doesn't like
|
|
//
|
|
// 78 8/17/98 4:35p Markd
|
|
// Added skipthread and cinematic stuff to worldspawn
|
|
//
|
|
// 77 8/08/98 7:51p Jimdose
|
|
// changed realWorld to world
|
|
//
|
|
// 76 7/26/98 12:35p Jimdose
|
|
// Got rid of backslash in filename
|
|
//
|
|
// 75 7/24/98 6:22p Jimdose
|
|
// Set config string CS_MAXCLIENTS
|
|
// removed unused layout stuff
|
|
//
|
|
// 74 7/15/98 12:14a Aldie
|
|
// Updated worldspawn to send over a deathmatch flag
|
|
//
|
|
// 73 7/13/98 5:57p Markd
|
|
// Added SetGameScript call
|
|
//
|
|
// 72 7/13/98 5:01p Aldie
|
|
// Added dead player bodies with gibbing
|
|
//
|
|
// 71 7/01/98 7:04p Aldie
|
|
// Mission computer stuff
|
|
//
|
|
// 70 6/27/98 7:58p Aldie
|
|
// Moved status bar to client
|
|
//
|
|
// 69 6/27/98 2:15p Aldie
|
|
// New status bar stuff
|
|
//
|
|
// 68 6/25/98 7:33p Aldie
|
|
// New HUD
|
|
//
|
|
// 67 6/24/98 1:38p Aldie
|
|
// Implementation of inventory system and picking stuff up
|
|
//
|
|
// 66 6/20/98 7:06p Aldie
|
|
// Updated HUD for inventory
|
|
//
|
|
// 65 6/20/98 2:23p Aldie
|
|
// Added Inventory to statusbar
|
|
//
|
|
// 64 6/19/98 6:38p Aldie
|
|
// Updated status bar for inventory
|
|
//
|
|
// 63 6/10/98 2:10p Aldie
|
|
// Updated damage function.
|
|
//
|
|
// 62 6/09/98 4:24p Jimdose
|
|
// Added multi-file scripting, so hacks to load multifiles were removed.
|
|
//
|
|
// 61 6/05/98 6:26p Aldie
|
|
// Updated stats bar for armor.
|
|
//
|
|
// 60 5/26/98 4:21p Markd
|
|
// Added TargetList stuff
|
|
//
|
|
// 59 5/25/98 2:28p Aldie
|
|
// Fixed issues with not loading game dll
|
|
//
|
|
// 58 5/24/98 2:46p Markd
|
|
// Made char *'s into const char *'s
|
|
//
|
|
// 57 5/19/98 11:13p Aldie
|
|
// Fixed statusbars for higher res
|
|
//
|
|
// 56 5/18/98 6:15p Aldie
|
|
// Updated ammo bar.
|
|
//
|
|
// 55 5/14/98 10:20p Jimdose
|
|
// world is now an EntityPtr
|
|
//
|
|
// 54 5/04/98 8:32p Markd
|
|
// Removed setlightstyle stuff
|
|
//
|
|
// 53 5/04/98 11:31a Markd
|
|
// Moved lightstyles into global.scr
|
|
//
|
|
// 52 5/02/98 9:39p Markd
|
|
// Fixed the gunsmoke lightstyle
|
|
//
|
|
// 51 5/02/98 8:47p Markd
|
|
// Took out a lot of precache stuff
|
|
//
|
|
// 50 5/01/98 5:07p Jimdose
|
|
// Changed *world to an Entity *
|
|
//
|
|
// 49 5/01/98 10:42a Markd
|
|
// Put in global.scr and precache.scr parsing
|
|
//
|
|
// 48 4/18/98 8:20p Markd
|
|
// Fixed sniperrifle precache
|
|
//
|
|
// 47 4/18/98 7:43p Markd
|
|
// Added correct weapon names to precache section
|
|
//
|
|
// 46 4/18/98 6:35p Aldie
|
|
// Updated sbar layout
|
|
//
|
|
// 45 4/18/98 6:12p Aldie
|
|
// Updated ammo stats bar.
|
|
//
|
|
// 44 4/16/98 8:40p Aldie
|
|
// Added DM status bar to new system
|
|
//
|
|
// 43 4/16/98 7:46p Aldie
|
|
// Added new status bar
|
|
//
|
|
// 42 4/10/98 1:24a Markd
|
|
// Added FL_SPARKS and FL_BLASTMARK flags
|
|
//
|
|
// 41 4/07/98 8:00p Markd
|
|
// removed defhandle, changed all SINMDL calls to modelindex calls, removed
|
|
// SINMDL prefix
|
|
//
|
|
// 40 4/03/98 3:37p Jimdose
|
|
// Got rid of disabled status bar
|
|
//
|
|
// 39 4/03/98 2:30p Jimdose
|
|
// Temporarily turned off status bar
|
|
//
|
|
// 38 4/02/98 4:52p Jimdose
|
|
// Changed stat bar layouts
|
|
//
|
|
// 37 3/31/98 4:21p Jimdose
|
|
// added precaches
|
|
//
|
|
// 36 3/31/98 1:19p Jimdose
|
|
// Precached footsteps
|
|
//
|
|
// 35 3/30/98 11:39p Markd
|
|
// Added modelIndex stuff
|
|
//
|
|
// 34 3/27/98 11:04p Jimdose
|
|
// changed explode.def to explode.spr
|
|
//
|
|
// 33 3/26/98 7:15p Aldie
|
|
// Added console type vars.
|
|
//
|
|
// 32 3/23/98 1:31p Jimdose
|
|
// Revamped event and command system
|
|
//
|
|
// 31 3/18/98 7:21p Jimdose
|
|
// Added precache for explosion sprite
|
|
//
|
|
// 30 3/02/98 8:49p Jimdose
|
|
// Changed the classid parameter of CLASS_DECLARATION to a quoted string so
|
|
// that you could have a NULL classid.
|
|
//
|
|
// 29 2/23/98 6:38p Jimdose
|
|
//
|
|
// 28 2/17/98 7:00p Jimdose
|
|
// levelVars are cleared upon spawning the world
|
|
//
|
|
// 27 2/16/98 2:06p Jimdose
|
|
// Changed movetype from MOVETYPE_PUSH to MOVETYPE_NONE, since the world
|
|
// shouldn't be moving around.
|
|
//
|
|
// 26 2/10/98 11:44a Jimdose
|
|
// Changed color of worldspawn in Sined
|
|
//
|
|
// 25 2/06/98 5:48p Jimdose
|
|
// Moved sined header to .cpp file.
|
|
// Prepended "maps/" to script file name
|
|
//
|
|
// 24 2/03/98 10:56a Jimdose
|
|
// Updated to work with Quake 2 engine
|
|
// Moved initialization to constructor and removed Init function
|
|
// Removed precache stuff (it was all out of date anyway).
|
|
//
|
|
// 22 12/15/97 4:32p Jimdose
|
|
// Precached new shotgun sounds
|
|
//
|
|
// 21 12/15/97 2:51p Markd
|
|
// Added speargun firing sounds
|
|
//
|
|
// 20 12/15/97 11:56a Markd
|
|
// Added speargun sounds
|
|
//
|
|
// 19 12/14/97 5:54p Jimdose
|
|
// Removed wrong check-in comment #18: " Added BettySpike"
|
|
// Changed precache of spear\spear.def to spear.def.
|
|
//
|
|
// 17 12/14/97 5:34p Markd
|
|
// Put in precaches for rocket launcher stuff
|
|
//
|
|
// 16 12/13/97 7:42p Markd
|
|
// Added RocketLauncher sound
|
|
//
|
|
// 15 12/13/97 6:52p Aldie
|
|
// Added precache for shotgun
|
|
//
|
|
// 14 12/12/97 1:19p Markd
|
|
// Added rocket launcher precache
|
|
//
|
|
// 13 12/06/97 12:35p Aldie
|
|
// Added tracer sprite to precache
|
|
//
|
|
// 12 11/18/97 5:26p Markd
|
|
// Changed model from sub-directory to parent directory for magnum.def
|
|
//
|
|
// 11 11/10/97 8:38p Jimdose
|
|
// Removed getMapTitle. Map name is now stored in netname.
|
|
// Made StartFrame get called indirectly through EVENT_PRETHINK.
|
|
// Added event function.
|
|
//
|
|
// 10 11/07/97 6:00p Markd
|
|
// Removed QUAKE specific sound effects prespawns
|
|
//
|
|
// 9 10/31/97 7:19p Markd
|
|
// Added precache for sprites
|
|
//
|
|
// 8 10/28/97 8:36p Jimdose
|
|
// Moved magnum model
|
|
//
|
|
// 7 10/28/97 8:20p Jimdose
|
|
// Added precache for bubble and spear
|
|
//
|
|
// 6 10/28/97 6:54p Markd
|
|
// Added precache for darkcaptain sound
|
|
//
|
|
// 5 10/27/97 3:29p Jimdose
|
|
// Removed dependency on quakedef.h
|
|
//
|
|
// 4 10/24/97 8:13p Jimdose
|
|
// Added precache for magnum
|
|
//
|
|
// 3 9/26/97 6:14p Jimdose
|
|
// Added standard Ritual headers
|
|
//
|
|
// DESCRIPTION:
|
|
// Base class for worldspawn objects. This should be subclassed whenever
|
|
// a DLL has new game behaviour that needs to be initialized before any other
|
|
// entities are created, or before any entity thinks each frame. Also controls
|
|
// spawning of clients.
|
|
//
|
|
|
|
#include "g_local.h"
|
|
#include "entity.h"
|
|
#include "scriptmaster.h"
|
|
#include "worldspawn.h"
|
|
#include "surface.h"
|
|
#include "console.h"
|
|
#include "deadbody.h"
|
|
#include "gravpath.h"
|
|
#include "earthquake.h"
|
|
|
|
extern void CreateMissionComputer( void );
|
|
|
|
WorldPtr world;
|
|
|
|
/*****************************************************************************/
|
|
/*SINED worldspawn (0 0 0) ? CINEMATIC
|
|
|
|
Only used for the world.
|
|
"sky" environment map name
|
|
"skyaxis" vector axis for rotating sky
|
|
"skyrotate" speed of rotation in degrees/second
|
|
"cdtrack" music cd track number
|
|
"gravity" 800 is default gravity
|
|
"message" text to print at user logon
|
|
"skipthread" thread that is activated to skip this level (if cinematic)
|
|
|
|
/*****************************************************************************/
|
|
|
|
#define CINEMATIC 1
|
|
|
|
CLASS_DECLARATION( Entity, World, "worldspawn" );
|
|
|
|
ResponseDef World::Responses[] =
|
|
{
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
World::World()
|
|
{
|
|
const char *text;
|
|
str mapname;
|
|
int i;
|
|
Vector water_color;
|
|
Vector lightvolume_color;
|
|
Vector lava_color;
|
|
|
|
world = this;
|
|
|
|
setMoveType( MOVETYPE_NONE );
|
|
setSolidType( SOLID_BSP );
|
|
|
|
// world model is always index 1
|
|
edict->s.modelindex = 1;
|
|
model = "*1";
|
|
|
|
// Anything that modifies configstrings, or spawns things is ignored when loading savegames
|
|
if ( LoadingSavegame )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// inform the client that this is deathmatch, and we should
|
|
// draw deathmatch stats. This goes around what the CS_STATUSBAR
|
|
// used to be used for since we moved all HUDS to the client.
|
|
if ( deathmatch->value )
|
|
{
|
|
gi.configstring( CS_STATUSBAR, "DEATHMATCH" );
|
|
}
|
|
else
|
|
{
|
|
gi.configstring( CS_STATUSBAR, "SINGLE_PLAYER" );
|
|
}
|
|
|
|
//
|
|
// see if the level has a soundtrack associated withit
|
|
//
|
|
text = G_GetSpawnArg( "soundtrack" );
|
|
if ( text )
|
|
{
|
|
gi.configstring( CS_SOUNDTRACK, text );
|
|
}
|
|
|
|
text = G_GetSpawnArg( "sky" );
|
|
if ( text )
|
|
{
|
|
gi.configstring( CS_SKY, text );
|
|
}
|
|
else
|
|
{
|
|
gi.configstring( CS_SKY, "sky_" );
|
|
}
|
|
|
|
text = G_GetSpawnArg( "skyrotate" );
|
|
gi.configstring( CS_SKYROTATE, text ? text : "0" );
|
|
|
|
text = G_GetSpawnArg( "skyaxis" );
|
|
gi.configstring( CS_SKYAXIS, text ? text : "0 0 0" );
|
|
|
|
text = G_GetSpawnArg( "cdtrack" );
|
|
gi.configstring( CS_CDTRACK, text ? text : "0" );
|
|
|
|
gi.configstring (CS_MAXCLIENTS, va("%i", (int)(maxclients->value) ) );
|
|
|
|
text = G_GetSpawnArg( "gravity" );
|
|
if ( !text )
|
|
{
|
|
gi.cvar_set( "sv_gravity", "800" );
|
|
}
|
|
else
|
|
{
|
|
gi.cvar_set( "sv_gravity", text );
|
|
}
|
|
|
|
// get skipthread
|
|
skipthread = G_GetStringArg( "skipthread" );
|
|
|
|
// the world takes blast marks and sparks by default
|
|
flags |= FL_BLASTMARK;
|
|
flags |= FL_SPARKS;
|
|
|
|
// Reserve some space for dead bodies
|
|
InitializeBodyQueue();
|
|
|
|
//
|
|
// see if this is a cinematic level
|
|
//
|
|
if ( spawnflags & CINEMATIC )
|
|
{
|
|
level.cinematic = true;
|
|
}
|
|
else
|
|
{
|
|
level.cinematic = false;
|
|
}
|
|
|
|
level.nextmap = G_GetStringArg( "nextmap" );
|
|
|
|
// make some data visible to the server
|
|
text = G_GetSpawnArg( "message" );
|
|
if ( text )
|
|
{
|
|
gi.configstring( CS_NAME, text );
|
|
level.level_name = text;
|
|
}
|
|
else
|
|
{
|
|
level.level_name = level.mapname;
|
|
}
|
|
|
|
// Set up script
|
|
text = G_GetSpawnArg( "script" );
|
|
if ( !text )
|
|
{
|
|
// No script specified. Try using the mapname as the script name
|
|
mapname = "maps/";
|
|
mapname += level.mapname;
|
|
for( i = mapname.length() - 1; i >= 0; i-- )
|
|
{
|
|
if ( mapname[ i ] == '.' )
|
|
{
|
|
mapname[ i ] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
mapname += ".scr";
|
|
|
|
text = &mapname[ 5 ];
|
|
|
|
// If there isn't a script with the same name as the map, then don't try to load script
|
|
if ( gi.LoadFile( mapname.c_str(), NULL, 0 ) == -1 )
|
|
{
|
|
text = NULL;
|
|
}
|
|
}
|
|
|
|
if ( text )
|
|
{
|
|
gi.dprintf( "Adding script: '%s'\n", text );
|
|
mapname = va( "maps/%s", text );
|
|
|
|
// just set the script, we will start it in G_Spawn
|
|
ScriptLib.SetGameScript( mapname.c_str() );
|
|
}
|
|
|
|
// Set the color for the blends.
|
|
water_color = G_GetVectorArg("watercolor",Vector(0,0,1));
|
|
level.water_alpha = G_GetFloatArg("wateralpha",0.1);
|
|
|
|
lightvolume_color = G_GetVectorArg("lightcolor",Vector(1,1,1));
|
|
level.lightvolume_alpha = G_GetFloatArg("lightalpha",0.5);
|
|
|
|
lava_color = G_GetVectorArg("lavacolor",Vector(1.0,0.3,0));
|
|
level.lava_alpha = G_GetFloatArg("lavaalpha",0.6);
|
|
|
|
level.water_color = water_color;
|
|
level.lightvolume_color = lightvolume_color;
|
|
level.lava_color = lava_color;
|
|
|
|
//
|
|
// reset the earthquake
|
|
//
|
|
level.earthquake = 0;
|
|
}
|
|
|
|
TargetList * World::GetTargetList( str &targetname )
|
|
{
|
|
TargetList * targetlist;
|
|
int i;
|
|
|
|
for( i = 1; i <= targetList.NumObjects(); i++ )
|
|
{
|
|
targetlist = targetList.ObjectAt( i );
|
|
if ( targetname == targetlist->targetname)
|
|
return targetlist;
|
|
}
|
|
targetlist = new TargetList( targetname );
|
|
targetList.AddObject( targetlist );
|
|
return targetlist;
|
|
}
|
|
|
|
void World::AddTargetEntity( str &targetname, Entity * ent )
|
|
{
|
|
TargetList * targetlist;
|
|
|
|
targetlist = GetTargetList( targetname );
|
|
targetlist->AddEntity( ent );
|
|
}
|
|
|
|
void World::RemoveTargetEntity( str &targetname, Entity * ent )
|
|
{
|
|
TargetList * targetlist;
|
|
|
|
targetlist = GetTargetList( targetname );
|
|
targetlist->RemoveEntity( ent );
|
|
}
|
|
|
|
Entity * World::GetNextEntity( str &targetname, Entity * ent )
|
|
{
|
|
TargetList * targetlist;
|
|
|
|
targetlist = GetTargetList( targetname );
|
|
return targetlist->GetNextEntity( ent );
|
|
}
|
|
|
|
World::~World()
|
|
{
|
|
FreeTargetList();
|
|
}
|
|
|
|
void World::FreeTargetList
|
|
(
|
|
void
|
|
)
|
|
|
|
{
|
|
int i;
|
|
int num;
|
|
|
|
num = targetList.NumObjects();
|
|
for( i = 1; i <= num; i++ )
|
|
{
|
|
delete targetList.ObjectAt( i );
|
|
}
|
|
|
|
targetList.FreeObjectList();
|
|
}
|
|
|
|
//
|
|
// List stuff for targets
|
|
//
|
|
|
|
CLASS_DECLARATION( Class, TargetList, NULL );
|
|
|
|
ResponseDef TargetList::Responses[] =
|
|
{
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
TargetList::TargetList()
|
|
{
|
|
}
|
|
|
|
TargetList::TargetList( str &tname )
|
|
{
|
|
targetname = tname;
|
|
}
|
|
|
|
TargetList::~TargetList()
|
|
{
|
|
}
|
|
|
|
void TargetList::AddEntity( Entity * ent )
|
|
{
|
|
if ( !list.ObjectInList( ent ) )
|
|
{
|
|
list.AddObject( ent );
|
|
}
|
|
}
|
|
|
|
void TargetList::RemoveEntity( Entity * ent )
|
|
{
|
|
if ( list.ObjectInList( ent ) )
|
|
{
|
|
list.RemoveObject( ent );
|
|
}
|
|
}
|
|
|
|
Entity * TargetList::GetNextEntity( Entity * ent )
|
|
{
|
|
int index;
|
|
|
|
index = 0;
|
|
if ( ent )
|
|
index = list.IndexOfObject( ent );
|
|
index++;
|
|
if ( index > list.NumObjects() )
|
|
return NULL;
|
|
else
|
|
return list.ObjectAt( index );
|
|
}
|
|
|