]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move some code that only needs to run once per frame out of PlayerP*Think()
authorbones_was_here <bones_was_here@xonotic.au>
Fri, 11 Aug 2023 18:01:26 +0000 (04:01 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Fri, 11 Aug 2023 18:03:08 +0000 (04:03 +1000)
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/main.qc

index 00063bba214fae3ba064a144ec18bf2983db2eae..58473889bb423d0d71334acd55f589922335cecb 100644 (file)
@@ -2423,135 +2423,23 @@ void PlayerUseKey(entity this)
 =============
 PlayerPreThink
 
-Called every frame for each client before the physics are run
+Called every frame for each real client by DP (and for each bot by StartFrame()),
+and when executing every asynchronous move, so only include things that MUST be done then.
+Use PlayerFrame() instead for code that only needs to run once per server frame.
+frametime == 0 in the asynchronous code path.
+
+TODO: move more stuff from here and PlayerThink() and ObserverOrSpectatorThink() to PlayerFrame() (frametime is always set there)
 =============
 */
 .float last_vehiclecheck;
 void PlayerPreThink (entity this)
 {
-       STAT(GUNALIGN, this) = CS_CVAR(this).cvar_cl_gunalign; // TODO
-       STAT(MOVEVARS_CL_TRACK_CANJUMP, this) = CS_CVAR(this).cvar_cl_movement_track_canjump;
-
        WarpZone_PlayerPhysics_FixVAngle(this);
 
-       if (frametime) {
-               // physics frames: update anticheat stuff
-               anticheat_prethink(this);
-
-               // WORKAROUND: only use dropclient in server frames (frametime set).
-               // Never use it in cl_movement frames (frametime zero).
-               if (blockSpectators && IS_REAL_CLIENT(this)
-                       && (IS_SPEC(this) || IS_OBSERVER(this)) && !INGAME(this)
-                       && time > (CS(this).spectatortime + autocvar_g_maxplayers_spectator_blocktime))
-               {
-                       if (dropclient_schedule(this))
-                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
-               }
-       }
-
        zoomstate_set = false;
 
-       // Check for nameless players
-       if (this.netname == "" || this.netname != CS(this).netname_previous)
-       {
-               bool assume_unchanged = (CS(this).netname_previous == "");
-               if (autocvar_sv_name_maxlength > 0 && strlennocol(this.netname) > autocvar_sv_name_maxlength)
-               {
-                       int new_length = textLengthUpToLength(this.netname, autocvar_sv_name_maxlength, strlennocol);
-                       this.netname = strzone(strcat(substring(this.netname, 0, new_length), "^7"));
-                       sprint(this, sprintf("Warning: your name is longer than %d characters, it has been truncated.\n", autocvar_sv_name_maxlength));
-                       assume_unchanged = false;
-                       // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
-               }
-               if (isInvisibleString(this.netname))
-               {
-                       this.netname = strzone(sprintf("Player#%d", this.playerid));
-                       sprint(this, "Warning: invisible names are not allowed.\n");
-                       assume_unchanged = false;
-                       // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
-               }
-               if (!assume_unchanged && autocvar_sv_eventlog)
-                       GameLogEcho(strcat(":name:", ftos(this.playerid), ":", playername(this.netname, this.team, false)));
-               strcpy(CS(this).netname_previous, this.netname);
-       }
-
-       // version nagging
-       if (CS(this).version_nagtime && CS_CVAR(this).cvar_g_xonoticversion && time > CS(this).version_nagtime) {
-        CS(this).version_nagtime = 0;
-        if (strstrofs(CS_CVAR(this).cvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(CS_CVAR(this).cvar_g_xonoticversion, "autobuild", 0) >= 0) {
-            // git client
-        } else if (strstrofs(autocvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(autocvar_g_xonoticversion, "autobuild", 0) >= 0) {
-            // git server
-            Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
-        } else {
-            int r = vercmp(CS_CVAR(this).cvar_g_xonoticversion, autocvar_g_xonoticversion);
-            if (r < 0) { // old client
-                Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
-            } else if (r > 0) { // old server
-                Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
-            }
-        }
-    }
-
-       // GOD MODE info
-       if (!(this.flags & FL_GODMODE) && this.max_armorvalue)
-       {
-               Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_GODMODE_OFF, this.max_armorvalue);
-               this.max_armorvalue = 0;
-       }
-
-       if (frametime && IS_PLAYER(this) && time >= game_starttime)
-       {
-               if (STAT(FROZEN, this) == FROZEN_TEMP_REVIVING)
-               {
-                       STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) + frametime * this.revive_speed, 1);
-                       SetResourceExplicit(this, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, this) * start_health));
-                       if (this.iceblock)
-                               this.iceblock.alpha = bound(0.2, 1 - STAT(REVIVE_PROGRESS, this), 1);
-
-                       if (STAT(REVIVE_PROGRESS, this) >= 1)
-                               Unfreeze(this, false);
-               }
-               else if (STAT(FROZEN, this) == FROZEN_TEMP_DYING)
-               {
-                       STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) - frametime * this.revive_speed, 1);
-                       SetResourceExplicit(this, RES_HEALTH, max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * STAT(REVIVE_PROGRESS, this)));
-
-                       if (GetResource(this, RES_HEALTH) < 1)
-                       {
-                               if (this.vehicle)
-                                       vehicles_exit(this.vehicle, VHEF_RELEASE);
-                               if(this.event_damage)
-                                       this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, DMG_NOWEP, this.origin, '0 0 0');
-                       }
-                       else if (STAT(REVIVE_PROGRESS, this) <= 0)
-                               Unfreeze(this, false);
-               }
-       }
-
        MUTATOR_CALLHOOK(PlayerPreThink, this);
 
