]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_main.c
load the JPEG dll when needed
[xonotic/darkplaces.git] / sv_main.c
index 864695fc471cb31d163a1fb653224afe0e03adbe..f6cc5e3936609f5b31ffff948e3928acf5600275 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -79,6 +79,7 @@ cvar_t sv_friction = {CVAR_NOTIFY, "sv_friction","4", "how fast you slow down"};
 cvar_t sv_gameplayfix_blowupfallenzombies = {0, "sv_gameplayfix_blowupfallenzombies", "1", "causes findradius to detect SOLID_NOT entities such as zombies and corpses on the floor, allowing splash damage to apply to them"};
 cvar_t sv_gameplayfix_delayprojectiles = {0, "sv_gameplayfix_delayprojectiles", "1", "causes entities to not move on the same frame they are spawned, meaning that projectiles wait until the next frame to perform their first move, giving proper interpolation and rocket trails, but making weapons harder to use at low framerates"};
 cvar_t sv_gameplayfix_droptofloorstartsolid = {0, "sv_gameplayfix_droptofloorstartsolid", "1", "prevents items and monsters that start in a solid area from falling out of the level (makes droptofloor treat trace_startsolid as an acceptable outcome)"};
+cvar_t sv_gameplayfix_droptofloorstartsolid_nudgetocorrect = {0, "sv_gameplayfix_droptofloorstartsolid_nudgetocorrect", "1", "tries to nudge stuck items and monsters out of walls before droptofloor is performed"};
 cvar_t sv_gameplayfix_easierwaterjump = {0, "sv_gameplayfix_easierwaterjump", "1", "changes water jumping to make it easier to get out of water (exactly like in QuakeWorld)"};
 cvar_t sv_gameplayfix_findradiusdistancetobox = {0, "sv_gameplayfix_findradiusdistancetobox", "1", "causes findradius to check the distance to the corner of a box rather than the center of the box, makes findradius detect bmodels such as very large doors that would otherwise be unaffected by splash damage"};
 cvar_t sv_gameplayfix_grenadebouncedownslopes = {0, "sv_gameplayfix_grenadebouncedownslopes", "1", "prevents MOVETYPE_BOUNCE (grenades) from getting stuck when fired down a downward sloping surface"};
@@ -148,8 +149,8 @@ cvar_t nehx18 = {0, "nehx18", "0", "nehahra data storage cvar (used in singlepla
 cvar_t nehx19 = {0, "nehx19", "0", "nehahra data storage cvar (used in singleplayer)"};
 cvar_t cutscene = {0, "cutscene", "1", "enables cutscenes in nehahra, can be used by other mods"};
 
-cvar_t sv_autodemo_perclient = {CVAR_SAVE, "sv_autodemo_perclient", "0", "set to 1 to enable autorecorded per-client demos (they'll start to record at the beginning of a match)"};
-cvar_t sv_autodemo_perclient_nameformat = {CVAR_SAVE, "sv_autodemo_perclient_nameformat", "sv_autodemos/%Y-%m-%d_%H-%M", "The format of the sv_autodemo_perclient filename, followed by the map name, the IP address + port number, and the client number, separated by underscores" };
+cvar_t sv_autodemo_perclient = {CVAR_SAVE, "sv_autodemo_perclient", "0", "set to 1 to enable autorecorded per-client demos (they'll start to record at the beginning of a match); set it to 2 to also record client->server packets (for debugging)"};
+cvar_t sv_autodemo_perclient_nameformat = {CVAR_SAVE, "sv_autodemo_perclient_nameformat", "sv_autodemos/%Y-%m-%d_%H-%M", "The format of the sv_autodemo_perclient filename, followed by the map name, the client number and the IP address + port number, separated by underscores" };
 
 
 server_t sv;
@@ -261,6 +262,7 @@ prvm_required_field_t reqfields[] =
        {ev_function, "SendEntity"},
        {ev_function, "contentstransition"}, // DRESK - Support for Entity Contents Transition Event
        {ev_function, "customizeentityforclient"},
+       {ev_function, "movetypesteplandevent"}, // DRESK - Support for MOVETYPE_STEP Entity Land Event
        {ev_string, "netaddress"},
        {ev_string, "playermodel"},
        {ev_string, "playerskin"},
@@ -349,6 +351,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_blowupfallenzombies);
        Cvar_RegisterVariable (&sv_gameplayfix_delayprojectiles);
        Cvar_RegisterVariable (&sv_gameplayfix_droptofloorstartsolid);
