]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
Merge branch 'Lyberta/TeamplayOverhaul' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / onslaught / sv_onslaught.qc
index 90ab772342e537a5a961bf910c5f30dff2463b1f..c20a4fac74a160b62e9d876a35092fd6afc5a2b4 100644 (file)
@@ -449,15 +449,17 @@ void ons_ControlPoint_Icon_Damage(entity this, entity inflictor, entity attacker
 
 bool ons_ControlPoint_Icon_Heal(entity targ, entity inflictor, float amount, float limit)
 {
-       float true_limit = ((limit >= 0) ? limit : targ.max_health);
-       if(GetResourceAmount(targ, RESOURCE_HEALTH) <= 0 || GetResourceAmount(targ, RESOURCE_HEALTH) >= true_limit)
+       float hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+       float true_limit = ((limit != RESOURCE_LIMIT_NONE) ? limit : targ.max_health);
+       if (hlth <= 0 || hlth >= true_limit)
                return false;
 
        GiveResourceWithLimit(targ, RESOURCE_HEALTH, amount, true_limit);
+       hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
        if(targ.owner.iscaptured)
-               WaypointSprite_UpdateHealth(targ.owner.sprite, GetResourceAmount(targ, RESOURCE_HEALTH));
+               WaypointSprite_UpdateHealth(targ.owner.sprite, hlth);
        else
-               WaypointSprite_UpdateBuildFinished(targ.owner.sprite, time + (targ.max_health - GetResourceAmount(targ, RESOURCE_HEALTH)) / (targ.count / ONS_CP_THINKRATE));
+               WaypointSprite_UpdateBuildFinished(targ.owner.sprite, time + (targ.max_health - hlth) / (targ.count / ONS_CP_THINKRATE));
        targ.SendFlags |= CPSF_STATUS;
        return true;
 }
@@ -904,13 +906,14 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
                }
        }
        TakeResource(this, RESOURCE_HEALTH, damage);
-       WaypointSprite_UpdateHealth(this.sprite, GetResourceAmount(this, RESOURCE_HEALTH));
+       float hlth = GetResourceAmount(this, RESOURCE_HEALTH);
+       WaypointSprite_UpdateHealth(this.sprite, hlth);
        // choose an animation frame based on health
-       this.frame = 10 * bound(0, (1 - GetResourceAmount(this, RESOURCE_HEALTH) / this.max_health), 1);
+       this.frame = 10 * bound(0, (1 - hlth / this.max_health), 1);
        // see if the generator is still functional, or dying
-       if (GetResourceAmount(this, RESOURCE_HEALTH) > 0)
+       if (hlth > 0)
        {
-               this.lasthealth = GetResourceAmount(this, RESOURCE_HEALTH);
+               this.lasthealth = hlth;
        }
        else
        {
@@ -963,14 +966,16 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d
 
 bool ons_GeneratorHeal(entity targ, entity inflictor, float amount, float limit)
 {
-       float true_limit = ((limit >= 0) ? limit : targ.max_health);
-       if(GetResourceAmount(targ, RESOURCE_HEALTH) <= 0 || GetResourceAmount(targ, RESOURCE_HEALTH) >= true_limit)
+       float true_limit = ((limit != RESOURCE_LIMIT_NONE) ? limit : targ.max_health);
+       float hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+       if (hlth <= 0 || hlth >= true_limit)
                return false;
 
        GiveResourceWithLimit(targ, RESOURCE_HEALTH, amount, true_limit);
-       WaypointSprite_UpdateHealth(targ.sprite, GetResourceAmount(targ, RESOURCE_HEALTH));
-       targ.frame = 10 * bound(0, (1 - GetResourceAmount(targ, RESOURCE_HEALTH) / targ.max_health), 1);
-       targ.lasthealth = GetResourceAmount(targ, RESOURCE_HEALTH);
+       hlth = GetResourceAmount(targ, RESOURCE_HEALTH);
+       WaypointSprite_UpdateHealth(targ.sprite, hlth);
+       targ.frame = 10 * bound(0, (1 - hlth / targ.max_health), 1);
+       targ.lasthealth = hlth;
        targ.SendFlags |= GSF_STATUS;
        return true;
 }
@@ -1108,46 +1113,52 @@ int total_generators;
 void Onslaught_count_generators()
 {
        entity e;
-       total_generators = redowned = blueowned = yellowowned = pinkowned = 0;
+       total_generators = 0;
+       for (int i = 1; i <= NUM_TEAMS; ++i)
+       {
+               Team_SetNumberOfControlPoints(Team_GetTeamFromIndex(i), 0);
+       }
        for(e = ons_worldgeneratorlist; e; e = e.ons_worldgeneratornext)
        {
                ++total_generators;
-               redowned += (e.team == NUM_TEAM_1 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
-               blueowned += (e.team == NUM_TEAM_2 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
-               yellowowned += (e.team == NUM_TEAM_3 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
-               pinkowned += (e.team == NUM_TEAM_4 && GetResourceAmount(e, RESOURCE_HEALTH) > 0);
+               if (GetResourceAmount(e, RESOURCE_HEALTH) < 1)
+               {
+                       continue;
+               }
+               entity team_ = Entity_GetTeam(e);
+               int num_control_points = Team_GetNumberOfControlPoints(team_);
+               ++num_control_points;
+               Team_SetNumberOfControlPoints(team_, num_control_points);
        }
 }
 
 int Onslaught_GetWinnerTeam()
 {
        int winner_team = 0;
-       if(redowned > 0)
-               winner_team = NUM_TEAM_1;
-       if(blueowned > 0)
+       if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(1)) >= 1)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_2;
+               winner_team = NUM_TEAM_1;
        }
-       if(yellowowned > 0)
+       for (int i = 2; i <= NUM_TEAMS; ++i)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_3;
+               if (Team_GetNumberOfControlPoints(Team_GetTeamFromIndex(i)) >= 1)
+               {
+                       if (winner_team != 0)
+                       {
+                               return 0;
+                       }
+                       winner_team = Team_IndexToTeam(i);
+               }
        }
-       if(pinkowned > 0)
+       if (winner_team)
        {
-               if(winner_team) return 0;
-               winner_team = NUM_TEAM_4;
-       }
-       if(winner_team)
                return winner_team;
+       }
        return -1; // no generators left?
 }
 
 void nades_Clear(entity e);
 
