]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move pass/throw/drop code out of the event handler section and give it a special...
authorSamual <samual@xonotic.org>
Sat, 31 Mar 2012 20:35:37 +0000 (16:35 -0400)
committerSamual <samual@xonotic.org>
Sat, 31 Mar 2012 20:35:37 +0000 (16:35 -0400)
defaultXonotic.cfg
qcsrc/server/autocvars.qh
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_ctf.qh

index 52713c2e9d516f26cb80b5272bee322090748d05..f723560b4a31885a1c1cd2b10f822e14a71e827f 100644 (file)
@@ -612,6 +612,7 @@ set g_ctf_allow_pass 1 "allow passing of flags to nearby team mates"
 set g_ctf_pass_radius 200 "maximum radius that you can pass to a team mate in"
 set g_ctf_pass_wait 2 "delay in seconds between how often players can pass the flag (antispam, essentially)"
 set g_ctf_dropped_capture_radius 100 "allow dropped flags to be automatically captured by base flags if the dropped flag is within this radius of it"
+set g_ctf_pass_request 1 "allow players to request the flag carrier to pass the flag to them"
 
 set g_ctf_shield_max_ratio 0   "shield at most this percentage of a team from the enemy flag (try: 0.4 for 40%)"
 set g_ctf_shield_min_negscore 20       "shield the player from the flag if he's got this negative amount of points or less"
index 966965b4b1e61a9afc057fefd1ee7e900f004b7f..fa8661673e20efca7f72b20d980ad217d3e6836d 100644 (file)
@@ -764,6 +764,7 @@ float autocvar_g_ctf_allow_drop;
 float autocvar_g_ctf_allow_pass;
 float autocvar_g_ctf_pass_radius;
 float autocvar_g_ctf_pass_wait;
+float autocvar_g_ctf_pass_request;
 float autocvar_g_ctf_throw_velocity;
 float autocvar_g_ctf_captimerecord_always;
 float autocvar_g_ctf_dynamiclights;
index 3d79134e8402553f298c5de3ce3e8c6c69544a67..a443dba61b32b0be5cfd117f20d2596ea49511d4 100644 (file)
@@ -28,6 +28,38 @@ void ctf_EventLog(string mode, float flagteam, entity actor) // use an alias for
                GameLogEcho(strcat(":ctf:", mode, ":", ftos(flagteam), ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
 }
 
+string ctf_CaptureRecord(entity player, entity flag)
+{
+       float cap_time, cap_record, success;
+       string cap_message, refername;
+       
+       if((autocvar_g_ctf_captimerecord_always) || (player_count - currentbots)) 
+       {
+               cap_record = ctf_captimerecord;
+               cap_time = (time - flag.ctf_pickuptime);
+
+               refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
+               refername = ((refername == player.netname) ? "their" : strcat(refername, "^7's"));
+
+               if(!ctf_captimerecord) 
+                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds"); success = TRUE; }
+               else if(cap_time < cap_record) 
+                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, breaking ", refername, " previous record of ", ftos_decimals(cap_record, 2), " seconds"); success = TRUE; }
+               else
+                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, failing to break ", refername, " record of ", ftos_decimals(cap_record, 2), " seconds"); success = FALSE; }
+
+               if(success) 
+               {
+                       ctf_captimerecord = cap_time;
+                       db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
+                       db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
+                       write_recordmarker(player, (time - cap_time), cap_time); 
+               } 
+       }
+       
+       return cap_message;
+}
+
 
 // =======================
 // CaptureShield Functions 
@@ -120,17 +152,59 @@ void ctf_CaptureShield_Spawn(entity flag)
        setsize(shield, shield.scale * shield.mins, shield.scale * shield.maxs);
 }
 
+// ====================
+// Drop/Pass/Throw Code
+// ====================
 
