]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Experimental support for QC-driven CTF flag physics
authorMario <zacjardine@y7mail.com>
Fri, 20 Feb 2015 07:10:25 +0000 (18:10 +1100)
committerMario <zacjardine@y7mail.com>
Fri, 20 Feb 2015 07:10:25 +0000 (18:10 +1100)
qcsrc/client/movetypes.qc
qcsrc/client/movetypes.qh
qcsrc/common/triggers/trigger/hurt.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/server/g_damage.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_ctf.qh
qcsrc/server/progs.src

index 2fa5f912213db76341a5d9e66ec93c04ec7b7768..916e6e0bda6119ce72ed1aabd816c10a10860837 100644 (file)
@@ -1,3 +1,5 @@
+#include "../common/physics.qh"
+
 #if defined(CSQC)
        #include "../dpdefs/csprogsdefs.qh"
        #include "defs.qh"
        #include "../server/t_items.qh"
 #elif defined(MENUQC)
 #elif defined(SVQC)
+       #include "../server/autocvars.qh"
 #endif
 
 
+#ifdef SVQC
+#define GRAVITY_UNAFFECTED_BY_TICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
+
+#define TICRATE sys_frametime
+#elif defined(CSQC)
 #define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
 
+#define TICRATE ticrate
+#endif
+
 .entity move_groundentity; // FIXME add move_groundnetworkentity?
 .float move_suspendedinair;
 .float move_didgravity;
@@ -542,16 +553,16 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
                if(GRAVITY_UNAFFECTED_BY_TICRATE)
                {
                        if(self.gravity)
-                               self.move_velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                               self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
                        else
-                               self.move_velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+                               self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY;
                }
                else
                {
                        if(self.gravity)
-                               self.move_velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                               self.move_velocity_z -= dt * self.gravity * PHYS_GRAVITY;
                        else
-                               self.move_velocity_z -= dt * getstatf(STAT_MOVEVARS_GRAVITY);
+                               self.move_velocity_z -= dt * PHYS_GRAVITY;
                }
        }
 
@@ -592,9 +603,9 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
                        bouncefac = self.move_bounce_factor;     if(!bouncefac)  bouncefac = 0.5;
                        bouncestop = self.move_bounce_stopspeed; if(!bouncestop) bouncestop = 60 / 800;
                        if(self.gravity)
-                               bouncestop *= self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                               bouncestop *= self.gravity * PHYS_GRAVITY;
                        else
-                               bouncestop *= getstatf(STAT_MOVEVARS_GRAVITY);
+                               bouncestop *= PHYS_GRAVITY;
 
                        self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1 + bouncefac);
 
@@ -639,9 +650,9 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
        if(!(self.move_flags & FL_ONGROUND))
        {
                if(self.gravity)
-                       self.move_velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                       self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
                else
-                       self.move_velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+                       self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY;
        }
 
        _Movetype_CheckWaterTransition(self);
@@ -663,8 +674,8 @@ void _Movetype_Physics_Frame(float movedt)
                        break;
                case MOVETYPE_NOCLIP:
                        _Movetype_CheckWater(self);
-                       self.move_origin = self.move_origin + ticrate * self.move_velocity;
-                       self.move_angles = self.move_angles + ticrate * self.move_avelocity;
+                       self.move_origin = self.move_origin + TICRATE * self.move_velocity;
+                       self.move_angles = self.move_angles + TICRATE * self.move_avelocity;
                        _Movetype_LinkEdict(false);
                        break;
                case MOVETYPE_STEP:
@@ -702,7 +713,7 @@ void Movetype_Physics_NoMatchServer() // optimized
 
 void Movetype_Physics_MatchServer(bool sloppy)
 {
-       Movetype_Physics_MatchTicrate(ticrate, sloppy);
+       Movetype_Physics_MatchTicrate(TICRATE, sloppy);
 }
 
 void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
