Beispiel #1
0
/*
  =================
  ReadLevel
  
  SpawnEntities will already have been called on the
  level the same way it was when the level was saved.
  
  That is necessary to get the baselines
  set up identically.
  
  The server will have cleared all of the world links before
  calling ReadLevel.
  
  No clients are connected yet.
  =================
*/
void ReadLevel (char *filename)
{
	int entnum;
	FILE *f;
	int i;
	void *base;
	edict_t *ent;

	f = fopen (filename, "rb");
	if (!f)
		gi.error ("Couldn't open %s", filename);

	// free any dynamic memory allocated by loading the level
	// base state
	gi.FreeTags (TAG_LEVEL);

	// wipe all the entities
	memset (g_edicts, 0, game.maxentities * sizeof (g_edicts[0]));
	globals.num_edicts = maxclients->value + 1;

	// check edict size
	fread (&i, sizeof (i), 1, f);
	if (i != sizeof (edict_t))
	{
		fclose (f);
		gi.error ("ReadLevel: mismatched edict size");
	}

	// check function pointer base address
	fread (&base, sizeof (base), 1, f);
	if (base != (void *) InitGame)
	{
		fclose (f);
		gi.error ("ReadLevel: function pointers have moved");
	}

	// load the level locals
	ReadLevelLocals (f);

	// load all the entities
	while (1)
	{
		if (fread (&entnum, sizeof (entnum), 1, f) != 1)
		{
			fclose (f);
			gi.error ("ReadLevel: failed to read entnum");
		}
		if (entnum == -1)
			break;
		if (entnum >= globals.num_edicts)
			globals.num_edicts = entnum + 1;

		ent = &g_edicts[entnum];
		ReadEdict (f, ent);

		// let the server rebuild world links for this ent
		memset (&ent->area, 0, sizeof (ent->area));
		gi.linkentity (ent);
	}

	fclose (f);

	// mark all clients as unconnected
	for (i = 0; i < maxclients->value; i++)
	{
		ent = &g_edicts[i + 1];
		ent->client = game.clients + i;
		ent->client->pers.connected = false;
	}

	// do any load time things at this point
	for (i = 0; i < globals.num_edicts; i++)
	{
		ent = &g_edicts[i];

		if (!ent->inuse)
			continue;

		// fire any cross-level triggers
		if (ent->classname && 
			strcmp (ent->classname, "target_crosslevel_target") == 0)
			ent->nextthink = level.time + ent->delay;
	}
}
Beispiel #2
0
void LoadTransitionEnts()
{
	if(developer->value)
		gi.dprintf("==== LoadTransitionEnts ====\n");
	if(game.transition_ents)
	{
		char		t_file[_MAX_PATH];
		int			i, j;
		FILE		*f;
		vec3_t		v_spawn;
		edict_t		*ent;
		edict_t		*spawn;
		
		VectorClear(v_spawn);
		if(strlen(game.spawnpoint))
		{
			spawn = G_Find(NULL,FOFS(targetname),game.spawnpoint);
			while(spawn)
			{
				if(!Q_stricmp(spawn->classname,"info_player_start"))
				{
					VectorCopy(spawn->s.origin,v_spawn);
					break;
				}
				spawn = G_Find(spawn,FOFS(targetname),game.spawnpoint);
			}
		}
		trans_ent_filename (t_file);
		f = fopen(t_file,"rb");
		if(!f)
			gi.error("LoadTransitionEnts: Cannot open %s\n",t_file);
		else
		{
			for(i=0; i<game.transition_ents; i++)
			{
				ent = G_Spawn();
				ReadEdict(f,ent);
				// Correction for monsters with health EXACTLY 0
				// If we don't do this, spawn function will bring
				// 'em back to life
				if(ent->svflags & SVF_MONSTER)
				{
					if(!ent->health)
					{
						ent->health = -1;
						ent->deadflag = DEAD_DEAD;
					}
					else if(ent->deadflag == DEAD_DEAD)
					{
						ent->health = min(ent->health,-1);
					}
				}
				VectorAdd(ent->s.origin,v_spawn,ent->s.origin);
				VectorCopy(ent->s.origin,ent->s.old_origin);
				ED_CallSpawn (ent);
				if(ent->owner_id)
				{
					if(ent->owner_id < 0)
					{
						ent->owner = &g_edicts[-ent->owner_id];
					}
					else
					{
						// We KNOW owners precede owned ents in the 
						// list because of the way it was constructed
						ent->owner = NULL;
						for(j=game.maxclients+1; j<globals.num_edicts && !ent->owner; j++)
						{
							if(ent->owner_id == g_edicts[j].id)
								ent->owner = &g_edicts[j];
						}
					}
					ent->owner_id = 0;
				}
				ent->s.renderfx |= RF_IR_VISIBLE;
			}
			fclose(f);
		}
	}
}
Beispiel #3
0
/*
 * Reads a level back into the memory.
 * SpawnEntities were already called
 * in the same way when the level was
 * saved. All world links were cleared
 * before this function was called. When
 * this function is called, no clients
 * are connected to the server.
 */