-#define ONS_OWNED_GENERATORS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
-#define ONS_OWNED_GENERATORS_OK() (ONS_OWNED_GENERATORS() > 1)
 bool Onslaught_CheckWinner()
 {
        if ((autocvar_timelimit && time > game_starttime + autocvar_timelimit * 60) || (round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0))
@@ -1193,8 +1204,10 @@ bool Onslaught_CheckWinner()
 
        Onslaught_count_generators();
 
-       if(ONS_OWNED_GENERATORS_OK())
+       if (Team_GetNumberOfTeamsWithControlPoints() > 1)
+       {
                return 0;
+       }
 
        int winner_team = Onslaught_GetWinnerTeam();
 
@@ -1955,17 +1968,14 @@ MUTATOR_HOOKFUNCTION(ons, HavocBot_ChooseRole)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(ons, CheckAllowedTeams)
+MUTATOR_HOOKFUNCTION(ons, TeamBalance_CheckAllowedTeams)
 {
        // onslaught is special
        for(entity tmp_entity = ons_worldgeneratorlist; tmp_entity; tmp_entity = tmp_entity.ons_worldgeneratornext)
        {
-               switch(tmp_entity.team)
+               if (Team_IsValidTeam(tmp_entity.team))
                {
-                       case NUM_TEAM_1: c1 = 0; break;
-                       case NUM_TEAM_2: c2 = 0; break;
-                       case NUM_TEAM_3: c3 = 0; break;
-                       case NUM_TEAM_4: c4 = 0; break;
+                       M_ARGV(0, float) |= Team_TeamToBit(tmp_entity.team);
                }
        }
 
@@ -2195,12 +2205,9 @@ spawnfunc(onslaught_generator)
 // scoreboard setup
 void ons_ScoreRules()
 {
-       CheckAllowedTeams(NULL);
-       int teams = 0;
-       if(c1 >= 0) teams |= BIT(0);
-       if(c2 >= 0) teams |= BIT(1);
-       if(c3 >= 0) teams |= BIT(2);
-       if(c4 >= 0) teams |= BIT(3);
+       entity balance = TeamBalance_CheckAllowedTeams(NULL);
+       int teams = TeamBalance_GetAllowedTeams(balance);
+       TeamBalance_Destroy(balance);
        GameRules_scoring(teams, SFL_SORT_PRIO_PRIMARY, 0, {
            field_team(ST_ONS_CAPS, "destroyed", SFL_SORT_PRIO_PRIMARY);
            field(SP_ONS_CAPS, "caps", SFL_SORT_PRIO_SECONDARY);