@@ -744,16 +755,16 @@ void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
                        if(GRAVITY_UNAFFECTED_BY_TICRATE)
                        {
                                if(self.gravity)
-                                       self.velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                                       self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
                                else
-                                       self.velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+                                       self.velocity_z -= 0.5 * dt * PHYS_GRAVITY;
                        }
                        else
                        {
                                if(self.gravity)
-                                       self.velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                                       self.velocity_z -= dt * self.gravity * PHYS_GRAVITY;
                                else
-                                       self.velocity_z -= dt * getstatf(STAT_MOVEVARS_GRAVITY);
+                                       self.velocity_z -= dt * PHYS_GRAVITY;
                        }
                }
 
@@ -775,9 +786,9 @@ void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
                        if(GRAVITY_UNAFFECTED_BY_TICRATE)
                        {
                                if(self.gravity)
-                                       self.velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+                                       self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
                                else
-                                       self.velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+                                       self.velocity_z -= 0.5 * dt * PHYS_GRAVITY;
                        }
                }
        }
index 41f0bb064f2879ce9889a9a9b1418e99d0ad786c..5fc04936e2d1e45df76f8a00c69afcdec5b3b5c7 100644 (file)
@@ -27,11 +27,14 @@ float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
 void Movetype_Physics_MatchTicrate(float tr, bool sloppy);
 void Movetype_Physics_MatchServer(bool sloppy);
 void Movetype_Physics_NoMatchServer();
+void _Movetype_LinkEdict(float touch_triggers);
+void _Movetype_LinkEdict_TouchAreaGrid();
 
 float _Movetype_UnstickEntity();
 
 const int MAX_CLIP_PLANES = 5;
 
+#ifdef CSQC
 const int MOVETYPE_NONE                                = 0;
 const int MOVETYPE_ANGLENOCLIP     = 1;
 const int MOVETYPE_ANGLECLIP       = 2;
@@ -45,14 +48,21 @@ const int MOVETYPE_FLYMISSILE           = 9;
 const int MOVETYPE_BOUNCE                  = 10;
 const int MOVETYPE_BOUNCEMISSILE       = 11;   // Like bounce but doesn't lose speed on bouncing
 const int MOVETYPE_FOLLOW           = 12;
-const int MOVETYPE_FAKEPUSH         = 13;
 const int MOVETYPE_FLY_WORLDONLY    = 33;
 
 const int FL_ITEM                   = 256;
 const int FL_ONGROUND                          = 512;
+#endif
+
+const int MOVETYPE_FAKEPUSH         = 13;
 
 const float MOVEFLAG_Q2AIRACCELERATE            = 1;
 const float MOVEFLAG_NOGRAVITYONGROUND          = 2;
 const float MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE = 4;
+
+#ifdef CSQC
+// TODO: figure out server's version of this
 #define moveflags (getstati(STAT_MOVEFLAGS))
 #endif
