]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/t_jumppads.qc
Merge remote-tracking branch 'origin/TimePath/experiments/csqc_prediction' into TimeP...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / t_jumppads.qc
index 3c797f97710e46b6d99e44164816554b122a3d3c..480f5c37f17015677e99b2c11ac52829f078d4fb 100644 (file)
@@ -1,19 +1,16 @@
-const float PUSH_ONCE                  = 1;
-const float PUSH_SILENT                = 2;
+#include "t_jumppads.qh"
 
-.float pushltime;
-.float istypefrag;
-.float height;
-
-void() SUB_UseTargets;
-
-float trigger_push_calculatevelocity_flighttime;
+#ifdef SVQC
 
 void trigger_push_use()
 {
        if(teamplay)
+       {
                self.team = activator.team;
+               self.SendFlags |= 2;
+       }
 }
+#endif
 
 /*
        trigger_push_calculatevelocity
@@ -36,11 +33,11 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
 
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
 
-       grav = autocvar_sv_gravity;
-       if(other.gravity)
-               grav *= other.gravity;
+       grav = PHYS_GRAVITY;
+       if(PHYS_ENTGRAVITY(other))
+               grav *= PHYS_ENTGRAVITY(other);
 
-       zdist = torg_z - org_z;
+       zdist = torg.z - org.z;
        sdist = vlen(torg - org - zdist * '0 0 1');
        sdir = normalize(torg - org - zdist * '0 0 1');
 
@@ -81,10 +78,10 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
        vector solution;
        solution = solve_quadratic(0.5 * grav, -vz, zdist); // equation "z(ti) = zdist"
        // ALWAYS solvable because jumpheight >= zdist
-       if(!solution_z)
-               solution_y = solution_x; // just in case it is not solvable due to roundoff errors, assume two equal solutions at their center (this is mainly for the usual case with ht == 0)
+       if(!solution.z)
+               solution.y = solution.x; // just in case it is not solvable due to roundoff errors, assume two equal solutions at their center (this is mainly for the usual case with ht == 0)
        if(zdist == 0)
-               solution_x = solution_y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually)
+               solution.x = solution.y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually)
 
        if(zdist < 0)
        {
@@ -94,14 +91,14 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
                        // almost straight line type
                        // jump apex is before the jump
                        // we must take the larger one
-                       trigger_push_calculatevelocity_flighttime = solution_y;
+                       trigger_push_calculatevelocity_flighttime = solution.y;
                }
                else
                {
                        // regular jump
                        // jump apex is during the jump
                        // we must take the larger one too
-                       trigger_push_calculatevelocity_flighttime = solution_y;
+                       trigger_push_calculatevelocity_flighttime = solution.y;
                }
        }
        else
@@ -112,14 +109,14 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
                        // almost straight line type
                        // jump apex is after the jump
                        // we must take the smaller one
-                       trigger_push_calculatevelocity_flighttime = solution_x;
+                       trigger_push_calculatevelocity_flighttime = solution.x;
                }
                else
                {
                        // regular jump
                        // jump apex is during the jump
                        // we must take the larger one
-                       trigger_push_calculatevelocity_flighttime = solution_y;
+                       trigger_push_calculatevelocity_flighttime = solution.y;
                }
        }
        vs = sdist / trigger_push_calculatevelocity_flighttime;
@@ -133,11 +130,13 @@ void trigger_push_touch()
        if (self.active == ACTIVE_NOT)
                return;
 
+#ifdef SVQC
        if (!isPushable(other))
                return;
+#endif
 
        if(self.team)
-               if(((self.spawnflags & 4) == 0) == (self.team != other.team))
+               if(((self.spawnflags & 4) == 0) == (DIFF_TEAM(self, other)))
                        return;
 
        EXACTTRIGGER_TOUCH;
@@ -164,8 +163,9 @@ void trigger_push_touch()
                other.velocity = self.movedir;
        }
 
-       other.flags &= ~FL_ONGROUND;
+       UNSET_ONGROUND(other);
 
+#ifdef SVQC
        if (IS_PLAYER(other))
        {
                // reset tracking of oldvelocity for impact damage (sudden velocity changes)
@@ -180,15 +180,13 @@ void trigger_push_touch()
                }
                if(IS_REAL_CLIENT(other) || IS_BOT_CLIENT(other))
                {
-                       float i;
-                       float found;
-                       found = FALSE;
-                       for(i = 0; i < other.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
+                       bool found = false;
+                       for(int i = 0; i < other.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
                                if(other.(jumppadsused[i]) == self)
-                                       found = TRUE;
+                                       found = true;
                        if(!found)
                        {
-                               other.(jumppadsused[mod(other.jumppadcount, NUM_JUMPPADSUSED)]) = self;
+                               other.(jumppadsused[other.jumppadcount % NUM_JUMPPADSUSED]) = self;
                                other.jumppadcount = other.jumppadcount + 1;
                        }
 
@@ -201,10 +199,10 @@ void trigger_push_touch()
                                other.lastteleporttime = time;
 
                        if (other.deadflag == DEAD_NO)
-                               animdecide_setaction(other, ANIMACTION_JUMP, TRUE);
+                               animdecide_setaction(other, ANIMACTION_JUMP, true);
                }
                else
-                       other.jumppadcount = TRUE;
+                       other.jumppadcount = true;
 
                // reset tracking of who pushed you into a hazard (for kill credit)
                other.pushltime = 0;
@@ -244,26 +242,31 @@ void trigger_push_touch()
                self.think = SUB_Remove;
                self.nextthink = time;
        }
+#endif
 }
 
 .vector dest;
+#ifdef SVQC
+void trigger_push_link();
+void trigger_push_updatelink();
+#endif
 void trigger_push_findtarget()
 {
-       entity e, t;
+       entity t;
        vector org;
 
        // first calculate a typical start point for the jump
        org = (self.absmin + self.absmax) * 0.5;
-       org_z = self.absmax_z - PL_MIN_z;
+       org.z = self.absmax.z - PL_MIN_z;
 
        if (self.target)
        {
-               float n;
-               n = 0;
+               float n = 0;
                for(t = world; (t = find(t, targetname, self.target)); )
                {
                        ++n;
-                       e = spawn();
+#ifdef SVQC
+                       entity e = spawn();
                        setorigin(e, org);
                        setsize(e, PL_MIN, PL_MAX);
                        e.velocity = trigger_push_calculatevelocity(org, t, self.height);
@@ -271,12 +274,15 @@ void trigger_push_findtarget()
                        if(e.movetype == MOVETYPE_NONE)
                                waypoint_spawnforteleporter(self, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity));
                        remove(e);
+#endif
                }
 
-               if(n == 0)
+               if(!n)
                {
                        // no dest!
+#ifdef SVQC
                        objerror ("Jumppad with nonexistant target");
+#endif
                        return;
                }
                else if(n == 1)
@@ -290,9 +296,10 @@ void trigger_push_findtarget()
                        self.enemy = world;
                }
        }
+#ifdef SVQC
        else
        {
-               e = spawn();
+               entity e = spawn();
                setorigin(e, org);
                setsize(e, PL_MIN, PL_MAX);
                e.velocity = self.movedir;
@@ -300,8 +307,67 @@ void trigger_push_findtarget()
                waypoint_spawnforteleporter(self, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity));
                remove(e);
        }
+
+       trigger_push_link();
+       defer(0.1, trigger_push_updatelink);
+#endif
 }
 
+#ifdef SVQC
+float trigger_push_send(entity to, float sf)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_TRIGGER_PUSH);
+       WriteByte(MSG_ENTITY, sf);
+
+       if(sf & 1)
+       {
+               WriteString(MSG_ENTITY, self.target);
+               WriteByte(MSG_ENTITY, self.team);
+               WriteInt24_t(MSG_ENTITY, self.spawnflags);
+               WriteByte(MSG_ENTITY, self.active);
+               WriteByte(MSG_ENTITY, self.warpzone_isboxy);
+               WriteByte(MSG_ENTITY, self.height);
+               WriteByte(MSG_ENTITY, self.scale);
+               WriteCoord(MSG_ENTITY, self.origin_x);
+               WriteCoord(MSG_ENTITY, self.origin_y);
+               WriteCoord(MSG_ENTITY, self.origin_z);
+
+               WriteCoord(MSG_ENTITY, self.mins_x);
+               WriteCoord(MSG_ENTITY, self.mins_y);
+               WriteCoord(MSG_ENTITY, self.mins_z);
+               WriteCoord(MSG_ENTITY, self.maxs_x);
+               WriteCoord(MSG_ENTITY, self.maxs_y);
+               WriteCoord(MSG_ENTITY, self.maxs_z);
+
+               WriteCoord(MSG_ENTITY, self.movedir_x);
+               WriteCoord(MSG_ENTITY, self.movedir_y);
+               WriteCoord(MSG_ENTITY, self.movedir_z);
+
+               WriteCoord(MSG_ENTITY, self.angles_x);
+               WriteCoord(MSG_ENTITY, self.angles_y);
+               WriteCoord(MSG_ENTITY, self.angles_z);
+       }
+
+       if(sf & 2)
+       {
+               WriteByte(MSG_ENTITY, self.team);
+               WriteByte(MSG_ENTITY, self.active);
+       }
+
+       return true;
+}
+
+void trigger_push_updatelink()
+{
+       self.SendFlags |= 1;
+}
+
+void trigger_push_link()
+{
+       Net_LinkEntity(self, false, 0, trigger_push_send);
+}
+#endif
+#ifdef SVQC
 /*
  * ENTITY PARAMETERS:
  *
@@ -329,7 +395,7 @@ void spawnfunc_trigger_push()
                self.speed = 1000;
        self.movedir = self.movedir * self.speed * 10;
 
-       if not(self.noise)
+       if (!self.noise)
                self.noise = "misc/jumppad.wav";
        precache_sound (self.noise);
 
@@ -337,6 +403,99 @@ void spawnfunc_trigger_push()
        InitializeEntity(self, trigger_push_findtarget, INITPRIO_FINDTARGET);
 }
 
-void spawnfunc_target_push() {}
-void spawnfunc_info_notnull() {}
-void spawnfunc_target_position() {}
+
+float target_push_send(entity to, float sf)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_TARGET_PUSH);
+
+       WriteByte(MSG_ENTITY, self.cnt);
+       WriteString(MSG_ENTITY, self.targetname);
+       WriteCoord(MSG_ENTITY, self.origin_x);
+       WriteCoord(MSG_ENTITY, self.origin_y);
+       WriteCoord(MSG_ENTITY, self.origin_z);
+
+       return true;
+}
+
+void target_push_link()
+{
+       Net_LinkEntity(self, false, 0, target_push_send);
+       self.SendFlags |= 1; // update
+}
+
+void spawnfunc_target_push() { target_push_link(); }
+void spawnfunc_info_notnull() { target_push_link(); }
+void spawnfunc_target_position() { target_push_link(); }
+
+#endif
+
+#ifdef CSQC
+void trigger_push_draw()
+{
+       float dt = time - self.move_time;
+       self.move_time = time;
+       if(dt <= 0) { return; }
+
+       trigger_touch_generic(trigger_push_touch);
+}
+
+void ent_trigger_push()
+{
+       float sf = ReadByte();
+
+       if(sf & 1)
+       {
+               self.classname = "jumppad";
+               self.target = strzone(ReadString());
+               float mytm = ReadByte(); if(mytm) { self.team = mytm - 1; }
+               self.spawnflags = ReadInt24_t();
+               self.active = ReadByte();
+               self.warpzone_isboxy = ReadByte();
+               self.height = ReadByte();
+               self.scale = ReadByte();
+               self.origin_x = ReadCoord();
+               self.origin_y = ReadCoord();
+               self.origin_z = ReadCoord();
+               setorigin(self, self.origin);
+               self.mins_x = ReadCoord();
+               self.mins_y = ReadCoord();
+               self.mins_z = ReadCoord();
+               self.maxs_x = ReadCoord();
+               self.maxs_y = ReadCoord();
+               self.maxs_z = ReadCoord();
+               setsize(self, self.mins, self.maxs);
+               self.movedir_x = ReadCoord();
+               self.movedir_y = ReadCoord();
+               self.movedir_z = ReadCoord();
+               self.angles_x = ReadCoord();
+               self.angles_y = ReadCoord();
+               self.angles_z = ReadCoord();
+
+               self.solid = SOLID_TRIGGER;
+               //self.draw = trigger_push_draw;
+               self.drawmask = MASK_ENGINE;
+               self.move_time = time;
+               //self.touch = trigger_push_touch;
+               trigger_push_findtarget();
+       }
+
+       if(sf & 2)
+       {
+               self.team = ReadByte();
+               self.active = ReadByte();
+       }
+}
+
+void ent_target_push()
+{
+       self.classname = "push_target";
+       self.cnt = ReadByte();
+       self.targetname = strzone(ReadString());
+       self.origin_x = ReadCoord();
+       self.origin_y = ReadCoord();
+       self.origin_z = ReadCoord();
+       setorigin(self, self.origin);
+
+       self.drawmask = MASK_ENGINE;
+}
+#endif