]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/mutator/gamemode_ctf.qc
Merge branch 'master' into terencehill/menu_hudskin_selector
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator / gamemode_ctf.qc
index 71db4feba2a8d0528095c1bf18fe9230cf69c0c3..086ab0cc22e7101b8b52532e38ac8613e1040704 100644 (file)
@@ -13,7 +13,7 @@ REGISTER_MUTATOR(ctf, false)
                ctf_Initialize();
 
                ActivateTeamplay();
-               SetLimits(autocvar_capturelimit_override, -1, autocvar_captureleadlimit_override, -1);
+               SetLimits(autocvar_capturelimit_override, autocvar_captureleadlimit_override, -1, -1);
                have_team_spawns = -1; // request team spawns
        }
 
@@ -249,6 +249,7 @@ bool autocvar_g_ctf_flag_dropped_floatinwater;
 bool autocvar_g_ctf_flag_glowtrails;
 int autocvar_g_ctf_flag_health;
 bool autocvar_g_ctf_flag_return;
+bool autocvar_g_ctf_flag_return_carrying;
 float autocvar_g_ctf_flag_return_carried_radius;
 float autocvar_g_ctf_flag_return_time;
 bool autocvar_g_ctf_flag_return_when_unreachable;
@@ -678,6 +679,10 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
        ctf_CaptureShield_Update(player, 0); // shield player from picking up flag
 }
 
+void shockwave_spawn(string m, vector org, float sz, float t1, float t2)
+{
+       return modeleffect_spawn(m, 0, 0, org, '0 0 0', '0 0 0', '0 0 0', 0, sz, 1, t1, t2);
+}
 
 // ==============
 // Event Handlers
@@ -936,7 +941,7 @@ bool ctf_Stalemate_Customize()
        return true;
 }
 
-void ctf_CheckStalemate(void)
+void ctf_CheckStalemate()
 {
        // declarations
        int stale_flags = 0, stale_red_flags = 0, stale_blue_flags = 0, stale_yellow_flags = 0, stale_pink_flags = 0, stale_neutral_flags = 0;
@@ -1235,6 +1240,11 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
                        }
                        else if(CTF_SAMETEAM(toucher, flag) && (toucher.flagcarried) && DIFF_TEAM(toucher.flagcarried, flag) && is_not_monster)
                                ctf_Handle_Capture(flag, toucher, CAPTURE_NORMAL); // toucher just captured the enemies flag to his base
+                       else if(CTF_DIFFTEAM(toucher, flag) && (toucher.flagcarried) && CTF_SAMETEAM(toucher.flagcarried, toucher) && (!toucher.ctf_captureshielded) && autocvar_g_ctf_flag_return_carrying && (time > toucher.next_take_time) && is_not_monster)
+                       {
+                               ctf_Handle_Return(toucher.flagcarried, toucher); // return their current flag
+                               ctf_Handle_Pickup(flag, toucher, PICKUP_BASE); // now pickup the flag
+                       }
                        else if(CTF_DIFFTEAM(toucher, flag) && (!toucher.flagcarried) && (!toucher.ctf_captureshielded) && (time > toucher.next_take_time) && is_not_monster)
                                ctf_Handle_Pickup(flag, toucher, PICKUP_BASE); // toucher just stole the enemies flag
                        break;
