]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/world.qc
Merge branch 'master' into pending-release
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / world.qc
index a54ad9aa792ebbfd07ab3c85d0ed24ce052e0ae3..c04b188fa4cd6addfb74e65809b6e2522d56c11f 100644 (file)
@@ -22,6 +22,7 @@
 #include <common/util.qh>
 #include <common/vehicles/all.qh>
 #include <common/weapons/_all.qh>
+#include <lib/warpzone/common.qh>
 #include <server/anticheat.qh>
 #include <server/antilag.qh>
 #include <server/bot/api.qh>
@@ -284,6 +285,7 @@ void cvar_changes_init()
                BADCVAR("g_keyhunt");
                BADCVAR("g_keyhunt_teams");
                BADCVAR("g_lms");
+               BADCVAR("g_mayhem");
                BADCVAR("g_nexball");
                BADCVAR("g_onslaught");
                BADCVAR("g_race");
@@ -298,6 +300,8 @@ void cvar_changes_init()
                BADCVAR("g_tdm");
                BADCVAR("g_tdm_on_dm_maps");
                BADCVAR("g_tdm_teams");
+               BADCVAR("g_tmayhem");
+               BADCVAR("g_tmayhem_teams");
                BADCVAR("g_vip");
                BADCVAR("leadlimit");
                BADCVAR("nextmap");
@@ -375,6 +379,10 @@ void cvar_changes_init()
                BADCVAR("g_spawn_alloweffects");
                BADCVAR("g_tdm_point_leadlimit");
                BADCVAR("g_tdm_point_limit");
+               BADCVAR("g_mayhem_point_limit");
+               BADCVAR("g_mayhem_point_leadlimit");
+               BADCVAR("g_tmayhem_point_limit");
+               BADCVAR("g_tmayhem_point_leadlimit");
                BADCVAR("leadlimit_and_fraglimit");
                BADCVAR("leadlimit_override");
                BADCVAR("pausable");
@@ -452,6 +460,7 @@ void cvar_changes_init()
                BADCVAR("g_keyhunt_point_limit");
                BADCVAR("g_keyhunt_teams_override");
                BADCVAR("g_lms_lives_override");
+               BADCVAR("g_mayhem_powerups");
                BADCVAR("g_maplist");
                BADCVAR("g_maxplayers");
                BADCVAR("g_mirrordamage");
@@ -468,6 +477,8 @@ void cvar_changes_init()
                BADCVAR("g_start_delay");
                BADCVAR("g_superspectate");
                BADCVAR("g_tdm_teams_override");
+               BADCVAR("g_tmayhem_teams_override");
+               BADCVAR("g_tmayhem_powerups");
                BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
                BADCVAR("hostname");
                BADCVAR("log_file");
@@ -659,10 +670,9 @@ void GameplayMode_DelayedInit(entity this)
                        int u = AVAILABLE_TEAMS - d;
                        map_minplayers += (u < d && u + map_minplayers <= m) ? u : -d;
                }
-               warmup_limit = -1;
        }
        else
-               map_minplayers = 0; // don't display a minimum if it's not used
+               map_minplayers = 0; // don't display a minimum if it's not used (g_maxplayers < 0 && g_warmup >= 0)
 }
 
 void InitGameplayMode()
