//----------------------------------------------------------------------------- // // $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 ); }