-// ==============
-// Event Handlers
-// ==============
+void ctf_Handle_Recieve(entity player, entity reciever)
+{
+       entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
+       entity flag = player.flagcarried;
+       if(!flag) { return; }
+       if(time < flag.pass_antispam) { return; } // antispam of passing
+       
+       // reset player
+       player.flagcarried = world;
+       WaypointSprite_Ping(player.wps_flagcarrier);
+       WaypointSprite_Kill(player.wps_flagcarrier);
+       
+       // transfer flag to reciever
+       flag.owner = reciever;
+       flag.owner.flagcarried = flag;
+       flag.ctf_pickupper = reciever;
+       setattachment(flag, reciever, "");
+       setorigin(flag, FLAG_CARRY_OFFSET);
+
+       // messages and sounds
+       sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTN_NORM);
+       ctf_EventLog("pass", flag.team, player);
+       ctf_EventLog("recieve", flag.team, reciever);
+       FOR_EACH_PLAYER(tmp_player)
+               if(tmp_player == player)
+                       centerprint(tmp_player, strcat("You passed the ", flag.netname, " to ", reciever.netname));
+               else if(tmp_player == reciever)
+                       centerprint(tmp_player, strcat("You recieved the ", flag.netname, " from ", player.netname));
+               else if(tmp_player.team == player.team)
+                       centerprint(tmp_player, strcat(player.netname, " passed the ", flag.netname, " to ", reciever.netname));
+                       
+       // effects
+       te_lightning2(world, reciever.origin, player.origin);
+       
+       // create new waypoint
+       WaypointSprite_Spawn("flagcarrier", 0, 0, reciever, '0 0 64', world, reciever.team, reciever, wps_flagcarrier, FALSE, RADARICON_FLAG, '1 1 0');
+       WaypointSprite_UpdateMaxHealth(reciever.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(start_health, start_armorvalue, autocvar_g_balance_armor_blockpercent) * 2);
+       WaypointSprite_UpdateHealth(reciever.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(reciever.health, reciever.armorvalue, autocvar_g_balance_armor_blockpercent));
+       WaypointSprite_UpdateTeamRadar(reciever.wps_flagcarrier, RADARICON_FLAGCARRIER, '1 1 0');
+       
+       flag.pass_antispam = time + autocvar_g_ctf_pass_wait;
+}
 
 void ctf_Handle_Pass(entity player, entity reciever)
 {
        entity tmp_player; // temporary entity which the FOR_EACH_PLAYER loop uses to scan players
        entity flag = player.flagcarried;
        if(!flag) { return; }
-       if(time < flag.wait) { return; } // antispam of passing
+       if(time < flag.pass_antispam) { return; } // antispam of passing
        
        // reset player
        player.flagcarried = world;
@@ -165,7 +239,7 @@ void ctf_Handle_Pass(entity player, entity reciever)
        WaypointSprite_UpdateHealth(reciever.wps_flagcarrier, '1 0 0' * healtharmor_maxdamage(reciever.health, reciever.armorvalue, autocvar_g_balance_armor_blockpercent));
        WaypointSprite_UpdateTeamRadar(reciever.wps_flagcarrier, RADARICON_FLAGCARRIER, '1 1 0');
        
-       flag.wait = time + autocvar_g_ctf_pass_wait;
+       flag.pass_antispam = time + autocvar_g_ctf_pass_wait;
 }
 
 void ctf_Handle_Drop(entity player, float droptype)
@@ -238,40 +312,22 @@ void ctf_Handle_Drop(entity player, float droptype)
                dprint("FLAG FALLTHROUGH will happen SOON\n");
 }
 
