]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
Merge branch 'master' into Mario/status_effects_extended
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / gamemodes / gamemode / clanarena / sv_clanarena.qc
index 686b0cbae06cddbf42a460a1ecae11a61f38b2fa..ba2402f2768229c8576c3399a1084bb99649b02e 100644 (file)
@@ -62,7 +62,6 @@ int CA_GetWinnerTeam()
 
 void nades_Clear(entity player);
 
-#define CA_ALIVE_TEAMS_OK() (Team_GetNumberOfAliveTeams() == NumTeams(ca_teams))
 float CA_CheckWinner()
 {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
@@ -115,7 +114,7 @@ bool CA_CheckTeams()
        static int prev_missing_teams_mask;
        allowed_to_spawn = true;
        CA_count_alive_players();
-       if(CA_ALIVE_TEAMS_OK())
+       if (Team_GetNumberOfAliveTeams() == NumTeams(ca_teams))
        {
                if(prev_missing_teams_mask > 0)
                        Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_MISSING_TEAMS);
@@ -148,7 +147,7 @@ bool CA_CheckTeams()
 
 bool ca_isEliminated(entity e)
 {
-       if(e.caplayer == 1 && (IS_DEAD(e) || e.frags == FRAGS_LMS_LOSER))
+       if(e.caplayer == 1 && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME))
                return true;
        if(e.caplayer == 0.5)
                return true;
@@ -164,7 +163,7 @@ entity CA_SpectateNext(entity player, entity start)
        {
                if (SAME_TEAM(player, e)) return e;
        }
-       // restart from begining
+       // restart from the beginning
        for (entity e = NULL; (e = find(e, classname, STR_PLAYER)); )
        {
                if (SAME_TEAM(player, e)) return e;
@@ -225,7 +224,6 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_players)
                        PutClientInServer(it);
                }
        });
-       bot_relinkplayerlist();
        return true;
 }
 
@@ -253,12 +251,13 @@ entity ca_LastPlayerForTeam(entity this)
 {
        entity last_pl = NULL;
        FOREACH_CLIENT(IS_PLAYER(it) && it != this, {
-               if (!IS_DEAD(it))
-               if (SAME_TEAM(this, it))
-               if (!last_pl)
-                       last_pl = it;
-               else
-                       return NULL;
+               if (!IS_DEAD(it) && SAME_TEAM(this, it))
+               {
+                       if (!last_pl)
+                               last_pl = it;
+                       else
+                               return NULL;
+               }
        });
        return last_pl;
 }
@@ -286,11 +285,7 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDies)
        }
        frag_target.respawn_flags |= RESPAWN_FORCE;
        if (!warmup_stage)
-       {
                eliminatedPlayers.SendFlags |= 1;
-               if (IS_BOT_CLIENT(frag_target))
-                       bot_clear(frag_target);
-       }
        return true;
 }
 
@@ -310,9 +305,12 @@ MUTATOR_HOOKFUNCTION(ca, MakePlayerObserver)
        if (IS_PLAYER(player) && !IS_DEAD(player))
                ca_LastPlayerForTeam_Notify(player);
        if (player.killindicator_teamchange == -2) // player wants to spectate
+       {
+               entcs_update_players(player);
                player.caplayer = 0;
+       }
        if (player.caplayer)
-               player.frags = FRAGS_LMS_LOSER;
+               player.frags = FRAGS_PLAYER_OUT_OF_GAME;
        if (!warmup_stage)
                eliminatedPlayers.SendFlags |= 1;
        if (!player.caplayer)
@@ -333,15 +331,15 @@ MUTATOR_HOOKFUNCTION(ca, GiveFragsForKill, CBC_ORDER_FIRST)
 
 MUTATOR_HOOKFUNCTION(ca, SetStartItems)
 {
-       start_items       &= ~IT_UNLIMITED_AMMO;
-       start_health       = warmup_start_health       = cvar("g_lms_start_health");
-       start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
-       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
-       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_lms_start_ammo_nails");
-       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_lms_start_ammo_rockets");
-       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_lms_start_ammo_cells");
-       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_lms_start_ammo_plasma");
-       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_lms_start_ammo_fuel");
+       start_items       &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS);
+       start_health       = warmup_start_health       = cvar("g_ca_start_health");
+       start_armorvalue   = warmup_start_armorvalue   = cvar("g_ca_start_armor");
+       start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_ca_start_ammo_shells");
+       start_ammo_nails   = warmup_start_ammo_nails   = cvar("g_ca_start_ammo_nails");
+       start_ammo_rockets = warmup_start_ammo_rockets = cvar("g_ca_start_ammo_rockets");
+       start_ammo_cells   = warmup_start_ammo_cells   = cvar("g_ca_start_ammo_cells");
+       start_ammo_plasma  = warmup_start_ammo_plasma  = cvar("g_ca_start_ammo_plasma");
+       start_ammo_fuel    = warmup_start_ammo_fuel    = cvar("g_ca_start_ammo_fuel");
 }
 
 MUTATOR_HOOKFUNCTION(ca, Damage_Calculate)