+       Cvar_RegisterVariable (&sv_gameplayfix_droptofloorstartsolid_nudgetocorrect);
        Cvar_RegisterVariable (&sv_gameplayfix_easierwaterjump);
        Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox);
        Cvar_RegisterVariable (&sv_gameplayfix_grenadebouncedownslopes);
@@ -430,6 +433,8 @@ void SV_Init (void)
        {
                // hipnotic mission pack has issues in their 'friendly monster' ai, which seem to attempt to attack themselves for some reason when findradius() returns non-solid entities.
                Cvar_SetValueQuick (&sv_gameplayfix_blowupfallenzombies, 0);
+               // hipnotic mission pack has issues with bobbing water entities 'jittering' between different heights on alternate frames at the default 0.0138889 ticrate, 0.02 avoids this issue
+               Cvar_SetValueQuick (&sys_ticrate, 0.02);
        }
        if (gamemode == GAME_ROGUE)
        {
@@ -794,7 +799,7 @@ void SV_SendServerinfo (client_t *client)
        client->clientcamera = PRVM_NUM_FOR_EDICT(client->edict);
        MSG_WriteByte (&client->netconnection->message, svc_setview);
        MSG_WriteShort (&client->netconnection->message, client->clientcamera);
-       
+
        MSG_WriteByte (&client->netconnection->message, svc_signonnum);
        MSG_WriteByte (&client->netconnection->message, 1);
 
@@ -828,7 +833,7 @@ void SV_SendServerinfo (client_t *client)
                for(i = 0; ipaddress[i]; ++i)
                        if(!isalnum(ipaddress[i]))
                                ipaddress[i] = '-';
-               dpsnprintf (demofile, sizeof(demofile), "%s_%s_%s_%d.dem", Sys_TimeString (sv_autodemo_perclient_nameformat.string), levelname, ipaddress, PRVM_NUM_FOR_EDICT(client->edict));
+               dpsnprintf (demofile, sizeof(demofile), "%s_%s_%d_%s.dem", Sys_TimeString (sv_autodemo_perclient_nameformat.string), levelname, PRVM_NUM_FOR_EDICT(client->edict), ipaddress);
 
                SV_StartDemoRecording(client, demofile, -1);
        }
@@ -925,7 +930,7 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        unsigned int customizeentityforclient;
        float f;
        vec3_t cullmins, cullmaxs;
-       model_t *model;
+       dp_model_t *model;
        prvm_eval_t *val;
 
        // this 2 billion unit check is actually to detect NAN origins
