/** * SV_InitGameProgs * * Init the game subsystem for a new map. */ public static void SV_InitGameProgs() { // unload anything we have now SV_GAME.SV_ShutdownGameProgs(); game_import_t gimport = new(); // all functions set in game_export_t (rst) GameBase.GetGameApi(gimport); GameSave.InitGame(); }
/** * PF_centerprintf * * centerprint to a single client. */ public static void PF_centerprintf(edict_t ent, string fmt) { int n; n = ent.index; if (n < 1 || n > SV_MAIN.maxclients.value) { return; // Com_Error (ERR_DROP, "centerprintf to a non-client"); } MSG.WriteByte(SV_INIT.sv.multicast, Defines.svc_centerprint); MSG.WriteString(SV_INIT.sv.multicast, fmt); SV_GAME.PF_Unicast(ent, true); }
/** * Called when each game quits, before Sys_Quit or Sys_Error. */ public static void SV_Shutdown(string finalmsg, bool reconnect) { if (SV_INIT.svs.clients != null) { SV_MAIN.SV_FinalMessage(finalmsg, reconnect); } SV_MAIN.Master_Shutdown(); SV_GAME.SV_ShutdownGameProgs(); // free current level if (SV_INIT.sv.demofile != null) { try { SV_INIT.sv.demofile.Close(); } catch (Exception e) { Console.WriteLine(e); } } SV_INIT.sv = new(); Globals.server_state = SV_INIT.sv.state; if (SV_INIT.svs.demofile != null) { try { SV_INIT.svs.demofile.Close(); } catch (Exception e1) { Console.WriteLine(e1); } } SV_INIT.svs = new(); }
/** * SV_InitGame. * * A brand new game has been started. */ public static void SV_InitGame() { int i; edict_t ent; //char idmaster[32]; string idmaster; if (SV_INIT.svs.initialized) { // cause any connected clients to reconnect SV_MAIN.SV_Shutdown("Server restarted\n", true); } else { // make sure the client is down Cl.Drop(); SCR.BeginLoadingPlaque(); } // get any latched variable changes (maxclients, etc) Cvar.GetLatchedVars(); SV_INIT.svs.initialized = true; if (Cvar.VariableValue("coop") != 0 && Cvar.VariableValue("deathmatch") != 0) { Com.Printf("Deathmatch and Coop both set, disabling Coop\n"); Cvar.FullSet("coop", "0", Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); } // dedicated servers are can't be single player and are usually DM // so unless they explicity set coop, force it to deathmatch if (Globals.dedicated.value != 0) { if (0 == Cvar.VariableValue("coop")) { Cvar.FullSet("deathmatch", "1", Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); } } // init clients if (Cvar.VariableValue("deathmatch") != 0) { if (SV_MAIN.maxclients.value <= 1) { Cvar.FullSet("maxclients", "8", Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); } else if (SV_MAIN.maxclients.value > Defines.MAX_CLIENTS) { Cvar.FullSet("maxclients", "" + Defines.MAX_CLIENTS, Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); } } else if (Cvar.VariableValue("coop") != 0) { if (SV_MAIN.maxclients.value <= 1 || SV_MAIN.maxclients.value > 4) { Cvar.FullSet("maxclients", "4", Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); } } else // non-deathmatch, non-coop is one player { Cvar.FullSet("maxclients", "1", Defines.CVAR_SERVERINFO | Defines.CVAR_LATCH); } SV_INIT.svs.spawncount = Lib.rand(); SV_INIT.svs.clients = new client_t[(int)SV_MAIN.maxclients.value]; for (var n = 0; n < SV_INIT.svs.clients.Length; n++) { SV_INIT.svs.clients[n] = new(); SV_INIT.svs.clients[n].serverindex = n; } SV_INIT.svs.num_client_entities = (int)SV_MAIN.maxclients.value * Defines.UPDATE_BACKUP * 64; //ok. SV_INIT.svs.client_entities = new entity_state_t[SV_INIT.svs.num_client_entities]; for (var n = 0; n < SV_INIT.svs.client_entities.Length; n++) { SV_INIT.svs.client_entities[n] = new(null); } // init network stuff NET.ConfigServer(SV_MAIN.maxclients.value > 1); // heartbeats will always be sent to the id master SV_INIT.svs.last_heartbeat = -99999; // send immediately idmaster = "192.246.40.37:" + Defines.PORT_MASTER; NET.StringToAdr(idmaster, SV_MAIN.master_adr[0]); // init game SV_GAME.SV_InitGameProgs(); for (i = 0; i < SV_MAIN.maxclients.value; i++) { ent = GameBase.g_edicts[i + 1]; SV_INIT.svs.clients[i].edict = ent; SV_INIT.svs.clients[i].lastcmd = new(); } }
/** * Centerprintf for critical messages. */ public static void PF_cprintfhigh(edict_t ent, string fmt) { SV_GAME.PF_cprintf(ent, Defines.PRINT_HIGH, fmt); }
/** * * Bmodel objects don't interact with each other, but push all box objects. */ public static void SV_Physics_Pusher(edict_t ent) { float[] move = { 0, 0, 0 }; float[] amove = { 0, 0, 0 }; edict_t part, mv; // if not a team captain, so movement will be handled elsewhere if ((ent.flags & Defines.FL_TEAMSLAVE) != 0) { return; } // make sure all team slaves can move before commiting // any moves or calling any think functions // if the move is blocked, all moved objects will be backed out // retry: GameBase.pushed_p = 0; for (part = ent; part != null; part = part.teamchain) { if (part.velocity[0] != 0 || part.velocity[1] != 0 || part.velocity[2] != 0 || part.avelocity[0] != 0 || part.avelocity[1] != 0 || part.avelocity[2] != 0) { // object // is // moving Math3D.VectorScale(part.velocity, Defines.FRAMETIME, move); Math3D.VectorScale(part.avelocity, Defines.FRAMETIME, amove); if (!SV.SV_Push(part, move, amove)) { break; // move was blocked } } } if (GameBase.pushed_p > Defines.MAX_EDICTS) { SV_GAME.PF_error(Defines.ERR_FATAL, "pushed_p > &pushed[MAX_EDICTS], memory corrupted"); } if (part != null) { // the move failed, bump all nextthink times and back out moves for (mv = ent; mv != null; mv = mv.teamchain) { if (mv.nextthink > 0) { mv.nextthink += Defines.FRAMETIME; } } // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone if (part.blocked != null) { part.blocked.blocked(part, GameBase.obstacle); } } else { // the move succeeded, so call all think functions for (part = ent; part != null; part = part.teamchain) { SV.SV_RunThink(part); } } }