+
+#endif
index 3a15a77ff4d4c3ff69fb1813c3d25886378684a6..433f0350dcf323da25c45ef1c635a750b4d3b4d8 100644 (file)
@@ -61,7 +61,7 @@ void spawnfunc_trigger_hurt()
 {
        EXACTTRIGGER_INIT;
        self.active = ACTIVE_ACTIVE;
-       self.touch = trigger_hurt_touch;
+       self.move_touch = self.touch = trigger_hurt_touch;
        self.use = trigger_hurt_use;
        self.enemy = world; // I hate you all
        if (!self.dmg)
index e852ff4e8ccc83236bf1dd3c5117354ce33a9c0b..d63b3a3935d4a652f024c061138b9600dfc18d1a 100644 (file)
@@ -1,6 +1,7 @@
 // TODO: split target_push and put it in the target folder
 #ifdef SVQC
 #include "jumppads.qh"
+#include "../../../client/movetypes.qh"
 
 void trigger_push_use()
 {
@@ -144,6 +145,7 @@ void trigger_push_touch()
        if(self.enemy)
        {
                other.velocity = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
+               other.move_velocity = other.velocity;
        }
        else if(self.target)
        {
@@ -157,14 +159,18 @@ void trigger_push_touch()
                                RandomSelection_Add(e, 0, string_null, 1, 1);
                }
                other.velocity = trigger_push_calculatevelocity(other.origin, RandomSelection_chosen_ent, self.height);
+               other.move_velocity = other.velocity;
        }
        else
        {
                other.velocity = self.movedir;
+               other.move_velocity = other.velocity;
        }
 
        UNSET_ONGROUND(other);
 
+       other.move_flags &= ~FL_ONGROUND;
+
 #ifdef SVQC
        if (IS_PLAYER(other))
        {
@@ -346,6 +352,29 @@ void trigger_push_link()
 {
        Net_LinkEntity(self, false, 0, trigger_push_send);
 }
+
+void trigger_push_think()
+{
+       self.nextthink = time;
+
+       entity e;
+       if(self.trigger_touch)
+       for(e = findradius((self.absmin + self.absmax) * 0.5, vlen(self.absmax - self.absmin) * 0.5 + 1); e; e = e.chain)
+       {
+               vector emin = e.absmin, emax = e.absmax;
+               if(self.solid == SOLID_BSP)
+               {
+                       emin -= '1 1 1';
+                       emax += '1 1 1';
+               }
+               if(boxesoverlap(emin, emax, self.absmin, self.absmax)) // quick
+               if(WarpZoneLib_BoxTouchesBrush(emin, emax, self, e)) // accurate
+               {
+                       other = e;
+                       self.trigger_touch();
+               }
+       }
+}
 #endif
 #ifdef SVQC
 /*
@@ -368,7 +397,9 @@ void spawnfunc_trigger_push()
 
        self.active = ACTIVE_ACTIVE;
        self.use = trigger_push_use;
-       self.touch = trigger_push_touch;
+       self.trigger_touch = trigger_push_touch;
+       self.think = trigger_push_think;
+       self.nextthink = time;
 
        // normal push setup
        if (!self.speed)
index cb62b61aade688b22925030684f7a7ccafc7c72c..eb784f6796f131391e7fa46e695c231639313222 100644 (file)
@@ -25,6 +25,7 @@
     #include "g_hook.qh"
     #include "scores.qh"
     #include "spawnpoints.qh"
+       #include "../client/movetypes.qh"
 #endif
 
 float Damage_DamageInfo_SendEntity(entity to, float sf)
@@ -917,8 +918,12 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        farcent.think = SUB_Remove;
                }
                else
+               {
                        self.velocity = self.velocity + farce;
+                       self.move_velocity = self.velocity;
+               }
                self.flags &= ~FL_ONGROUND;
+               self.move_flags &= ~FL_ONGROUND;
                UpdateCSQCProjectile(self);
        }
        // apply damage
index 2e6eb4ff732533e927fc4359459ea5fec9f940f6..a040bff121a1caa1ced77eb096e189f6114041fc 100644 (file)
@@ -1,7 +1,4 @@
-// ================================================================
-//  Official capture the flag game mode coding, reworked by Samual
-//  Last updated: September, 2012
-// ================================================================
+#include "../../client/movetypes.qh"
 
 void ctf_FakeTimeLimit(entity e, float t)
 {
@@ -60,24 +57,24 @@ void ctf_CalculatePassVelocity(entity flag, vector to, vector from, float turnra
        if(current_height) // make sure we can actually do this arcing path
        {
                targpos = (to + ('0 0 1' * current_height));
-               WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
+               WarpZone_TraceLine(flag.move_origin, targpos, MOVE_NOMONSTERS, flag);
                if(trace_fraction < 1)
                {
                        //print("normal arc line failed, trying to find new pos...");
                        WarpZone_TraceLine(to, targpos, MOVE_NOMONSTERS, flag);
                        targpos = (trace_endpos + FLAG_PASS_ARC_OFFSET);
-                       WarpZone_TraceLine(flag.origin, targpos, MOVE_NOMONSTERS, flag);
+                       WarpZone_TraceLine(flag.move_origin, targpos, MOVE_NOMONSTERS, flag);
                        if(trace_fraction < 1) { targpos = to; /* print(" ^1FAILURE^7, reverting to original direction.\n"); */ }
                        /*else { print(" ^3SUCCESS^7, using new arc line.\n"); } */
                }
        }
        else { targpos = to; }
 
-       //flag.angles = normalize(('0 1 0' * to_y) - ('0 1 0' * from_y));
+       //flag.move_angles = normalize(('0 1 0' * to_y) - ('0 1 0' * from_y));
 
        vector desired_direction = normalize(targpos - from);
