]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
CA: avoid fractional score by giving players 1 point every 100 units of damage
authorterencehill <piuntn@gmail.com>
Wed, 19 Jan 2022 18:10:21 +0000 (18:10 +0000)
committerterencehill <piuntn@gmail.com>
Wed, 19 Jan 2022 18:10:21 +0000 (18:10 +0000)
gamemodes-server.cfg
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc

index 62570e5239e86bbd3b749efe7b20b036d67abec2..09c84f0f85a79cd552eb1e912c8046d9c452c8d5 100644 (file)
@@ -224,7 +224,7 @@ set g_ca_point_limit -1 "Clan Arena point limit overriding the mapinfo specified
 set g_ca_point_leadlimit -1 "Clan Arena point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 set g_ca_spectate_enemies 0 "allow eliminated players to spectate enemy players during Clan Arena games"
 set g_ca_warmup 10 "time players get to run around before the round starts"
-set g_ca_damage2score_multiplier 0.01
+set g_ca_damage2score 100  "every this amount of damage done give players 1 point"
 set g_ca_round_timelimit 180 "round time limit in seconds"
 set g_ca_teams_override 0
 set g_ca_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
index 866a00419c36c0a2be08367f156c3b4c98d98cca..1b8f68e7ea83fe6d8a671cd0097c73b8e0297512 100644 (file)
@@ -1,6 +1,6 @@
 #include "sv_clanarena.qh"
 
-float autocvar_g_ca_damage2score_multiplier;
+float autocvar_g_ca_damage2score = 100;
 bool autocvar_g_ca_spectate_enemies;
 
 float autocvar_g_ca_start_health = 200;
@@ -12,6 +12,8 @@ float autocvar_g_ca_start_ammo_cells = 180;
 float autocvar_g_ca_start_ammo_plasma = 180;
 float autocvar_g_ca_start_ammo_fuel = 0;
 
+.float ca_damage_counter;
+
 void CA_count_alive_players()
 {
        total_players = 0;
@@ -155,6 +157,8 @@ MUTATOR_HOOKFUNCTION(ca, PlayerSpawn)
        entity player = M_ARGV(0, entity);
 
        INGAME_STATUS_SET(player, INGAME_STATUS_JOINED);
+       if (time <= game_starttime) // reset on game restart, not on round start
+               player.ca_damage_counter = autocvar_g_ca_damage2score / 2; // for rounding purposes
        if (!warmup_stage)
                eliminatedPlayers.SendFlags |= 1;
 }
@@ -259,6 +263,12 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDies)
        return true;
 }
 
+MUTATOR_HOOKFUNCTION(ca, ClientConnect)
+{
+       entity player = M_ARGV(0, entity);
+       player.ca_damage_counter = autocvar_g_ca_damage2score / 2; // for rounding purposes
+}
+
 MUTATOR_HOOKFUNCTION(ca, ClientDisconnect)
 {
        entity player = M_ARGV(0, entity);
@@ -364,28 +374,53 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDamage_SplitHealthArmor)
 
        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);
+       if (autocvar_g_ca_damage2score <= 0 || frag_damage - excess == 0) return;
+
+       entity scorer = NULL;
+       float scorer_damage = 0;
+
+       if (IS_PLAYER(frag_attacker))
+       {
+               if (DIFF_TEAM(frag_target, frag_attacker))
+                       scorer_damage = frag_damage - excess;
+               else // friendly fire
+                       scorer_damage = -(frag_damage - excess);
+
+               scorer = frag_attacker;
+       }
+       else
+       {
+               //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 (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)
+               {
+                       scorer_damage = -(frag_damage - excess);
+                       scorer = frag_target;
+               }
+       }
+
+       if (scorer)
+       {
+               scorer.ca_damage_counter += scorer_damage;
+               if (fabs(scorer.ca_damage_counter) < autocvar_g_ca_damage2score)
+                       return;
+               // NOTE: here we are actually rounding since ca_damage_counter is
+               // initialized on player spawn to half autocvar_g_ca_damage2score
+               // Also note that this code works for subtracting score too
+               int points = floor(scorer.ca_damage_counter / autocvar_g_ca_damage2score);
+               GameRules_scoring_add(scorer, SCORE, points);
+
+               scorer.ca_damage_counter -= points * autocvar_g_ca_damage2score;
+       }
 }
 
 MUTATOR_HOOKFUNCTION(ca, CalculateRespawnTime)