@@ -1242,7 +1252,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
 
                case FLAG_DROPPED:
                {
-                       if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1) && flag.team) // automatically return if there's only 1 player on the team
+                       if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried)) && flag.team) // automatically return if there's only 1 player on the team
                                ctf_Handle_Return(flag, toucher); // toucher just returned his own flag
                        else if(is_not_monster && (!toucher.flagcarried) && ((toucher != flag.ctf_dropper) || (time > flag.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
                                ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
@@ -1321,16 +1331,15 @@ void ctf_RespawnFlag(entity flag)
        ctf_CheckStalemate();
 }
 
-void ctf_Reset()
-{SELFPARAM();
-       if(self.owner)
-               if(IS_PLAYER(self.owner))
-                       ctf_Handle_Throw(self.owner, world, DROP_RESET);
+void ctf_Reset(entity this)
+{
+       if(this.owner && IS_PLAYER(this.owner))
+        ctf_Handle_Throw(this.owner, world, DROP_RESET);
 
-       ctf_RespawnFlag(self);
+       ctf_RespawnFlag(this);
 }
 
-void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf_FlagSetup()
+void ctf_DelayedFlagSetup() // called after a flag is placed on a map by ctf_FlagSetup()
 {SELFPARAM();
        // bot waypoints
        waypoint_spawnforitem_force(self, self.origin);
@@ -1356,12 +1365,6 @@ void ctf_DelayedFlagSetup(void) // called after a flag is placed on a map by ctf
        ctf_CaptureShield_Spawn(self);
 }
 
-void set_flag_string(entity flag, .string field, string value, string teamname)
-{
-       if(flag.(field) == "")
-               flag.(field) = strzone(sprintf(value,teamname));
-}
-
 void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
 {SELFPARAM();
        // declarations
@@ -1402,20 +1405,20 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
        if(!flag.scale)                         { flag.scale = FLAG_SCALE; }
        if(flag.skin == 0)                      { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); }
        if(flag.model == "")            { flag.model = cvar_string(sprintf("g_ctf_flag_%s_model", teamname)); }
-       set_flag_string(flag, toucheffect,      "%sflag_touch", teamname);
-       set_flag_string(flag, passeffect,       "%s_pass",              teamname);
-       set_flag_string(flag, capeffect,        "%s_cap",               teamname);
+       if (flag.toucheffect == "") { flag.toucheffect = EFFECT_FLAG_TOUCH(teamnumber).eent_eff_name; }
+       if (flag.passeffect == "")      { flag.passeffect = EFFECT_PASS(teamnumber).eent_eff_name; }
+       if (flag.capeffect == "")       { flag.capeffect = EFFECT_CAP(teamnumber).eent_eff_name; }
 
        // sounds
-       flag.snd_flag_taken = SND(CTF_TAKEN(teamnumber));
-       flag.snd_flag_returned = SND(CTF_RETURNED(teamnumber));
-       flag.snd_flag_capture = SND(CTF_CAPTURE(teamnumber));
-       flag.snd_flag_dropped = SND(CTF_DROPPED(teamnumber));
-       if (flag.snd_flag_respawn == "") flag.snd_flag_respawn = SND(CTF_RESPAWN); // if there is ever a team-based sound for this, update the code to match.
+       flag.snd_flag_taken = strzone(SND(CTF_TAKEN(teamnumber)));
+       flag.snd_flag_returned = strzone(SND(CTF_RETURNED(teamnumber)));
+       flag.snd_flag_capture = strzone(SND(CTF_CAPTURE(teamnumber)));
+       flag.snd_flag_dropped = strzone(SND(CTF_DROPPED(teamnumber)));
+       if (flag.snd_flag_respawn == "") flag.snd_flag_respawn = strzone(SND(CTF_RESPAWN)); // if there is ever a team-based sound for this, update the code to match.
        precache_sound(flag.snd_flag_respawn);
-       if (flag.snd_flag_touch == "") flag.snd_flag_touch = SND(CTF_TOUCH); // again has no team-based sound
+       if (flag.snd_flag_touch == "") flag.snd_flag_touch = strzone(SND(CTF_TOUCH)); // again has no team-based sound
        precache_sound(flag.snd_flag_touch);
-       if (flag.snd_flag_pass == "") flag.snd_flag_pass = SND(CTF_PASS); // same story here
+       if (flag.snd_flag_pass == "") flag.snd_flag_pass = strzone(SND(CTF_PASS)); // same story here
        precache_sound(flag.snd_flag_pass);
 
        // precache