@@ -368,7 +366,7 @@ MUTATOR_HOOKFUNCTION(ca, FilterItem)
        entity item = M_ARGV(0, entity);
 
        if (autocvar_g_powerups <= 0)
-       if (item.flags & FL_POWERUP)
+       if (item.itemdef.instanceOfPowerup)
                return true;
 
        if (autocvar_g_pickup_items <= 0)
@@ -377,16 +375,40 @@ MUTATOR_HOOKFUNCTION(ca, FilterItem)
 
 MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor)
 {
+       if (time < game_starttime || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
+               return;
+
        entity frag_attacker = M_ARGV(1, entity);
        entity frag_target = M_ARGV(2, entity);
+       float frag_deathtype = M_ARGV(6, float);
        float frag_damage = M_ARGV(7, float);
-       float damage_take = bound(0, M_ARGV(4, float), GetResourceAmount(frag_target, RESOURCE_HEALTH));
-       float damage_save = bound(0, M_ARGV(5, float), GetResourceAmount(frag_target, RESOURCE_ARMOR));
+       float damage_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
+       float damage_save = bound(0, M_ARGV(5, float), GetResource(frag_target, RES_ARMOR));
 
        float excess = max(0, frag_damage - damage_take - damage_save);
 
+       //non-friendly fire
        if (frag_target != frag_attacker && IS_PLAYER(frag_attacker) && DIFF_TEAM(frag_target, frag_attacker))
                GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * autocvar_g_ca_damage2score_multiplier);
+
+       //friendly fire
+       if (SAME_TEAM(frag_target, frag_attacker))
+               GameRules_scoring_add_team(frag_attacker, SCORE, (-1 * (frag_damage - excess)) * autocvar_g_ca_damage2score_multiplier);
+
+       //handle (environmental hazard) suiciding, check first if player has a registered attacker who most likely pushed them there to avoid punishing pushed players as pushers are already rewarded
+       //deathtypes:
+       //kill = suicide, drown = drown in water/liquid, hurttrigger = out of the map void or hurt triggers inside maps like electric sparks
+       //camp = campcheck, lava = lava, slime = slime
+       //team change / rebalance suicides are currently not included
+       if (!IS_PLAYER(frag_attacker) && (
+               frag_deathtype == DEATH_KILL.m_id ||
+               frag_deathtype == DEATH_DROWN.m_id ||
+               frag_deathtype == DEATH_HURTTRIGGER.m_id ||
+               frag_deathtype == DEATH_CAMP.m_id ||
+               frag_deathtype == DEATH_LAVA.m_id ||
+               frag_deathtype == DEATH_SLIME.m_id ||
+               frag_deathtype == DEATH_SWAMP.m_id))
+                       GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * autocvar_g_ca_damage2score_multiplier);
 }
 
 MUTATOR_HOOKFUNCTION(ca, CalculateRespawnTime)
@@ -421,7 +443,8 @@ MUTATOR_HOOKFUNCTION(ca, SpectateNext)
 {
        entity client = M_ARGV(0, entity);
 
-       if (!autocvar_g_ca_spectate_enemies && client.caplayer)
+       if (!autocvar_g_ca_spectate_enemies && client.caplayer
+               && Team_GetNumberOfAlivePlayers(Entity_GetTeam(client)))
        {
                entity targ = M_ARGV(1, entity);
                M_ARGV(1, entity) = CA_SpectateNext(client, targ);
@@ -435,7 +458,8 @@ MUTATOR_HOOKFUNCTION(ca, SpectatePrev)
        entity targ = M_ARGV(1, entity);
        entity first = M_ARGV(2, entity);
 
-       if (!autocvar_g_ca_spectate_enemies && client.caplayer)
+       if (!autocvar_g_ca_spectate_enemies && client.caplayer
+               && Team_GetNumberOfAlivePlayers(Entity_GetTeam(client)))
        {
                do { targ = targ.chain; }
                while(targ && DIFF_TEAM(targ, client));
@@ -481,11 +505,6 @@ MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate)
        return MUT_SPECCMD_CONTINUE;
 }
 
-MUTATOR_HOOKFUNCTION(ca, WantWeapon)
-{
-       M_ARGV(2, bool) = true; // all weapons
-}
-
 MUTATOR_HOOKFUNCTION(ca, HideTeamNagger)
 {
        return true; // doesn't work well with the whole spectator as player thing
@@ -500,6 +519,14 @@ MUTATOR_HOOKFUNCTION(ca, GetPlayerStatus)
 
 MUTATOR_HOOKFUNCTION(ca, SetWeaponArena)
 {
-       // most weapons arena
-       if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "") M_ARGV(0, string) = "most";
+       if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
+               M_ARGV(0, string) = autocvar_g_ca_weaponarena;
+}
+
+MUTATOR_HOOKFUNCTION(ca, SV_ParseServerCommand)
+{
+       string cmd_name = M_ARGV(0, string);
+       if (cmd_name == "shuffleteams")
+               shuffleteams_on_reset_map = !allowed_to_spawn;
+       return false;
 }