/// <summary> /// CL_ClearState /// </summary> static void ClearState() { if (!Server.sv.active) { Host.ClearMemory(); } // wipe the entire cl structure _State.Clear(); Cls.message.Clear(); // clear other arrays foreach (EFrag ef in _EFrags) { ef.Clear(); } foreach (Entity et in _Entities) { et.Clear(); } foreach (DynamicLight dl in _DLights) { dl.Clear(); } Array.Clear(_LightStyle, 0, _LightStyle.Length); foreach (Entity et in _TempEntities) { et.Clear(); } foreach (Beam b in _Beams) { b.Clear(); } // // allocate the efrags and chain together into a free list // Cl.free_efrags = _EFrags[0];// cl_efrags; for (int i = 0; i < MAX_EFRAGS - 1; i++) { _EFrags[i].entnext = _EFrags[i + 1]; } _EFrags[MAX_EFRAGS - 1].entnext = null; }
/// <summary> /// SV_SpawnServer /// </summary> public static void SpawnServer(string server) { // let's not have any servers with no name if (String.IsNullOrEmpty(Net.HostName)) { Cvar.Set("hostname", "UNNAMED"); } Scr.CenterTimeOff = 0; Con.DPrint("SpawnServer: {0}\n", server); svs.changelevel_issued = false; // now safe to issue another // // tell all connected clients that we are going to a new level // if (sv.active) { SendReconnect(); } // // make cvars consistant // if (Host.IsCoop) { Cvar.Set("deathmatch", 0); } Host.CurrentSkill = (int)(Host.Skill + 0.5); if (Host.CurrentSkill < 0) { Host.CurrentSkill = 0; } if (Host.CurrentSkill > 3) { Host.CurrentSkill = 3; } Cvar.Set("skill", (float)Host.CurrentSkill); // // set up the new server // Host.ClearMemory(); sv.Clear(); sv.name = server; // load progs to get entity field count Progs.LoadProgs(); // allocate server memory sv.max_edicts = QDef.MAX_EDICTS; sv.edicts = new edict_t[sv.max_edicts]; for (int i = 0; i < sv.edicts.Length; i++) { sv.edicts[i] = new edict_t(); } // leave slots at start for clients only sv.num_edicts = svs.maxclients + 1; edict_t ent; for (int i = 0; i < svs.maxclients; i++) { ent = EdictNum(i + 1); svs.clients[i].edict = ent; } sv.state = server_state_t.Loading; sv.paused = false; sv.time = 1.0; sv.modelname = String.Format("maps/{0}.bsp", server); sv.worldmodel = Mod.ForName(sv.modelname, false); if (sv.worldmodel == null) { Con.Print("Couldn't spawn server {0}\n", sv.modelname); sv.active = false; return; } sv.models[1] = sv.worldmodel; // // clear world interaction links // ClearWorld(); sv.sound_precache[0] = String.Empty; sv.model_precache[0] = String.Empty; sv.model_precache[1] = sv.modelname; for (int i = 1; i < sv.worldmodel.numsubmodels; i++) { sv.model_precache[1 + i] = _LocalModels[i]; sv.models[i + 1] = Mod.ForName(_LocalModels[i], false); } // // load the rest of the entities // ent = EdictNum(0); ent.Clear(); ent.v.model = Progs.StringOffset(sv.worldmodel.name); if (ent.v.model == -1) { ent.v.model = Progs.NewString(sv.worldmodel.name); } ent.v.modelindex = 1; // world model ent.v.solid = Solids.SOLID_BSP; ent.v.movetype = Movetypes.MOVETYPE_PUSH; if (Host.IsCoop) { Progs.GlobalStruct.coop = 1; //coop.value; } else { Progs.GlobalStruct.deathmatch = Host.Deathmatch; } int offset = Progs.NewString(sv.name); Progs.GlobalStruct.mapname = offset; // serverflags are for cross level information (sigils) Progs.GlobalStruct.serverflags = svs.serverflags; Progs.LoadFromFile(sv.worldmodel.entities); sv.active = true; // all setup is completed, any further precache statements are errors sv.state = server_state_t.Active; // run two frames to allow everything to settle Host.FrameTime = 0.1; Physics(); Physics(); // create a baseline for more efficient communications CreateBaseline(); // send serverinfo to all connected clients for (int i = 0; i < svs.maxclients; i++) { Host.HostClient = svs.clients[i]; if (Host.HostClient.active) { SendServerInfo(Host.HostClient); } } GC.Collect(); Con.DPrint("Server spawned.\n"); }