void VM_CustomStats_Clear (void);
void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats);
-void EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numstates, const entity_state_t *states);
cvar_t coop = {0, "coop","0", "coop mode, 0 = no coop, 1 = coop mode, multiple players playing through the singleplayer game (coop mode also shuts off deathmatch)"};
cvar_t deathmatch = {0, "deathmatch","0", "deathmatch mode, values depend on mod but typically 0 = no deathmatch, 1 = normal deathmatch with respawning weapons, 2 = weapons stay (players can only pick up new weapons)"};
cvar_t sv_cullentities_trace_samples_players = {0, "sv_cullentities_trace_samples_players", "8", "number of samples to test for entity culling when the entity is a player entity"};
cvar_t sv_debugmove = {CVAR_NOTIFY, "sv_debugmove", "0", "disables collision detection optimizations for debugging purposes"};
cvar_t sv_echobprint = {CVAR_SAVE, "sv_echobprint", "1", "prints gamecode bprint() calls to server console"};
-cvar_t sv_edgefriction = {0, "edgefriction", "2", "how much you slow down when nearing a ledge you might fall off"};
+cvar_t sv_edgefriction = {0, "edgefriction", "1", "how much you slow down when nearing a ledge you might fall off, multiplier of sv_friction (Quake used 2, QuakeWorld used 1 due to a bug in physics code)"};
cvar_t sv_entpatch = {0, "sv_entpatch", "1", "enables loading of .ent files to override entities in the bsp (for example Threewave CTF server pack contains .ent patch files enabling play of CTF on id1 maps)"};
cvar_t sv_fixedframeratesingleplayer = {0, "sv_fixedframeratesingleplayer", "1", "allows you to use server-style timing system in singleplayer (don't run faster than sys_ticrate)"};
cvar_t sv_freezenonclients = {CVAR_NOTIFY, "sv_freezenonclients", "0", "freezes time, except for players, allowing you to walk around and take screenshots of explosions"};
{ev_entity, "nodrawtoclient"},
{ev_entity, "tag_entity"},
{ev_entity, "viewmodelforclient"},
+ {ev_float, "SendFlags"},
{ev_float, "Version"},
{ev_float, "alpha"},
{ev_float, "ammo_cells1"},
}
// reset csqc entity versions
- memset(client->csqcentityversion, 0, sizeof(client->csqcentityversion));
+ for (i = 0;i < prog->max_edicts;i++)
+ {
+ client->csqcentityscope[i] = 0;
+ client->csqcentitysendflags[i] = 0xFFFFFF;
+ client->csqcentityglobalhistory[i] = 0;
+ }
+ for (i = 0;i < NUM_CSQCENTITYDB_FRAMES;i++)
+ {
+ client->csqcentityframehistory[i].num = 0;
+ client->csqcentityframehistory[i].framenum = -1;
+ }
+ client->csqcnumedicts = 0;
+ client->csqcentityframehistory_next = 0;
SZ_Clear (&client->netconnection->message);
MSG_WriteByte (&client->netconnection->message, svc_print);
static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int enumber)
{
int i;
+ unsigned int sendflags;
+ unsigned int version;
unsigned int modelindex, effects, flags, glowsize, lightstyle, lightpflags, light[4], specialvisibilityradius;
unsigned int customizeentityforclient;
float f;
vec3_t cullmins, cullmaxs;
dp_model_t *model;
- prvm_eval_t *val;
+ prvm_eval_t *val, *val2;
// this 2 billion unit check is actually to detect NAN origins
// (we really don't want to send those)
// calculate the visible box of this entity (don't use the physics box
// as that is often smaller than a model, and would not count
// specialvisibilityradius)
- if ((model = sv.models[modelindex]))
+ if ((model = sv.models[modelindex]) && (model->type != mod_null))
{
float scale = cs->scale * (1.0f / 16.0f);
if (cs->angles[0] || cs->angles[2]) // pitch and roll
}
}
+ // we need to do some csqc entity upkeep here
+ // get self.SendFlags and clear them
+ // (to let the QC know that they've been read)
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.SendEntity);
+ if (val->function)
+ {
+ val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.SendFlags);
+ sendflags = (unsigned int)val->_float;
+ val->_float = 0;
+ // legacy self.Version system
+ val2 = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.Version);
+ if (val2->_float)
+ {
+ version = (unsigned int)val2->_float;
+ if (sv.csqcentityversion[enumber] != version)
+ sendflags = 0xFFFFFF;
+ sv.csqcentityversion[enumber] = version;
+ }
+ // move sendflags into the per-client sendflags
+ if (sendflags)
+ for (i = 0;i < svs.maxclients;i++)
+ svs.clients[i].csqcentitysendflags[enumber] |= sendflags;
+ }
+
return true;
}
if (sv_cullentities_stats.integer)
Con_Printf("client \"%s\" entities: %d total, %d visible, %d culled by: %d pvs %d trace\n", client->name, sv.writeentitiestoclient_stats_totalentities, sv.writeentitiestoclient_stats_visibleentities, sv.writeentitiestoclient_stats_culled_pvs + sv.writeentitiestoclient_stats_culled_trace, sv.writeentitiestoclient_stats_culled_pvs, sv.writeentitiestoclient_stats_culled_trace);
- EntityFrameCSQC_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates);
+ if(client->entitydatabase5)
+ EntityFrameCSQC_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates, client->entitydatabase5->latestframenum + 1);
+ else
+ EntityFrameCSQC_WriteFrame(msg, maxsize, numsendstates, sv.writeentitiestoclient_sendstates, 0);
if (client->entitydatabase5)
EntityFrame5_WriteFrame(msg, maxsize, client->entitydatabase5, numsendstates, sv.writeentitiestoclient_sendstates, client - svs.clients + 1, client->movesequence);
if (strcmp(host_client->old_name, host_client->name))
{
if (host_client->spawned)
- SV_BroadcastPrintf("%s changed name to %s\n", host_client->old_name, host_client->name);
+ SV_BroadcastPrintf("%s ^7changed name to %s\n", host_client->old_name, host_client->name);
strlcpy(host_client->old_name, host_client->name, sizeof(host_client->old_name));
// send notification to all clients
MSG_WriteByte (&sv.reliable_datagram, svc_updatename);
}
}
- host_client->download_file = FS_Open(host_client->download_name, "rb", true, false);
+ host_client->download_file = FS_OpenVirtualFile(host_client->download_name, true);
if (!host_client->download_file)
{
SV_ClientPrintf("Download rejected: server could not open the file \"%s\"\n", host_client->download_name);
static void SV_VM_CB_FreeEdict(prvm_edict_t *ed)
{
+ int i;
+ int e;
+
World_UnlinkEdict(ed); // unlink from world bsp
ed->fields.server->model = 0;
VectorClear(ed->fields.server->angles);
ed->fields.server->nextthink = -1;
ed->fields.server->solid = 0;
+
+ // make sure csqc networking is aware of the removed entity
+ e = PRVM_NUM_FOR_EDICT(ed);
+ sv.csqcentityversion[e] = 0;
+ for (i = 0;i < svs.maxclients;i++)
+ {
+ if (svs.clients[i].csqcentityscope[e])
+ svs.clients[i].csqcentityscope[e] = 1; // removed, awaiting send
+ svs.clients[i].csqcentitysendflags[e] = 0xFFFFFF;
+ }
}
static void SV_VM_CB_CountEdicts(void)