]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/warpzonelib/server.qc
Merge remote-tracking branch 'origin/nifrek/skinfixes'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / warpzonelib / server.qc
index f71fbe2d985b37fc9279f11f98009f307c5540c5..921b2ed58289df9fadff0acb3d409feca06d498f 100644 (file)
@@ -1,5 +1,6 @@
 .vector warpzone_oldorigin, warpzone_oldvelocity, warpzone_oldangles;
 .float warpzone_teleport_time;
+.entity warpzone_teleport_zone;
 
 void WarpZone_StoreProjectileData(entity e)
 {
@@ -21,17 +22,23 @@ void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector
        player.fixangle = TRUE;
        player.velocity = to_velocity;
 
-       if(player.effects & EF_TELEPORT_BIT)
-               player.effects &~= EF_TELEPORT_BIT;
-       else
-               player.effects |= EF_TELEPORT_BIT;
+       BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT);
 
        if(player.classname == "player")
-               player.flags &~= FL_ONGROUND;
+               BITCLR_ASSIGN(player.flags, FL_ONGROUND);
 
        WarpZone_PostTeleportPlayer_Callback(player);
 }
 
+float WarpZone_Teleported_Send(entity to, float sf)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE_TELEPORTED);
+       WriteCoord(MSG_ENTITY, self.angles_x);
+       WriteCoord(MSG_ENTITY, self.angles_y);
+       WriteCoord(MSG_ENTITY, self.angles_z);
+       return TRUE;
+}
+
 float WarpZone_Teleport(entity player)
 {
        vector o0, a0, v0, o1, a1, v1;
@@ -90,6 +97,24 @@ float WarpZone_Teleport(entity player)
        WarpZone_TeleportPlayer(self, player, o1 - player.view_ofs, a1, v1);
        WarpZone_StoreProjectileData(player);
        player.warpzone_teleport_time = time;
+       player.warpzone_teleport_zone = self;
+#ifndef WARPZONE_USE_FIXANGLE
+       // instead of fixangle, send the transform to the client for smoother operation
+       player.fixangle = FALSE;
+
+       entity ts = spawn();
+       setmodel(ts, "null");
+       ts.SendEntity = WarpZone_Teleported_Send;
+       ts.SendFlags = 0xFFFFFF;
+       ts.drawonlytoclient = player;
+       ts.think = SUB_Remove;
+       ts.nextthink = time + 1;
+       ts.owner = player;
+       ts.enemy = self;
+       ts.effects = EF_NODEPTHTEST;
+       ts.classname = "warpzone_teleported";
+       ts.angles = self.warpzone_transform;
+#endif
 
        return 1;
 }
@@ -143,11 +168,11 @@ float WarpZone_Send(entity to, float sendflags)
        // we must send this flag for clientside to match properly too
        f = 0;
        if(self.warpzone_isboxy)
-               f |= 1;
+               BITSET_ASSIGN(f, 1);
        if(self.warpzone_fadestart)
-               f |= 2;
+               BITSET_ASSIGN(f, 2);
        if(self.origin != '0 0 0')
-               f |= 4;
+               BITSET_ASSIGN(f, 4);
        WriteByte(MSG_ENTITY, f);
 
        // we need THESE to render the warpzone (and cull properly)...
@@ -196,9 +221,9 @@ float WarpZone_Camera_Send(entity to, float sendflags)
        WriteByte(MSG_ENTITY, ENT_CLIENT_WARPZONE_CAMERA);
 
        if(self.warpzone_fadestart)
-               f |= 2;
+               BITSET_ASSIGN(f, 2);
        if(self.origin != '0 0 0')
-               f |= 4;
+               BITSET_ASSIGN(f, 4);
        WriteByte(MSG_ENTITY, f);
 
        // we need THESE to render the warpzone (and cull properly)...
@@ -383,7 +408,7 @@ void WarpZone_InitStep_UpdateTransform()
                tex = getsurfacetexture(self, i_s);
                if not(tex)
                        break; // this is beyond the last one
-               if(tex == "textures/common/trigger")
+               if(tex == "textures/common/trigger" || tex == "trigger")
                        continue;
                n_t = getsurfacenumtriangles(self, i_s);
                for(i_t = 0; i_t < n_t; ++i_t)
@@ -544,7 +569,7 @@ void spawnfunc_trigger_warpzone(void)
                setsize(self, self.mins, self.maxs);
        self.SendEntity = WarpZone_Send;
        self.SendFlags = 0xFFFFFF;
-       self.effects |= EF_NODEPTHTEST;
+       BITSET_ASSIGN(self.effects, EF_NODEPTHTEST);
        self.warpzone_next = warpzone_first;
        warpzone_first = self;
 }
@@ -604,8 +629,41 @@ void WarpZone_StartFrame()
                self = e;
                WarpZones_Reconnect();
        }
-       for(e = world; (e = nextent(e)); )
-               WarpZone_StoreProjectileData(e);
+
+       if(warpzone_warpzones_exist)
+       {
+               entity oldself, oldother;
+               oldself = self;
+               oldother = other;
+               for(e = world; (e = nextent(e)); )
+               {
+                       WarpZone_StoreProjectileData(e);
+                       float f;
+                       f = clienttype(e);
+                       if(f == CLIENTTYPE_REAL)
+                       {
+                               if(e.solid != SOLID_NOT) // not spectating?
+                                       continue;
+                               if(e.movetype != MOVETYPE_NOCLIP && e.movetype != MOVETYPE_FLY) // not spectating? (this is to catch observers)
+                                       continue;
+                               self = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs);
+                               if(!self)
+                                       continue;
+                               other = e;
+                               if(WarpZoneLib_ExactTrigger_Touch())
+                                       continue;
+                               WarpZone_Teleport(e); // NOT triggering targets by this!
+                       }
+                       if(f == CLIENTTYPE_NOTACLIENT)
+                       {
+                               for(; (e = nextent(e)); )
+                                       WarpZone_StoreProjectileData(e);
+                               break;
+                       }
+               }
+               self = oldself;
+               other = oldother;
+       }
 }
 
 .float warpzone_reconnecting;
@@ -652,3 +710,16 @@ void spawnfunc_target_warpzone_reconnect()
 {
        spawnfunc_trigger_warpzone_reconnect(); // both names make sense here :(
 }
+
+void WarpZone_PlayerPhysics_FixVAngle(void)
+{
+#ifndef WARPZONE_DONT_FIX_VANGLE
+       if(clienttype(self) == CLIENTTYPE_REAL)
+       if(self.v_angle_z <= 360) // if not already adjusted
+       if(time - self.ping * 0.001 < self.warpzone_teleport_time)
+       {
+               self.v_angle = WarpZone_TransformVAngles(self.warpzone_teleport_zone, self.v_angle);
+               self.v_angle_z += 720; // mark as adjusted
+       }
+#endif
+}