-       if(turnrate) { flag.velocity = (normalize(normalize(flag.velocity) + (desired_direction * autocvar_g_ctf_pass_turnrate)) * autocvar_g_ctf_pass_velocity); }
-       else { flag.velocity = (desired_direction * autocvar_g_ctf_pass_velocity); }
+       if(turnrate) { flag.move_velocity = (normalize(normalize(flag.move_velocity) + (desired_direction * autocvar_g_ctf_pass_turnrate)) * autocvar_g_ctf_pass_velocity); }
+       else { flag.move_velocity = (desired_direction * autocvar_g_ctf_pass_velocity); }
 }
 
 float ctf_CheckPassDirection(vector head_center, vector passer_center, vector passer_angle, vector nearest_to_passer)
@@ -210,9 +207,9 @@ void ctf_Handle_Drop(entity flag, entity player, float droptype)
        player = (player ? player : flag.pass_sender);
 
        // main
-       flag.movetype = MOVETYPE_TOSS;
+       flag.move_movetype = MOVETYPE_TOSS;
        flag.takedamage = DAMAGE_YES;
-       flag.angles = '0 0 0';
+       flag.move_angles = '0 0 0';
        flag.health = flag.max_flag_health;
        flag.ctf_droptime = time;
        flag.ctf_dropper = player;
@@ -260,18 +257,18 @@ void ctf_Handle_Retrieve(entity flag, entity player)
        if(player.vehicle)
        {
                setattachment(flag, player.vehicle, "");
-               setorigin(flag, VEHICLE_FLAG_OFFSET);
+               flag.move_origin = VEHICLE_FLAG_OFFSET;
                flag.scale = VEHICLE_FLAG_SCALE;
        }
        else
        {
                setattachment(flag, player, "");
-               setorigin(flag, FLAG_CARRY_OFFSET);
+               flag.move_origin = VEHICLE_FLAG_OFFSET;
        }
-       flag.movetype = MOVETYPE_NONE;
+       flag.move_movetype = MOVETYPE_NONE;
        flag.takedamage = DAMAGE_NO;
        flag.solid = SOLID_NOT;
-       flag.angles = '0 0 0';
+       flag.move_angles = '0 0 0';
        flag.ctf_status = FLAG_CARRY;
 
        // messages and sounds
@@ -311,14 +308,15 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
 
        // reset the flag
        setattachment(flag, world, "");
-       setorigin(flag, player.origin + FLAG_DROP_OFFSET);
+       flag.move_origin = player.origin + FLAG_DROP_OFFSET;
        flag.owner.flagcarried = world;
        flag.owner = world;
        flag.solid = SOLID_TRIGGER;
        flag.ctf_dropper = player;
        flag.ctf_droptime = time;
 
-       flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
+       flag.move_flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
+       flag.flags = flag.move_flags;
 
        switch(droptype)
        {
@@ -335,7 +333,7 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
                        ctf_CalculatePassVelocity(flag, targ_origin, player.origin, false);
 
                        // main
-                       flag.movetype = MOVETYPE_FLY;
+                       flag.move_movetype = MOVETYPE_FLY;
                        flag.takedamage = DAMAGE_NO;
                        flag.pass_sender = player;
                        flag.pass_target = receiver;
@@ -353,21 +351,21 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
                        makevectors((player.v_angle.y * '0 1 0') + (bound(autocvar_g_ctf_throw_angle_min, player.v_angle.x, autocvar_g_ctf_throw_angle_max) * '1 0 0'));
 
                        flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & IT_STRENGTH) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
-                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, false);
+                       flag.move_velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, false);
                        ctf_Handle_Drop(flag, player, droptype);
                        break;
                }
 
                case DROP_RESET:
                {
-                       flag.velocity = '0 0 0'; // do nothing
+                       flag.move_velocity = '0 0 0'; // do nothing
                        break;
                }
 
                default:
                case DROP_NORMAL:
                {
-                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, (('0 0 1' * autocvar_g_ctf_drop_velocity_up) + ((('0 1 0' * crandom()) + ('1 0 0' * crandom())) * autocvar_g_ctf_drop_velocity_side)), false);
+                       flag.move_velocity = W_CalculateProjectileVelocity(player.velocity, (('0 0 1' * autocvar_g_ctf_drop_velocity_up) + ((('0 1 0' * crandom()) + ('1 0 0' * crandom())) * autocvar_g_ctf_drop_velocity_side)), false);
                        ctf_Handle_Drop(flag, player, droptype);
                        break;
                }