+
+// ==============
+// Event Handlers
+// ==============
+
 void ctf_Handle_Dropped_Capture(entity flag, entity enemy_flag)
 {
        // declarations
-       float cap_time, cap_record, success;
-       string cap_message, refername;
-       
+       string cap_message;
        entity player = enemy_flag.ctf_dropper;
        
        if not(player) { return; } // without someone to give the reward to, we can't possibly cap
-
-       // records
-       if((autocvar_g_ctf_captimerecord_always) || (player_count - currentbots)) {
-               cap_record = ctf_captimerecord;
-               cap_time = (time - enemy_flag.ctf_pickuptime);
-
-               refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
-               refername = ((refername == player.netname) ? "their" : strcat(refername, "^7's"));
-
-               if(!ctf_captimerecord) 
-                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds"); success = TRUE; }
-               else if(cap_time < cap_record) 
-                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, breaking ", refername, " previous record of ", ftos_decimals(cap_record, 2), " seconds"); success = TRUE; }
-               else
-                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, failing to break ", refername, " record of ", ftos_decimals(cap_record, 2), " seconds"); success = FALSE; }
-
-               if(success) {
-                       ctf_captimerecord = cap_time;
-                       db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
-                       db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
-                       write_recordmarker(player, (time - cap_time), cap_time); } }
        
        // messages and sounds
-       Send_KillNotification(player.netname, enemy_flag.netname, cap_message, INFO_CAPTUREFLAG, MSG_INFO);
-       sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTN_NONE); // "ctf/*_capture.wav"
+       Send_KillNotification(player.netname, enemy_flag.netname, ctf_CaptureRecord(player, enemy_flag), INFO_CAPTUREFLAG, MSG_INFO);
+       sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTN_NONE);
        ctf_EventLog("droppedcapture", enemy_flag.team, player);
        
        // scoring
@@ -279,7 +335,7 @@ void ctf_Handle_Dropped_Capture(entity flag, entity enemy_flag)
        PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, 1);
 
        // effects
