]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
New passing/dropping system, flags are now "thrown" instead of dropped, and some...
authorSamual <samual@xonotic.org>
Sat, 31 Mar 2012 00:07:19 +0000 (20:07 -0400)
committerSamual <samual@xonotic.org>
Sat, 31 Mar 2012 00:07:19 +0000 (20:07 -0400)
defaultXonotic.cfg
qcsrc/client/announcer.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_ctf.qh
qcsrc/server/portals.qc

index 14701d62f6ffbd6f981f317c012dade42173cfd8..52138f06a8be86001bf44b41c6c5b4e3ba112d7a 100644 (file)
@@ -605,6 +605,10 @@ set g_ctf_flag_take_damage 0
 set g_ctf_flag_dropped_waypoint 2 "show dropped flag waypointsprite when a flag is lost. 1 = team only, 2 = for all players"
 set g_ctf_flag_pickup_verbosename 1 "show the name of the person who picked up the flag too"
 set g_ctf_flag_return_when_unreachable 1 "automatically return the flag if it falls into lava/slime/trigger hurt"
+set g_ctf_throw_velocity 500 "how far a player can throw the flag"
+set g_ctf_allow_pass 0 "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_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 3e109e78052036fd77f33f88b5138e12844f4418..db1ae41336d5e1eb54d30c437975b7323b330739 100644 (file)
@@ -134,52 +134,10 @@ void Announcer_Time()
        }
 }
 
-float redflag_prev;
-float blueflag_prev;
-void carrierAnnouncer() {
-       float stat_items, redflag, blueflag;
-       float pickup;
-       string item;
-
-       if not(autocvar_cl_notify_carried_items)
-               return;
-
-       stat_items = getstati(STAT_ITEMS);
-
-       redflag = (stat_items/IT_RED_FLAG_TAKEN) & 3;
-       blueflag = (stat_items/IT_BLUE_FLAG_TAKEN) & 3;
-
-       if (redflag == 3 && redflag != redflag_prev) {
-               item = _("^1RED^7 flag");
-               pickup = (redflag_prev == 2);
-       }
-
-       if (blueflag == 3 && blueflag != blueflag_prev) {
-               item = _("^4BLUE^7 flag");
-               pickup = (blueflag_prev == 2);
-       }
-
-       if (item)
-       {
-               if (pickup) {
-                       if (autocvar_cl_notify_carried_items & 2)
-                               centerprint_hud(sprintf(_("You picked up the %s!"), item));
-               }
-               else {
-                       if (autocvar_cl_notify_carried_items & 1)
-                               centerprint_hud(sprintf(_("You got the %s!"), item));
-               }
-       }
-
-       blueflag_prev = blueflag;
-       redflag_prev = redflag;
-}
-
 void Announcer()
 {
        Announcer_Gamestart();
        Announcer_Time();
-       carrierAnnouncer();
 }
 
 void Announcer_Precache () 
index c808577254a94e7710e34d3c1521871401ca5a8b..79a81a6b73181cb6c58ed256c416b96ede0b0945 100644 (file)
@@ -761,6 +761,9 @@ float autocvar_g_chat_flood_spl_tell;
 float autocvar_g_chat_nospectators;
 float autocvar_g_chat_teamcolors;
 float autocvar_g_ctf_allow_drop;
+float autocvar_g_ctf_allow_pass;
+float autocvar_g_ctf_pass_radius;
+float autocvar_g_ctf_throw_velocity;
 float autocvar_g_ctf_captimerecord_always;
 float autocvar_g_ctf_dynamiclights;
 string autocvar_g_ctf_flag_blue_model;
index 5d630057e4864c908b312e6c3a879054b255ceeb..d80770f97b00202b7f2e4adadd68772db7110b57 100644 (file)
@@ -417,9 +417,6 @@ void PutObserverInServer (void)
        if(self.vehicle)
            vehicles_exit(VHEF_RELESE);
 
-       if(self.flagcarried)
-               ctf_Handle_Drop(self); // FIXCTF
-
        WaypointSprite_PlayerDead();
 
        if not(g_ca)  // don't reset teams when moving a ca player to the spectators
@@ -1652,8 +1649,6 @@ void ClientDisconnect (void)
        Portal_ClearAll(self);
 
        RemoveGrapplingHook(self);
-       if(self.flagcarried)
-               ctf_Handle_Drop(self); // FIXCTF
 
        // Here, everything has been done that requires this player to be a client.
 
