X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=sv_main.c;h=c330e94bc8630afaafa8989269fb0f75d17f1510;hb=3d19b4fbe87586e1a28e4af52f11d637ee389e18;hp=996aedeb2cc3674092601abd8a71cf9c85df7ef4;hpb=fde3c6bb95867c5e547775c9ba4ad5a51533fd75;p=xonotic%2Fdarkplaces.git diff --git a/sv_main.c b/sv_main.c index 996aedeb..c330e94b 100644 --- a/sv_main.c +++ b/sv_main.c @@ -40,11 +40,15 @@ cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "1"}; cvar_t sv_gameplayfix_stepwhilejumping = {0, "sv_gameplayfix_stepwhilejumping", "1"}; cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1"}; cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1"}; +cvar_t sv_gameplayfix_blowupfallenzombies = {0, "sv_gameplayfix_blowupfallenzombies", "1"}; +cvar_t sv_gameplayfix_findradiusdistancetobox = {0, "sv_gameplayfix_findradiusdistancetobox", "1"}; + +cvar_t sv_progs = {0, "sv_progs", "progs.dat" }; server_t sv; server_static_t svs; -mempool_t *sv_edicts_mempool = NULL; +mempool_t *sv_mempool = NULL; //============================================================================ @@ -81,14 +85,17 @@ void SV_Init (void) Cvar_RegisterVariable (&sv_gameplayfix_stepwhilejumping); Cvar_RegisterVariable (&sv_gameplayfix_swiminbmodels); Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox); + Cvar_RegisterVariable (&sv_gameplayfix_blowupfallenzombies); + Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox); Cvar_RegisterVariable (&sv_protocolname); Cvar_RegisterVariable (&sv_ratelimitlocalplayer); Cvar_RegisterVariable (&sv_maxrate); + Cvar_RegisterVariable (&sv_progs); SV_Phys_Init(); SV_World_Init(); - sv_edicts_mempool = Mem_AllocPool("server edicts", 0, NULL); + sv_mempool = Mem_AllocPool("server", 0, NULL); } static void SV_SaveEntFile_f(void) @@ -194,7 +201,7 @@ Larger attenuations will drop off. (max 4 attenuation) ================== */ -void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation) +void SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, float attenuation) { int sound_num, field_mask, i, ent; @@ -304,14 +311,14 @@ void SV_SendServerinfo (client_t *client) EntityFrame5_FreeDatabase(client->entitydatabase5); if (sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3) - client->entitydatabase = EntityFrame_AllocDatabase(sv_clients_mempool); + client->entitydatabase = EntityFrame_AllocDatabase(sv_mempool); if (sv.protocol == PROTOCOL_DARKPLACES4) - client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_clients_mempool); + client->entitydatabase4 = EntityFrame4_AllocDatabase(sv_mempool); if (sv.protocol == PROTOCOL_DARKPLACES5 || sv.protocol == PROTOCOL_DARKPLACES6) - client->entitydatabase5 = EntityFrame5_AllocDatabase(sv_clients_mempool); + client->entitydatabase5 = EntityFrame5_AllocDatabase(sv_mempool); MSG_WriteByte (&client->message, svc_print); - snprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, pr_crc); + dpsnprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, pr_crc); MSG_WriteString (&client->message,message); MSG_WriteByte (&client->message, svc_serverinfo); @@ -449,6 +456,7 @@ void SV_PrepareEntitiesForSending(void) int e, i; float f; edict_t *ent; + eval_t *val; entity_state_t cs; // send all entities that touch the pvs numsendentities = 0; @@ -465,10 +473,10 @@ void SV_PrepareEntitiesForSending(void) VectorCopy(ent->v->origin, cs.origin); VectorCopy(ent->v->angles, cs.angles); cs.flags = 0; - cs.effects = (int)ent->v->effects; - cs.colormap = (qbyte)ent->v->colormap; - cs.skin = (qbyte)ent->v->skin; - cs.frame = (qbyte)ent->v->frame; + cs.effects = (unsigned)ent->v->effects; + cs.colormap = (unsigned)ent->v->colormap; + cs.skin = (unsigned)ent->v->skin; + cs.frame = (unsigned)ent->v->frame; cs.viewmodelforclient = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)->edict; cs.exteriormodelforclient = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)->edict; cs.nodrawtoclient = GETEDICTFIELDVALUE(ent, eval_nodrawtoclient)->edict; @@ -480,6 +488,16 @@ void SV_PrepareEntitiesForSending(void) if (GETEDICTFIELDVALUE(ent, eval_glow_trail)->_float) cs.flags |= RENDER_GLOWTRAIL; + // don't need to init cs.colormod because the defaultstate did that for us + //cs.colormod[0] = cs.colormod[1] = cs.colormod[2] = 32; + val = GETEDICTFIELDVALUE(ent, eval_colormod); + if (val->vector[0] || val->vector[1] || val->vector[2]) + { + i = val->vector[0] * 32.0f;cs.colormod[0] = bound(0, i, 255); + i = val->vector[1] * 32.0f;cs.colormod[1] = bound(0, i, 255); + i = val->vector[2] * 32.0f;cs.colormod[2] = bound(0, i, 255); + } + cs.modelindex = 0; i = (int)ent->v->modelindex; if (i >= 1 && i < MAX_MODELS && *PR_GetString(ent->v->model)) @@ -742,7 +760,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s) sententities[s->number] = sententitiesmark; } -entity_state_t sendstates[MAX_EDICTS]; +entity_state_t sendstates[MAX_EDICTS]; void SV_WriteEntitiesToClient(client_t *client, edict_t *clent, sizebuf_t *msg, int *stats) { @@ -877,11 +895,6 @@ void SV_WriteClientdataToMessage (client_t *client, edict_t *ent, sizebuf_t *msg VectorCopy(val->vector, punchvector); weaponmodelindex = SV_ModelIndex(PR_GetString(ent->v->weaponmodel), 1); - if (!weaponmodelindex) - { - Con_DPrintf("weaponmodel \"%s\" not precached\n", PR_GetString(ent->v->weaponmodel)); - weaponmodelindex = 0; - } viewzoom = 255; if ((val = GETEDICTFIELDVALUE(ent, eval_viewzoom))) @@ -1123,7 +1136,9 @@ void SV_UpdateToReliableMessages (void) int i, j; client_t *client; eval_t *val; - char *name; + const char *name; + const char *model; + const char *skin; // check for changes to be sent over the reliable streams for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++) @@ -1137,7 +1152,7 @@ void SV_UpdateToReliableMessages (void) name = ""; // always point the string back at host_client->name to keep it safe strlcpy (host_client->name, name, sizeof (host_client->name)); - host_client->edict->v->netname = PR_SetString(host_client->name); + host_client->edict->v->netname = PR_SetEngineString(host_client->name); if (strcmp(host_client->old_name, host_client->name)) { if (host_client->spawned) @@ -1162,6 +1177,26 @@ void SV_UpdateToReliableMessages (void) MSG_WriteByte (&sv.reliable_datagram, host_client->colors); } + // NEXUIZ_PLAYERMODEL + if( eval_playermodel ) { + model = PR_GetString(GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string); + if (model == NULL) + model = ""; + // always point the string back at host_client->name to keep it safe + strlcpy (host_client->playermodel, model, sizeof (host_client->playermodel)); + GETEDICTFIELDVALUE(host_client->edict, eval_playermodel)->string = PR_SetEngineString(host_client->playermodel); + } + + // NEXUIZ_PLAYERSKIN + if( eval_playerskin ) { + skin = PR_GetString(GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string); + if (skin == NULL) + skin = ""; + // always point the string back at host_client->name to keep it safe + strlcpy (host_client->playerskin, skin, sizeof (host_client->playerskin)); + GETEDICTFIELDVALUE(host_client->edict, eval_playerskin)->string = PR_SetEngineString(host_client->playerskin); + } + // frags host_client->frags = (int)host_client->edict->v->frags; if (host_client->old_frags != host_client->frags) @@ -1298,7 +1333,7 @@ SV_ModelIndex ================ */ -int SV_ModelIndex(char *s, int precachemode) +int SV_ModelIndex(const char *s, int precachemode) { int i, limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_MODELS); char filename[MAX_QPATH]; @@ -1314,30 +1349,22 @@ int SV_ModelIndex(char *s, int precachemode) { if (precachemode) { - if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5) + if (sv.state != ss_loading && (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)) { - // not able to precache during game - if (precachemode == 2 && sv.state != ss_loading) - { - Con_Printf("SV_ModelIndex(\"%s\"): precache_model can only be done in spawn functions\n", filename); - return 0; - } + Con_Printf("SV_ModelIndex(\"%s\"): precache_model can only be done in spawn functions\n", filename); + return 0; } - else + if (precachemode == 1) + Con_Printf("SV_ModelIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename); + strlcpy(sv.model_precache[i], filename, sizeof(sv.model_precache[i])); + sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, false); + if (sv.protocol == PROTOCOL_DARKPLACES6 && sv.state != ss_loading) { - // able to precache during game - if (precachemode == 1) - Con_Printf("SV_ModelIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename); - strlcpy(sv.model_precache[i], filename, sizeof(sv.model_precache[i])); - sv.models[i] = Mod_ForName (sv.model_precache[i], true, false, false); - if (sv.state != ss_loading) - { - MSG_WriteByte(&sv.reliable_datagram, svc_precache); - MSG_WriteShort(&sv.reliable_datagram, i); - MSG_WriteString(&sv.reliable_datagram, filename); - } - return i; + MSG_WriteByte(&sv.reliable_datagram, svc_precache); + MSG_WriteShort(&sv.reliable_datagram, i); + MSG_WriteString(&sv.reliable_datagram, filename); } + return i; } Con_Printf("SV_ModelIndex(\"%s\"): not precached\n", filename); return 0; @@ -1345,10 +1372,7 @@ int SV_ModelIndex(char *s, int precachemode) if (!strcmp(sv.model_precache[i], filename)) return i; } - if (precachemode) - Con_Printf("SV_ModelIndex(\"%s\"): i == MAX_MODELS\n", filename); - else - Con_Printf("SV_ModelIndex(\"%s\"): not precached\n", filename); + Con_Printf("SV_ModelIndex(\"%s\"): i (%i) == MAX_MODELS (%i)\n", filename, i, MAX_MODELS); return 0; } @@ -1358,39 +1382,37 @@ SV_SoundIndex ================ */ -int SV_SoundIndex(char *s, int precachemode) +int SV_SoundIndex(const char *s, int precachemode) { int i, limit = (sv.protocol == PROTOCOL_QUAKE ? 256 : MAX_SOUNDS); char filename[MAX_QPATH]; if (!s || !*s) return 0; + // testing + //if (precachemode == 2) + // return 0; strlcpy(filename, s, sizeof(filename)); for (i = 1;i < limit;i++) { if (!sv.sound_precache[i][0]) { - if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5) + if (precachemode) { - // not able to precache during game - if (precachemode == 2 && sv.state != ss_loading) + if (sv.state != ss_loading && (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4 || sv.protocol == PROTOCOL_DARKPLACES5)) { Con_Printf("SV_SoundIndex(\"%s\"): precache_sound can only be done in spawn functions\n", filename); return 0; } - } - else - { - // able to precache during game - if (precachemode) + if (precachemode == 1) + Con_Printf("SV_SoundIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename); + strlcpy(sv.sound_precache[i], filename, sizeof(sv.sound_precache[i])); + if (sv.protocol == PROTOCOL_DARKPLACES6 && sv.state != ss_loading) { - if (precachemode == 1) - Con_Printf("SV_SoundIndex(\"%s\"): not precached (fix your code), precaching anyway\n", filename); - strlcpy(sv.sound_precache[i], filename, sizeof(sv.sound_precache[i])); MSG_WriteByte(&sv.reliable_datagram, svc_precache); MSG_WriteShort(&sv.reliable_datagram, i + 32768); MSG_WriteString(&sv.reliable_datagram, filename); - return i; } + return i; } Con_Printf("SV_SoundIndex(\"%s\"): not precached\n", filename); return 0; @@ -1398,10 +1420,7 @@ int SV_SoundIndex(char *s, int precachemode) if (!strcmp(sv.sound_precache[i], filename)) return i; } - if (precachemode) - Con_Printf("SV_SoundIndex(\"%s\"): i == MAX_SOUNDS\n", filename); - else - Con_Printf("SV_SoundIndex(\"%s\"): not precached\n", filename); + Con_Printf("SV_SoundIndex(\"%s\"): i (%i) == MAX_SOUNDS (%i)\n", filename, i, MAX_SOUNDS); return 0; } @@ -1552,9 +1571,9 @@ void SV_IncreaseEdicts(void) SV_ClearWorld(); sv.max_edicts = min(sv.max_edicts + 256, MAX_EDICTS); - sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t)); - sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size); - sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *)); + sv.edictsengineprivate = PR_Alloc(sv.max_edicts * sizeof(edict_engineprivate_t)); + sv.edictsfields = PR_Alloc(sv.max_edicts * pr_edict_size); + sv.moved_edicts = PR_Alloc(sv.max_edicts * sizeof(edict_t *)); memcpy(sv.edictsengineprivate, oldedictsengineprivate, oldmax_edicts * sizeof(edict_engineprivate_t)); memcpy(sv.edictsfields, oldedictsfields, oldmax_edicts * pr_edict_size); @@ -1568,9 +1587,9 @@ void SV_IncreaseEdicts(void) SV_LinkEdict(ent, false); } - Mem_Free(oldedictsengineprivate); - Mem_Free(oldedictsfields); - Mem_Free(oldmoved_edicts); + PR_Free(oldedictsengineprivate); + PR_Free(oldedictsfields); + PR_Free(oldmoved_edicts); } /* @@ -1592,7 +1611,10 @@ void SV_SpawnServer (const char *server) Con_DPrintf("SpawnServer: %s\n", server); - snprintf (modelname, sizeof(modelname), "maps/%s.bsp", server); + if (cls.state != ca_dedicated) + SCR_BeginLoadingPlaque(); + + dpsnprintf (modelname, sizeof(modelname), "maps/%s.bsp", server); worldmodel = Mod_ForName(modelname, false, true, true); if (!worldmodel || !worldmodel->TraceBox) { @@ -1624,9 +1646,10 @@ void SV_SpawnServer (const char *server) // if (coop.integer) Cvar_SetValue ("deathmatch", 0); - current_skill = bound(0, (int)(skill.value + 0.5), 3); - - Cvar_SetValue ("skill", (float)current_skill); + // LordHavoc: 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); + current_skill = (int)(skill.value + 0.5); // // set up the new server @@ -1664,23 +1687,21 @@ void SV_SpawnServer (const char *server) } // load progs to get entity field count - PR_LoadProgs (); + PR_LoadProgs ( sv_progs.string ); // allocate server memory // start out with just enough room for clients and a reasonable estimate of entities sv.max_edicts = max(svs.maxclients + 1, 512); sv.max_edicts = min(sv.max_edicts, MAX_EDICTS); - // clear the edict memory pool - Mem_EmptyPool(sv_edicts_mempool); // edict_t structures (hidden from progs) - sv.edicts = Mem_Alloc(sv_edicts_mempool, MAX_EDICTS * sizeof(edict_t)); + sv.edicts = PR_Alloc(MAX_EDICTS * sizeof(edict_t)); // engine private structures (hidden from progs) - sv.edictsengineprivate = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_engineprivate_t)); + sv.edictsengineprivate = PR_Alloc(sv.max_edicts * sizeof(edict_engineprivate_t)); // progs fields, often accessed by server - sv.edictsfields = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * pr_edict_size); + sv.edictsfields = PR_Alloc(sv.max_edicts * pr_edict_size); // used by PushMove to move back pushed entities - sv.moved_edicts = Mem_Alloc(sv_edicts_mempool, sv.max_edicts * sizeof(edict_t *)); + sv.moved_edicts = PR_Alloc(sv.max_edicts * sizeof(edict_t *)); for (i = 0;i < sv.max_edicts;i++) { ent = sv.edicts + i; @@ -1731,7 +1752,7 @@ void SV_SpawnServer (const char *server) strlcpy(sv.model_precache[1], sv.modelname, sizeof(sv.model_precache[1])); for (i = 1;i < sv.worldmodel->brush.numsubmodels;i++) { - snprintf(sv.model_precache[i+1], sizeof(sv.model_precache[i+1]), "*%i", i); + dpsnprintf(sv.model_precache[i+1], sizeof(sv.model_precache[i+1]), "*%i", i); sv.models[i+1] = Mod_ForName (sv.model_precache[i+1], false, false, false); } @@ -1741,7 +1762,7 @@ void SV_SpawnServer (const char *server) ent = EDICT_NUM(0); memset (ent->v, 0, progs->entityfields * 4); ent->e->free = false; - ent->v->model = PR_SetString(sv.modelname); + ent->v->model = PR_SetEngineString(sv.modelname); ent->v->modelindex = 1; // world model ent->v->solid = SOLID_BSP; ent->v->movetype = MOVETYPE_PUSH; @@ -1751,7 +1772,7 @@ void SV_SpawnServer (const char *server) else pr_global_struct->deathmatch = deathmatch.integer; - pr_global_struct->mapname = PR_SetString(sv.name); + pr_global_struct->mapname = PR_SetEngineString(sv.name); // serverflags are for cross level information (sigils) pr_global_struct->serverflags = svs.serverflags;