]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Make observers view from predefined locations if available
authorMario <mario.mario@y7mail.com>
Mon, 23 Sep 2024 19:40:32 +0000 (19:40 +0000)
committerterencehill <piuntn@gmail.com>
Mon, 23 Sep 2024 19:40:32 +0000 (19:40 +0000)
.gitlab-ci.yml
qcsrc/server/cheats.qc
qcsrc/server/client.qc
qcsrc/server/client.qh

index 3d2d310a028d30ddfd0dc7722d5af104bc25c70f..c0057d597584ff0ad2cd54731a34c759d8e8c82a 100644 (file)
@@ -36,7 +36,7 @@ test_compilation_units:
 test_sv_game:
   stage: test
   script:
-    - export EXPECT=82b429be1301d38fbe0af0c60511ceed
+    - export EXPECT=13aa630f559c7683195b8c8d5e0a1522
     - qcsrc/tools/sv_game-hashtest.sh
     - exit $?
 
index 9ec7cc69a637466cfc9759ac3fe398cc5a02558c..f7c55af4c2b2b7ebd7c2ea3745e4c8d5a48efab4 100644 (file)
@@ -21,6 +21,7 @@
 #include <lib/warpzone/anglestransform.qh>
 #include <lib/warpzone/common.qh>
 #include <lib/warpzone/util_server.qh>
+#include <server/client.qh>
 #include <server/clientkill.qh>
 #include <server/damage.qh>
 #include <server/main.qh>
@@ -125,6 +126,10 @@ spawnfunc(info_autoscreenshot)
        }
        if(this.target != "")
                InitializeEntity(this, info_autoscreenshot_findtarget, INITPRIO_FINDTARGET);
+
+       tracebox(this.origin, PL_CROUCH_MIN_CONST, PL_CROUCH_MAX_CONST, this.origin, MOVE_WORLDONLY, this);
+       if(!trace_startsolid)
+               IL_PUSH(g_observepoints, this);
 }
 
 float CheatImpulse(entity this, int imp)
index bd7ab6a9bffd76218ea7ebeb451c3e2b053e92b2..92256c58f734dbd2e2efd4e2ff8e1cb049b619cd 100644 (file)
@@ -238,6 +238,16 @@ void setplayermodel(entity e, string modelname)
                UpdatePlayerSounds(e);
 }
 
+entity SelectObservePoint(entity this)
+{
+       RandomSelection_Init();
+       IL_EACH(g_observepoints, true,
+       {
+               RandomSelection_AddEnt(it, 1, 1);
+       });
+       return RandomSelection_chosen_ent;
+}
+
 /** putting a client as observer in the server */
 void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
 {
@@ -265,11 +275,16 @@ void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
 
        if (use_spawnpoint)
        {
-               entity spot = SelectSpawnPoint(this, true);
+               // first try to find a random "nice" location to view from
+               entity spot = SelectObservePoint(this);
+               bool is_observepoint = (spot != NULL);
+               if(!spot) // otherwise just use the player spawn points
+                       spot = SelectSpawnPoint(this, true);
                if (!spot) LOG_FATAL("No spawnpoints for observers?!?");
+
                this.angles = vec2(spot.angles);
                // offset it so that the spectator spawns higher off the ground, looks better this way
-               setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this));
+               setorigin(this, spot.origin + (is_observepoint ? '0 0 0' : autocvar_sv_player_viewoffset));
        }
        else // change origin to restore previous view origin
                setorigin(this, this.origin + STAT(PL_VIEW_OFS, this) - STAT(PL_CROUCH_VIEW_OFS, this));
index 815e2639041f006759e05d0fd83cee3a5b7f8588..28f454522934f77524a05580b234134919459f52 100644 (file)
@@ -370,7 +370,12 @@ void FixClientCvars(entity e);
 .void(entity this, entity player) init_for_player;
 
 IntrusiveList g_initforplayer;
-STATIC_INIT(g_initforplayer) { g_initforplayer = IL_NEW(); }
+IntrusiveList g_observepoints;
+STATIC_INIT(client_lists)
+{
+    g_initforplayer = IL_NEW();
+    g_observepoints = IL_NEW();
+}
 
 void play_countdown(entity this, float finished, Sound samp);
 void player_powerups_remove_all(entity this);