/*	The entities are directly placed in the array, rather than allocated with
	ED_Alloc, because otherwise an error loading the map would have entity
	number references out of order.

	Creates a server's entity / program execution context by
	parsing textual entity definitions out of an ent file.

	Used for both fresh maps and savegame loads.  A fresh map would also need
	to call ED_CallSpawnFunctions () to let the objects initialize themselves.
*/
void ED_LoadFromFile(char *data)
{
	ServerEntity_t	*eEntity = NULL;

	for(;;)
	{
		// parse the opening brace
		data = COM_Parse(data);
		if(!data)
			break;

		if(com_token[0] != '{')
			Sys_Error ("ED_LoadFromFile: found %s when expecting {",com_token);

		if(!eEntity)
			eEntity = EDICT_NUM(0);
		else
			eEntity = ED_Alloc();

		data = ED_ParseEdict(data,eEntity);

		// Immediately call spawn function
		if(!Game->Server_SpawnEntity(eEntity))
		{
			if(developer.value)
				Edict_Print(eEntity);

			ED_Free(eEntity);
			continue;
		}
	}
}
Example #2
0
/* DESCRIPTION: ED_LoadFromFile
// LOCATION: pr_edict.c, but it's conspicuously absent in FTEQW.
// PATH: SV_LoadEntities
//
// To quote the text block that came with it:
// The entities are directly placed in the array, rather than allocated with
// ED_Alloc, because otherwise an error loading the map would have entity
// number references out of order.
//
// Creates a server's entity / program execution context by
// parsing textual entity definitions out of an ent file.
//
// Used for both fresh maps and savegame loads.  A fresh map would also need
// to call ED_CallSpawnFunctions () to let the objects initialize themselves.
*/
void ED_LoadFromFile(const char *data) {

   edict_t *ent;
   int inhibit;

   ent = NULL;
   inhibit = 0;
   gGlobalVariables.time = global_sv.time0c;

   //parse ents
   while(1) {

      // parse the opening brace
      data = COM_Parse(data);

      if(data == NULL) { break; }
      if(global_com_token[0] != '{') {
         Sys_Error ("%s: found %s when expecting {", __FUNCTION__, global_com_token);
      }

      if(ent == NULL) {
         ent = &(global_sv.edicts[0]);
         ReleaseEntityDLLFields(ent);
         InitEntityDLLFields(ent);
      }
      else { ent = ED_Alloc(); }

      data = ED_ParseEdict(data, ent);

      // remove things from different skill levels or deathmatch
      if(cvar_deathmatch.value != 0) {

         if((ent->v.spawnflags & 0x800) != 0) { //SPAWNFLAG_NOT_DEATHMATCH

            ED_Free(ent);
            inhibit++;
            continue;
         }
      }
      // immediately call spawn function
      if(ent->v.classname == 0) {

         Con_Printf("%s: Ent with no classname.\n", __FUNCTION__);
         ED_Free(ent);
         continue;
      }

      if(gEntityInterface.pfnSpawn(ent) < 0 || ent->v.flags & FL_KILLME) {

         ED_Free(ent);
      }
   }

   Con_Printf("%i entities inhibited\n", inhibit);
}
Example #3
0
/*
================
ED_LoadFromFile
 
The entities are directly placed in the array, rather than allocated with
ED_Alloc, because otherwise an error loading the map would have entity
number references out of order.
 
Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.
 
Used for both fresh maps and savegame loads.  A fresh map would also need
to call ED_CallSpawnFunctions () to let the objects initialize themselves.
================
*/
void ED_LoadFromFile (char *data)
{
	extern cvar_t cl_curlybraces;
	edict_t		*ent;
	int			inhibit;
	dfunction_t	*func;
	float curlybraces_oldvalue = cl_curlybraces.value;

	if (curlybraces_oldvalue) {
		Cvar_SetValue(&cl_curlybraces, 0);
	}
	ent = NULL;
	inhibit = 0;
	pr_global_struct->time = sv.time;

	// parse ents
	while (1)
	{
		// parse the opening brace
		data = COM_Parse (data);
		if (!data)
			break;
		if (com_token[0] != '{')
			SV_Error ("ED_LoadFromFile: found %s when expecting {",com_token);

		if (!ent)
			ent = EDICT_NUM(0);
		else
			ent = ED_Alloc ();
		data = ED_ParseEdict (data, ent);

		// remove things from different skill levels or deathmatch
		if ((int)deathmatch.value)
		{
			if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
			{
				ED_Free (ent);
				inhibit++;
				continue;
			}
		}
		else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY))
		         || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM))
		         || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) )
		{
			ED_Free (ent);
			inhibit++;
			continue;
		}

		//
		// immediately call spawn function
		//
		if (!ent->v.classname)
		{
			Con_Printf ("No classname for:\n");
			ED_Print (ent);
			ED_Free (ent);
			continue;
		}

		// look for the spawn function
		func = ED_FindFunction ( PR_GetString(ent->v.classname) );

		if (!func)
		{
			Con_Printf ("No spawn function for:\n");
			ED_Print (ent);
			ED_Free (ent);
			continue;
		}

		pr_global_struct->self = EDICT_TO_PROG(ent);
		PR_ExecuteProgram (func - pr_functions);
		SV_FlushSignon();
	}

	Con_DPrintf ("%i entities inhibited\n", inhibit);
	if (curlybraces_oldvalue) {
		Cvar_SetValue(&cl_curlybraces, curlybraces_oldvalue);
	}
}
Example #4
0
/*
===============
Host_Loadgame_f
===============
*/
void Host_Loadgame_f (void)
{
	char	name[MAX_OSPATH];
	FILE	*f;
	char	mapname[MAX_QPATH];
	float	time, tfloat;
	char	*str, *start;
	int		i, r;
	edict_t	*ent;
	int		entnum;
	int		version;
	float			spawn_parms[NUM_SPAWN_PARMS];

	if (cmd_source != src_command)
		return;

	if (Cmd_Argc() != 2)
	{
		Con_Printf ("load <savename> : load a game\n");
		return;
	}

	cls.demonum = -1;		// stop demo loop in case this fails

	sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
	COM_DefaultExtension (name, ".sav");

#define LOAD_BUFFER_SIZE (4096)

	str = (char*)malloc(LOAD_BUFFER_SIZE);
	if(str == 0)
	{
		Con_Printf ("ERROR: couldn't malloc %d.\n",LOAD_BUFFER_SIZE);
		goto cleanup;
	}
	
// we can't call SCR_BeginLoadingPlaque, because too much stack space has
// been used.  The menu calls it before stuffing loadgame command
//	SCR_BeginLoadingPlaque ();

	Con_Printf ("Loading game from %s...\n", name);
	f = fopen (name, "r");
	if (!f)
	{
		Con_Printf ("ERROR: couldn't open.\n");
		goto cleanup;
		//return;
	}

	fscanf (f, "%i\n", &version);
	if (version != SAVEGAME_VERSION)
	{
		fclose (f);
		Con_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION);
		goto cleanup;
		//return;
	}
	fscanf (f, "%s\n", str);
	for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
		fscanf (f, "%f\n", &spawn_parms[i]);
