public static string ED_ParseEdict(string data, edict_t ent)
    {
        bool init = false;

        // clear it
        if (ent != sv.edicts[0])        // hack
        {
            ent.Clear();
        }

        // go through all the dictionary pairs
        bool anglehack;

        while (true)
        {
            // parse key
            data = COM_Parse(data);
            if (com_token.StartsWith("}"))
            {
                break;
            }

            if (data == null)
            {
                Sys_Error("ED_ParseEntity: EOF without closing brace");
            }

            string token = com_token;

            // anglehack is to allow QuakeEd to write single scalar angles
            // and allow them to be turned into vectors. (FIXME...)
            if (token == "angle")
            {
                token     = "angles";
                anglehack = true;
            }
            else
            {
                anglehack = false;
            }

            // FIXME: change light to _light to get rid of this hack
            if (token == "light")
            {
                token = "light_lev";    // hack for single light def
            }
            string keyname = token.TrimEnd();

            // parse value
            data = COM_Parse(data);
            if (data == null)
            {
                Sys_Error("ED_ParseEntity: EOF without closing brace");
            }

            if (com_token.StartsWith("}"))
            {
                Sys_Error("ED_ParseEntity: closing brace without data");
            }

            init = true;

            // keynames with a leading underscore are used for utility comments,
            // and are immediately discarded by quake
            if (keyname[0] == '_')
            {
                continue;
            }

            ddef_t key = ED_FindField(keyname);
            if (key == null)
            {
                Con_Printf("'{0}' is not a field\n", keyname);
                continue;
            }

            token = com_token;
            if (anglehack)
            {
                token = "0 " + token + " 0";
            }

            if (!ParsePair(ent, key, token))
            {
                Host_Error("ED_ParseEdict: parse error");
            }
        }

        if (!init)
        {
            ent.free = true;
        }

        return(data);
    }
Beispiel #2
0
    public static void Host_Loadgame_f()
    {
        if (cmd_source != cmd_source_t.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

        string name = Path.ChangeExtension(Path.Combine(com_gamedir, Cmd_Argv(1)), ".sav");

        // 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 {0}...\n", name);
        FileStream fs = Sys_FileOpenRead(name);

        if (fs == null)
        {
            Con_Printf("ERROR: couldn't open.\n");
            return;
        }

        using (StreamReader reader = new StreamReader(fs, Encoding.ASCII))
        {
            string line    = reader.ReadLine();
            int    version = atoi(line);
            if (version != q_shared.SAVEGAME_VERSION)
            {
                Con_Printf("Savegame is version {0}, not {1}\n", version, q_shared.SAVEGAME_VERSION);
                return;
            }
            line = reader.ReadLine();

            float[] spawn_parms = new float[q_shared.NUM_SPAWN_PARMS];
            for (int i = 0; i < spawn_parms.Length; i++)
            {
                line           = reader.ReadLine();
                spawn_parms[i] = atof(line);
            }
            // this silliness is so we can load 1.06 save files, which have float skill values
            line = reader.ReadLine();
            float tfloat = atof(line);
            current_skill = (int)(tfloat + 0.1);
            Cvar.Cvar_SetValue("skill", (float)current_skill);

            string mapname = reader.ReadLine();
            line = reader.ReadLine();
            float time = atof(line);

            CL_Disconnect_f();
            SV_SpawnServer(mapname);

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

            // load the light styles

            for (int i = 0; i < q_shared.MAX_LIGHTSTYLES; i++)
            {
                line = reader.ReadLine();
                sv.lightstyles[i] = line;
            }

            // load the edicts out of the savegame file
            int           entnum = -1;  // -1 is the globals
            StringBuilder sb     = new StringBuilder(32768);
            while (!reader.EndOfStream)
            {
                line = reader.ReadLine();
                if (line == null)
                {
                    Sys_Error("EOF without closing brace");
                }

                sb.AppendLine(line);
                int idx = line.IndexOf('}');
                if (idx != -1)
                {
                    int    length = 1 + sb.Length - (line.Length - idx);
                    string data   = COM_Parse(sb.ToString(0, length));
                    if (String.IsNullOrEmpty(com_token))
                    {
                        break; // end of file
                    }
                    if (com_token != "{")
                    {
                        Sys_Error("First token isn't a brace");
                    }

                    if (entnum == -1)
                    {
                        // parse the global vars
                        ED_ParseGlobals(data);
                    }
                    else
                    {
                        // parse an edict
                        edict_t ent = EDICT_NUM(entnum);
                        ent.Clear();
                        ED_ParseEdict(data, ent);

                        // link it into the bsp tree
                        if (!ent.free)
                        {
                            SV_LinkEdict(ent, false);
                        }
                    }

                    entnum++;
                    sb.Remove(0, length);
                }
            }

            sv.num_edicts = entnum;
            sv.time       = time;

            for (int i = 0; i < q_shared.NUM_SPAWN_PARMS; i++)
            {
                svs.clients[0].spawn_parms[i] = spawn_parms[i];
            }
        }

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