cvar_t pr_checkextension = {CF_SERVER | CF_READONLY, "pr_checkextension", "1", "indicates to QuakeC that the standard quakec extensions system is available (if 0, quakec should not attempt to use extensions)"};
cvar_t samelevel = {CF_SERVER | CF_NOTIFY, "samelevel","0", "repeats same level if level ends (due to timelimit or someone hitting an exit)"};
cvar_t skill = {CF_SERVER, "skill","1", "difficulty level of game, affects monster layouts in levels, 0 = easy, 1 = normal, 2 = hard, 3 = nightmare (same layout as hard but monsters fire twice)"};
+cvar_t campaign = {CF_SERVER, "campaign", "0", "singleplayer mode"};
cvar_t host_timescale = {CF_CLIENT | CF_SERVER, "host_timescale", "1.0", "controls game speed, 0.5 is half speed, 2 is double speed"};
cvar_t sv_accelerate = {CF_SERVER, "sv_accelerate", "10", "rate at which a player accelerates to sv_maxspeed"};
cvar_t sv_gameplayfix_nostepmoveonsteepslopes = {CF_SERVER, "sv_gameplayfix_nostepmoveonsteepslopes", "0", "crude fix which prevents MOVETYPE_STEP (not swimming or flying) to move on slopes whose angle is bigger than 45 degree"};
cvar_t sv_gameplayfix_swiminbmodels = {CF_SERVER, "sv_gameplayfix_swiminbmodels", "1", "causes pointcontents (used to determine if you are in a liquid) to check bmodel entities as well as the world model, so you can swim around in (possibly moving) water bmodel entities"};
cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag = {CF_SERVER, "sv_gameplayfix_upwardvelocityclearsongroundflag", "1", "prevents monsters, items, and most other objects from being stuck to the floor when pushed around by damage, and other situations in mods"};
-cvar_t sv_gameplayfix_downtracesupportsongroundflag = {CF_SERVER, "sv_gameplayfix_downtracesupportsongroundflag", "1", "prevents very short moves from clearing onground (which may make the player stick to the floor at high netfps)"};
+cvar_t sv_gameplayfix_downtracesupportsongroundflag = {CF_SERVER, "sv_gameplayfix_downtracesupportsongroundflag", "1", "prevents very short moves from clearing onground (which may make the player stick to the floor at high netfps), fixes groundentity not being set when walking onto a mover with sv_gameplayfix_nogravityonground"};
cvar_t sv_gameplayfix_q1bsptracelinereportstexture = {CF_SERVER, "sv_gameplayfix_q1bsptracelinereportstexture", "1", "enables mods to get accurate trace_texture results on q1bsp by using a surface-hitting traceline implementation rather than the standard solidbsp method, q3bsp always reports texture accurately"};
cvar_t sv_gameplayfix_unstickplayers = {CF_SERVER, "sv_gameplayfix_unstickplayers", "1", "big hack to try and fix the rare case of MOVETYPE_WALK entities getting stuck in the world clipping hull."};
cvar_t sv_gameplayfix_unstickentities = {CF_SERVER, "sv_gameplayfix_unstickentities", "1", "hack to check if entities are crossing world collision hull and try to move them to the right position"};
Cvar_RegisterVariable (&pr_checkextension);
Cvar_RegisterVariable (&samelevel);
Cvar_RegisterVariable (&skill);
+ Cvar_RegisterVariable (&campaign);
Cvar_RegisterVariable (&host_timescale);
Cvar_RegisterCallback (&host_timescale, Host_Timescale_c);
- Cvar_RegisterAlias (&host_timescale, "slowmo");
- Cvar_RegisterAlias (&host_timescale, "timescale");
+ Cvar_RegisterVirtual (&host_timescale, "slowmo");
+ Cvar_RegisterVirtual (&host_timescale, "timescale");
Cvar_RegisterVariable (&sv_accelerate);
Cvar_RegisterVariable (&sv_aim);
Cvar_RegisterVariable (&sv_airaccel_qw);
Cvar_RegisterVariable (&sv_protocolname);
Cvar_RegisterVariable (&sv_random_seed);
Cvar_RegisterVariable (&host_limitlocal);
- Cvar_RegisterAlias(&host_limitlocal, "sv_ratelimitlocalplayer");
+ Cvar_RegisterVirtual(&host_limitlocal, "sv_ratelimitlocalplayer");
Cvar_RegisterVariable (&sv_sound_land);
Cvar_RegisterVariable (&sv_sound_watersplash);
Cvar_RegisterVariable (&sv_stepheight);
SV_DropClient
Called when the player is getting totally kicked off the host
-if (crash = true), don't bother sending signofs
+if (leaving = true), don't bother sending signofs
=====================
*/
-void SV_DropClient(qbool crash)
+void SV_DropClient(qbool leaving, const char *fmt, ... )
{
prvm_prog_t *prog = SVVM_prog;
int i;
- Con_Printf("Client \"%s\" dropped\n", host_client->name);
+
+ va_list argptr;
+ char reason[512] = "";
+
+ Con_Printf("Client \"%s\" dropped", host_client->name);
+
+ if(fmt)
+ {
+ va_start(argptr, fmt);
+ dpvsnprintf(reason, sizeof(reason), fmt, argptr);
+ va_end(argptr);
+
+ Con_Printf(" (%s)\n", reason);
+ }
+ else
+ {
+ Con_Printf(" \n");
+ }
SV_StopDemoRecording(host_client);
if (host_client->netconnection)
{
// tell the client to be gone
- if (!crash)
+ if (!leaving)
{
// LadyHavoc: no opportunity for resending, so use unreliable 3 times
- unsigned char bufdata[8];
+ unsigned char bufdata[520]; // Disconnect reason string can be 512 characters
sizebuf_t buf;
memset(&buf, 0, sizeof(buf));
buf.data = bufdata;
buf.maxsize = sizeof(bufdata);
MSG_WriteByte(&buf, svc_disconnect);
+ if(fmt)
+ {
+ if(sv.protocol == PROTOCOL_DARKPLACES8)
+ MSG_WriteString(&buf, reason);
+ else
+ SV_ClientPrintf("%s\n", reason);
+ }
NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
NetConn_SendUnreliableMessage(host_client->netconnection, &buf, sv.protocol, 10000, 0, false);
NetConn_Close(host_client->netconnection);
host_client->netconnection = NULL;
}
+ if(fmt)
+ SV_BroadcastPrintf("\003^3%s left the game (%s)\n", host_client->name, reason);
+ else
+ SV_BroadcastPrintf("\003^3%s left the game\n", host_client->name);
// if a download is active, close it
if (host_client->download_file)
{
prvm_prog_t *prog = SVVM_prog;
int modelindex;
- if (!ed || ed->priv.server->free)
+ if (!ed || ed->free)
return NULL;
modelindex = (int)PRVM_serveredictfloat(ed, modelindex);
return (modelindex > 0 && modelindex < MAX_MODELS) ? sv.models[modelindex] : NULL;
// LadyHavoc: always clear state values, whether the entity is in use or not
svent->priv.server->baseline = defaultstate;
- if (svent->priv.server->free)
+ if (svent->free)
continue;
if (entnum > svs.maxclients && !PRVM_serveredictfloat(svent, modelindex))
continue;
//
// make cvars consistant
//
+
if (coop.integer)
+ {
Cvar_SetValueQuick(&deathmatch, 0);
+ Cvar_SetValueQuick(&campaign, 0);
+ }
+ else if(!deathmatch.integer)
+ Cvar_SetValueQuick(&campaign, 1);
+ else
+ Cvar_SetValueQuick(&campaign, 0);
// LadyHavoc: it can be useful to have skills outside the range 0-3...
//current_skill = bound(0, (int)(skill.value + 0.5), 3);
//Cvar_SetValue ("skill", (float)current_skill);
// AK possible hack since num_edicts is still 0
ent = PRVM_EDICT_NUM(0);
memset (ent->fields.fp, 0, prog->entityfields * sizeof(prvm_vec_t));
- ent->priv.server->free = false;
+ ent->free = false;
PRVM_serveredictstring(ent, model) = PRVM_SetEngineString(prog, sv.worldname);
PRVM_serveredictfloat(ent, modelindex) = 1; // world model
PRVM_serveredictfloat(ent, solid) = SOLID_BSP;
}
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
if (host_client->active)
- SV_DropClient(false); // server shutdown
+ SV_DropClient(false, "Server shutting down"); // server shutdown
NetConn_CloseServerPorts();
// link every entity except world
for (i = 1, ent = prog->edicts;i < prog->num_edicts;i++, ent++)
- if (!ent->priv.server->free && !VectorCompare(PRVM_serveredictvector(ent, absmin), PRVM_serveredictvector(ent, absmax)))
+ if (!ent->free && !VectorCompare(PRVM_serveredictvector(ent, absmin), PRVM_serveredictvector(ent, absmax)))
SV_LinkEdict(ent);
}
PRVM_serveredictfloat(ed, solid) = 0;
VM_RemoveEdictSkeleton(prog, ed);
+#ifdef USEODE
World_Physics_RemoveFromEntity(&sv.world, ed);
World_Physics_RemoveJointFromEntity(&sv.world, ed);
-
+#endif
// make sure csqc networking is aware of the removed entity
e = PRVM_NUM_FOR_EDICT(ed);
sv.csqcentityversion[e] = 0;
for (i=0 ; i<prog->num_edicts ; i++)
{
ent = PRVM_EDICT_NUM(i);
- if (ent->priv.server->free)
+ if (ent->free)
continue;
active++;
if (PRVM_serveredictfloat(ent, solid))
// never timeout loopback connections
for (i = (host_isclient.integer ? 1 : 0), host_client = &svs.clients[i]; i < svs.maxclients; i++, host_client++)
- {
if (host_client->netconnection && host.realtime > host_client->netconnection->timeout)
- {
- if (host_client->begun)
- SV_BroadcastPrintf("Client \"%s\" connection timed out\n", host_client->name);
- else
- Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
-
- SV_DropClient(false);
- }
- }
+ SV_DropClient(false, "Timed out");
}
/*