@@ -421,8 +419,8 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
                PlayerScore_Add(player, SP_CTF_CAPTIME, new_time - old_time);
 
        // effects
-       pointparticles(particleeffectnum(flag.capeffect), flag.origin, '0 0 0', 1);
-       //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
+       pointparticles(particleeffectnum(flag.capeffect), flag.move_origin, '0 0 0', 1);
+       //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.move_origin - '0 0 15', -0.8, 0, 1);
 
        // other
        if(capturetype == CAPTURE_NORMAL)
@@ -487,20 +485,20 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
        if(player.vehicle)
        {
                setattachment(flag, player.vehicle, "");
-               setorigin(flag, VEHICLE_FLAG_OFFSET);
+               flag.move_origin = VEHICLE_FLAG_OFFSET;
                flag.scale = VEHICLE_FLAG_SCALE;
        }
        else
        {
                setattachment(flag, player, "");
-               setorigin(flag, FLAG_CARRY_OFFSET);
+               flag.move_origin = FLAG_CARRY_OFFSET;
        }
 
        // flag setup
-       flag.movetype = MOVETYPE_NONE;
+       flag.move_movetype = MOVETYPE_NONE;
        flag.takedamage = DAMAGE_NO;
        flag.solid = SOLID_NOT;
-       flag.angles = '0 0 0';
+       flag.move_angles = '0 0 0';
        flag.ctf_status = FLAG_CARRY;
 
        switch(pickuptype)
@@ -647,6 +645,7 @@ void ctf_CheckStalemate(void)
 
 void ctf_FlagDamage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
+       self.move_velocity = self.velocity;
        if(ITEM_DAMAGE_NEEDKILL(deathtype))
        {
                // automatically kill the flag and return it
@@ -663,13 +662,11 @@ void ctf_FlagDamage(entity inflictor, entity attacker, float damage, float death
        }
 }
 
