From 779adf70f8b08e80b9ca268db57efe025af128ce Mon Sep 17 00:00:00 2001 From: TimePath Date: Tue, 16 Dec 2014 14:09:10 +1100 Subject: [PATCH] Major infection cleanup --- qcsrc/common/mapinfo.qc | 9 - qcsrc/server/bot/aim.qc | 3 - qcsrc/server/bot/bot.qc | 2 - qcsrc/server/cl_client.qc | 4 +- qcsrc/server/defs.qh | 4 - qcsrc/server/g_damage.qc | 3 +- qcsrc/server/mutators/gamemode_infection.qc | 349 ++++++++------------ 7 files changed, 133 insertions(+), 241 deletions(-) diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 30ce6cd788..727ba44c06 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -427,7 +427,6 @@ string _MapInfo_GetDefault(float t) case MAPINFO_TYPE_NEXBALL: return "5 20 0"; case MAPINFO_TYPE_CTS: return "20 0 0"; case MAPINFO_TYPE_FREEZETAG: return "10 20 0"; - case MAPINFO_TYPE_INFECTION: return "5 20 0"; // NOTE: DO NOT ADD ANY MORE GAME TYPES HERE // THIS IS JUST LEGACY SUPPORT FOR NEXUIZ MAPS // ONLY ADD NEW STUFF TO _MapInfo_GetDefaultEx @@ -503,14 +502,6 @@ void _MapInfo_Map_ApplyGametype(string s, float pWantedType, float pThisType, fl s = cdr(s); } - if(pWantedType == MAPINFO_TYPE_INFECTION) - { - sa = car(s); - if(sa != "") - cvar_set("fraglimit", sa); - s = cdr(s); - } - if(pWantedType == MAPINFO_TYPE_INFECTION) { sa = car(s); diff --git a/qcsrc/server/bot/aim.qc b/qcsrc/server/bot/aim.qc index bb8451afdd..f2de8b50f3 100644 --- a/qcsrc/server/bot/aim.qc +++ b/qcsrc/server/bot/aim.qc @@ -110,9 +110,6 @@ float bot_shouldattack(entity e) return FALSE; } - if(g_infection && e.infectioncolor == self.infectioncolor) - return FALSE; - if(e.frozen) return FALSE; diff --git a/qcsrc/server/bot/bot.qc b/qcsrc/server/bot/bot.qc index ea15130664..9b4d5ff5d0 100644 --- a/qcsrc/server/bot/bot.qc +++ b/qcsrc/server/bot/bot.qc @@ -407,8 +407,6 @@ void bot_clientconnect() self.team = NUM_TEAM_4; else JoinBestTeam(self, FALSE, TRUE); - - self.infection_playernum = -1; havocbot_setupbot(); } diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index e1c76fb39f..c2a434a3e7 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -345,7 +345,7 @@ void FixPlayermodel() UpdatePlayerSounds(); // update skin sounds } - if(!teamplay || !g_infection) //&& ? + if(!(teamplay || g_infection)) if(strlen(autocvar_sv_defaultplayercolors)) if(self.clientcolors != stof(autocvar_sv_defaultplayercolors)) setcolor(self, stof(autocvar_sv_defaultplayercolors)); @@ -1188,8 +1188,6 @@ void ClientConnect (void) if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca && !g_cts && !g_race) // teamnagger is currently bad for ca, race & cts send_CSQC_teamnagger(); - - self.infection_playernum = -1; CheatInitClient(); diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index e951c04fab..ab4dee3185 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -565,10 +565,6 @@ string deathmessage; float serverflags; -.float infection_playernum; -.float infectioncolor; -.float infectioncolor_original; - .float team_forced; // can be a team number to force a team, or 0 for default action, or -1 for forced spectator .float player_blocked; diff --git a/qcsrc/server/g_damage.qc b/qcsrc/server/g_damage.qc index ef81b236bb..e0cb97df6c 100644 --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@ -849,8 +849,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float } if (targ == attacker) - damage *= //g_infection ? 0 : - autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself + damage *= autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself // count the damage if(attacker) diff --git a/qcsrc/server/mutators/gamemode_infection.qc b/qcsrc/server/mutators/gamemode_infection.qc index ea2502819a..94bc29c504 100644 --- a/qcsrc/server/mutators/gamemode_infection.qc +++ b/qcsrc/server/mutators/gamemode_infection.qc @@ -1,311 +1,221 @@ -#define INFECTIONCOLOR_MAX 16 +float infection_players_count = 0; +float infection_coloridx; -entity infection_players[INFECTIONCOLOR_MAX]; -float infection_players_count; float next_round; +.float infection_jointime; +.float infectioncolor; +.float infectioncolor_original; + +void infection_SetColor(entity e, float _color) +{ + setcolor(e, (_color << 4) | _color); +} + void infection_Initialize() { - float i; - for(i = 0; i < INFECTIONCOLOR_MAX; ++i) - { - infection_players[i] = world; - } - next_round = time + 5; + infection_coloridx = 0; + next_round = time + autocvar_g_infection_delay_round; } void infection_CheckWinner() { + if (infection_players_count <= 1) return; // There can be no winner + // Check if only one color remains - float i, previnfectioncolor, we_have_a_winner; + float previnfectioncolor = -1; + float we_have_a_winner = TRUE; // TRUE until below loop proves us wrong entity e; - we_have_a_winner = TRUE; // TRUE until below loop proves us wrong - entity winner = world; //? - previnfectioncolor = FALSE; + FOR_EACH_PLAYER(e) + { + // All infection colors are the same if we have a winner + if (previnfectioncolor != -1 && previnfectioncolor != e.infectioncolor) + { + // In this case we still have more than one color alive + we_have_a_winner = FALSE; + break; + } + previnfectioncolor = e.infectioncolor; + } - float temp_infection_players_count; - temp_infection_players_count = infection_players_count; + if (!we_have_a_winner) return; - for(i = 0; i < temp_infection_players_count; ++i) + // Who is it? + entity winner = world; + FOR_EACH_PLAYER(e) { - e = infection_players[i]; - if(e == world) // empty slot, skip to next + if (e.infectioncolor == e.infectioncolor_original) { - if(temp_infection_players_count < INFECTIONCOLOR_MAX - 1) // just in case - ++temp_infection_players_count; // keep on searching for one additional since this was empty - continue; + winner = e; + break; } + } + + if (winner.netname) + { + UpdateFrags(winner, 1); - if(i > 0) + FOR_EACH_PLAYER(e) { - if(previnfectioncolor != e.infectioncolor) // all infection colors are the same if we have a winner, in this case we still have more than one color alive - { - we_have_a_winner = FALSE; - break; - } + centerprint(e, strcat(winner.netname, "^1 wins the round since their color survived.\n")); } - - previnfectioncolor = e.infectioncolor; + bprint(winner.netname, "^1 wins the round since their color survived.\n"); } - if(we_have_a_winner) + infection_Initialize(); +} + +string color_owner_green, color_owner_red; +// find whose color your attacker is carrying, TRUE if it's his own, otherwise set color_owner_* to the other owner +float infection_GetColorOwner(entity me) +{ + entity e; + FOR_EACH_PLAYER(e) { - temp_infection_players_count = infection_players_count; - for(i = 0; i < temp_infection_players_count; ++i) + if (e.infectioncolor_original == me.infectioncolor_original) { - e = infection_players[i]; - if(e == world) // empty slot, skip to next - { - if(temp_infection_players_count < INFECTIONCOLOR_MAX - 1) // just in case - ++temp_infection_players_count; - continue; - } - - if(e.infectioncolor == e.infectioncolor_original) // here's our winner :) - { - winner = e; - break; // break, we found the winner - } + return TRUE; } - - if(winner.netname != "" && infection_players_count > 1) + else if (e.infectioncolor_original == me.infectioncolor) { - UpdateFrags(winner, +1); - - FOR_EACH_PLAYER(e) - { - centerprint(e, strcat(winner.netname, "^1 wins the round since their color survived.\n")); - } - bprint(winner.netname, "^1 wins the round since their color survived.\n"); + color_owner_green = strcat(e.netname, "^2's"); + color_owner_red = strcat(e.netname, "^1's"); + break; } - - next_round = time + 5; } + return FALSE; } -string color_owner_green, color_owner_red; -float color_owner_self; -// find whose color your attacker is carrying, set color_owner_self to 1 if it's his own, otherwise set color_owner_* to the other owner -#define infection_GetFragAttackers_ColorOwner()\ -{\ - float j;\ - entity get_frag_attacker_temp;\ - temp_infection_players_count = infection_players_count;\ - color_owner_self = 0;\ - for(j = 0; j < temp_infection_players_count; ++j)\ - {\ - get_frag_attacker_temp = infection_players[j];\ - if(get_frag_attacker_temp == world)\ - {\ - if(temp_infection_players_count < INFECTIONCOLOR_MAX - 1)\ - ++temp_infection_players_count;\ - continue;\ - }\ - if(get_frag_attacker_temp.infectioncolor_original == frag_attacker.infectioncolor_original)\ - {\ - color_owner_self = 1;\ - break;\ - }\ - else if(get_frag_attacker_temp.infectioncolor_original == frag_attacker.infectioncolor)\ - {\ - color_owner_green = strcat(get_frag_attacker_temp.netname, "^2's");\ - color_owner_red = strcat(get_frag_attacker_temp.netname, "^1's");\ - break;\ - }\ - }\ -} ENDS_WITH_CURLY_BRACE - MUTATOR_HOOKFUNCTION(infection_PlayerDies) { - float i; - entity e; - - float temp_infection_players_count; - temp_infection_players_count = infection_players_count; - - if(frag_target.infectioncolor == frag_target.infectioncolor_original) // if this is the first time we die... (our infectioncolor remained unchanged) + // If this is the first time we die... (our infectioncolor remained unchanged) + if (frag_target.infectioncolor == frag_target.infectioncolor_original) { - for(i = 0; i < temp_infection_players_count; ++i) // check other players... + infection_GetColorOwner(frag_attacker); + entity e; + FOR_EACH_PLAYER(e) // check other players... { - e = infection_players[i]; - if(e == world) // empty slot, skip to next + if (e.infectioncolor == frag_target.infectioncolor) // And see if they have our original infection color { - if(temp_infection_players_count < INFECTIONCOLOR_MAX - 1) // just in case - ++temp_infection_players_count; - continue; - } - - if(e.infectioncolor == frag_target.infectioncolor_original) // and see if they have our original infection color - { - infection_GetFragAttackers_ColorOwner(); + // If so, remove it, our infection color has now "died out" from this round and we can not win anymore. + // The attacker will "summon" all of our previously fragged targets, and also us. centerprint(e, strcat("^1Your master ^7", frag_target.netname, "^1 was infected by ^7", frag_attacker.netname, " ^1with ^7", color_owner_red, " ^1color.\n")); - e.infectioncolor = frag_attacker.infectioncolor; // if so, remove it, our infection color has now "died out" from this round and we can not win anymore. The attacker will "summon" all of our previously fragged targets, and also us. - setcolor(e, 16 * e.infectioncolor + e.infectioncolor); + e.infectioncolor = frag_attacker.infectioncolor; + infection_SetColor(e, e.infectioncolor); } } } else { frag_target.infectioncolor = frag_attacker.infectioncolor; - setcolor(frag_target, 16 * frag_target.infectioncolor + frag_target.infectioncolor); + infection_SetColor(frag_target, frag_target.infectioncolor); } - infection_GetFragAttackers_ColorOwner(); - - if(color_owner_self) + if (infection_GetColorOwner(frag_attacker)) + { color_owner_green = "^2your own"; - centerprint(frag_attacker, strcat("^2You infected ^7", frag_target.netname, " ^2with ^7", color_owner_green, " ^2color.\n")); - - if(color_owner_self) color_owner_red = "^1their own"; + } + centerprint(frag_attacker, strcat("^2You infected ^7", frag_target.netname, " ^2with ^7", color_owner_green, " ^2color.\n")); centerprint(frag_target, strcat("^1You were infected by ^7", frag_attacker.netname, " ^1with ^7", color_owner_red, " ^1color.\n")); + bprint("^7", frag_target.netname, "^1 was infected by ^7", frag_attacker.netname, " ^1with ^7", color_owner_red, " ^1color.\n"); - frag_target.health = cvar("g_balance_health_start"); // "respawn" the player :P + frag_target.health = cvar("g_balance_health_start"); // "respawn" the player infection_CheckWinner(); - return 1; + return TRUE; } MUTATOR_HOOKFUNCTION(infection_RemovePlayer) { - if(self.infection_playernum == -1) - return 0; // nothing to remove + if (!self.infection_jointime) + return FALSE; // nothing to remove - float i, j; - /*for (i = self.infection_playernum; i < infection_players_count; ++i) - { - infection_players[i] = infection_players[i+1]; - infection_players[i].infection_playernum = infection_players[i].infection_playernum - 1; - } - */ - - infection_players[self.infection_playernum] = world; - infection_players_count = infection_players_count - 1; + infection_players_count--; // if other players have our color, randomize their color - entity e; - float temp_infection_players_count; - temp_infection_players_count = infection_players_count; - - if(!next_round) // ... but ONLY if next_round isn't set. We don't care about the colors if the round has already ended - for(i = 0; i < temp_infection_players_count; ++i) // check other players... + // ... but ONLY if next_round isn't set. We don't care about the colors if the round has already ended + if (!time < next_round) { - e = infection_players[i]; - if(e == world) // empty slot, skip to next + entity e; + FOR_EACH_PLAYER(e) // check other players... { - if(temp_infection_players_count < INFECTIONCOLOR_MAX - 1) // just in case - ++temp_infection_players_count; - continue; - } - - if(e.infectioncolor == self.infectioncolor_original) // and see if they have our original infection color - { - entity random_player = world; - - for(j = 0; j < 100; ++j) // try 100 times to find a color that isn't the same as our color. If this fails we are either damn unlucky, or there are really only players left of our color + if (e.infectioncolor == self.infectioncolor_original) // and see if they have our original infection color { - random_player = infection_players[floor(random() * (INFECTIONCOLOR_MAX - 1))]; - - if(random_player == world) // hit empty slot, try again - continue; - - if(random_player.infectioncolor != self.infectioncolor_original) // break if we found another color - { - break; - } + e.infectioncolor_original = self.infectioncolor; + centerprint(frag_attacker, "^2You are now a master.\n"); + break; } - e.infectioncolor = random_player.infectioncolor; - setcolor(e, 16 * e.infectioncolor + e.infectioncolor); } } - self.infection_playernum = -1; - - if(infection_players_count > 1 && time > autocvar_g_infection_delay_round) + if (infection_players_count > 1 && time >= next_round) infection_CheckWinner(); - return 1; + return TRUE; } MUTATOR_HOOKFUNCTION(infection_PlayerSpawn) { - float i; - if(infection_players_count == 1 && time > autocvar_g_infection_delay_round) - next_round = time; // start a new round immediately + if (self.infection_jointime) return TRUE; // only add if we don't have a infection_jointime + self.infection_jointime = time; + if (++infection_players_count > 1 && time >= next_round) + next_round = time + autocvar_g_infection_delay_round; // start a new round immediately - if(infection_players_count + 1 >= INFECTIONCOLOR_MAX) + if (time >= next_round) // spawn too late, give player a random color { - bprint("^1Sorry, only ", ftos(INFECTIONCOLOR_MAX), " players can play infection at once."); - return 0; - } - - if(self.infection_playernum == -1) // only add if we don't have a infection_playernum - { - // add player to the players array, give him a playernum - for(i = 0; i <= infection_players_count; ++i) // <= because we might not find any empty slots until then, and in that case we need a new slot + float skip = floor(random() * infection_players_count); + entity e; + FOR_EACH_PLAYER(e) { - if(infection_players[i] == world) // empty slot, give player this slot - { - self.infection_playernum = i; - break; - } + if (skip--) continue; + self.infectioncolor = e.infectioncolor; + self.infectioncolor_original = -1; // can't win if player didn't spawn during the round delay } - infection_players[i] = self; - infection_players_count = infection_players_count + 1; - } - - if(time > autocvar_g_infection_delay_round) // spawn too late, give player a random color - { - entity random_player = world; - - for(i = 0; i < 100; ++i) // try 100 times to find a color that isn't the same as our color. If this fails we are either damn unlucky, or there are really only players left of our color - { - random_player = infection_players[floor(random() * (INFECTIONCOLOR_MAX - 1))]; - - if(random_player == world) // hit empty slot, try again - continue; - - if(random_player.infectioncolor != self.infectioncolor_original) // break if we found another color - { - break; - } - } - - self.infectioncolor = random_player.infectioncolor; - self.infectioncolor_original = -1; // can't win if player didn't spawn during the round delay } else // we are still in the delay period before the round starts { - self.infectioncolor = self.infection_playernum; + self.infectioncolor = infection_coloridx++; self.infectioncolor_original = self.infectioncolor; } - setcolor(self, 16 * self.infectioncolor + self.infectioncolor); + infection_SetColor(self, self.infectioncolor); - return 1; + return TRUE; } MUTATOR_HOOKFUNCTION(infection_GiveFragsForKill) { - frag_score = 0; // no frags counted in infection, maybe later (TODO) - return 1; + frag_score = 0; // TODO: no frags counted in infection, maybe later + return TRUE; } MUTATOR_HOOKFUNCTION(infection_PlayerPreThink) { - setcolor(self, 16 * self.infectioncolor + self.infectioncolor); // prevent cheating by changing player colors - return 1; + infection_SetColor(self, self.infectioncolor); // prevent cheating by changing player colors + return TRUE; } MUTATOR_HOOKFUNCTION(infection_PlayerDamage_Calculate) { - if ((frag_attacker.infectioncolor == frag_target.infectioncolor && frag_attacker != frag_target) || (frag_deathtype == DEATH_FALL) || (frag_deathtype == DEATH_DROWN) || (frag_deathtype == DEATH_SLIME) || (frag_deathtype == DEATH_LAVA)) - { - frag_damage = 0; - frag_force = '0 0 0'; - } - return 1; + if ( + (frag_attacker.infectioncolor == frag_target.infectioncolor && frag_attacker != frag_target) + || (frag_deathtype == DEATH_FALL) + || (frag_deathtype == DEATH_DROWN) + || (frag_deathtype == DEATH_SLIME) + || (frag_deathtype == DEATH_LAVA) + ) + { + frag_damage = 0; + frag_force = '0 0 0'; + } + return TRUE; +} + +MUTATOR_HOOKFUNCTION(infection_BotShouldAttack) +{ + return checkentity.infectioncolor == self.infectioncolor; // FIXME: Has reverse meaning } MUTATOR_DEFINITION(gamemode_infection) @@ -317,18 +227,21 @@ MUTATOR_DEFINITION(gamemode_infection) MUTATOR_HOOK(GiveFragsForKill, infection_GiveFragsForKill, CBC_ORDER_FIRST); MUTATOR_HOOK(PlayerPreThink, infection_PlayerPreThink, CBC_ORDER_FIRST); MUTATOR_HOOK(PlayerDamage_Calculate, infection_PlayerDamage_Calculate, CBC_ORDER_ANY); + MUTATOR_HOOK(BotShouldAttack, infection_BotShouldAttack, CBC_ORDER_ANY); MUTATOR_ONADD { - if(time > 1) // game loads at time 1 + if (time > 1) // game loads at time 1 error("This is a game type and it cannot be added at runtime."); - //g_infection = 1; infection_Initialize(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + } + MUTATOR_ONREMOVE { - //g_infection = 0; error("This is a game type and it cannot be removed at runtime."); return -1; } -- 2.39.2