-       if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !game_stopped && !this.vehicle)
-       if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this) && !IS_INDEPENDENT_PLAYER(this))
-       {
-               FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it) && !IS_DEAD(it) && it.takedamage != DAMAGE_NO,
-               {
-                       if(!it.owner)
-                       {
-                               if(!it.team || SAME_TEAM(this, it))
-                                       Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER);
-                               else if(autocvar_g_vehicles_steal)
-                                       Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
-                       }
-                       else if((it.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(it.owner, this))
-                       {
-                               Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER);
-                       }
-               });
-
-               this.last_vehiclecheck = time + 1;
-       }
-
        if(PHYS_INPUT_BUTTON_USE(this) && !CS(this).usekeypressed)
                PlayerUseKey(this);
        CS(this).usekeypressed = PHYS_INPUT_BUTTON_USE(this);
@@ -2599,6 +2487,7 @@ void PlayerPreThink (entity this)
                SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
        }
 
+       // Voice sound effects
        if (CS(this).teamkill_soundtime && time > CS(this).teamkill_soundtime)
        {
                CS(this).teamkill_soundtime = 0;
@@ -2669,15 +2558,180 @@ void Player_Physics(entity this)
 =============
 PlayerPostThink
 
-Called every frame for each client after the physics are run
+Called every frame for each real client by DP (and for each bot by StartFrame()),
+and when executing every asynchronous move, so only include things that MUST be done then.
+Use PlayerFrame() instead for code that only needs to run once per server frame.
+frametime == 0 in the asynchronous code path.
 =============
 */
 void PlayerPostThink (entity this)
 {
        Player_Physics(this);
 
+       if (IS_PLAYER(this)) {
+               if(this.death_time == time && IS_DEAD(this))
+               {
+                       // player's bbox gets resized now, instead of in the damage event that killed the player,
+                       // once all the damage events of this frame have been processed with normal size
+                       this.maxs.z = 5;
+                       setsize(this, this.mins, this.maxs);
+               }
+               DrownPlayer(this);
+               UpdateChatBubble(this);
+               if (CS(this).impulse) ImpulseCommands(this);
+               GetPressedKeys(this);
+               if (game_stopped)
+               {
+                       CSQCMODEL_AUTOUPDATE(this);
+                       return;
+               }
+       }
+       else if (IS_OBSERVER(this) && STAT(PRESSED_KEYS, this))
+       {
+               CS(this).pressedkeys = 0;
+               STAT(PRESSED_KEYS, this) = 0;
+       }
+
+       CSQCMODEL_AUTOUPDATE(this);
+}
+
+/*
+=============
+PlayerFrame
+
+Called every frame for each client by StartFrame().
+Use this for code that only needs to run once per server frame.
+frametime is always set here.
+=============
+*/
+void PlayerFrame (entity this)
+{
+// formerly PreThink code
+       STAT(GUNALIGN, this) = CS_CVAR(this).cvar_cl_gunalign; // TODO
+       STAT(MOVEVARS_CL_TRACK_CANJUMP, this) = CS_CVAR(this).cvar_cl_movement_track_canjump;
+
+       // physics frames: update anticheat stuff
+       anticheat_prethink(this);
+
+       // Check if spectating is allowed
+       if (blockSpectators && IS_REAL_CLIENT(this)
+       && (IS_SPEC(this) || IS_OBSERVER(this)) && !INGAME(this)
+       && time > (CS(this).spectatortime + autocvar_g_maxplayers_spectator_blocktime))
+       {
+               if (dropclient_schedule(this))
+                       Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
+       }
+
+       // Check for nameless players
+       if (this.netname == "" || this.netname != CS(this).netname_previous)
+       {
+               bool assume_unchanged = (CS(this).netname_previous == "");
+               if (autocvar_sv_name_maxlength > 0 && strlennocol(this.netname) > autocvar_sv_name_maxlength)
+               {
+                       int new_length = textLengthUpToLength(this.netname, autocvar_sv_name_maxlength, strlennocol);
+                       this.netname = strzone(strcat(substring(this.netname, 0, new_length), "^7"));
+                       sprint(this, sprintf("Warning: your name is longer than %d characters, it has been truncated.\n", autocvar_sv_name_maxlength));
+                       assume_unchanged = false;
+                       // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
+               }
+               if (isInvisibleString(this.netname))
+               {
+                       this.netname = strzone(sprintf("Player#%d", this.playerid));
+                       sprint(this, "Warning: invisible names are not allowed.\n");
+                       assume_unchanged = false;
+                       // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
+               }
+               if (!assume_unchanged && autocvar_sv_eventlog)
+                       GameLogEcho(strcat(":name:", ftos(this.playerid), ":", playername(this.netname, this.team, false)));
+               strcpy(CS(this).netname_previous, this.netname);
+       }
+
+       // version nagging
+       if (CS(this).version_nagtime && CS_CVAR(this).cvar_g_xonoticversion && time > CS(this).version_nagtime)
+       {
+               CS(this).version_nagtime = 0;
+               if (strstrofs(CS_CVAR(this).cvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(CS_CVAR(this).cvar_g_xonoticversion, "autobuild", 0) >= 0)
+               {
+                       // git client
+               }
+               else if (strstrofs(autocvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(autocvar_g_xonoticversion, "autobuild", 0) >= 0)
+               {
+                       // git server
+                       Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
+               }
+               else
+               {
+                       int r = vercmp(CS_CVAR(this).cvar_g_xonoticversion, autocvar_g_xonoticversion);
+                       if (r < 0) // old client
+                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
+                       else if (r > 0) // old server
+                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, CS_CVAR(this).cvar_g_xonoticversion);
+               }
+       }
+
+       // GOD MODE info
+       if (!(this.flags & FL_GODMODE) && this.max_armorvalue)
+       {
+               Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_GODMODE_OFF, this.max_armorvalue);
+               this.max_armorvalue = 0;
+       }
+
+       // FreezeTag
+       if (IS_PLAYER(this) && time >= game_starttime)
+       {
+               if (STAT(FROZEN, this) == FROZEN_TEMP_REVIVING)
+               {
+                       STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) + frametime * this.revive_speed, 1);
+                       SetResourceExplicit(this, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, this) * start_health));
+                       if (this.iceblock)
+                               this.iceblock.alpha = bound(0.2, 1 - STAT(REVIVE_PROGRESS, this), 1);
+
+                       if (STAT(REVIVE_PROGRESS, this) >= 1)
+                               Unfreeze(this, false);
+               }
+               else if (STAT(FROZEN, this) == FROZEN_TEMP_DYING)
+               {
+                       STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) - frametime * this.revive_speed, 1);
+                       SetResourceExplicit(this, RES_HEALTH, max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * STAT(REVIVE_PROGRESS, this)));
+
+                       if (GetResource(this, RES_HEALTH) < 1)
+                       {
+                               if (this.vehicle)
+                                       vehicles_exit(this.vehicle, VHEF_RELEASE);
+                               if(this.event_damage)
+                                       this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, DMG_NOWEP, this.origin, '0 0 0');
+                       }
+                       else if (STAT(REVIVE_PROGRESS, this) <= 0)
+                               Unfreeze(this, false);
+               }
+       }
+
+       // Vehicles
+       if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !game_stopped && !this.vehicle)
+       if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this) && !IS_INDEPENDENT_PLAYER(this))
+       {
+               FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it) && !IS_DEAD(it) && it.takedamage != DAMAGE_NO,
+               {
+                       if(!it.owner)
+                       {
+                               if(!it.team || SAME_TEAM(this, it))
+                                       Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER);
+                               else if(autocvar_g_vehicles_steal)
+                                       Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
+                       }
+                       else if((it.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(it.owner, this))
+                       {
+                               Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER);
+                       }
+               });
+
+               this.last_vehiclecheck = time + 1;
+       }
+
+
+
+// formerly PostThink code
        if (autocvar_sv_maxidle > 0 || (IS_PLAYER(this) && autocvar_sv_maxidle_playertospectator > 0))