// this silliness is so we can load 1.06 save files, which have float skill values
	fscanf (f, "%f\n", &tfloat);
	current_skill = (int)(tfloat + 0.1);
	Cvar_SetValue ("skill", (float)current_skill);

	fscanf (f, "%s\n",mapname);
	fscanf (f, "%f\n",&time);

	CL_Disconnect_f ();
	
	SV_SpawnServer (mapname);

	if (!sv.active)
	{
		Con_Printf ("Couldn't load map\n");
		goto cleanup;
		//return;
	}
	sv.paused = true;		// pause until all clients connect
	sv.loadgame = true;

// load the light styles

	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
	{
		fscanf (f, "%s\n", str);
		sv.lightstyles[i] = (char *)Hunk_Alloc (strlen(str)+1);
		strcpy (sv.lightstyles[i], str);
	}

	//Con_Printf("%d\n",__LINE__);
	//waitforit();
// load the edicts out of the savegame file
	entnum = -1;		// -1 is the globals
	while (!feof(f))
	{
		for (i=0 ; i<LOAD_BUFFER_SIZE-1 ; i++)
		{
			r = fgetc (f);
			if (r == EOF || !r)
				break;
			str[i] = r;
			if (r == '}')
			{
				i++;
				break;
			}
		}
		if (i == LOAD_BUFFER_SIZE-1)
			Sys_Error ("Loadgame buffer overflow");
		str[i] = 0;
		start = str;
		start = COM_Parse(str);
		if (!com_token[0])
			break;		// end of file
		if (strcmp(com_token,"{"))
			Sys_Error ("First token isn't a brace");
			
		if (entnum == -1)
		{	// parse the global vars
			ED_ParseGlobals (start);
		}
		else
		{	// parse an edict

			while(entnum >= sv.num_edicts)
			{
				ED_Alloc();
			}
			ent = EDICT_NUM(entnum);
			memset (&ent->v, 0, progs->entityfields * 4);
			ent->free = false;
			ED_ParseEdict (start, ent);
	
		// link it into the bsp tree
			if (!ent->free)
				SV_LinkEdict (ent, false);
		}

		entnum++;
	}
	
	sv.num_edicts = entnum;
	sv.time = time;
	//waitforit();

	fclose (f);

	for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
		svs.clients->spawn_parms[i] = spawn_parms[i];

	if (cls.state != ca_dedicated)
	{
		CL_EstablishConnection ("local");
		Host_Reconnect_f ();
	}
cleanup:

	if(str)
		free(str);
}