From 1e382694490f14866a41b7c42994c613476cdb53 Mon Sep 17 00:00:00 2001 From: terencehill Date: Wed, 19 Jan 2022 18:10:21 +0000 Subject: [PATCH] CA: avoid fractional score by giving players 1 point every 100 units of damage --- gamemodes-server.cfg | 2 +- .../gamemode/clanarena/sv_clanarena.qc | 81 +++++++++++++------ 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg index 62570e523..09c84f0f8 100644 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@ -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" diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index 866a00419..1b8f68e7e 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -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) -- 2.39.2