void
ReadLevel(const char *filename)
{
    int entnum;
    FILE *f;
    int i;
    edict_t *ent;
    
    f = fopen(filename, "rb");
    
    if (!f)
    {
        gi.error("Couldn't open %s", filename);
    }
    
    /* free any dynamic memory allocated by
     loading the level  base state */
    gi.FreeTags(TAG_LEVEL);
    
    /* wipe all the entities */
    memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0]));
    globals.num_edicts = maxclients->value + 1;
    
    /* check edict size */
    fread(&i, sizeof(i), 1, f);
    
    if (i != sizeof(edict_t))
    {
        fclose(f);
        gi.error("ReadLevel: mismatched edict size");
    }
    
    /* load the level locals */
    ReadLevelLocals(f);
    
    /* load all the entities */
    while (1)
    {
        if (fread(&entnum, sizeof(entnum), 1, f) != 1)
        {
            fclose(f);
            gi.error("ReadLevel: failed to read entnum");
        }
        
        if (entnum == -1)
        {
            break;
        }
        
        if (entnum >= globals.num_edicts)
        {
            globals.num_edicts = entnum + 1;
        }
        
        ent = &g_edicts[entnum];
        ReadEdict(f, ent);
        
        /* let the server rebuild world links for this ent */
        memset(&ent->area, 0, sizeof(ent->area));
        gi.linkentity(ent);
    }
    
    fclose(f);
    
    /* mark all clients as unconnected */
    for (i = 0; i < maxclients->value; i++)
    {
        ent = &g_edicts[i + 1];
        ent->client = game.clients + i;
        ent->client->pers.connected = false;
    }
    
    /* do any load time things at this point */
    for (i = 0; i < globals.num_edicts; i++)
    {
        ent = &g_edicts[i];
        
        if (!ent->inuse)
        {
            continue;
        }
        
        /* fire any cross-level triggers */
        if (ent->classname)
        {
            if (strcmp(ent->classname, "target_crosslevel_target") == 0)
            {
                ent->nextthink = level.time + ent->delay;
            }
        }
    }
}
Beispiel #4
0
void ReadLevel (char *filename)
{
    int		entnum;
    FILE	*f;
    int		i;
    void	*base;
    edict_t	*ent;

    if(developer->value)
        gi.dprintf ("==== ReadLevel ====\n");

    f = fopen (filename, "rb");
    if (!f)
        gi.error ("Couldn't open %s", filename);

    // free any dynamic memory allocated by loading the level
    // base state
    gi.FreeTags (TAG_LEVEL);

    // wipe all the entities
    memset (g_edicts, 0, game.maxentities*sizeof(g_edicts[0]));
    globals.num_edicts = maxclients->value+1;

    // check edict size
    fread (&i, sizeof(i), 1, f);
    if (i != sizeof(edict_t))
    {
        fclose (f);
        gi.error ("ReadLevel: mismatched edict size");
    }

    // check function pointer base address
    fread (&base, sizeof(base), 1, f);

    /*	Lazarus: The __DATE__ check in ReadGame is sufficient for a version
    	         check. The following is reported to fail under some
    	         circumstances (though I've never seen it).

    #ifdef _WIN32
    	if (base != (void *)InitGame)
    	{
    		fclose (f);
    		gi.error ("ReadLevel: function pointers have moved");
    	}
    #else
    	gi.dprintf("Function offsets %d\n", ((byte *)base) - ((byte *)InitGame));
    #endif

    */

    // load the level locals
    ReadLevelLocals (f);

    // load all the entities
    while (1)
    {
        if (fread (&entnum, sizeof(entnum), 1, f) != 1)
        {
            fclose (f);
            gi.error ("ReadLevel: failed to read entnum");
        }
        if (entnum == -1)
            break;
        if (entnum >= globals.num_edicts)
            globals.num_edicts = entnum+1;

        ent = &g_edicts[entnum];
        ReadEdict (f, ent);

        // let the server rebuild world links for this ent
        memset (&ent->area, 0, sizeof(ent->area));
        gi.linkentity (ent);
    }

    fclose (f);

    // mark all clients as unconnected
    for (i=0 ; i<maxclients->value ; i++)
    {
        ent = &g_edicts[i+1];
        ent->client = game.clients + i;
        ent->client->pers.connected = false;
    }

    // do any load time things at this point
    for (i=0 ; i<globals.num_edicts ; i++)
    {
        ent = &g_edicts[i];

        if (!ent->inuse)
            continue;

        // fire any cross-level triggers
        if (ent->classname)
            if (strcmp(ent->classname, "target_crosslevel_target") == 0)
                ent->nextthink = level.time + ent->delay;
    }

    // DWH: Load transition entities
    if(game.transition_ents)
    {
        LoadTransitionEnts();
        actor_files();
    }
}