@@ -734,8 +744,7 @@ spawnfunc(worldspawn)
        {
                if (!server_is_dedicated)
                {
-                       // force unloading of server pk3 files when starting a listen server
-                       // localcmd("\nfs_rescan\n"); // FIXME: does more harm than good, has unintended side effects. What we really want is to unload temporary pk3s only
+                       // DP unloads dlcache pk3s before starting a listen server since https://gitlab.com/xonotic/darkplaces/-/merge_requests/134
                        // restore csqc_progname too
                        string expect = "csprogs.dat";
                        wantrestart = cvar_string("csqc_progname") != expect;
@@ -864,9 +873,6 @@ spawnfunc(worldspawn)
 
        GameRules_limit_fallbacks();
 
-       if(warmup_limit == 0)
-               warmup_limit = autocvar_timelimit * 60;
-
        player_count = 0;
        bot_waypoints_for_items = autocvar_g_waypoints_for_items;
        if(bot_waypoints_for_items == 1)
@@ -2099,13 +2105,27 @@ void readlevelcvars()
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
 
-       sv_ready_restart_after_countdown = cvar("sv_ready_restart_after_countdown");
+       serverflags &= ~SERVERFLAG_FORBID_PICKUPTIMER;
+       if(cvar("sv_forbid_pickuptimer"))
+               serverflags |= SERVERFLAG_FORBID_PICKUPTIMER;
 
-       warmup_stage = cvar("g_warmup");
-       warmup_limit = cvar("g_warmup_limit");
+       sv_ready_restart_after_countdown = cvar("sv_ready_restart_after_countdown");
 
        if(cvar("g_campaign"))
                warmup_stage = 0; // no warmup during campaign
+       else
+       {
+               warmup_stage = autocvar_g_warmup;
+               if (warmup_stage < 0 || warmup_stage > 1)
+                       warmup_limit = -1; // don't start until there's enough players
+               else if (warmup_stage == 1)
+               {
+                       // this code is duplicated in ReadyCount()
+                       warmup_limit = cvar("g_warmup_limit");
+                       if(warmup_limit == 0)
+                               warmup_limit = autocvar_timelimit * 60;
+               }
+       }
 
        g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
        g_pickup_respawntime_superweapon = cvar("g_pickup_respawntime_superweapon");
@@ -2258,11 +2278,20 @@ void DropToFloor_Handler(entity this)
                return;
        }
 
-       vector end = this.origin - '0 0 256';
+       vector end = this.origin;
+       if (autocvar_sv_mapformat_is_quake3)
+               end.z -= 4096;
+       else if (autocvar_sv_mapformat_is_quake2)
+               end.z -= 128;
+       else
+               end.z -= 256; // Quake, QuakeWorld
 
-       // NOTE: NudgeOutOfSolid support is not added as Xonotic's physics do not use it!
-       //if(autocvar_sv_gameplayfix_droptofloorstartsolid_nudgetocorrect)
-               //SV_NudgeOutOfSolid(this);
+       // NOTE: SV_NudgeOutOfSolid is used in the engine here
+       if(autocvar_sv_gameplayfix_droptofloorstartsolid_nudgetocorrect)
+       {
+               _Movetype_UnstickEntity(this);
+               move_out_of_solid(this);
+       }
 
        tracebox(this.origin, this.mins, this.maxs, end, MOVE_NORMAL, this);
 
@@ -2284,9 +2313,12 @@ void DropToFloor_Handler(entity this)
                else if(trace_fraction < 1)
                {
                        LOG_DEBUGF("DropToFloor_Handler: %v fixed badly placed entity", this.origin);
-                       //if(autocvar_sv_gameplayfix_droptofloorstartsolid_nudgetocorrect)
-                               //SV_NudgeOutOfSolid(this);
                        setorigin(this, trace_endpos);
+                       if(autocvar_sv_gameplayfix_droptofloorstartsolid_nudgetocorrect)
+                       {
+                               _Movetype_UnstickEntity(this);
+                               move_out_of_solid(this);
+                       }
                        SET_ONGROUND(this);
                        this.groundentity = trace_ent;
                        // if support is destroyed, keep suspended (gross hack for floating items in various maps)
@@ -2303,6 +2335,12 @@ void DropToFloor_Handler(entity this)
                        // if support is destroyed, keep suspended (gross hack for floating items in various maps)
                        this.move_suspendedinair = true;
                }
+               else
+               {
+                       // if we can't get the entity out of solid, mark it as on ground so physics doesn't attempt to drop it
+                       // hacky workaround for #2774
+                       SET_ONGROUND(this);
+               }
        }
        this.dropped_origin = this.origin;
 }