index 54468b34faebab0434b33754dd5966f224e74ca3..475171161c153309733d323553d4d28074ed9320 100644 (file)
@@ -693,16 +693,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                RemoveGrapplingHook(self);
 
-               if(self.flagcarried)
-               {
-                       // FIXCTF
-                       if(attacker.classname != "player")
-                               ctf_Handle_Drop(self); // penalty for flag loss by suicide
-                       else if(attacker.team == self.team)
-                               ctf_Handle_Drop(self); // penalty for flag loss by suicide/teamkill
-                       else
-                               ctf_Handle_Drop(self);
-               }
                Portal_ClearAllLater(self);
 
                if(clienttype(self) == CLIENTTYPE_REAL)
index 097f213b6bfa3040af401e20434d26dd11e50b74..c5cfa39366250764aa3b4df638e2f13cc80261a2 100644 (file)
@@ -16,8 +16,6 @@ noref float require_spawnfunc_prefix; // if this float exists, only functions wi
 
 // Globals
 
-float ctf_ReadScore(string parameter); // SOON WON'T BE NEEDED. // FIXCTF
-
 float g_cloaked, g_footsteps, g_jump_grunt, g_grappling_hook, g_midair, g_minstagib, g_pinata, g_norecoil, g_minstagib_invis_alpha, g_bloodloss;
 float g_warmup_limit;
 float g_warmup_allguns;
@@ -342,7 +340,6 @@ string gamemode_name;
 
 float startitem_failed;
 
-void ctf_Handle_Drop(entity player); // FIXCTF
 void DropAllRunes(entity pl);
 
 
index d57c565c9cc7594d30fc795fdbd5bfb5cb239a2e..e2174480baa6e51a831b4d62e520f359f337b9c1 100644 (file)
@@ -125,7 +125,7 @@ void ctf_CaptureShield_Spawn(entity flag)
 // Event Handlers
 // ==============
 
-void ctf_Handle_Drop(entity player)
+void ctf_Handle_Pass(entity player)
 {
        entity flag = player.flagcarried;
 
@@ -179,6 +179,77 @@ void ctf_Handle_Drop(entity player)
                dprint("FLAG FALLTHROUGH will happen SOON\n");
 }
 
