/* ============ WriteGame This will be called whenever the game goes to a new level, and when the user explicitly saves the game. Game information include cross level data, like multi level triggers, help computer info, and all client states. A single player death will automatically restore from the last save position. ============ */ void WriteGame(const char *filename, qboolean autosave) { FILE *f; int i; if (!autosave) SaveClientData(); f = fopen(filename, "wb"); if (!f) gi.error("Couldn't open %s", filename); write_int(f, SAVE_MAGIC1); write_int(f, SAVE_VERSION); game.autosaved = autosave; write_fields(f, gamefields, &game); game.autosaved = qfalse; for (i = 0; i < game.maxclients; i++) { write_fields(f, clientfields, &game.clients[i]); } fclose(f); }
/* ============ WriteGame This will be called whenever the game goes to a new level, and when the user explicitly saves the game. Game information include cross level data, like multi level triggers, help computer info, and all client states. A single player death will automatically restore from the last save position. ============ */ void WriteGame (char *filename, qboolean autosave) { FILE *f; int i; char str[16]; if (!autosave) SaveClientData (); f = fopen (filename, "wb"); if (!f) gi.error ("Couldn't open %s", filename); memset (str, 0, sizeof(str)); strcpy (str, __DATE__); fwrite (str, sizeof(str), 1, f); game.autosaved = autosave; fwrite (&game, sizeof(game), 1, f); game.autosaved = false; for (i=0 ; i<game.maxclients ; i++) WriteClient (f, &game.clients[i]); fclose (f); }
/* * Writes the game struct into * a file. This is called when * ever the games goes to e new * level or the user saves the * game. Saved informations are: * - cross level data * - client states * - help computer info */ void WriteGame(const char *filename, qboolean autosave) { FILE *f; int i; char str_ver[32]; char str_game[32]; char str_os[32]; char str_arch[32]; if (!autosave) { SaveClientData(); } f = fopen(filename, "wb"); if (!f) { gi.error("Couldn't open %s", filename); } /* Savegame identification */ memset(str_ver, 0, sizeof(str_ver)); memset(str_game, 0, sizeof(str_game)); memset(str_os, 0, sizeof(str_os)); memset(str_arch, 0, sizeof(str_arch)); strncpy(str_ver, SAVEGAMEVER, sizeof(str_ver)); strncpy(str_game, GAMEVERSION, sizeof(str_game)); strncpy(str_os, OS, sizeof(str_os)); strncpy(str_arch, ARCH, sizeof(str_arch)); fwrite(str_ver, sizeof(str_ver), 1, f); fwrite(str_game, sizeof(str_game), 1, f); fwrite(str_os, sizeof(str_os), 1, f); fwrite(str_arch, sizeof(str_arch), 1, f); game.autosaved = autosave; fwrite(&game, sizeof(game), 1, f); game.autosaved = false; for (i = 0; i < game.maxclients; i++) { WriteClient(f, &game.clients[i]); } fclose(f); }
/* * Creates a server's entity / program execution context by * parsing textual entity definitions out of an ent file. */ void SpawnEntities(char *mapname, char *entities, char *spawnpoint) { edict_t *ent; int inhibit; char *com_token; int i; float skill_level; skill_level = floor(skill->value); if (skill_level < 0) { skill_level = 0; } if (skill_level > 3) { skill_level = 3; } if (skill->value != skill_level) { gi.cvar_forceset("skill", va("%f", skill_level)); } SaveClientData(); gi.FreeTags(TAG_LEVEL); memset(&level, 0, sizeof(level)); memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0])); strncpy(level.mapname, mapname, sizeof(level.mapname) - 1); strncpy(game.spawnpoint, spawnpoint, sizeof(game.spawnpoint) - 1); /* set client fields on player ents */ for (i = 0; i < game.maxclients; i++) { g_edicts[i + 1].client = game.clients + i; } ent = NULL; inhibit = 0; /* parse ents */ while (1) { /* parse the opening brace */ com_token = COM_Parse(&entities); if (!entities) { break; } if (com_token[0] != '{') { gi.error("ED_LoadFromFile: found %s when expecting {", com_token); } if (!ent) { ent = g_edicts; } else { ent = G_Spawn(); } entities = ED_ParseEdict(entities, ent); /* yet another map hack */ if (!Q_stricmp(level.mapname, "command") && !Q_stricmp(ent->classname, "trigger_once") && !Q_stricmp(ent->model, "*27")) { ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; } /* remove things (except the world) from different skill levels or deathmatch */ if (ent != g_edicts) { if (deathmatch->value) { if (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) { G_FreeEdict(ent); inhibit++; continue; } } else { if (((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict(ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_COOP | SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn(ent); } gi.dprintf("%i entities inhibited.\n", inhibit); G_FindTeams(); PlayerTrail_Init(); CTFSpawn(); }
/* ============== SpawnEntities Creates a server's entity / program execution context by parsing textual entity definitions out of an ent file. ============== */ void SpawnEntities (char *mapname, char *entities, char *spawnpoint) { edict_t *ent; int inhibit; char *com_token; int i; float skill_level; skill_level = floor (skill->value); if (skill_level < 0) skill_level = 0; if (skill_level > 3) skill_level = 3; if (skill->value != skill_level) gi.cvar_forceset("skill", va("%f", skill_level)); SaveClientData (); gi.FreeTags (TAG_LEVEL); memset (&level, 0, sizeof(level)); memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0])); strncpy (level.mapname, mapname, sizeof(level.mapname)-1); strncpy (game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)-1); // set client fields on player ents for (i=0 ; i<game.maxclients ; i++) g_edicts[i+1].client = game.clients + i; ent = NULL; inhibit = 0; // parse ents while (1) { // parse the opening brace com_token = COM_Parse (&entities); if (!entities) break; if (com_token[0] != '{') gi.error ("ED_LoadFromFile: found %s when expecting {",com_token); if (!ent) ent = g_edicts; else ent = G_Spawn (); entities = ED_ParseEdict (entities, ent); // yet another map hack if (!Q_stricmp(level.mapname, "command") && !Q_stricmp(ent->classname, "trigger_once") && !Q_stricmp(ent->model, "*27")) ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; // remove things (except the world) from different skill levels or deathmatch if (ent != g_edicts) { if (deathmatch->value) { if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH ) { G_FreeEdict (ent); inhibit++; continue; } } else { if ( /* ((coop->value) && (ent->spawnflags & SPAWNFLAG_NOT_COOP)) || */ ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict (ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_COOP|SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn (ent); } gi.dprintf ("%i entities inhibited\n", inhibit); #ifdef DEBUG i = 1; ent = EDICT_NUM(i); while (i < globals.num_edicts) { if (ent->inuse != 0 || ent->inuse != 1) Com_DPrintf("Invalid entity %d\n", i); i++, ent++; } #endif G_FindTeams (); PlayerTrail_Init (); }
/* ============== SpawnEntities Creates a server's entity / program execution context by parsing textual entity definitions out of an ent file. ============== */ void SpawnEntities (char *mapname, char *entities, char *spawnpoint) { edict_t *ent = NULL; int inhibit = 0; char *com_token; int i; float skill_level; //AQ2:TNG New Location Code char locfile[MAX_QPATH], line[256]; FILE *f; int readmore, x, y, z, rx, ry, rz, count; char *locationstr, *param; cvar_t *game_cvar; int u; // placedata_t temp; // Reset teamplay stuff for(i = TEAM1; i < TEAM_TOP; i++) { teams[i].score = teams[i].total = 0; teams[i].ready = teams[i].locked = 0; teams[i].pauses_used = teams[i].wantReset = 0; gi.cvar_forceset(teams[i].teamscore->name, "0"); } matchtime = 0; day_cycle_at = 0; team_round_going = team_game_going = team_round_countdown = 0; lights_camera_action = holding_on_tie_check = 0; timewarning = fragwarning = 0; teamCount = 2; if (ctf->value) { // Make sure teamplay is enabled if (!teamplay->value) { gi.dprintf ("CTF Enabled - Forcing teamplay on\n"); gi.cvar_forceset(teamplay->name, "1"); } if (use_3teams->value) { gi.dprintf ("CTF Enabled - Forcing 3Teams off\n"); gi.cvar_forceset(use_3teams->name, "0"); } if(teamdm->value) { gi.dprintf ("CTF Enabled - Forcing Team DM off\n"); gi.cvar_forceset(teamdm->name, "0"); } if (use_tourney->value) { gi.dprintf ("CTF Enabled - Forcing Tourney off\n"); gi.cvar_forceset(use_tourney->name, "0"); } if (!((int) (dmflags->value) & DF_NO_FRIENDLY_FIRE)) { gi.dprintf ("CTF Enabled - Forcing Friendly Fire off\n"); gi.cvar_forceset(dmflags->name, va("%i", (int)dmflags->value | DF_NO_FRIENDLY_FIRE)); } strcpy(teams[TEAM1].name, "RED"); strcpy(teams[TEAM2].name, "BLUE"); strcpy(teams[TEAM1].skin, "male/ctf_r"); strcpy(teams[TEAM2].skin, "male/ctf_b"); strcpy(teams[TEAM1].skin_index, "../players/male/ctf_r_i"); strcpy(teams[TEAM2].skin_index, "../players/male/ctf_b_i"); if(ctf->value == 2) gi.cvar_forceset(ctf->name, "1"); //for now } else if(teamdm->value) { if (!teamplay->value) { gi.dprintf ("Team Deathmatch Enabled - Forcing teamplay on\n"); gi.cvar_forceset(teamplay->name, "1"); } if (use_3teams->value) { gi.dprintf ("Team Deathmatch Enabled - Forcing 3Teams off\n"); gi.cvar_forceset(use_3teams->name, "0"); } if (use_tourney->value) { gi.dprintf ("Team Deathmatch Enabled - Forcing Tourney off\n"); gi.cvar_forceset(use_tourney->name, "0"); } } else if (use_3teams->value) { teamCount = 3; if (!teamplay->value) { gi.dprintf ("3 Teams Enabled - Forcing teamplay on\n"); gi.cvar_forceset(teamplay->name, "1"); } if (use_tourney->value) { gi.dprintf ("3 Teams Enabled - Forcing Tourney off\n"); gi.cvar_forceset(use_tourney->name, "0"); } if (!use_oldspawns->value) { gi.dprintf ("3 Teams Enabled - Forcing use_oldspawns on\n"); gi.cvar_forceset(use_oldspawns->name, "1"); } } else if (matchmode->value) { if (!teamplay->value) { gi.dprintf ("Matchmode Enabled - Forcing teamplay on\n"); gi.cvar_forceset(teamplay->name, "1"); } if (use_tourney->value) { gi.dprintf ("Matchmode Enabled - Forcing Tourney off\n"); gi.cvar_forceset(use_tourney->name, "0"); } } else if (use_tourney->value) { if (!teamplay->value) { gi.dprintf ("Tourney Enabled - Forcing teamplay on\n"); gi.cvar_forceset(teamplay->name, "1"); } } skill_level = floor (skill->value); if (skill_level < 0) skill_level = 0; if (skill_level > 3) skill_level = 3; if (skill->value != skill_level) gi.cvar_forceset ("skill", va("%f", skill_level)); SaveClientData (); gi.FreeTags (TAG_LEVEL); memset (&level, 0, sizeof (level)); memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0])); Q_strncpyz(level.mapname, mapname, sizeof(level.mapname)); Q_strncpyz(game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)); // set client fields on player ents for (i = 0; i < game.maxclients; i++) g_edicts[i + 1].client = game.clients + i; // parse ents while (1) { // parse the opening brace com_token = COM_Parse (&entities); if (!entities) break; if (com_token[0] != '{') gi.error ("ED_LoadFromFile: found %s when expecting {", com_token); if (!ent) ent = g_edicts; else ent = G_Spawn (); entities = ED_ParseEdict (entities, ent); // yet another map hack if (!Q_stricmp (level.mapname, "command") && !Q_stricmp (ent->classname, "trigger_once") && !Q_stricmp (ent->model, "*27")) ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; // remove things (except the world) from different skill levels or deathmatch if (ent != g_edicts) { if (deathmatch->value) { if (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) { G_FreeEdict (ent); inhibit++; continue; } } else { if ( /* ((coop->value) && (ent->spawnflags & SPAWNFLAG_NOT_COOP)) || */ ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD))) { G_FreeEdict (ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_COOP | SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn (ent); } gi.dprintf ("%i entities inhibited\n", inhibit); // AQ2:TNG Igor adding .flg files // CTF configuration if(ctf->value) { if(!CTFLoadConfig(level.mapname)) { if ((!G_Find(NULL, FOFS (classname), "item_flag_team1") || !G_Find(NULL, FOFS (classname), "item_flag_team2"))) { gi.dprintf ("No native CTF map, loading flag positions from file\n"); if (LoadFlagsFromFile (level.mapname)) ChangePlayerSpawns (); } } } // AQ2:TNG End adding .flg files G_FindTeams (); PlayerTrail_Init (); // TNG:Freud - Ghosts num_ghost_players = 0; //FIREBLADE if (!teamplay->value || teamdm->value || ctf->value == 2) { //FIREBLADE //zucc for special items SetupSpecSpawn (); } else if (teamplay->value) { GetSpawnPoints (); //TNG:Freud - New spawning system if(!use_oldspawns->value) NS_GetSpawnPoints(); } //AQ2:TNG Slicer - New location code memset (ml_build, 0, sizeof (ml_build)); memset (ml_creator, 0, sizeof (ml_creator)); game_cvar = gi.cvar ("game", "", 0); if (!*game_cvar->string) Com_sprintf(locfile, sizeof(locfile), "%s/tng/%s.aqg", GAMEVERSION, level.mapname); else Com_sprintf(locfile, sizeof(locfile), "%s/tng/%s.aqg", game_cvar->string, level.mapname); f = fopen (locfile, "rt"); if (!f) { ml_count = 0; gi.dprintf ("No location file for %s\n", level.mapname); return; } gi.dprintf ("Location file: %s\n", level.mapname); readmore = 1; count = 0; while (readmore) { readmore = (fgets (line, 256, f) != NULL); param = strtok (line, " :\r\n\0"); if (line[0] == '#' && line[2] == 'C') { u = 0; for (i = 10; line[i] != '\n'; i++) { if (line[i] == '\r') continue; ml_creator[u] = line[i]; u++; } } if (line[0] == '#' && line[2] == 'B') { u = 0; for (i = 8; line[i] != '\n'; i++) { if (line[i] != ' ' && line[i] != '\r') { ml_build[u] = line[i]; u++; } } } ml_build[5] = 0; ml_creator[100] = 0; // TODO: better support for file comments if (!param || param[0] == '#') continue; x = atoi (param); param = strtok (NULL, " :\r\n\0"); if (!param) continue; y = atoi (param); param = strtok (NULL, " :\r\n\0"); if (!param) continue; z = atoi (param); param = strtok (NULL, " :\r\n\0"); if (!param) continue; rx = atoi (param); param = strtok (NULL, " :\r\n\0"); if (!param) continue; ry = atoi (param); param = strtok (NULL, " :\r\n\0"); if (!param) continue; rz = atoi (param); param = strtok (NULL, "\r\n\0"); if (!param) continue; locationstr = param; locationbase[count].x = x; locationbase[count].y = y; locationbase[count].z = z; locationbase[count].rx = rx; locationbase[count].ry = ry; locationbase[count].rz = rz; Q_strncpyz (locationbase[count].desc, locationstr, sizeof(locationbase[count].desc)); count++; if (count >= MAX_LOCATIONS_IN_BASE) { gi.dprintf ("Cannot read more than %d locations.\n", MAX_LOCATIONS_IN_BASE); break; } } ml_count = count; fclose (f); gi.dprintf ("Found %d locations.\n", count); }
/* ============== SpawnEntities Creates a server's entity / program execution context by parsing textual entity definitions out of an ent file. ============== */ void SpawnEntities (char *mapname, char *entities, char *spawnpoint) { edict_t *ent; int inhibit; char *com_token; int i; float skill_level; extern int max_modelindex; extern int max_soundindex; extern int lastgibframe; if (developer->value) gi.dprintf("====== SpawnEntities ========\n"); skill_level = floor (skill->value); if (skill_level < 0) skill_level = 0; if (skill_level > 3) skill_level = 3; if (skill->value != skill_level) gi.cvar_forceset("skill", va("%f", skill_level)); SaveClientData (); gi.FreeTags (TAG_LEVEL); memset (&level, 0, sizeof(level)); memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0])); // Lazarus: these are used to track model and sound indices // in g_main.c: max_modelindex = 0; max_soundindex = 0; // Lazarus: last frame a gib was spawned in lastgibframe = 0; strncpy (level.mapname, mapname, sizeof(level.mapname)-1); strncpy (game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)-1); // set client fields on player ents for (i=0 ; i<game.maxclients ; i++) g_edicts[i+1].client = game.clients + i; ent = NULL; inhibit = 0; // Knightamre- load the entity alias script file LoadAliasData(); //gi.dprintf ("Size of alias data: %i\n", alias_data_size); // parse ents while (1) { // parse the opening brace com_token = COM_Parse (&entities); if (!entities) break; if (com_token[0] != '{') gi.error ("ED_LoadFromFile: found %s when expecting {",com_token); if (!ent) ent = g_edicts; else ent = G_Spawn (); entities = ED_ParseEdict (entities, ent); // yet another map hack if (!Q_stricmp(level.mapname, "command") && !Q_stricmp(ent->classname, "trigger_once") && !Q_stricmp(ent->model, "*27")) ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; // remove things (except the world) from different skill levels or deathmatch if (ent != g_edicts) { if (deathmatch->value) { if ( ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH ) { G_FreeEdict (ent); inhibit++; continue; } } else if (coop->value) // Knightmare added- not in coop flag support { if ( ent->spawnflags & SPAWNFLAG_NOT_COOP ) { G_FreeEdict (ent); inhibit++; continue; } // NOT_EASY && NOT_MEDIUM && NOT_HARD && NOT_DM == COOP_ONLY if ( (ent->spawnflags & SPAWNFLAG_NOT_EASY) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM) && (ent->spawnflags & SPAWNFLAG_NOT_HARD) && (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) ) goto removeflags; if( ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || ((skill->value >= 2) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict (ent); inhibit++; continue; } } else // single player { if( ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || ((skill->value >= 2) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict (ent); inhibit++; continue; } } removeflags: // Knightmare- remove no coop flag ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_DEATHMATCH|SPAWNFLAG_NOT_COOP); } ED_CallSpawn (ent); ent->s.renderfx |= RF_IR_VISIBLE; // ir goggles flag } // Knightmare- unload the alias script file if (alias_data) { // If no alias file was loaded, don't bother #ifdef KMQUAKE2_ENGINE_MOD // use new engine function instead gi.FreeFile(alias_data); #else if (alias_from_pak) gi.TagFree(alias_data); else free(&alias_data); #endif } // Knightmare- unload the replacement entity data /* if (newents) // If no alias file was loaded, don't bother #ifdef KMQUAKE2_ENGINE_MOD // use new engine function instead gi.FreeFile(newents); #else free(&newents); #endif*/ gi.dprintf ("%i entities inhibited\n", inhibit); #ifdef DEBUG i = 1; ent = EDICT_NUM(i); while (i < globals.num_edicts) { if (ent->inuse != 0 || ent->inuse != 1) Com_DPrintf("Invalid entity %d\n", i); i++, ent++; } #endif G_FindTeams (); // DWH G_FindCraneParts(); // Get origin offsets (mainly for brush models w/o origin brushes) for (i=1, ent=g_edicts+i ; i < globals.num_edicts ; i++,ent++) { VectorAdd(ent->absmin,ent->absmax,ent->origin_offset); VectorScale(ent->origin_offset,0.5,ent->origin_offset); VectorSubtract(ent->origin_offset,ent->s.origin,ent->origin_offset); } // end DWH PlayerTrail_Init (); //ZOID CTFSpawn(); // Knightmare added if (deathmatch->value && !ctf->value) CTFSetupTechSpawn(); //ZOID if (!deathmatch->value) SetupHintPaths(); for(i=1, ent=g_edicts+i; i < globals.num_edicts; i++, ent++) { if(!ent->movewith) continue; if(ent->movewith_ent) continue; ent->movewith_ent = G_Find(NULL,FOFS(targetname),ent->movewith); // Make sure that we can really "movewith" this guy. This check // allows us to have movewith parent with same targetname as // other entities while(ent->movewith_ent && (Q_stricmp(ent->movewith_ent->classname,"func_train") && Q_stricmp(ent->movewith_ent->classname,"model_train") && Q_stricmp(ent->movewith_ent->classname,"func_door") && Q_stricmp(ent->movewith_ent->classname,"func_vehicle") && Q_stricmp(ent->movewith_ent->classname,"func_tracktrain") )) ent->movewith_ent = G_Find(ent->movewith_ent,FOFS(targetname),ent->movewith); if(ent->movewith_ent) movewith_init(ent->movewith_ent); } /* for(i=1, ent=g_edicts+i; i < globals.num_edicts; i++, ent++) { gi.dprintf("%s:%s - movewith=%s, movewith_ent=%s:%s, movewith_next=%s:%s\n====================\n", ent->classname, (ent->targetname ? ent->targetname : "noname"), (ent->movewith ? ent->movewith : "N/A"), (ent->movewith_ent ? ent->movewith_ent->classname : "N/A"), (ent->movewith_ent ? (ent->movewith_ent->targetname ? ent->movewith_ent->targetname : "noname") : "N/A"), (ent->movewith_next ? ent->movewith_next->classname : "N/A"), (ent->movewith_next ? (ent->movewith_next->targetname ? ent->movewith_next->targetname : "noname") : "N/A")); } */ if(game.transition_ents) LoadTransitionEnts(); actor_files(); }
/* ============== SpawnEntities Creates a server's entity / program execution context by parsing textual entity definitions out of an ent file. ============== */ void SpawnEntities (const char *mapname, char *entities, const char *spawnpoint) { edict_t *ent; int inhibit; const char *com_token; int i; float skill_level; int oldmaxent; skill_level = floor (skill->value); if (skill_level < 0) skill_level = 0; if (skill_level > 3) skill_level = 3; if (skill->value != skill_level) gi.cvar_forceset("skill", va("%f", skill_level)); SaveClientData (); gi.FreeTags (TAG_LEVEL); memset (&level, 0, sizeof(level)); memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0])); strncpy (level.mapname, mapname, sizeof(level.mapname)-1); strncpy (game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)-1); // set client fields on player ents for (i=0 ; i<game.maxclients ; i++) g_edicts[i+1].client = game.clients + i; ent = NULL; inhibit = 0; // parse ents while (1) { // parse the opening brace com_token = COM_Parse (&entities); if (!entities) break; if (com_token[0] != '{') gi.error ("ED_LoadFromFile: found %s when expecting {",com_token); if (!ent) ent = g_edicts; else ent = G_Spawn (); ent->spawnflags2 = 0; entities = ED_ParseEdict (entities, ent); // yet another map hack if (!Q_stricmp(level.mapname, "command") && !Q_stricmp(ent->classname, "trigger_once") && !Q_stricmp(ent->model, "*27")) ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; // remove things (except the world) from different skill levels or deathmatch if (ent != g_edicts) { if (deathmatch->value) { if ( (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) || (ent->spawnflags2 & SPAWNFLAG2_NOT_SINGLE) ) { G_FreeEdict (ent); inhibit++; continue; } } #if 0 // FIXME: DG: coop stuff from rogue else if (coop->value) { if (ent->spawnflags & SPAWNFLAG_NOT_COOP) { G_FreeEdict(ent); inhibit++; continue; } /* stuff marked !easy & !med & !hard are coop only, all levels */ if (!((ent->spawnflags & SPAWNFLAG_NOT_EASY) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM) && (ent->spawnflags & SPAWNFLAG_NOT_HARD))) { if (((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD))) { G_FreeEdict(ent); inhibit++; continue; } } } #endif // 0 else { if (((!coop->value) && (ent->spawnflags2 & SPAWNFLAG2_NOT_SINGLE)) || ((coop->value) && (ent->spawnflags2 & SPAWNFLAG2_NOT_COOP)) || ((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict (ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY|SPAWNFLAG_NOT_MEDIUM|SPAWNFLAG_NOT_HARD|SPAWNFLAG_NOT_COOP|SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn (ent); } oldmaxent = globals.num_edicts; gi.dprintf("%i entities created\n", globals.num_edicts); gi.dprintf ("%i entities inhibited\n", inhibit); G_FindTeams (); PlayerTrail_Init (); Z_SpawnDMItems(); }
/* * Creates a server's entity / program execution context by * parsing textual entity definitions out of an ent file. */ void SpawnEntities(const char *mapname, char *entities, const char *spawnpoint) { edict_t *ent; int inhibit; const char *com_token; int i; float skill_level; static qboolean monster_count_city3 = false; if (!mapname || !entities || !spawnpoint) { return; } skill_level = floor(skill->value); if (skill_level < 0) { skill_level = 0; } if (skill_level > 3) { skill_level = 3; } if (skill->value != skill_level) { gi.cvar_forceset("skill", va("%f", skill_level)); } SaveClientData(); gi.FreeTags(TAG_LEVEL); memset(&level, 0, sizeof(level)); memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0])); Q_strlcpy(level.mapname, mapname, sizeof(level.mapname)); Q_strlcpy(game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)); /* set client fields on player ents */ for (i = 0; i < game.maxclients; i++) { g_edicts[i + 1].client = game.clients + i; } ent = NULL; inhibit = 0; /* parse ents */ while (1) { /* parse the opening brace */ com_token = COM_Parse(&entities); if (!entities) { break; } if (com_token[0] != '{') { gi.error("ED_LoadFromFile: found %s when expecting {", com_token); } if (!ent) { ent = g_edicts; } else { ent = G_Spawn(); } entities = ED_ParseEdict(entities, ent); /* yet another map hack */ if (!Q_stricmp(level.mapname, "command") && !Q_stricmp(ent->classname, "trigger_once") && !Q_stricmp(ent->model, "*27")) { ent->spawnflags &= ~SPAWNFLAG_NOT_HARD; } /* * The 'monsters' count in city3.bsp is wrong. * There're two monsters triggered in a hidden * and unreachable room next to the security * pass. * * We need to make sure that this hack is only * applied once! */ if(!Q_stricmp(level.mapname, "city3") && !monster_count_city3) { level.total_monsters = level.total_monsters - 2; monster_count_city3 = true; } /* remove things (except the world) from different skill levels or deathmatch */ if (ent != g_edicts) { if (deathmatch->value) { if (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) { G_FreeEdict(ent); inhibit++; continue; } } else { if (((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD)) ) { G_FreeEdict(ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_COOP | SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn(ent); } gi.dprintf("%i entities inhibited.\n", inhibit); G_FindTeams(); PlayerTrail_Init(); }