]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/gamemode_ctf.qc
Add support for old (Quake 3/Live) oneflag maps
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / gamemode_ctf.qc
index 4afec770e4fd96d400c92dd4c91ff3c6877ae8c2..87447880e5f0d51c065a5bf01bf02ff6a6f7da30 100644 (file)
@@ -1,4 +1,5 @@
 #include "../../common/effects.qh"
+#include "../../common/movetypes/movetypes.qh"
 
 void ctf_FakeTimeLimit(entity e, float t)
 {
@@ -89,13 +90,11 @@ float ctf_CheckPassDirection(vector head_center, vector passer_center, vector pa
                makevectors(passer_angle);
 
                // find the closest point on the enemy to the center of the attack
-               float ang; // angle between shotdir and h
                float h; // hypotenuse, which is the distance between attacker to head
                float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
 
                h = vlen(head_center - passer_center);
-               ang = acos(dotproduct(normalize(head_center - passer_center), v_forward));
-               a = h * cos(ang);
+               a = h * (normalize(head_center - passer_center) * v_forward);
 
                vector nearest_on_line = (passer_center + a * v_forward);
                float distance_from_line = vlen(nearest_to_passer - nearest_on_line);
@@ -377,7 +376,7 @@ 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)));
+                       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);
                        ctf_Handle_Drop(flag, player, droptype);
                        break;
@@ -736,6 +735,7 @@ void ctf_CheckStalemate(void)
 
 void ctf_FlagDamage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
+       self.velocity = self.velocity;
        if(ITEM_DAMAGE_NEEDKILL(deathtype))
        {
                if(autocvar_g_ctf_flag_return_damage_delay)
@@ -758,13 +758,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)
@@ -907,6 +905,22 @@ void ctf_FlagThink()
        }
 }
 
+void ctf_FlagThink()
+{
+       self.nextthink = time + FLAG_THINKRATE;
+
+       ctf_FlagUpdate();
+
+       /*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; }
@@ -1105,6 +1119,10 @@ void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf
 
        // captureshield setup
        ctf_CaptureShield_Spawn(self);
+
+       //self.move_origin = self.origin;
+       //self.angles = self.angles;
+       //self.velocity = self.velocity;
 }
 
 void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
@@ -2152,6 +2170,8 @@ MUTATOR_HOOKFUNCTION(ctf_VehicleEnter)
 {
        if(vh_player.flagcarried)
        {
+               vh_player.flagcarried.nodrawtoclient = vh_player; // hide the flag from the driver
+
                if(!autocvar_g_ctf_allow_vehicle_carry && !autocvar_g_ctf_allow_vehicle_touch)
                {
                        ctf_Handle_Throw(vh_player, world, DROP_NORMAL);
@@ -2174,9 +2194,10 @@ MUTATOR_HOOKFUNCTION(ctf_VehicleExit)
        if(vh_player.flagcarried)
        {
                setattachment(vh_player.flagcarried, vh_player, "");
-               setorigin(vh_player.flagcarried, FLAG_CARRY_OFFSET);
+               setorigin(vh_player.flagcarried, VEHICLE_FLAG_OFFSET);
                vh_player.flagcarried.scale = FLAG_SCALE;
                vh_player.flagcarried.angles = '0 0 0';
+               vh_player.flagcarried.nodrawtoclient = world;
                return true;
        }
 
@@ -2400,6 +2421,9 @@ void spawnfunc_team_CTF_blueplayer() { spawnfunc_info_player_team2();  }
 void spawnfunc_team_CTF_redspawn()   { spawnfunc_info_player_team1();  }
 void spawnfunc_team_CTF_bluespawn()  { spawnfunc_info_player_team2();  }
 
+void team_CTF_neutralflag()                     { spawnfunc_item_flag_neutral();  }
+void team_neutralobelisk()                      { spawnfunc_item_flag_neutral();  }
+
 
 // ==============
 // Initialization