-       if (autocvar_g_ctf_flag_capture_effects) 
+       if(autocvar_g_ctf_flag_capture_effects) 
        {
                pointparticles(particleeffectnum((player.team == COLOR_TEAM1) ? "red_ground_quake" : "blue_ground_quake"), flag.origin, '0 0 0', 1);
                //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
@@ -291,34 +347,9 @@ void ctf_Handle_Dropped_Capture(entity flag, entity enemy_flag)
 
 void ctf_Handle_Capture(entity flag, entity player)
 {
-       // declarations
-       float cap_time, cap_record, success;
-       string cap_message, refername;
-
-       // records
-       if((autocvar_g_ctf_captimerecord_always) || (player_count - currentbots)) {
-               cap_record = ctf_captimerecord;
-               cap_time = (time - player.flagcarried.ctf_pickuptime);
-
-               refername = db_get(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"));
-               refername = ((refername == player.netname) ? "their" : strcat(refername, "^7's"));
-
-               if(!ctf_captimerecord) 
-                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds"); success = TRUE; }
-               else if(cap_time < cap_record) 
-                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, breaking ", refername, " previous record of ", ftos_decimals(cap_record, 2), " seconds"); success = TRUE; }
-               else
-                       { cap_message = strcat(" in ", ftos_decimals(cap_time, 2), " seconds, failing to break ", refername, " record of ", ftos_decimals(cap_record, 2), " seconds"); success = FALSE; }
-
-               if(success) {
-                       ctf_captimerecord = cap_time;
-                       db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/time"), ftos(cap_time));
-                       db_put(ServerProgsDB, strcat(GetMapname(), "/captimerecord/netname"), player.netname);
-                       write_recordmarker(player, (time - cap_time), cap_time); } }
-       
        // messages and sounds
-       Send_KillNotification(player.netname, player.flagcarried.netname, cap_message, INFO_CAPTUREFLAG, MSG_INFO);
-       sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTN_NONE); // "ctf/*_capture.wav"
+       Send_KillNotification(player.netname, player.flagcarried.netname, ctf_CaptureRecord(player, flag), INFO_CAPTUREFLAG, MSG_INFO);
+       sound(player, CH_TRIGGER, flag.snd_flag_capture, VOL_BASE, ATTN_NONE);
        ctf_EventLog("capture", player.flagcarried.team, player);
        
        // scoring
@@ -326,7 +357,7 @@ void ctf_Handle_Capture(entity flag, entity player)
        PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, 1);
 
        // effects
-       if (autocvar_g_ctf_flag_capture_effects) 
+       if(autocvar_g_ctf_flag_capture_effects) 
        {
                pointparticles(particleeffectnum((player.team == COLOR_TEAM1) ? "red_ground_quake" : "blue_ground_quake"), flag.origin, '0 0 0', 1);
                //shockwave_spawn("models/ctf/shockwavetransring.md3", flag.origin - '0 0 15', -0.8, 0, 1);
@@ -855,34 +886,39 @@ MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
 {
        entity player = self;
 
-       if((player.flagcarried) && !(player.speedrunning))
+       // pass the flag to a team mate
+       if(autocvar_g_ctf_allow_pass && (time > player.pass_antispam))
        {
-               if(autocvar_g_ctf_allow_pass)
+               entity head, closest_target;
+               head = findradius(player.origin, autocvar_g_ctf_pass_radius);
+               
+               while(head) // find the closest acceptable target to pass to
                {
-                       entity head, closest_target;
-                       head = findradius(player.origin, autocvar_g_ctf_pass_radius);
-                       
-                       while(head) // find the closest acceptable target to pass to
+                       if(head.classname == "player" && head.deadflag == DEAD_NO)
+                       if(head != player && !IsDifferentTeam(head, player))
+                       if(!player.speedrunning && !head.speedrunning)
                        {
-                               if(head.classname == "player" && head.deadflag == DEAD_NO)
-                               if(head != player && !IsDifferentTeam(head, player))
+                               if(autocvar_g_ctf_pass_request && head.flagcarried) 
+                               { 
+                                       centerprint(head, strcat(player.netname, " requests you to pass the ", head.flagcarried.netname)); 
+                                       player.pass_antispam = time + autocvar_g_ctf_pass_wait; 
+                                       return 0; 
+                               }
+                               else if(player.flagcarried)
                                {
-                                       if(closest_target)
-                                       {
-                                               if(vlen(player.origin - head.origin) < vlen(player.origin - closest_target.origin))
-                                                       closest_target = head;
-                                       }
-                                       else 
-                                               closest_target = head;
+                                       if(closest_target) { if(vlen(player.origin - head.origin) < vlen(player.origin - closest_target.origin)) { closest_target = head; } }
+                                       else { closest_target = head; }
                                }
-                               head = head.chain;
                        }
-                       
-                       if(closest_target) { ctf_Handle_Pass(player, closest_target); return 0; }
+                       head = head.chain;
                }
                
-               if(autocvar_g_ctf_allow_drop) { ctf_Handle_Drop(player, DROPTYPE_THROWN); }
+               if(closest_target) { ctf_Handle_Pass(player, closest_target); return 0; }
        }
+       
+       // throw the flag in front of you
+       if(autocvar_g_ctf_allow_drop && player.flagcarried && !player.speedrunning)
+               { ctf_Handle_Drop(player, DROPTYPE_THROWN); }
                
        return 0;
 }
index 09a05a75c9dc20967df42c3bedcb56a8bd1791ac..6d80ffdf49590d887b26344de9ec764fc5080b42 100644 (file)
@@ -56,6 +56,7 @@ entity ctf_worldflaglist;
 #define FLAG_BASE 1
 #define FLAG_CARRY 2
 #define FLAG_DROPPED 3
+#define FLAG_PASSING 4
 
 #define DROPTYPE_NORMAL 1
 #define DROPTYPE_THROWN 2
@@ -70,6 +71,9 @@ float ctf_captimerecord; // record time for capturing the flag
 .entity ctf_pickupper;
 .entity ctf_dropper; // don't allow spam of dropping the flag
 
+// other properties
+.float pass_antispam;
+
 // CaptureShield: If the player is too bad to be allowed to capture, shield them from taking the flag.
 .float ctf_captureshielded; // set to 1 if the player is too bad to be allowed to capture
 float ctf_captureshield_min_negscore; // punish at -20 points