]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/mutators/mutator/gamemode_ctf.qc
Merge branch 'master' into Mario/killsound
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator / gamemode_ctf.qc
index 6b497227244a7f0eb04b849fbae1d0d75e495dfb..8a88d5d2e8d7ac60ab0b4bd45601914650fb14ba 100644 (file)
@@ -479,6 +479,7 @@ void ctf_Handle_Throw(entity player, entity receiver, int droptype)
        flag.solid = SOLID_TRIGGER;
        flag.ctf_dropper = player;
        flag.ctf_droptime = time;
+       navigation_dynamicgoal_set(flag);
 
        flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
 
@@ -597,8 +598,14 @@ void ctf_Handle_Capture(entity flag, entity toucher, int capturetype)
        }
 
        // scoring
-       PlayerTeamScore_AddScore(player, ((enemy_flag.score_capture) ? enemy_flag.score_capture : autocvar_g_ctf_score_capture));
-       PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, ((enemy_flag.score_team_capture) ? enemy_flag.score_team_capture : 1));
+       float pscore = 0;
+       if(enemy_flag.score_capture || flag.score_capture)
+               pscore = floor((max(1, enemy_flag.score_capture) + max(1, flag.score_capture)) * 0.5);
+       PlayerTeamScore_AddScore(player, ((pscore) ? pscore : autocvar_g_ctf_score_capture));
+       float capscore = 0;
+       if(enemy_flag.score_team_capture || flag.score_team_capture)
+               capscore = floor((max(1, enemy_flag.score_team_capture) + max(1, flag.score_team_capture)) * 0.5);
+       PlayerTeamScore_Add(player, SP_CTF_CAPS, ST_CTF_CAPS, ((capscore) ? capscore : 1));
 
        old_time = PlayerScore_Add(player, SP_CTF_CAPTIME, 0);
        new_time = TIME_ENCODE(time - enemy_flag.ctf_pickuptime);
@@ -915,11 +922,11 @@ void ctf_FlagThink(entity this)
                FOREACH_CLIENT(true, LAMBDA(ctf_CaptureShield_Update(it, 1))); // release shield only
 
        // sanity checks
-       if(this.mins != CTF_FLAG.m_mins || this.maxs != CTF_FLAG.m_maxs) { // reset the flag boundaries in case it got squished
+       if(this.mins != this.m_mins || this.maxs != this.m_maxs) { // reset the flag boundaries in case it got squished
                LOG_TRACE("wtf the flag got squashed?");
-               tracebox(this.origin, CTF_FLAG.m_mins, CTF_FLAG.m_maxs, this.origin, MOVE_NOMONSTERS, this);
+               tracebox(this.origin, this.m_mins, this.m_maxs, this.origin, MOVE_NOMONSTERS, this);
                if(!trace_startsolid || this.noalign) // can we resize it without getting stuck?
-                       setsize(this, CTF_FLAG.m_mins, CTF_FLAG.m_maxs);
+                       setsize(this, this.m_mins, this.m_maxs);
        }
 
        // main think method
@@ -1191,6 +1198,7 @@ void ctf_RespawnFlag(entity flag)
        flag.ctf_pickuptime = 0;
        flag.ctf_droptime = 0;
        flag.ctf_flagdamaged_byworld = false;
+       navigation_dynamicgoal_unset(flag);
 
        ctf_CheckStalemate();
 }
@@ -1219,8 +1227,7 @@ void ctf_DelayedFlagSetup(entity this) // called after a flag is placed on a map
 {
        // bot waypoints
        waypoint_spawnforitem_force(this, this.origin);
-       this.nearestwaypointtimeout = 0; // activate waypointing again
-       this.bot_basewaypoint = this.nearestwaypoint;
+       navigation_dynamicgoal_init(this, true);
 
        // waypointsprites
        entity basename;
@@ -1311,7 +1318,9 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
 
        // appearence
        _setmodel(flag, flag.model); // precision set below
-       setsize(flag, CTF_FLAG.m_mins, CTF_FLAG.m_maxs);
+       setsize(flag, CTF_FLAG.m_mins * flag.scale, CTF_FLAG.m_maxs * flag.scale);
+       flag.m_mins = flag.mins; // store these for squash checks
+       flag.m_maxs = flag.maxs;
        setorigin(flag, (flag.origin + FLAG_SPAWN_OFFSET));
 
        if(autocvar_g_ctf_flag_glowtrails)
@@ -1445,6 +1454,8 @@ int havocbot_ctf_teamcount(entity bot, vector org, float tc_radius)
        return c;
 }
 