@@ -1183,7 +1188,7 @@ void SV_PrepareEntitiesForSending(void)
 void SV_MarkWriteEntityStateToClient(entity_state_t *s)
 {
        int isbmodel;
-       model_t *model;
+       dp_model_t *model;
        prvm_edict_t *ed;
        if (sv.sententitiesconsideration[s->number] == sv.sententitiesmark)
                return;
@@ -1801,6 +1806,7 @@ static void SV_SendClientDatagram (client_t *client)
        msg.data = sv_sendclientdatagram_buf;
        msg.maxsize = maxsize;
        msg.cursize = 0;
+       msg.allowoverflow = false;
 
        if (host_client->spawned)
        {
@@ -1863,9 +1869,9 @@ static void SV_SendClientDatagram (client_t *client)
 
        // reliable only if none is in progress
        if(client->sendsignon != 2 && !client->netconnection->sendMessageLength)
-               SV_WriteDemoMessage(client, &(client->netconnection->message));
+               SV_WriteDemoMessage(client, &(client->netconnection->message), false);
        // unreliable
-       SV_WriteDemoMessage(client, &msg);
+       SV_WriteDemoMessage(client, &msg, false);
 
 // send the datagram
        NetConn_SendUnreliableMessage (client->netconnection, &msg, sv.protocol, clientrate, client->sendsignon == 2);
@@ -2474,18 +2480,37 @@ void SV_SpawnServer (const char *server)
        prvm_edict_t *ent;
        int i;
        char *entities;
-       model_t *worldmodel;
+       dp_model_t *worldmodel;
        char modelname[sizeof(sv.modelname)];
 
        Con_DPrintf("SpawnServer: %s\n", server);
 
+       dpsnprintf (modelname, sizeof(modelname), "maps/%s.bsp", server);
+
+       if (!FS_FileExists(modelname))
+       {
+               Con_Printf("SpawnServer: no map file named %s\n", modelname);
+               return;
+       }
+
        if (cls.state != ca_dedicated)
        {
                SCR_BeginLoadingPlaque();
                S_StopAllSounds();
        }
 
-       dpsnprintf (modelname, sizeof(modelname), "maps/%s.bsp", server);
+       if(sv.active)
+       {
+               SV_VM_Begin();
+               if(prog->funcoffsets.SV_Shutdown)
+               {
+                       func_t s = prog->funcoffsets.SV_Shutdown;
+                       prog->funcoffsets.SV_Shutdown = 0; // prevent it from getting called again
+                       PRVM_ExecuteProgram(s,"SV_Shutdown() required");
+               }
+               SV_VM_End();
+       }
+
        worldmodel = Mod_ForName(modelname, false, true, true);
        if (!worldmodel || !worldmodel->TraceBox)
        {
@@ -2601,9 +2626,7 @@ void SV_SpawnServer (const char *server)
 //
 // clear world interaction links
 //
-       VectorCopy(sv.worldmodel->normalmins, sv.world.areagrid_mins);
-       VectorCopy(sv.worldmodel->normalmaxs, sv.world.areagrid_maxs);
-       World_Clear(&sv.world);
+       World_SetSize(&sv.world, sv.worldmodel->name, sv.worldmodel->normalmins, sv.worldmodel->normalmaxs);
 
        strlcpy(sv.sound_precache[0], "", sizeof(sv.sound_precache[0]));
 
@@ -2626,10 +2649,10 @@ void SV_SpawnServer (const char *server)
        ent->fields.server->modelindex = 1;             // world model
        ent->fields.server->solid = SOLID_BSP;
        ent->fields.server->movetype = MOVETYPE_PUSH;
-       VectorCopy(sv.worldmodel->normalmins, ent->fields.server->mins);
-       VectorCopy(sv.worldmodel->normalmaxs, ent->fields.server->maxs);
-       VectorCopy(sv.worldmodel->normalmins, ent->fields.server->absmin);
-       VectorCopy(sv.worldmodel->normalmaxs, ent->fields.server->absmax);
+       VectorCopy(sv.world.mins, ent->fields.server->mins);
+       VectorCopy(sv.world.maxs, ent->fields.server->maxs);
+       VectorCopy(sv.world.mins, ent->fields.server->absmin);
+       VectorCopy(sv.world.maxs, ent->fields.server->absmax);
 
        if (coop.value)
                prog->globals.server->coop = coop.integer;
@@ -2721,17 +2744,8 @@ void SV_SpawnServer (const char *server)
 
 static void SV_VM_CB_BeginIncreaseEdicts(void)
 {
-       int i;
-       prvm_edict_t *ent;
-
        // links don't survive the transition, so unlink everything
-       for (i = 0, ent = prog->edicts;i < prog->max_edicts;i++, ent++)
-       {
-               if (!ent->priv.server->free)
-                       World_UnlinkEdict(prog->edicts + i);
-               memset(&ent->priv.server->areagrid, 0, sizeof(ent->priv.server->areagrid));
-       }
-       World_Clear(&sv.world);
+       World_UnlinkAll(&sv.world);
 }
 
 static void SV_VM_CB_EndIncreaseEdicts(void)
@@ -2866,6 +2880,7 @@ static void SV_VM_Setup(void)
        prog->builtins = vm_sv_builtins;
        prog->numbuiltins = vm_sv_numbuiltins;
        prog->headercrc = PROGHEADER_CRC;
+       prog->headercrc2 = PROGHEADER_CRC_TENEBRAE;
        prog->max_edicts = 512;
        if (sv.protocol == PROTOCOL_QUAKE)
                prog->limit_edicts = 640; // before quake mission pack 1 this was 512