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); }
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(); } }