+// unused
+#if 0
 void havocbot_goalrating_ctf_ourflag(entity this, float ratingscale)
 {
        entity head;
@@ -1458,6 +1469,7 @@ void havocbot_goalrating_ctf_ourflag(entity this, float ratingscale)
        if (head)
                navigation_routerating(this, head, ratingscale, 10000);
 }
+#endif
 
 void havocbot_goalrating_ctf_ourbase(entity this, float ratingscale)
 {
@@ -1466,7 +1478,15 @@ void havocbot_goalrating_ctf_ourbase(entity this, float ratingscale)
        while (head)
        {
                if (CTF_SAMETEAM(this, head))
+               {
+                       if (this.flagcarried)
+                       if ((this.flagcarried.cnt || head.cnt) && this.flagcarried.cnt != head.cnt)
+                       {
+                               head = head.ctf_worldflagnext; // skip base if it has a different group
+                               continue;
+                       }
                        break;
+               }
                head = head.ctf_worldflagnext;
        }
        if (!head)
@@ -1666,7 +1686,7 @@ void havocbot_role_ctf_carrier(entity this)
 
                navigation_goalrating_end(this);
 
-               if (this.navigation_hasgoals)
+               if (this.goalentity)
                        this.havocbot_cantfindflag = time + 10;
                else if (time > this.havocbot_cantfindflag)
                {
@@ -2049,6 +2069,7 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
        entity player = M_ARGV(0, entity);
 
        int t = 0, t2 = 0, t3 = 0;
+       bool b1 = false, b2 = false, b3 = false, b4 = false, b5 = false; // TODO: kill this, we WANT to show the other flags, somehow! (note: also means you don't see if you're FC)
 
        // initially clear items so they can be set as necessary later.
        player.ctf_flagstatus &= ~(CTF_RED_FLAG_CARRYING                | CTF_RED_FLAG_TAKEN            | CTF_RED_FLAG_LOST
@@ -2061,11 +2082,11 @@ MUTATOR_HOOKFUNCTION(ctf, PlayerPreThink)
        // scan through all the flags and notify the client about them
        for(entity flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext)
        {
-               if(flag.team == NUM_TEAM_1) { t = CTF_RED_FLAG_CARRYING;                t2 = CTF_RED_FLAG_TAKEN;                t3 = CTF_RED_FLAG_LOST; }
-               if(flag.team == NUM_TEAM_2) { t = CTF_BLUE_FLAG_CARRYING;               t2 = CTF_BLUE_FLAG_TAKEN;               t3 = CTF_BLUE_FLAG_LOST; }
-               if(flag.team == NUM_TEAM_3) { t = CTF_YELLOW_FLAG_CARRYING;     t2 = CTF_YELLOW_FLAG_TAKEN;             t3 = CTF_YELLOW_FLAG_LOST; }
-               if(flag.team == NUM_TEAM_4) { t = CTF_PINK_FLAG_CARRYING;               t2 = CTF_PINK_FLAG_TAKEN;               t3 = CTF_PINK_FLAG_LOST; }
-               if(flag.team == 0)                      { t = CTF_NEUTRAL_FLAG_CARRYING;        t2 = CTF_NEUTRAL_FLAG_TAKEN;    t3 = CTF_NEUTRAL_FLAG_LOST; player.ctf_flagstatus |= CTF_FLAG_NEUTRAL; }
+               if(flag.team == NUM_TEAM_1 && !b1) { b1 = true; t = CTF_RED_FLAG_CARRYING;              t2 = CTF_RED_FLAG_TAKEN;                t3 = CTF_RED_FLAG_LOST; }
+               if(flag.team == NUM_TEAM_2 && !b2) { b2 = true; t = CTF_BLUE_FLAG_CARRYING;             t2 = CTF_BLUE_FLAG_TAKEN;               t3 = CTF_BLUE_FLAG_LOST; }
+               if(flag.team == NUM_TEAM_3 && !b3) { b3 = true; t = CTF_YELLOW_FLAG_CARRYING;   t2 = CTF_YELLOW_FLAG_TAKEN;             t3 = CTF_YELLOW_FLAG_LOST; }
+               if(flag.team == NUM_TEAM_4 && !b4) { b4 = true; t = CTF_PINK_FLAG_CARRYING;             t2 = CTF_PINK_FLAG_TAKEN;               t3 = CTF_PINK_FLAG_LOST; }
+               if(flag.team == 0 && !b5)                  { b5 = true; t = CTF_NEUTRAL_FLAG_CARRYING;  t2 = CTF_NEUTRAL_FLAG_TAKEN;    t3 = CTF_NEUTRAL_FLAG_LOST; player.ctf_flagstatus |= CTF_FLAG_NEUTRAL; }
 
                switch(flag.ctf_status)
                {