-       if (frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
        if (IS_REAL_CLIENT(this))
        if (IS_PLAYER(this) || autocvar_sv_maxidle_alsokickspectators)
        if (!intermission_running) // NextLevel() kills all centerprints after setting this true
@@ -2764,36 +2818,10 @@ void PlayerPostThink (entity this)
                CS(this).teamkill_soundsource = NULL;
        }
 
-       if (IS_PLAYER(this)) {
-               if(this.death_time == time && IS_DEAD(this))
-               {
-                       // player's bbox gets resized now, instead of in the damage event that killed the player,
-                       // once all the damage events of this frame have been processed with normal size
-                       this.maxs.z = 5;
-                       setsize(this, this.mins, this.maxs);
-               }
-               DrownPlayer(this);
-               UpdateChatBubble(this);
-               if (CS(this).impulse) ImpulseCommands(this);
-               GetPressedKeys(this);
-               if (game_stopped)
-               {
-                       CSQCMODEL_AUTOUPDATE(this);
-                       return;
-               }
-       }
-       else if (IS_OBSERVER(this) && STAT(PRESSED_KEYS, this))
-       {
-               CS(this).pressedkeys = 0;
-               STAT(PRESSED_KEYS, this) = 0;
-       }
-
        if (this.waypointsprite_attachedforcarrier) {
                float hp = healtharmor_maxdamage(GetResource(this, RES_HEALTH), GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x;
                WaypointSprite_UpdateHealth(this.waypointsprite_attachedforcarrier, hp);
        }
-
-       CSQCMODEL_AUTOUPDATE(this);
 }
 
 // hack to copy the button fields from the client entity to the Client State
index f982955ddfbbd7851a8bf9be66a482f55f0eb135..9611df4e87980f2fb639198e7f94fd1cae7f70ca 100644 (file)
@@ -402,6 +402,8 @@ const int MIN_SPEC_TIME = 1;
 bool joinAllowed(entity this);
 void Join(entity this);
 
+void PlayerFrame (entity this);
+
 #define SPECTATE_COPY() ACCUMULATE void SpectateCopy(entity this, entity spectatee)
 #define SPECTATE_COPYFIELD(fld) SPECTATE_COPY() { this.(fld) = spectatee.(fld); }
 
index 03306e76d7e0f4019657c2259a74c7caee1f2410..a290f4032eaf2ff9a76a6d41b1bd264b39131e70 100644 (file)
@@ -364,6 +364,7 @@ void StartFrame()
                GlobalStats_update(it);
                if (IS_FAKE_CLIENT(it))
                        PlayerPostThink(it); // DP calls this for real clients only
+               PlayerFrame(it);
        });
 }