codemp/game/g_spawn.c

Go to the documentation of this file.
00001 // Copyright (C) 1999-2000 Id Software, Inc.
00002 //
00003 
00004 #include "g_local.h"
00005 
00006 qboolean        G_SpawnString( const char *key, const char *defaultString, char **out ) {
00007         int             i;
00008 
00009         if ( !level.spawning ) {
00010                 *out = (char *)defaultString;
00011 //              G_Error( "G_SpawnString() called while not spawning" );
00012         }
00013 
00014         for ( i = 0 ; i < level.numSpawnVars ; i++ ) {
00015                 if ( !Q_stricmp( key, level.spawnVars[i][0] ) ) {
00016                         *out = level.spawnVars[i][1];
00017                         return qtrue;
00018                 }
00019         }
00020 
00021         *out = (char *)defaultString;
00022         return qfalse;
00023 }
00024 
00025 qboolean        G_SpawnFloat( const char *key, const char *defaultString, float *out ) {
00026         char            *s;
00027         qboolean        present;
00028 
00029         present = G_SpawnString( key, defaultString, &s );
00030         *out = atof( s );
00031         return present;
00032 }
00033 
00034 qboolean        G_SpawnInt( const char *key, const char *defaultString, int *out ) {
00035         char            *s;
00036         qboolean        present;
00037 
00038         present = G_SpawnString( key, defaultString, &s );
00039         *out = atoi( s );
00040         return present;
00041 }
00042 
00043 qboolean        G_SpawnVector( const char *key, const char *defaultString, float *out ) {
00044         char            *s;
00045         qboolean        present;
00046 
00047         present = G_SpawnString( key, defaultString, &s );
00048         sscanf( s, "%f %f %f", &out[0], &out[1], &out[2] );
00049         return present;
00050 }
00051 
00052 
00053 
00054 BG_field_t fields[] = {
00055         {"classname", FOFS(classname), F_LSTRING},
00056         {"teamnodmg", FOFS(teamnodmg), F_INT},
00057         {"teamowner", FOFS(s.teamowner), F_INT},
00058         {"teamuser", FOFS(alliedTeam), F_INT},
00059         {"alliedTeam", FOFS(alliedTeam), F_INT},//for misc_turrets
00060         {"roffname", FOFS(roffname), F_LSTRING},
00061         {"rofftarget", FOFS(rofftarget), F_LSTRING},
00062         {"healingclass", FOFS(healingclass), F_LSTRING},
00063         {"healingsound", FOFS(healingsound), F_LSTRING},
00064         {"healingrate", FOFS(healingrate), F_INT},
00065         {"ownername", FOFS(ownername), F_LSTRING},
00066         {"origin", FOFS(s.origin), F_VECTOR},
00067         {"model", FOFS(model), F_LSTRING},
00068         {"model2", FOFS(model2), F_LSTRING},
00069         {"spawnflags", FOFS(spawnflags), F_INT},
00070         {"speed", FOFS(speed), F_FLOAT},
00071         {"target", FOFS(target), F_LSTRING},
00072         {"target2", FOFS(target2), F_LSTRING},
00073         {"target3", FOFS(target3), F_LSTRING},
00074         {"target4", FOFS(target4), F_LSTRING},
00075         {"target5", FOFS(target5), F_LSTRING},
00076         {"target6", FOFS(target6), F_LSTRING},
00077         {"NPC_targetname", FOFS(NPC_targetname), F_LSTRING},
00078         {"NPC_target", FOFS(NPC_target), F_LSTRING},
00079         {"NPC_target2", FOFS(target2), F_LSTRING},//NPC_spawner only
00080         {"NPC_target4", FOFS(target4), F_LSTRING},//NPC_spawner only
00081         {"NPC_type", FOFS(NPC_type), F_LSTRING},
00082         {"targetname", FOFS(targetname), F_LSTRING},
00083         {"message", FOFS(message), F_LSTRING},
00084         {"team", FOFS(team), F_LSTRING},
00085         {"wait", FOFS(wait), F_FLOAT},
00086         {"delay", FOFS(delay), F_INT},
00087         {"random", FOFS(random), F_FLOAT},
00088         {"count", FOFS(count), F_INT},
00089         {"health", FOFS(health), F_INT},
00090         {"light", 0, F_IGNORE},
00091         {"dmg", FOFS(damage), F_INT},
00092         {"angles", FOFS(s.angles), F_VECTOR},
00093         {"angle", FOFS(s.angles), F_ANGLEHACK},
00094         {"targetShaderName", FOFS(targetShaderName), F_LSTRING},
00095         {"targetShaderNewName", FOFS(targetShaderNewName), F_LSTRING},
00096         {"linear", FOFS(alt_fire), F_INT},//for movers to use linear movement
00097 
00098         {"closetarget", FOFS(closetarget), F_LSTRING},//for doors
00099         {"opentarget", FOFS(opentarget), F_LSTRING},//for doors
00100         {"paintarget", FOFS(paintarget), F_LSTRING},//for doors
00101 
00102         {"goaltarget", FOFS(goaltarget), F_LSTRING},//for siege
00103         {"idealclass", FOFS(idealclass), F_LSTRING},//for siege spawnpoints
00104 
00105         //rww - icarus stuff:
00106         {"spawnscript", FOFS(behaviorSet[BSET_SPAWN]), F_LSTRING},//name of script to run
00107         {"usescript", FOFS(behaviorSet[BSET_USE]), F_LSTRING},//name of script to run
00108         {"awakescript", FOFS(behaviorSet[BSET_AWAKE]), F_LSTRING},//name of script to run
00109         {"angerscript", FOFS(behaviorSet[BSET_ANGER]), F_LSTRING},//name of script to run
00110         {"attackscript", FOFS(behaviorSet[BSET_ATTACK]), F_LSTRING},//name of script to run
00111         {"victoryscript", FOFS(behaviorSet[BSET_VICTORY]), F_LSTRING},//name of script to run
00112         {"lostenemyscript", FOFS(behaviorSet[BSET_LOSTENEMY]), F_LSTRING},//name of script to run
00113         {"painscript", FOFS(behaviorSet[BSET_PAIN]), F_LSTRING},//name of script to run
00114         {"fleescript", FOFS(behaviorSet[BSET_FLEE]), F_LSTRING},//name of script to run
00115         {"deathscript", FOFS(behaviorSet[BSET_DEATH]), F_LSTRING},//name of script to run
00116         {"delayscript", FOFS(behaviorSet[BSET_DELAYED]), F_LSTRING},//name of script to run
00117         {"delayscripttime", FOFS(delayScriptTime), F_INT},//name of script to run
00118         {"blockedscript", FOFS(behaviorSet[BSET_BLOCKED]), F_LSTRING},//name of script to run
00119         {"ffirescript", FOFS(behaviorSet[BSET_FFIRE]), F_LSTRING},//name of script to run
00120         {"ffdeathscript", FOFS(behaviorSet[BSET_FFDEATH]), F_LSTRING},//name of script to run
00121         {"mindtrickscript", FOFS(behaviorSet[BSET_MINDTRICK]), F_LSTRING},//name of script to run
00122         {"script_targetname", FOFS(script_targetname), F_LSTRING},//scripts look for this when "affecting"
00123 
00124         {"fullName", FOFS(fullName), F_LSTRING},
00125 
00126         {"soundSet", FOFS(soundSet), F_LSTRING},
00127         {"radius", FOFS(radius), F_FLOAT},
00128         {"numchunks", FOFS(radius), F_FLOAT},//for func_breakables
00129         {"chunksize", FOFS(mass), F_FLOAT},//for func_breakables
00130 
00131 //Script parms - will this handle clamping to 16 or whatever length of parm[0] is?
00132         {"parm1", 0, F_PARM1},
00133         {"parm2", 0, F_PARM2},
00134         {"parm3", 0, F_PARM3},
00135         {"parm4", 0, F_PARM4},
00136         {"parm5", 0, F_PARM5},
00137         {"parm6", 0, F_PARM6},
00138         {"parm7", 0, F_PARM7},
00139         {"parm8", 0, F_PARM8},
00140         {"parm9", 0, F_PARM9},
00141         {"parm10", 0, F_PARM10},
00142         {"parm11", 0, F_PARM11},
00143         {"parm12", 0, F_PARM12},
00144         {"parm13", 0, F_PARM13},
00145         {"parm14", 0, F_PARM14},
00146         {"parm15", 0, F_PARM15},
00147         {"parm16", 0, F_PARM16},
00148 
00149         {NULL}
00150 };
00151 
00152 
00153 typedef struct {
00154         char    *name;
00155         void    (*spawn)(gentity_t *ent);
00156 } spawn_t;
00157 
00158 void SP_info_player_start (gentity_t *ent);
00159 void SP_info_player_duel( gentity_t *ent );
00160 void SP_info_player_duel1( gentity_t *ent );
00161 void SP_info_player_duel2( gentity_t *ent );
00162 void SP_info_player_deathmatch (gentity_t *ent);
00163 void SP_info_player_siegeteam1 (gentity_t *ent);
00164 void SP_info_player_siegeteam2 (gentity_t *ent);
00165 void SP_info_player_intermission (gentity_t *ent);
00166 void SP_info_player_intermission_red (gentity_t *ent);
00167 void SP_info_player_intermission_blue (gentity_t *ent);
00168 void SP_info_jedimaster_start (gentity_t *ent);
00169 void SP_info_player_start_red (gentity_t *ent);
00170 void SP_info_player_start_blue (gentity_t *ent);
00171 void SP_info_firstplace(gentity_t *ent);
00172 void SP_info_secondplace(gentity_t *ent);
00173 void SP_info_thirdplace(gentity_t *ent);
00174 void SP_info_podium(gentity_t *ent);
00175 
00176 void SP_info_siege_objective (gentity_t *ent);
00177 void SP_info_siege_radaricon (gentity_t *ent);
00178 void SP_info_siege_decomplete (gentity_t *ent);
00179 void SP_target_siege_end (gentity_t *ent);
00180 void SP_misc_siege_item (gentity_t *ent);
00181 
00182 void SP_func_plat (gentity_t *ent);
00183 void SP_func_static (gentity_t *ent);
00184 void SP_func_rotating (gentity_t *ent);
00185 void SP_func_bobbing (gentity_t *ent);
00186 void SP_func_pendulum( gentity_t *ent );
00187 void SP_func_button (gentity_t *ent);
00188 void SP_func_door (gentity_t *ent);
00189 void SP_func_train (gentity_t *ent);
00190 void SP_func_timer (gentity_t *self);
00191 void SP_func_breakable (gentity_t *ent);
00192 void SP_func_glass (gentity_t *ent);
00193 void SP_func_usable( gentity_t *ent);
00194 void SP_func_wall( gentity_t *ent );
00195 
00196 void SP_trigger_lightningstrike( gentity_t *ent );
00197 
00198 void SP_trigger_always (gentity_t *ent);
00199 void SP_trigger_multiple (gentity_t *ent);
00200 void SP_trigger_once( gentity_t *ent );
00201 void SP_trigger_push (gentity_t *ent);
00202 void SP_trigger_teleport (gentity_t *ent);
00203 void SP_trigger_hurt (gentity_t *ent);
00204 void SP_trigger_space(gentity_t *self);
00205 void SP_trigger_shipboundary(gentity_t *self);
00206 void SP_trigger_hyperspace(gentity_t *self);
00207 void SP_trigger_asteroid_field(gentity_t *self);
00208 
00209 void SP_target_remove_powerups( gentity_t *ent );
00210 void SP_target_give (gentity_t *ent);
00211 void SP_target_delay (gentity_t *ent);
00212 void SP_target_speaker (gentity_t *ent);
00213 void SP_target_print (gentity_t *ent);
00214 void SP_target_laser (gentity_t *self);
00215 void SP_target_character (gentity_t *ent);
00216 void SP_target_score( gentity_t *ent );
00217 void SP_target_teleporter( gentity_t *ent );
00218 void SP_target_relay (gentity_t *ent);
00219 void SP_target_kill (gentity_t *ent);
00220 void SP_target_position (gentity_t *ent);
00221 void SP_target_location (gentity_t *ent);
00222 void SP_target_counter (gentity_t *self);
00223 void SP_target_random (gentity_t *self);
00224 void SP_target_scriptrunner( gentity_t *self );
00225 void SP_target_interest (gentity_t *self);
00226 void SP_target_activate (gentity_t *self);
00227 void SP_target_deactivate (gentity_t *self);
00228 void SP_target_level_change( gentity_t *self );
00229 void SP_target_play_music( gentity_t *self );
00230 void SP_target_push (gentity_t *ent);
00231 
00232 void SP_light (gentity_t *self);
00233 void SP_info_null (gentity_t *self);
00234 void SP_info_notnull (gentity_t *self);
00235 void SP_info_camp (gentity_t *self);
00236 void SP_path_corner (gentity_t *self);
00237 
00238 void SP_misc_teleporter_dest (gentity_t *self);
00239 void SP_misc_model(gentity_t *ent);
00240 void SP_misc_model_static(gentity_t *ent);
00241 void SP_misc_G2model(gentity_t *ent);
00242 void SP_misc_portal_camera(gentity_t *ent);
00243 void SP_misc_portal_surface(gentity_t *ent);
00244 void SP_misc_weather_zone( gentity_t *ent );
00245 
00246 void SP_misc_bsp (gentity_t *ent);
00247 void SP_terrain (gentity_t *ent);
00248 void SP_misc_skyportal_orient (gentity_t *ent);
00249 void SP_misc_skyportal (gentity_t *ent);
00250 
00251 void SP_misc_ammo_floor_unit(gentity_t *ent);
00252 void SP_misc_shield_floor_unit( gentity_t *ent );
00253 void SP_misc_model_shield_power_converter( gentity_t *ent );
00254 void SP_misc_model_ammo_power_converter( gentity_t *ent );
00255 void SP_misc_model_health_power_converter( gentity_t *ent );
00256 
00257 void SP_fx_runner( gentity_t *ent );
00258 
00259 void SP_target_screenshake(gentity_t *ent);
00260 void SP_target_escapetrig(gentity_t *ent);
00261 
00262 void SP_misc_maglock ( gentity_t *self );
00263 
00264 void SP_misc_faller(gentity_t *ent);
00265 
00266 void SP_misc_holocron(gentity_t *ent);
00267 
00268 void SP_reference_tag ( gentity_t *ent );
00269 
00270 void SP_misc_weapon_shooter( gentity_t *self );
00271 
00272 void SP_NPC_spawner( gentity_t *self );
00273 
00274 void SP_NPC_Vehicle( gentity_t *self);
00275 
00276 void SP_NPC_Kyle( gentity_t *self );
00277 void SP_NPC_Lando( gentity_t *self );
00278 void SP_NPC_Jan( gentity_t *self );
00279 void SP_NPC_Luke( gentity_t *self );
00280 void SP_NPC_MonMothma( gentity_t *self );
00281 void SP_NPC_Tavion( gentity_t *self );
00282 void SP_NPC_Tavion_New( gentity_t *self );
00283 void SP_NPC_Alora( gentity_t *self );
00284 void SP_NPC_Reelo( gentity_t *self );
00285 void SP_NPC_Galak( gentity_t *self );
00286 void SP_NPC_Desann( gentity_t *self );
00287 void SP_NPC_Bartender( gentity_t *self );
00288 void SP_NPC_MorganKatarn( gentity_t *self );
00289 void SP_NPC_Jedi( gentity_t *self );
00290 void SP_NPC_Prisoner( gentity_t *self );
00291 void SP_NPC_Rebel( gentity_t *self );
00292 void SP_NPC_Stormtrooper( gentity_t *self );
00293 void SP_NPC_StormtrooperOfficer( gentity_t *self );
00294 void SP_NPC_Snowtrooper( gentity_t *self);
00295 void SP_NPC_Tie_Pilot( gentity_t *self );
00296 void SP_NPC_Ugnaught( gentity_t *self );
00297 void SP_NPC_Jawa( gentity_t *self );
00298 void SP_NPC_Gran( gentity_t *self );
00299 void SP_NPC_Rodian( gentity_t *self );
00300 void SP_NPC_Weequay( gentity_t *self );
00301 void SP_NPC_Trandoshan( gentity_t *self );
00302 void SP_NPC_Tusken( gentity_t *self );
00303 void SP_NPC_Noghri( gentity_t *self );
00304 void SP_NPC_SwampTrooper( gentity_t *self );
00305 void SP_NPC_Imperial( gentity_t *self );
00306 void SP_NPC_ImpWorker( gentity_t *self );
00307 void SP_NPC_BespinCop( gentity_t *self );
00308 void SP_NPC_Reborn( gentity_t *self );
00309 void SP_NPC_ShadowTrooper( gentity_t *self );
00310 void SP_NPC_Monster_Murjj( gentity_t *self );
00311 void SP_NPC_Monster_Swamp( gentity_t *self );
00312 void SP_NPC_Monster_Howler( gentity_t *self );
00313 void SP_NPC_Monster_Claw( gentity_t *self );
00314 void SP_NPC_Monster_Glider( gentity_t *self );
00315 void SP_NPC_Monster_Flier2( gentity_t *self );
00316 void SP_NPC_Monster_Lizard( gentity_t *self );
00317 void SP_NPC_Monster_Fish( gentity_t *self );
00318 void SP_NPC_Monster_Wampa( gentity_t *self );
00319 void SP_NPC_Monster_Rancor( gentity_t *self );
00320 void SP_NPC_MineMonster( gentity_t *self );
00321 void SP_NPC_Droid_Interrogator( gentity_t *self );
00322 void SP_NPC_Droid_Probe( gentity_t *self );
00323 void SP_NPC_Droid_Mark1( gentity_t *self );
00324 void SP_NPC_Droid_Mark2( gentity_t *self );
00325 void SP_NPC_Droid_ATST( gentity_t *self );
00326 void SP_NPC_Droid_Seeker( gentity_t *self );
00327 void SP_NPC_Droid_Remote( gentity_t *self );
00328 void SP_NPC_Droid_Sentry( gentity_t *self );
00329 void SP_NPC_Droid_Gonk( gentity_t *self );
00330 void SP_NPC_Droid_Mouse( gentity_t *self );
00331 void SP_NPC_Droid_R2D2( gentity_t *self );
00332 void SP_NPC_Droid_R5D2( gentity_t *self );
00333 void SP_NPC_Droid_Protocol( gentity_t *self );
00334 
00335 void SP_NPC_Reborn_New( gentity_t *self);
00336 void SP_NPC_Cultist( gentity_t *self );
00337 void SP_NPC_Cultist_Saber( gentity_t *self );
00338 void SP_NPC_Cultist_Saber_Powers( gentity_t *self );
00339 void SP_NPC_Cultist_Destroyer( gentity_t *self );
00340 void SP_NPC_Cultist_Commando( gentity_t *self );
00341 
00342 void SP_waypoint (gentity_t *ent);
00343 void SP_waypoint_small (gentity_t *ent);
00344 void SP_waypoint_navgoal (gentity_t *ent);
00345 void SP_waypoint_navgoal_8 (gentity_t *ent);
00346 void SP_waypoint_navgoal_4 (gentity_t *ent);
00347 void SP_waypoint_navgoal_2 (gentity_t *ent);
00348 void SP_waypoint_navgoal_1 (gentity_t *ent);
00349 
00350 void SP_CreateSpaceDust( gentity_t *ent );
00351 void SP_CreateSnow( gentity_t *ent );
00352 void SP_CreateRain( gentity_t *ent );
00353 
00354 void SP_point_combat( gentity_t *self );
00355 
00356 void SP_shooter_blaster( gentity_t *ent );
00357 
00358 void SP_team_CTF_redplayer( gentity_t *ent );
00359 void SP_team_CTF_blueplayer( gentity_t *ent );
00360 
00361 void SP_team_CTF_redspawn( gentity_t *ent );
00362 void SP_team_CTF_bluespawn( gentity_t *ent );
00363 
00364 void SP_misc_turret( gentity_t *ent );
00365 void SP_misc_turretG2( gentity_t *base );
00366 
00367 
00368 void SP_item_botroam( gentity_t *ent )
00369 {
00370 }
00371 
00372 void SP_gametype_item ( gentity_t* ent )
00373 {
00374         gitem_t *item = NULL;
00375         char *value;
00376         int team = -1;
00377 
00378         G_SpawnString("teamfilter", "", &value);
00379 
00380         G_SetOrigin( ent, ent->s.origin );
00381 
00382         // If a team filter is set then override any team settings for the spawns
00383         if ( level.mTeamFilter[0] )
00384         {
00385                 if ( Q_stricmp ( level.mTeamFilter, "red") == 0 )
00386                 {
00387                         team = TEAM_RED;
00388                 }
00389                 else if ( Q_stricmp ( level.mTeamFilter, "blue") == 0 )
00390                 {
00391                         team = TEAM_BLUE;
00392                 }
00393         }
00394 
00395         if (ent->targetname && ent->targetname[0])
00396         {
00397                 if (team != -1)
00398                 {
00399                         if (strstr(ent->targetname, "flag"))
00400                         {
00401                                 if (team == TEAM_RED)
00402                                 {
00403                                         item = BG_FindItem("team_CTF_redflag");
00404                                 }
00405                                 else
00406                                 { //blue
00407                                         item = BG_FindItem("team_CTF_blueflag");
00408                                 }
00409                         }
00410                 }
00411                 else if (strstr(ent->targetname, "red_flag"))
00412                 {
00413                         item = BG_FindItem("team_CTF_redflag");
00414                 }
00415                 else if (strstr(ent->targetname, "blue_flag"))
00416                 {
00417                         item = BG_FindItem("team_CTF_blueflag");
00418                 }
00419                 else
00420                 {
00421                         item = NULL;
00422                 }
00423 
00424                 if (item)
00425                 {
00426                         ent->targetname = NULL;
00427                         ent->classname = item->classname;
00428                         G_SpawnItem( ent, item );
00429                 }
00430         }
00431 }
00432 
00433 void SP_emplaced_gun( gentity_t *ent );
00434 
00435 spawn_t spawns[] = {
00436         // info entities don't do anything at all, but provide positional
00437         // information for things controlled by other processes
00438         {"info_player_start", SP_info_player_start},
00439         {"info_player_duel", SP_info_player_duel},
00440         {"info_player_duel1", SP_info_player_duel1},
00441         {"info_player_duel2", SP_info_player_duel2},
00442         {"info_player_deathmatch", SP_info_player_deathmatch},
00443         {"info_player_siegeteam1", SP_info_player_siegeteam1},
00444         {"info_player_siegeteam2", SP_info_player_siegeteam2},
00445         {"info_player_intermission", SP_info_player_intermission},
00446         {"info_player_intermission_red", SP_info_player_intermission_red},
00447         {"info_player_intermission_blue", SP_info_player_intermission_blue},
00448         {"info_jedimaster_start", SP_info_jedimaster_start},
00449         {"info_player_start_red", SP_info_player_start_red},
00450         {"info_player_start_blue", SP_info_player_start_blue},
00451         {"info_null", SP_info_null},
00452         {"info_notnull", SP_info_notnull},              // use target_position instead
00453         {"info_camp", SP_info_camp},
00454 
00455         {"info_siege_objective", SP_info_siege_objective},
00456         {"info_siege_radaricon", SP_info_siege_radaricon},
00457         {"info_siege_decomplete", SP_info_siege_decomplete},
00458         {"target_siege_end", SP_target_siege_end},
00459         {"misc_siege_item", SP_misc_siege_item},
00460 
00461         {"func_plat", SP_func_plat},
00462         {"func_button", SP_func_button},
00463         {"func_door", SP_func_door},
00464         {"func_static", SP_func_static},
00465         {"func_rotating", SP_func_rotating},
00466         {"func_bobbing", SP_func_bobbing},
00467         {"func_pendulum", SP_func_pendulum},
00468         {"func_train", SP_func_train},
00469         {"func_group", SP_info_null},
00470         {"func_timer", SP_func_timer},                  // rename trigger_timer?
00471         {"func_breakable", SP_func_breakable},
00472         {"func_glass", SP_func_glass},
00473         {"func_usable", SP_func_usable},
00474         {"func_wall", SP_func_wall},
00475 
00476         // Triggers are brush objects that cause an effect when contacted
00477         // by a living player, usually involving firing targets.
00478         // While almost everything could be done with
00479         // a single trigger class and different targets, triggered effects
00480         // could not be client side predicted (push and teleport).
00481         {"trigger_lightningstrike", SP_trigger_lightningstrike},
00482 
00483         {"trigger_always", SP_trigger_always},
00484         {"trigger_multiple", SP_trigger_multiple},
00485         {"trigger_once", SP_trigger_once},
00486         {"trigger_push", SP_trigger_push},
00487         {"trigger_teleport", SP_trigger_teleport},
00488         {"trigger_hurt", SP_trigger_hurt},
00489         {"trigger_space", SP_trigger_space},
00490         {"trigger_shipboundary", SP_trigger_shipboundary},
00491         {"trigger_hyperspace", SP_trigger_hyperspace},
00492         {"trigger_asteroid_field", SP_trigger_asteroid_field},
00493 
00494         // targets perform no action by themselves, but must be triggered
00495         // by another entity
00496         {"target_give", SP_target_give},
00497         {"target_remove_powerups", SP_target_remove_powerups},
00498         {"target_delay", SP_target_delay},
00499         {"target_speaker", SP_target_speaker},
00500         {"target_print", SP_target_print},
00501         {"target_laser", SP_target_laser},
00502         {"target_score", SP_target_score},
00503         {"target_teleporter", SP_target_teleporter},
00504         {"target_relay", SP_target_relay},
00505         {"target_kill", SP_target_kill},
00506         {"target_position", SP_target_position},
00507         {"target_location", SP_target_location},
00508         {"target_counter", SP_target_counter},
00509         {"target_random", SP_target_random},
00510         {"target_scriptrunner", SP_target_scriptrunner},
00511         {"target_interest", SP_target_interest},
00512         {"target_activate", SP_target_activate},
00513         {"target_deactivate", SP_target_deactivate},
00514         {"target_level_change", SP_target_level_change},
00515         {"target_play_music", SP_target_play_music},
00516         {"target_push", SP_target_push},
00517 
00518         {"light", SP_light},
00519         {"path_corner", SP_path_corner},
00520 
00521         {"misc_teleporter_dest", SP_misc_teleporter_dest},
00522         {"misc_model", SP_misc_model},
00523         {"misc_model_static", SP_misc_model_static},
00524         {"misc_G2model", SP_misc_G2model},
00525         {"misc_portal_surface", SP_misc_portal_surface},
00526         {"misc_portal_camera", SP_misc_portal_camera},
00527         {"misc_weather_zone", SP_misc_weather_zone},
00528 
00529         {"misc_bsp", SP_misc_bsp},
00530         {"terrain", SP_terrain},
00531         {"misc_skyportal_orient", SP_misc_skyportal_orient},
00532         {"misc_skyportal", SP_misc_skyportal},
00533 
00534         //rwwFIXMEFIXME: only for testing rmg team stuff
00535         {"gametype_item", SP_gametype_item },
00536 
00537         {"misc_ammo_floor_unit", SP_misc_ammo_floor_unit},
00538         {"misc_shield_floor_unit", SP_misc_shield_floor_unit},
00539         {"misc_model_shield_power_converter", SP_misc_model_shield_power_converter},
00540         {"misc_model_ammo_power_converter", SP_misc_model_ammo_power_converter},
00541         {"misc_model_health_power_converter", SP_misc_model_health_power_converter},
00542 
00543         {"fx_runner", SP_fx_runner},
00544 
00545         {"target_screenshake", SP_target_screenshake},
00546         {"target_escapetrig", SP_target_escapetrig},
00547 
00548         {"misc_maglock", SP_misc_maglock},
00549 
00550         {"misc_faller", SP_misc_faller},
00551 
00552         {"ref_tag",     SP_reference_tag},
00553         {"ref_tag_huge",        SP_reference_tag},
00554 
00555         {"misc_weapon_shooter", SP_misc_weapon_shooter},
00556 
00557         //new NPC ents
00558         {"NPC_spawner", SP_NPC_spawner},
00559 
00560         {"NPC_Vehicle", SP_NPC_Vehicle },
00561         {"NPC_Kyle", SP_NPC_Kyle },
00562         {"NPC_Lando", SP_NPC_Lando },
00563         {"NPC_Jan", SP_NPC_Jan },
00564         {"NPC_Luke", SP_NPC_Luke },
00565         {"NPC_MonMothma", SP_NPC_MonMothma },
00566         {"NPC_Tavion", SP_NPC_Tavion },
00567         
00568         //new tavion
00569         {"NPC_Tavion_New", SP_NPC_Tavion_New },
00570 
00571         //new alora
00572         {"NPC_Alora", SP_NPC_Alora },
00573 
00574         {"NPC_Reelo", SP_NPC_Reelo },
00575         {"NPC_Galak", SP_NPC_Galak },
00576         {"NPC_Desann", SP_NPC_Desann },
00577         {"NPC_Bartender", SP_NPC_Bartender },
00578         {"NPC_MorganKatarn", SP_NPC_MorganKatarn },
00579         {"NPC_Jedi", SP_NPC_Jedi },
00580         {"NPC_Prisoner", SP_NPC_Prisoner },
00581         {"NPC_Rebel", SP_NPC_Rebel },
00582         {"NPC_Stormtrooper", SP_NPC_Stormtrooper },
00583         {"NPC_StormtrooperOfficer", SP_NPC_StormtrooperOfficer },
00584         {"NPC_Snowtrooper", SP_NPC_Snowtrooper },
00585         {"NPC_Tie_Pilot", SP_NPC_Tie_Pilot },
00586         {"NPC_Ugnaught", SP_NPC_Ugnaught },
00587         {"NPC_Jawa", SP_NPC_Jawa },
00588         {"NPC_Gran", SP_NPC_Gran },
00589         {"NPC_Rodian", SP_NPC_Rodian },
00590         {"NPC_Weequay", SP_NPC_Weequay },
00591         {"NPC_Trandoshan", SP_NPC_Trandoshan },
00592         {"NPC_Tusken", SP_NPC_Tusken },
00593         {"NPC_Noghri", SP_NPC_Noghri },
00594         {"NPC_SwampTrooper", SP_NPC_SwampTrooper },
00595         {"NPC_Imperial", SP_NPC_Imperial },
00596         {"NPC_ImpWorker", SP_NPC_ImpWorker },
00597         {"NPC_BespinCop", SP_NPC_BespinCop },
00598         {"NPC_Reborn", SP_NPC_Reborn },
00599         {"NPC_ShadowTrooper", SP_NPC_ShadowTrooper },
00600         {"NPC_Monster_Murjj", SP_NPC_Monster_Murjj },
00601         {"NPC_Monster_Swamp", SP_NPC_Monster_Swamp },
00602         {"NPC_Monster_Howler", SP_NPC_Monster_Howler },
00603         {"NPC_MineMonster",     SP_NPC_MineMonster },
00604         {"NPC_Monster_Claw", SP_NPC_Monster_Claw },
00605         {"NPC_Monster_Glider", SP_NPC_Monster_Glider },
00606         {"NPC_Monster_Flier2", SP_NPC_Monster_Flier2 },
00607         {"NPC_Monster_Lizard", SP_NPC_Monster_Lizard },
00608         {"NPC_Monster_Fish", SP_NPC_Monster_Fish },
00609         {"NPC_Monster_Wampa", SP_NPC_Monster_Wampa },
00610         {"NPC_Monster_Rancor", SP_NPC_Monster_Rancor },
00611         {"NPC_Droid_Interrogator", SP_NPC_Droid_Interrogator },
00612         {"NPC_Droid_Probe", SP_NPC_Droid_Probe },
00613         {"NPC_Droid_Mark1", SP_NPC_Droid_Mark1 },
00614         {"NPC_Droid_Mark2", SP_NPC_Droid_Mark2 },
00615         {"NPC_Droid_ATST", SP_NPC_Droid_ATST },
00616         {"NPC_Droid_Seeker", SP_NPC_Droid_Seeker },
00617         {"NPC_Droid_Remote", SP_NPC_Droid_Remote },
00618         {"NPC_Droid_Sentry", SP_NPC_Droid_Sentry },
00619         {"NPC_Droid_Gonk", SP_NPC_Droid_Gonk },
00620         {"NPC_Droid_Mouse", SP_NPC_Droid_Mouse },
00621         {"NPC_Droid_R2D2", SP_NPC_Droid_R2D2 },
00622         {"NPC_Droid_R5D2", SP_NPC_Droid_R5D2 },
00623         {"NPC_Droid_Protocol", SP_NPC_Droid_Protocol },
00624 
00625         //maybe put these guys in some day, for now just spawn reborns in their place.
00626         {"NPC_Reborn_New", SP_NPC_Reborn_New },
00627         {"NPC_Cultist", SP_NPC_Cultist },
00628         {"NPC_Cultist_Saber", SP_NPC_Cultist_Saber },
00629         {"NPC_Cultist_Saber_Powers", SP_NPC_Cultist_Saber_Powers },
00630         {"NPC_Cultist_Destroyer", SP_NPC_Cultist_Destroyer },
00631         {"NPC_Cultist_Commando", SP_NPC_Cultist_Commando },
00632 
00633         //rwwFIXMEFIXME: Faked for testing NPCs (another other things) in RMG with sof2 assets
00634         {"NPC_Colombian_Soldier", SP_NPC_Reborn },
00635         {"NPC_Colombian_Rebel", SP_NPC_Reborn },
00636         {"NPC_Colombian_EmplacedGunner", SP_NPC_ShadowTrooper },
00637         {"NPC_Manuel_Vergara_RMG", SP_NPC_Desann },
00638 //      {"info_NPCnav", SP_waypoint},
00639 
00640         {"waypoint", SP_waypoint},
00641         {"waypoint_small", SP_waypoint_small},
00642         {"waypoint_navgoal", SP_waypoint_navgoal},
00643         {"waypoint_navgoal_8", SP_waypoint_navgoal_8},
00644         {"waypoint_navgoal_4", SP_waypoint_navgoal_4},
00645         {"waypoint_navgoal_2", SP_waypoint_navgoal_2},
00646         {"waypoint_navgoal_1", SP_waypoint_navgoal_1},
00647 
00648         {"fx_spacedust", SP_CreateSpaceDust},
00649         {"fx_rain", SP_CreateRain},
00650         {"fx_snow", SP_CreateSnow},
00651 
00652         {"point_combat", SP_point_combat},
00653 
00654         {"misc_holocron", SP_misc_holocron},
00655 
00656         {"shooter_blaster", SP_shooter_blaster},
00657 
00658         {"team_CTF_redplayer", SP_team_CTF_redplayer},
00659         {"team_CTF_blueplayer", SP_team_CTF_blueplayer},
00660 
00661         {"team_CTF_redspawn", SP_team_CTF_redspawn},
00662         {"team_CTF_bluespawn", SP_team_CTF_bluespawn},
00663 
00664         {"item_botroam", SP_item_botroam},
00665 
00666         {"emplaced_gun", SP_emplaced_gun},
00667 
00668         {"misc_turret", SP_misc_turret},
00669         {"misc_turretG2", SP_misc_turretG2},
00670 
00671 
00672         {0, 0}
00673 };
00674 
00675 /*
00676 ===============
00677 G_CallSpawn
00678 
00679 Finds the spawn function for the entity and calls it,
00680 returning qfalse if not found
00681 ===============
00682 */
00683 qboolean G_CallSpawn( gentity_t *ent ) {
00684         spawn_t *s;
00685         gitem_t *item;
00686 
00687         if ( !ent->classname ) {
00688                 G_Printf ("G_CallSpawn: NULL classname\n");
00689                 return qfalse;
00690         }
00691 
00692         // check item spawn functions
00693         for ( item=bg_itemlist+1 ; item->classname ; item++ ) {
00694                 if ( !strcmp(item->classname, ent->classname) ) {
00695                         G_SpawnItem( ent, item );
00696                         return qtrue;
00697                 }
00698         }
00699 
00700         // check normal spawn functions
00701         for ( s=spawns ; s->name ; s++ ) {
00702                 if ( !strcmp(s->name, ent->classname) ) {
00703                         // found it
00704                         if (ent->healingsound && ent->healingsound[0])
00705                         { //yeah...this can be used for anything, so.. precache it if it's there
00706                                 G_SoundIndex(ent->healingsound);
00707                         }
00708                         s->spawn(ent);
00709                         return qtrue;
00710                 }
00711         }
00712         G_Printf ("%s doesn't have a spawn function\n", ent->classname);
00713         return qfalse;
00714 }
00715 
00716 /*
00717 =============
00718 G_NewString
00719 
00720 Builds a copy of the string, translating \n to real linefeeds
00721 so message texts can be multi-line
00722 =============
00723 */
00724 char *G_NewString( const char *string ) {
00725         char    *newb, *new_p;
00726         int             i,l;
00727         
00728         l = strlen(string) + 1;
00729 
00730         newb = (char *) G_Alloc( l );
00731 
00732         new_p = newb;
00733 
00734         // turn \n into a real linefeed
00735         for ( i=0 ; i< l ; i++ ) {
00736                 if (string[i] == '\\' && i < l-1) {
00737                         i++;
00738                         if (string[i] == 'n') {
00739                                 *new_p++ = '\n';
00740                         } else {
00741                                 *new_p++ = '\\';
00742                         }
00743                 } else {
00744                         *new_p++ = string[i];
00745                 }
00746         }
00747         
00748         return newb;
00749 }
00750 
00751 
00752 
00753 
00754 
00755 /*
00756 ===================
00757 G_SpawnGEntityFromSpawnVars
00758 
00759 Spawn an entity and fill in all of the level fields from
00760 level.spawnVars[], then call the class specfic spawn function
00761 ===================
00762 */
00763 #include "../namespace_begin.h"
00764 void BG_ParseField( BG_field_t *l_fields, const char *key, const char *value, byte *ent );
00765 #include "../namespace_end.h"
00766 void G_SpawnGEntityFromSpawnVars( qboolean inSubBSP ) {
00767         int                     i;
00768         gentity_t       *ent;
00769         char            *s, *value, *gametypeName;
00770         static char *gametypeNames[] = {"ffa", "holocron", "jedimaster", "duel", "powerduel", "single", "team", "siege", "ctf", "cty"};
00771 
00772         // get the next free entity
00773         ent = G_Spawn();
00774 
00775         for ( i = 0 ; i < level.numSpawnVars ; i++ ) {
00776                 BG_ParseField( fields, level.spawnVars[i][0], level.spawnVars[i][1], (byte *)ent );
00777         }
00778 
00779         // check for "notsingle" flag
00780         if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
00781                 G_SpawnInt( "notsingle", "0", &i );
00782                 if ( i ) {
00783                         G_FreeEntity( ent );
00784                         return;
00785                 }
00786         }
00787         // check for "notteam" flag (GT_FFA, GT_DUEL, GT_SINGLE_PLAYER)
00788         if ( g_gametype.integer >= GT_TEAM ) {
00789                 G_SpawnInt( "notteam", "0", &i );
00790                 if ( i ) {
00791                         G_FreeEntity( ent );
00792                         return;
00793                 }
00794         } else {
00795                 G_SpawnInt( "notfree", "0", &i );
00796                 if ( i ) {
00797                         G_FreeEntity( ent );
00798                         return;
00799                 }
00800         }
00801 
00802         G_SpawnInt( "notta", "0", &i );
00803         if ( i ) {
00804                 G_FreeEntity( ent );
00805                 return;
00806         }
00807 
00808         if( G_SpawnString( "gametype", NULL, &value ) ) {
00809                 if( g_gametype.integer >= GT_FFA && g_gametype.integer < GT_MAX_GAME_TYPE ) {
00810                         gametypeName = gametypeNames[g_gametype.integer];
00811 
00812                         s = strstr( value, gametypeName );
00813                         if( !s ) {
00814                                 G_FreeEntity( ent );
00815                                 return;
00816                         }
00817                 }
00818         }
00819 
00820         // move editor origin to pos
00821         VectorCopy( ent->s.origin, ent->s.pos.trBase );
00822         VectorCopy( ent->s.origin, ent->r.currentOrigin );
00823 
00824         // if we didn't get a classname, don't bother spawning anything
00825         if ( !G_CallSpawn( ent ) ) {
00826                 G_FreeEntity( ent );
00827         }
00828 
00829         //Tag on the ICARUS scripting information only to valid recipients
00830         if ( trap_ICARUS_ValidEnt( ent ) )
00831         {
00832                 trap_ICARUS_InitEnt( ent );
00833 
00834                 if ( ent->classname && ent->classname[0] )
00835                 {
00836                         if ( Q_strncmp( "NPC_", ent->classname, 4 ) != 0 )
00837                         {//Not an NPC_spawner (rww - probably don't even care for MP, but whatever)
00838                                 G_ActivateBehavior( ent, BSET_SPAWN );
00839                         }
00840                 }
00841         }
00842 }
00843 
00844 
00845 
00846 /*
00847 ====================
00848 G_AddSpawnVarToken
00849 ====================
00850 */
00851 char *G_AddSpawnVarToken( const char *string ) {
00852         int             l;
00853         char    *dest;
00854 
00855         l = strlen( string );
00856         if ( level.numSpawnVarChars + l + 1 > MAX_SPAWN_VARS_CHARS ) {
00857                 G_Error( "G_AddSpawnVarToken: MAX_SPAWN_CHARS" );
00858         }
00859 
00860         dest = level.spawnVarChars + level.numSpawnVarChars;
00861         memcpy( dest, string, l+1 );
00862 
00863         level.numSpawnVarChars += l + 1;
00864 
00865         return dest;
00866 }
00867 
00868 void AddSpawnField(char *field, char *value)
00869 {
00870         int     i;
00871 
00872         for(i=0;i<level.numSpawnVars;i++)
00873         {
00874                 if (Q_stricmp(level.spawnVars[i][0], field) == 0)
00875                 {
00876                         level.spawnVars[ i ][1] = G_AddSpawnVarToken( value );
00877                         return;
00878                 }
00879         }
00880 
00881         level.spawnVars[ level.numSpawnVars ][0] = G_AddSpawnVarToken( field );
00882         level.spawnVars[ level.numSpawnVars ][1] = G_AddSpawnVarToken( value );
00883         level.numSpawnVars++;
00884 }
00885 
00886 #define NOVALUE "novalue"
00887 
00888 static void HandleEntityAdjustment(void)
00889 {
00890         char            *value;
00891         vec3_t          origin, newOrigin, angles;
00892         char            temp[MAX_QPATH];
00893         float           rotation;
00894 
00895         G_SpawnString("origin", NOVALUE, &value);
00896         if (Q_stricmp(value, NOVALUE) != 0)
00897         {
00898                 sscanf( value, "%f %f %f", &origin[0], &origin[1], &origin[2] );
00899         }
00900         else
00901         {
00902                 origin[0] = origin[1] = origin[2] = 0.0;
00903         }
00904 
00905         rotation = DEG2RAD(level.mRotationAdjust);
00906         newOrigin[0] = origin[0]*cos(rotation) - origin[1]*sin(rotation);
00907         newOrigin[1] = origin[0]*sin(rotation) + origin[1]*cos(rotation);
00908         newOrigin[2] = origin[2];
00909         VectorAdd(newOrigin, level.mOriginAdjust, newOrigin);
00910         // damn VMs don't handle outputing a float that is compatible with sscanf in all cases
00911         Com_sprintf(temp, MAX_QPATH, "%0.0f %0.0f %0.0f", newOrigin[0], newOrigin[1], newOrigin[2]);
00912         AddSpawnField("origin", temp);
00913 
00914         G_SpawnString("angles", NOVALUE, &value);
00915         if (Q_stricmp(value, NOVALUE) != 0)
00916         {
00917                 sscanf( value, "%f %f %f", &angles[0], &angles[1], &angles[2] );
00918 
00919                 angles[1] = fmod(angles[1] + level.mRotationAdjust, 360.0f);
00920                 // damn VMs don't handle outputing a float that is compatible with sscanf in all cases
00921                 Com_sprintf(temp, MAX_QPATH, "%0.0f %0.0f %0.0f", angles[0], angles[1], angles[2]);
00922                 AddSpawnField("angles", temp);
00923         }
00924         else
00925         {
00926                 G_SpawnString("angle", NOVALUE, &value);
00927                 if (Q_stricmp(value, NOVALUE) != 0)
00928                 {
00929                         sscanf( value, "%f", &angles[1] );
00930                 }
00931                 else
00932                 {
00933                         angles[1] = 0.0;
00934                 }
00935                 angles[1] = fmod(angles[1] + level.mRotationAdjust, 360.0f);
00936                 Com_sprintf(temp, MAX_QPATH, "%0.0f", angles[1]);
00937                 AddSpawnField("angle", temp);
00938         }
00939 
00940         // RJR experimental code for handling "direction" field of breakable brushes
00941         // though direction is rarely ever used.
00942         G_SpawnString("direction", NOVALUE, &value);
00943         if (Q_stricmp(value, NOVALUE) != 0)
00944         {
00945                 sscanf( value, "%f %f %f", &angles[0], &angles[1], &angles[2] );
00946         }
00947         else
00948         {
00949                 angles[0] = angles[1] = angles[2] = 0.0;
00950         }
00951         angles[1] = fmod(angles[1] + level.mRotationAdjust, 360.0f);
00952         Com_sprintf(temp, MAX_QPATH, "%0.0f %0.0f %0.0f", angles[0], angles[1], angles[2]);
00953         AddSpawnField("direction", temp);
00954 
00955 
00956         AddSpawnField("BSPInstanceID", level.mTargetAdjust);
00957 
00958         G_SpawnString("targetname", NOVALUE, &value);
00959         if (Q_stricmp(value, NOVALUE) != 0)
00960         {
00961                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
00962                 AddSpawnField("targetname", temp);
00963         }
00964 
00965         G_SpawnString("target", NOVALUE, &value);
00966         if (Q_stricmp(value, NOVALUE) != 0)
00967         {
00968                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
00969                 AddSpawnField("target", temp);
00970         }
00971 
00972         G_SpawnString("killtarget", NOVALUE, &value);
00973         if (Q_stricmp(value, NOVALUE) != 0)
00974         {
00975                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
00976                 AddSpawnField("killtarget", temp);
00977         }
00978 
00979         G_SpawnString("brushparent", NOVALUE, &value);
00980         if (Q_stricmp(value, NOVALUE) != 0)
00981         {
00982                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
00983                 AddSpawnField("brushparent", temp);
00984         }
00985 
00986         G_SpawnString("brushchild", NOVALUE, &value);
00987         if (Q_stricmp(value, NOVALUE) != 0)
00988         {
00989                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
00990                 AddSpawnField("brushchild", temp);
00991         }
00992 
00993         G_SpawnString("enemy", NOVALUE, &value);
00994         if (Q_stricmp(value, NOVALUE) != 0)
00995         {
00996                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
00997                 AddSpawnField("enemy", temp);
00998         }
00999 
01000         G_SpawnString("ICARUSname", NOVALUE, &value);
01001         if (Q_stricmp(value, NOVALUE) != 0)
01002         {
01003                 Com_sprintf(temp, MAX_QPATH, "%s%s", level.mTargetAdjust, value);
01004                 AddSpawnField("ICARUSname", temp);
01005         }
01006 }
01007 
01008 /*
01009 ====================
01010 G_ParseSpawnVars
01011 
01012 Parses a brace bounded set of key / value pairs out of the
01013 level's entity strings into level.spawnVars[]
01014 
01015 This does not actually spawn an entity.
01016 ====================
01017 */
01018 qboolean G_ParseSpawnVars( qboolean inSubBSP ) {
01019         char            keyname[MAX_TOKEN_CHARS];
01020         char            com_token[MAX_TOKEN_CHARS];
01021 
01022         level.numSpawnVars = 0;
01023         level.numSpawnVarChars = 0;
01024 
01025         // parse the opening brace
01026         if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) {
01027                 // end of spawn string
01028                 return qfalse;
01029         }
01030         if ( com_token[0] != '{' ) {
01031                 G_Error( "G_ParseSpawnVars: found %s when expecting {",com_token );
01032         }
01033 
01034         // go through all the key / value pairs
01035         while ( 1 ) {   
01036                 // parse key
01037                 if ( !trap_GetEntityToken( keyname, sizeof( keyname ) ) ) {
01038                         G_Error( "G_ParseSpawnVars: EOF without closing brace" );
01039                 }
01040 
01041                 if ( keyname[0] == '}' ) {
01042                         break;
01043                 }
01044                 
01045                 // parse value  
01046                 if ( !trap_GetEntityToken( com_token, sizeof( com_token ) ) ) {
01047                         G_Error( "G_ParseSpawnVars: EOF without closing brace" );
01048                 }
01049 
01050                 if ( com_token[0] == '}' ) {
01051                         G_Error( "G_ParseSpawnVars: closing brace without data" );
01052                 }
01053                 if ( level.numSpawnVars == MAX_SPAWN_VARS ) {
01054                         G_Error( "G_ParseSpawnVars: MAX_SPAWN_VARS" );
01055                 }
01056                 level.spawnVars[ level.numSpawnVars ][0] = G_AddSpawnVarToken( keyname );
01057                 level.spawnVars[ level.numSpawnVars ][1] = G_AddSpawnVarToken( com_token );
01058                 level.numSpawnVars++;
01059         }
01060 
01061         if (inSubBSP)
01062         {
01063                 HandleEntityAdjustment();
01064         }
01065 
01066         return qtrue;
01067 }
01068 
01069 
01070 static  char *defaultStyles[32][3] = 
01071 {
01072         {       // 0 normal
01073                 "z",
01074                 "z",
01075                 "z"
01076         },
01077         {       // 1 FLICKER (first variety)
01078                 "mmnmmommommnonmmonqnmmo",
01079                 "mmnmmommommnonmmonqnmmo",
01080                 "mmnmmommommnonmmonqnmmo"
01081         },
01082         {       // 2 SLOW STRONG PULSE
01083                 "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb",
01084                 "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb",
01085                 "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcb"
01086         },
01087         {       // 3 CANDLE (first variety)
01088                 "mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
01089                 "mmmmmaaaaammmmmaaaaaabcdefgabcdefg",
01090                 "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"
01091         },
01092         {       // 4 FAST STROBE
01093                 "mamamamamama",
01094                 "mamamamamama",
01095                 "mamamamamama"
01096         },
01097         {       // 5 GENTLE PULSE 1
01098                 "jklmnopqrstuvwxyzyxwvutsrqponmlkj",
01099                 "jklmnopqrstuvwxyzyxwvutsrqponmlkj",
01100                 "jklmnopqrstuvwxyzyxwvutsrqponmlkj"
01101         },
01102         {       // 6 FLICKER (second variety)
01103                 "nmonqnmomnmomomno",
01104                 "nmonqnmomnmomomno",
01105                 "nmonqnmomnmomomno"
01106         },
01107         {       // 7 CANDLE (second variety)
01108                 "mmmaaaabcdefgmmmmaaaammmaamm",
01109                 "mmmaaaabcdefgmmmmaaaammmaamm",
01110                 "mmmaaaabcdefgmmmmaaaammmaamm"
01111         },
01112         {       // 8 CANDLE (third variety)
01113                 "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
01114                 "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa",
01115                 "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"
01116         },
01117         {       // 9 SLOW STROBE (fourth variety)
01118                 "aaaaaaaazzzzzzzz",
01119                 "aaaaaaaazzzzzzzz",
01120                 "aaaaaaaazzzzzzzz"
01121         },
01122         {       // 10 FLUORESCENT FLICKER
01123                 "mmamammmmammamamaaamammma",
01124                 "mmamammmmammamamaaamammma",
01125                 "mmamammmmammamamaaamammma"
01126         },
01127         {       // 11 SLOW PULSE NOT FADE TO BLACK
01128                 "abcdefghijklmnopqrrqponmlkjihgfedcba",
01129                 "abcdefghijklmnopqrrqponmlkjihgfedcba",
01130                 "abcdefghijklmnopqrrqponmlkjihgfedcba"
01131         },
01132         {       // 12 FAST PULSE FOR JEREMY
01133                 "mkigegik",
01134                 "mkigegik",
01135                 "mkigegik"
01136         },
01137         {       // 13 Test Blending
01138                 "abcdefghijklmqrstuvwxyz",
01139                 "zyxwvutsrqmlkjihgfedcba",
01140                 "aammbbzzccllcckkffyyggp"
01141         },
01142         {       // 14
01143                 "",
01144                 "",
01145                 ""
01146         },
01147         {       // 15
01148                 "",
01149                 "",
01150                 ""
01151         },
01152         {       // 16
01153                 "",
01154                 "",
01155                 ""
01156         },
01157         {       // 17
01158                 "",
01159                 "",
01160                 ""
01161         },
01162         {       // 18
01163                 "",
01164                 "",
01165                 ""
01166         },
01167         {       // 19
01168                 "",
01169                 "",
01170                 ""
01171         },
01172         {       // 20
01173                 "",
01174                 "",
01175                 ""
01176         },
01177         {       // 21
0