-void ctf_FlagThink()
+void ctf_FlagUpdate()
 {
        // declarations
        entity tmp_entity;
 
-       self.nextthink = time + FLAG_THINKRATE; // only 5 fps, more is unnecessary.
-
        // captureshield
        if(self == ctf_worldflaglist) // only for the first flag
                FOR_EACH_CLIENT(tmp_entity)
@@ -678,7 +675,7 @@ void ctf_FlagThink()
        // sanity checks
        if(self.mins != FLAG_MIN || self.maxs != FLAG_MAX) { // reset the flag boundaries in case it got squished
                dprint("wtf the flag got squashed?\n");
-               tracebox(self.origin, FLAG_MIN, FLAG_MAX, self.origin, MOVE_NOMONSTERS, self);
+               tracebox(self.move_origin, FLAG_MIN, FLAG_MAX, self.move_origin, MOVE_NOMONSTERS, self);
                if(!trace_startsolid || self.noalign) // can we resize it without getting stuck?
                        setsize(self, FLAG_MIN, FLAG_MAX); }
 
@@ -686,7 +683,7 @@ void ctf_FlagThink()
        {
                case FLAG_DROPPED:
                {
-                       self.angles = '0 0 0';
+                       self.move_angles = '0 0 0';
                        break;
                }
 
@@ -702,7 +699,7 @@ void ctf_FlagThink()
                        {
                                for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
                                        if(tmp_entity.ctf_status == FLAG_DROPPED)
-                                       if(vlen(self.origin - tmp_entity.origin) < autocvar_g_ctf_dropped_capture_radius)
+                                       if(vlen(self.move_origin - tmp_entity.move_origin) < autocvar_g_ctf_dropped_capture_radius)
                                        if(time > tmp_entity.ctf_droptime + autocvar_g_ctf_dropped_capture_delay)
                                                ctf_Handle_Capture(self, tmp_entity, CAPTURE_DROPPED);
                        }
@@ -716,18 +713,18 @@ void ctf_FlagThink()
                                vector midpoint = ((self.absmin + self.absmax) * 0.5);
                                if(pointcontents(midpoint) == CONTENT_WATER)
                                {
-                                       self.velocity = self.velocity * 0.5;
+                                       self.move_velocity = self.move_velocity * 0.5;
 
                                        if(pointcontents(midpoint + FLAG_FLOAT_OFFSET) == CONTENT_WATER)
-                                               { self.velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
+                                               { self.move_velocity_z = autocvar_g_ctf_flag_dropped_floatinwater; }
                                        else
-                                               { self.movetype = MOVETYPE_FLY; }
+                                               { self.move_movetype = MOVETYPE_FLY; }
                                }
-                               else if(self.movetype == MOVETYPE_FLY) { self.movetype = MOVETYPE_TOSS; }
+                               else if(self.move_movetype == MOVETYPE_FLY) { self.move_movetype = MOVETYPE_TOSS; }
                        }
                        if(autocvar_g_ctf_flag_return_dropped)
                        {
-                               if((vlen(self.origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_dropped) || (autocvar_g_ctf_flag_return_dropped == -1))
+                               if((vlen(self.move_origin - self.ctf_spawnorigin) <= autocvar_g_ctf_flag_return_dropped) || (autocvar_g_ctf_flag_return_dropped == -1))
                                {
                                        self.health = 0;
                                        ctf_CheckFlagReturn(self, RETURN_DROPPED);
@@ -771,12 +768,12 @@ void ctf_FlagThink()
                {
                        vector targ_origin = ((self.pass_target.absmin + self.pass_target.absmax) * 0.5);
                        targ_origin = WarpZone_RefSys_TransformOrigin(self.pass_target, self, targ_origin); // origin of target as seen by the flag (us)
-                       WarpZone_TraceLine(self.origin, targ_origin, MOVE_NOMONSTERS, self);
+                       WarpZone_TraceLine(self.move_origin, targ_origin, MOVE_NOMONSTERS, self);
 
                        if((self.pass_target == world)
                                || (self.pass_target.deadflag != DEAD_NO)
                                || (self.pass_target.flagcarried)
-                               || (vlen(self.origin - targ_origin) > autocvar_g_ctf_pass_radius)
+                               || (vlen(self.move_origin - targ_origin) > autocvar_g_ctf_pass_radius)
                                || ((trace_fraction < 1) && (trace_ent != self.pass_target))
                                || (time > self.ctf_droptime + autocvar_g_ctf_pass_timelimit))
                        {
@@ -786,7 +783,7 @@ void ctf_FlagThink()
                        else
                        {
                                // still a viable target, go for it
-                               ctf_CalculatePassVelocity(self, targ_origin, self.origin, true);
+                               ctf_CalculatePassVelocity(self, targ_origin, self.move_origin, true);
                        }
                        return;
                }
@@ -799,6 +796,20 @@ void ctf_FlagThink()
        }
 }
 
+void ctf_FlagThink()
+{
+       self.nextthink = time;
+
+       if(time >= self.ctf_thinkrate)
+       {
+               self.ctf_thinkrate = time + FLAG_THINKRATE;
+               ctf_FlagUpdate();
+       }
+
+       //Movetype_Physics_NoMatchServer();
+       Movetype_Physics_MatchTicrate(sys_frametime, 0);
+}
+
 void ctf_FlagTouch()
 {
        if(gameover) { return; }
@@ -833,7 +844,7 @@ void ctf_FlagTouch()
        {
                if(time > self.wait) // if we haven't in a while, play a sound/effect
                {
-                       pointparticles(particleeffectnum(self.toucheffect), self.origin, '0 0 0', 1);
+                       pointparticles(particleeffectnum(self.toucheffect), self.move_origin, '0 0 0', 1);
                        sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
                        self.wait = time + FLAG_TOUCHRATE;
                }
@@ -912,15 +923,16 @@ void ctf_RespawnFlag(entity flag)
 
        // reset the flag
        setattachment(flag, world, "");
-       setorigin(flag, flag.ctf_spawnorigin);
+       flag.move_origin = flag.ctf_spawnorigin;
 
-       flag.movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS);
+       flag.move_movetype = ((flag.noalign) ? MOVETYPE_NONE : MOVETYPE_TOSS);
        flag.takedamage = DAMAGE_NO;
        flag.health = flag.max_flag_health;
        flag.solid = SOLID_TRIGGER;
-       flag.velocity = '0 0 0';
-       flag.angles = flag.mangle;
-       flag.flags = FL_ITEM | FL_NOTARGET;
+       flag.move_velocity = '0 0 0';
+       flag.move_angles = flag.mangle;
+       flag.move_flags = FL_ITEM | FL_NOTARGET;
+       flag.flags = flag.move_flags;
 
        flag.ctf_status = FLAG_BASE;
        flag.owner = world;
@@ -951,11 +963,16 @@ void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf
        self.bot_basewaypoint = self.nearestwaypoint;
 
        // waypointsprites
+       // move_origin isnt accessible just yet
        WaypointSprite_SpawnFixed(((self.team == NUM_TEAM_1) ? "redbase" : "bluebase"), self.origin + FLAG_WAYPOINT_OFFSET, self, wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, false));
        WaypointSprite_UpdateTeamRadar(self.wps_flagbase, RADARICON_FLAG, colormapPaletteColor(self.team - 1, false));
 
        // captureshield setup
        ctf_CaptureShield_Spawn(self);
+
+       self.move_origin = self.origin;
+       self.move_angles = self.angles;
+       self.move_velocity = self.velocity;
 }
 
 void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
@@ -975,7 +992,8 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
        flag.items = ((teamnumber) ? IT_KEY2 : IT_KEY1); // IT_KEY2: gold key (redish enough) - IT_KEY1: silver key (bluish enough)
        flag.classname = "item_flag_team";
        flag.target = "###item###"; // wut?
-       flag.flags = FL_ITEM | FL_NOTARGET;
+       flag.move_flags = FL_ITEM | FL_NOTARGET;
+       flag.flags = flag.move_flags;
        flag.solid = SOLID_TRIGGER;
        flag.takedamage = DAMAGE_NO;
        flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;
@@ -986,13 +1004,15 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
        flag.teleportable = TELEPORT_NORMAL;
        flag.damagedbytriggers = autocvar_g_ctf_flag_return_when_unreachable;
        flag.damagedbycontents = autocvar_g_ctf_flag_return_when_unreachable;
-       flag.velocity = '0 0 0';
+       flag.move_velocity = '0 0 0';
        flag.mangle = flag.angles;
        flag.reset = ctf_Reset;
        flag.touch = ctf_FlagTouch;
+       flag.move_touch = flag.touch;
        flag.think = ctf_FlagThink;
        flag.nextthink = time + FLAG_THINKRATE;
        flag.ctf_status = FLAG_BASE;
+       flag.move_time = time;
 
        // appearence
        if(flag.model == "")       { flag.model = ((teamnumber) ? autocvar_g_ctf_flag_red_model : autocvar_g_ctf_flag_blue_model); }
@@ -1044,14 +1064,14 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
        {
                flag.dropped_origin = flag.origin;
                flag.noalign = true;
-               flag.movetype = MOVETYPE_NONE;
+               flag.move_movetype = MOVETYPE_NONE;
        }
        else // drop to floor, automatically find a platform and set that as spawn origin
        {
                flag.noalign = false;
                self = flag;
                droptofloor();
-               flag.movetype = MOVETYPE_TOSS;
+               flag.move_movetype = MOVETYPE_TOSS;
        }
 
        InitializeEntity(flag, ctf_DelayedFlagSetup, INITPRIO_SETLOCATION);
@@ -1074,7 +1094,7 @@ void havocbot_calculate_middlepoint()
        f = ctf_worldflaglist;
        while (f)
        {
-               fo = f.origin;
+               fo = f.move_origin;
                s = s + fo;
                f = f.ctf_worldflagnext;
        }
@@ -1218,7 +1238,7 @@ void havocbot_goalrating_ctf_droppedflags(float ratingscale, vector org, float d
                {
                        if(df_radius)
                        {
-                               if(vlen(org-head.origin)<df_radius)
+                               if(vlen(org-head.move_origin)<df_radius)
                                        navigation_routerating(head, ratingscale, 10000);
                        }
                        else
@@ -1382,7 +1402,7 @@ void havocbot_role_ctf_escort()
        // If the flag carrier reached the base switch to defense
        mf = havocbot_ctf_find_flag(self);
        if(mf.ctf_status!=FLAG_BASE)
-       if(vlen(ef.origin - mf.dropped_origin) < 300)
+       if(vlen(ef.move_origin - mf.dropped_origin) < 300)
        {
                havocbot_role_ctf_setrole(self, HAVOCBOT_CTF_ROLE_DEFENSE);
                return;
@@ -1441,7 +1461,7 @@ void havocbot_role_ctf_offense()
                if(mf.tag_entity)
                        pos = mf.tag_entity.origin;
                else
-                       pos = mf.origin;
+                       pos = mf.move_origin;
 
                // Try to get it if closer than the enemy base
                if(vlen(self.origin-ef.dropped_origin)>vlen(self.origin-pos))
@@ -1457,7 +1477,7 @@ void havocbot_role_ctf_offense()
                if(ef.tag_entity)
                        pos = ef.tag_entity.origin;
                else
-                       pos = ef.origin;
+                       pos = ef.move_origin;
 
                if(vlen(pos-mf.dropped_origin)>700)
                {
@@ -1954,9 +1974,9 @@ MUTATOR_HOOKFUNCTION(ctf_VehicleEnter)
                else
                {
                        setattachment(vh_player.flagcarried, vh_vehicle, "");
-                       setorigin(vh_player.flagcarried, VEHICLE_FLAG_OFFSET);
+                       vh_player.flagcarried.move_origin = VEHICLE_FLAG_OFFSET;
                        vh_player.flagcarried.scale = VEHICLE_FLAG_SCALE;
-                       //vh_player.flagcarried.angles = '0 0 0';
+                       //vh_player.flagcarried.move_angles = '0 0 0';
                }
                return true;
        }
@@ -1969,9 +1989,9 @@ MUTATOR_HOOKFUNCTION(ctf_VehicleExit)
        if(vh_player.flagcarried)
        {
                setattachment(vh_player.flagcarried, vh_player, "");
-               setorigin(vh_player.flagcarried, FLAG_CARRY_OFFSET);
+               vh_player.flagcarried.move_origin = VEHICLE_FLAG_OFFSET;
                vh_player.flagcarried.scale = FLAG_SCALE;
-               vh_player.flagcarried.angles = '0 0 0';
+               vh_player.flagcarried.move_angles = '0 0 0';
                return true;
        }
 
@@ -2002,7 +2022,7 @@ MUTATOR_HOOKFUNCTION(ctf_MatchEnd)
                        case FLAG_PASSING:
                        {
                                // lock the flag, game is over
-                               flag.movetype = MOVETYPE_NONE;
+                               flag.move_movetype = MOVETYPE_NONE;
                                flag.takedamage = DAMAGE_NO;
                                flag.solid = SOLID_NOT;
                                flag.nextthink = false; // stop thinking
index 0e5930db2cbe83c95b439e8f75461cdce64eda7f..5d57dced798d7757ed8b3a086d2eec78e8842ab0 100644 (file)
@@ -103,6 +103,7 @@ float ctf_captimerecord; // record time for capturing the flag
 .entity ctf_dropper; // don't allow spam of dropping the flag
 .float max_flag_health;
 .float next_take_time;
+.float ctf_thinkrate;
 
 // passing/throwing properties
 .float pass_distance;
index cd62a169f333c03d51e317ecd2fd5a8593523e66..d407a4d66d664e0e8e1d74436ada61cb3606bce2 100644 (file)
@@ -74,6 +74,8 @@ weapons/tracing.qc
 weapons/weaponstats.qc
 weapons/weaponsystem.qc
 
+../client/movetypes.qc
+
 ../common/animdecide.qc
 ../common/buffs.qc
 ../common/campaign_file.qc