示例#1
0
        /// <summary>
        /// ED_ParseEdict
        /// Parses an edict out of the given string, returning the new position
        /// ed should be a properly initialized empty edict.
        /// Used for initial level load and for savegames.
        /// </summary>
        public static string ParseEdict(string data, edict_t ent)
        {
            bool init = false;

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

            // go through all the dictionary pairs
            bool anglehack;

            while (true)
            {
                // parse key
                data = Common.Parse(data);
                if (Common.Token.StartsWith("}"))
                {
                    break;
                }

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

                string token = Common.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 = Common.Parse(data);
                if (data == null)
                {
                    Sys.Error("ED_ParseEntity: EOF without closing brace");
                }

                if (Common.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 = FindField(keyname);
                if (key == null)
                {
                    Con.Print("'{0}' is not a field\n", keyname);
                    continue;
                }

                token = Common.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);
        }
示例#2
0
        /// <summary>
        /// Host_Loadgame_f
        /// </summary>
        static void Loadgame_f()
        {
            if (Cmd.Source != cmd_source_t.src_command)
            {
                return;
            }

            if (Cmd.Argc != 2)
            {
                Con.Print("load <savename> : load a game\n");
                return;
            }

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

            string name = Path.ChangeExtension(Path.Combine(Common.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.Print("Loading game from {0}...\n", name);
            FileStream fs = Sys.FileOpenRead(name);

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

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

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

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

                Client.Disconnect_f();
                Server.SpawnServer(mapname);

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

                // load the light styles

                for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++)
                {
                    line = reader.ReadLine();
                    Server.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   = Common.Parse(sb.ToString(0, length));
                        if (String.IsNullOrEmpty(Common.Token))
                        {
                            break; // end of file
                        }
                        if (Common.Token != "{")
                        {
                            Sys.Error("First token isn't a brace");
                        }

                        if (entnum == -1)
                        {
                            // parse the global vars
                            Progs.ParseGlobals(data);
                        }
                        else
                        {
                            // parse an edict
                            edict_t ent = Server.EdictNum(entnum);
                            ent.Clear();
                            Progs.ParseEdict(data, ent);

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

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

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

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

            if (Client.cls.state != cactive_t.ca_dedicated)
            {
                Client.EstablishConnection("local");
                Reconnect_f();
            }
        }