+void ctf_Handle_Drop(entity player, float droptype)
+{
+       entity flag = player.flagcarried;
+
+       if(!flag) { return; }
+       if(flag.speedrunning) { ctf_RespawnFlag(flag); return; }
+       
+       makevectors((player.v_angle_y * '0 1 0') + (player.v_angle_x * '0.5 0 0'));
+       
+       // reset the flag
+       setattachment(flag, world, "");
+       setorigin(flag, player.origin + FLAG_DROP_OFFSET);
+       flag.owner.flagcarried = world;
+       flag.owner = world;
+       flag.movetype = MOVETYPE_TOSS;
+       flag.solid = SOLID_TRIGGER;
+       flag.takedamage = DAMAGE_YES;
+       flag.health = flag.max_flag_health;
+       
+       switch(droptype)
+       {
+               case DROPTYPE_THROWN:
+               {
+                       flag.velocity = W_CalculateProjectileVelocity(player.velocity, ('0 0 200' + (v_forward * autocvar_g_ctf_throw_velocity)), FALSE);
+                       break;
+               }
+               
+               default:
+               case DROPTYPE_NORMAL:
+               {
+                       flag.velocity = ('0 0 200' + ('0 100 0' * crandom()) + ('100 0 0' * crandom()));
+                       break;
+               }
+       }
+       
+       flag.ctf_droptime = time;
+       flag.ctf_dropperid = player.playerid;
+       flag.ctf_status = FLAG_DROPPED;
+
+       // messages and sounds
+       Send_KillNotification(player.netname, flag.netname, "", INFO_LOSTFLAG, MSG_INFO);
+       sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTN_NONE);
+       ctf_EventLog("dropped", player.team, player);
+       
+       // scoring
+       PlayerTeamScore_AddScore(player, -ctf_ReadScore("penalty_drop"));       
+       PlayerScore_Add(player, SP_CTF_DROPS, 1);
+
+       // waypoints
+       if(autocvar_g_ctf_flag_dropped_waypoint)
+               WaypointSprite_Spawn("flagdropped", 0, 0, flag, '0 0 64', world, ((autocvar_g_ctf_flag_dropped_waypoint == 2) ? 0 : player.team), flag, wps_flagdropped, FALSE, RADARICON_FLAG, '0 0.5 0' + ((flag.team == COLOR_TEAM1) ? '0.75 0 0' : '0 0 0.75')); // (COLOR_TEAM1 + COLOR_TEAM2 - flag.team)
+       
+       WaypointSprite_Ping(player.wps_flagcarrier);
+       WaypointSprite_Kill(player.wps_flagcarrier);
+
+       if(autocvar_g_ctf_flag_returntime || (autocvar_g_ctf_flag_take_damage && autocvar_g_ctf_flag_health))
+       {
+               WaypointSprite_UpdateMaxHealth(flag.wps_flagdropped, flag.max_flag_health);
+               WaypointSprite_UpdateHealth(flag.wps_flagdropped, flag.health);
+       }
+
+       // captureshield
+       ctf_CaptureShield_Update(player, 0); // shield only
+
+       // check if the flag will fall off the map
+       trace_startsolid = FALSE;
+       tracebox(flag.origin, flag.mins, flag.maxs, flag.origin, TRUE, flag);
+       if(trace_startsolid)
+               dprint("FLAG FALLTHROUGH will happen SOON\n");
+}
+
 void ctf_Handle_Capture(entity flag, entity player)
 {
        // declarations
@@ -234,6 +305,7 @@ void ctf_Handle_Capture(entity flag, entity player)
 void ctf_Handle_Return(entity flag, entity player)
 {
        // messages and sounds
+       //centerprint(player, strcat("You returned ", flag.netname));
        Send_KillNotification (player.netname, flag.netname, "", INFO_RETURNFLAG, MSG_INFO);
        sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTN_NONE);
        ctf_EventLog("return", flag.team, player);
@@ -279,10 +351,12 @@ void ctf_Handle_Pickup_Base(entity flag, entity player)
        ctf_EventLog("steal", flag.team, player);
        verbosename = ((autocvar_g_ctf_flag_pickup_verbosename) ? strcat(Team_ColorCode(player.team), "(^7", player.netname, Team_ColorCode(player.team), ") ") : "");
        FOR_EACH_PLAYER(tmp_player)
-               if(tmp_player.team == flag.team)
-                       centerprint(tmp_player, strcat("The ", Team_ColorCode(player.team), "enemy ", verbosename, "^7got your flag! Retrieve it!"));
-               else if((tmp_player.team == player.team) && (tmp_player != player))
+               if(tmp_player == player)
+                       centerprint(tmp_player, strcat("You got the ", flag.netname, "!"));
+               else if(tmp_player.team == player.team)
                        centerprint(tmp_player, strcat("Your ", Team_ColorCode(player.team), "team mate ", verbosename, "^7got the flag! Protect them!"));
+               else if(tmp_player.team == flag.team)
+                       centerprint(tmp_player, strcat("The ", Team_ColorCode(player.team), "enemy ", verbosename, "^7got your flag! Retrieve it!"));
        
        // scoring
        PlayerTeamScore_AddScore(player, ctf_ReadScore("score_pickup_base"));
@@ -336,10 +410,12 @@ void ctf_Handle_Pickup_Dropped(entity flag, entity player) // make sure this wor
        ctf_EventLog("pickup", flag.team, player);
        verbosename = ((autocvar_g_ctf_flag_pickup_verbosename) ? strcat(Team_ColorCode(player.team), "(^7", player.netname, Team_ColorCode(player.team), ") ") : "");
        FOR_EACH_PLAYER(tmp_player)
-               if(tmp_player.team == flag.team)
-                       centerprint(tmp_player, strcat("The ", Team_ColorCode(player.team), "enemy ", verbosename, "^7got your flag! Retrieve it!"));
-               else if((tmp_player.team == player.team) && (tmp_player != player))
+               if(tmp_player == player)
+                       centerprint(tmp_player, strcat("You got the ", flag.netname, "!"));
+               else if(tmp_player.team == player.team)
                        centerprint(tmp_player, strcat("Your ", Team_ColorCode(player.team), "team mate ", verbosename, "^7got the flag! Protect them!"));
+               else if(tmp_player.team == flag.team)
+                       centerprint(tmp_player, strcat("The ", Team_ColorCode(player.team), "enemy ", verbosename, "^7got your flag! Retrieve it!"));
                        
        // scoring
        returnscore = floor((ctf_ReadScore("score_pickup_dropped_late") * (1-returnscore) + ctf_ReadScore("score_pickup_dropped_early") * returnscore) + 0.5);
@@ -523,7 +599,7 @@ void ctf_Reset()
 {
        if(self.owner)
                if(self.owner.classname == "player")
-                       ctf_Handle_Drop(self.owner);
+                       ctf_Handle_Drop(self.owner, DROPTYPE_NORMAL);
                        
        ctf_RespawnFlag(self);
 }
@@ -644,7 +720,7 @@ void ctf_FlagSetup(float teamnumber, entity flag) // called when spawning a flag
 
 MUTATOR_HOOKFUNCTION(ctf_RemovePlayer)
 {
-       if(self.flagcarried) { ctf_Handle_Drop(self); }
+       if(self.flagcarried) { ctf_Handle_Drop(self, DROPTYPE_NORMAL); }
        return 0;
 }
 
@@ -703,8 +779,29 @@ MUTATOR_HOOKFUNCTION(ctf_GiveFragsForKill)
 
 MUTATOR_HOOKFUNCTION(ctf_PlayerUseKey)
 {
-       if(autocvar_g_ctf_allow_drop)
-               ctf_Handle_Drop(self);
+       entity player = self;
+
+       if(player.flagcarried)
+       {
+               if(autocvar_g_ctf_allow_pass)
+               {
+                       entity head;
+                       head = findradius(player.origin, autocvar_g_ctf_pass_radius);
+                       
+                       while(head)
+                       {
+                               if(head.classname == "player" && head.deadflag == DEAD_NO)
+                               if(head != player && !IsDifferentTeam(head, player))
+                               {
+                                       ctf_Handle_Pass(player);
+                                       return 0;
+                               }
+                               head = head.chain;
+                       }
+               }
+               
+               if(autocvar_g_ctf_allow_drop) { ctf_Handle_Drop(player, DROPTYPE_THROWN); }
+       }
                
        return 0;
 }
index f171d9635afb5e970f7cd796369512c3f7582bc1..63ac7a0cfd66cbb5e9819b189dbe27c6e3b4f913 100644 (file)
@@ -3,6 +3,12 @@
 // used in cheats.qc
 void ctf_RespawnFlag(entity flag)
 
+// used in portals.qc
+void ctf_Handle_Drop(entity player, float droptype);
+
+// used in g_damage.qc
+float ctf_ReadScore(string parameter); // SOON WON'T BE NEEDED. // FIXCTF
+
 // used in t_quake3.qc
 void spawnfunc_info_player_team1();
 void spawnfunc_info_player_team2();
@@ -15,15 +21,14 @@ void spawnfunc_ctf_team();
 // flag constants 
 #define FLAG_MIN (PL_MIN + '0 0 -13')
 #define FLAG_MAX (PL_MAX + '0 0 -13')
-#define FLAG_CARRY_OFFSET ('-15 0 7')
-#define FLAG_SPAWN_OFFSET ('0 0 1' * (PL_MAX_z - 13))
-#define FLAG_WAYPOINT_OFFSET ('0 0 64')
 #define FLAG_SCALE 0.6
+
 #define FLAG_THINKRATE 0.2
 
-#define FLAG_BASE 1
-#define FLAG_CARRY 2
-#define FLAG_DROPPED 3
+#define FLAG_DROP_OFFSET ('0 0 32')
+#define FLAG_CARRY_OFFSET ('-15 0 7')
+#define FLAG_SPAWN_OFFSET ('0 0 1' * (PL_MAX_z - 13))
+#define FLAG_WAYPOINT_OFFSET ('0 0 64')
 
 // sounds 
 .string noise4;
@@ -46,6 +51,14 @@ entity ctf_worldflaglist;
 .entity wps_flagcarrier;
 .entity wps_flagdropped;
 
+// statuses
+#define FLAG_BASE 1
+#define FLAG_CARRY 2
+#define FLAG_DROPPED 3
+
+#define DROPTYPE_NORMAL 1
+#define DROPTYPE_THROWN 2
+
 // flag properties
 #define ctf_spawnorigin dropped_origin
 float ctf_captimerecord; // record time for capturing the flag
index 1c6cf17eb68a1af9eaec0acd73b56ce7b62d030d..1c09b8b0c4f7f041af248cb4a740b7771aa16cbe 100644 (file)
@@ -155,7 +155,7 @@ float Portal_TeleportPlayer(entity teleporter, entity player)
        player.right_vector = -1 * AnglesTransform_Apply(transform, player.right_vector);
 
        if(player.flagcarried)
-               ctf_Handle_Drop(player); // FIXCTF
+               ctf_Handle_Drop(player, DROPTYPE_NORMAL); // FIXCTF
 
        if not(teleporter.enemy)
        {