]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
More infection cleanup
authorTimePath <andrew.hardaker1995@gmail.com>
Tue, 16 Dec 2014 10:37:11 +0000 (21:37 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Tue, 16 Dec 2014 10:37:11 +0000 (21:37 +1100)
gamemodes.cfg
qcsrc/common/mapinfo.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/mutators/gamemode_infection.qc

index 5c97c7cd05b74d600243c4e4988fcae76b9fdfd9..338f6975ea8f30cd48f3bfc3d0742df894d4c3c9 100644 (file)
@@ -37,6 +37,7 @@ alias cl_hook_gamestart_nb
 alias cl_hook_gamestart_cts
 alias cl_hook_gamestart_ka
 alias cl_hook_gamestart_ft
+alias cl_hook_gamestart_inf
 alias cl_hook_gamestart_inv
 alias cl_hook_gameend "rpn /cl_matchcount dup load 1 + =" // increase match count every time a game ends
 alias cl_hook_activeweapon
@@ -58,6 +59,7 @@ alias sv_hook_gamestart_nb
 alias sv_hook_gamestart_cts
 alias sv_hook_gamestart_ka
 alias sv_hook_gamestart_ft
+alias sv_hook_gamestart_inf
 alias sv_hook_gamestart_inv
 alias sv_hook_gamerestart
 alias sv_hook_gameend
@@ -75,6 +77,7 @@ alias sv_vote_gametype_hook_cts
 alias sv_vote_gametype_hook_dm
 alias sv_vote_gametype_hook_dom
 alias sv_vote_gametype_hook_ft
+alias sv_vote_gametype_hook_inf
 alias sv_vote_gametype_hook_inv
 alias sv_vote_gametype_hook_ka
 alias sv_vote_gametype_hook_kh
@@ -208,6 +211,13 @@ set g_ft_respawn_delay_large_count 0
 set g_ft_respawn_delay_max 0
 set g_ft_respawn_waves 0
 set g_ft_weapon_stay 0
+set g_inf_respawn_delay_small 0
+set g_inf_respawn_delay_small_count 0
+set g_inf_respawn_delay_large 0
+set g_inf_respawn_delay_large_count 0
+set g_inf_respawn_delay_max 0
+set g_inf_respawn_waves 0
+set g_inf_weapon_stay 0
 set g_inv_respawn_delay_small 0
 set g_inv_respawn_delay_small_count 0
 set g_inv_respawn_delay_large 0
@@ -500,6 +510,16 @@ set g_race_qualifying_timelimit_override -1
 set g_race_teams 0     "when 2, 3, or 4, the race is played as a team game (the team members can add up their laps)"
 
 
+// ===========
+//  infection
+// ===========
+set g_infection 0 "Infection: Infect everyone with your color"
+set g_infection_round_timelimit 180 "round time limit in seconds"
+set g_infection_warmup 5 "Time players get to run around before the round starts"
+set g_infection_teams 4 "Maximum number of teams (from 2 to 15 inclusive)"
+set g_infection_conversions 1 "Enable stealing when killing an alpha"
+
+
 // ==========
 //  invasion
 // ==========
@@ -512,10 +532,3 @@ set g_invasion_spawn_delay 0.25
 set g_invasion_spawnpoint_spawn_delay 0.5
 set g_invasion_teams 0 "number of teams in invasion (note: use mapinfo to set this)"
 set g_invasion_team_spawns 1 "use team spawns in teamplay invasion mode"
-
-
-// ===========
-//  infection
-// ===========
-set g_infection 0 "Infection: Infect everyone with your color to win!"
-set g_infection_delay_round 5 "delay during which new colors can still be formed, after this a new player will join an existing team (and as such cannot win anymore)"
index bd51473a45e0776a2a84a07409eec54a8c0b5718..659f9ce328c4a3a5f8402e818adb6f27e7c58312 100644 (file)
@@ -82,7 +82,7 @@ REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,TRUE,"timelimit=20 pointl
 REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,FALSE,"pointlimit=50 teams=0",_("Survive against waves of monsters"));
 #define g_invasion IS_GAMETYPE(INVASION)
 
-REGISTER_GAMETYPE(_("Infection"),inf,g_infection,INFECTION,FALSE,"timelimit=20",_("Survive against the infection"))
+REGISTER_GAMETYPE(_("Infection"),inf,g_infection,INFECTION,TRUE,"timelimit=20",_("Survive against the infection"))
 #define g_infection IS_GAMETYPE(INFECTION)
 
 const float MAPINFO_FEATURE_WEAPONS       = 1; // not defined for instagib-only maps
index 0d74b49c91c17022442bbcd1d5394449f961343c..4b9468552db2ce915736e5321ff8d27da540d3ef 100644 (file)
@@ -837,7 +837,6 @@ float autocvar_g_campcheck_damage;
 float autocvar_g_campcheck_distance;
 float autocvar_g_campcheck_interval;
 float autocvar_g_jump_grunt;
-float autocvar_g_infection_delay_round = 5;
 float autocvar_g_spawn_near_teammate_distance;
 float autocvar_g_spawn_near_teammate_ignore_spawnpoint;
 float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay;
index c2a434a3e7abd5750b406729464804075dbb9400..b1dccc7b5c3bc4e3e6517106fd7919eb5976f393 100644 (file)
@@ -345,7 +345,7 @@ void FixPlayermodel()
                UpdatePlayerSounds(); // update skin sounds
        }
 
-       if(!(teamplay || g_infection))
+       if(!teamplay)
                if(strlen(autocvar_sv_defaultplayercolors))
                        if(self.clientcolors != stof(autocvar_sv_defaultplayercolors))
                                setcolor(self, stof(autocvar_sv_defaultplayercolors));
index 3e6817c2c97ed4e9c9281c159ac48919484cce3c..fc94ccb9e14461451da234367150468d453a2ca0 100644 (file)
@@ -299,7 +299,6 @@ void calculate_player_respawn_time()
 }
 
 void ClientKill_Now_TeamChange();
-void infection_CheckWinner();
 
 void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
@@ -537,23 +536,13 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                // print an obituary message
                Obituary (attacker, inflictor, self, deathtype);
-               
-               if(g_infection)
-               {
-                       if(deathtype == DEATH_HURTTRIGGER || deathtype == DEATH_KILL)
-                       {
-                               PutClientInServer(); // respawn with a random color
-                               infection_CheckWinner();
-                               return;
-                       }
-               }
 
         // increment frag counter for used weapon type
         float w;
         w = DEATH_WEAPONOF(deathtype);
         if(WEP_VALID(w))
-       if(accuracy_isgooddamage(attacker, self))
-        attacker.accuracy.(accuracy_frags[w-1]) += 1;
+                       if(accuracy_isgooddamage(attacker, self))
+                               attacker.accuracy.(accuracy_frags[w-1]) += 1;
 
                frag_attacker = attacker;
                frag_inflictor = inflictor;
index 94bc29c5041e60168251feee1b366cfa604df958..012e44213e00575577fd127a1d9a1442e8a18b6c 100644 (file)
-float infection_players_count = 0;
-float infection_coloridx;
+float autocvar_g_infection_round_timelimit;
+float autocvar_g_infection_warmup;
+float autocvar_g_infection_teams;
+float autocvar_g_infection_conversions;
 
-float next_round;
+float infection_players_count;
 
-.float infection_jointime;
 .float infectioncolor;
 .float infectioncolor_original;
 
-void infection_SetColor(entity e, float _color)
-{
-       setcolor(e, (_color << 4) | _color);
-}
+const float INFECTIONTEAM_NONE = -1;
+const float INFECTIONTEAM_UNDEFINED = -2;
 
-void infection_Initialize()
+void infection_SetColor(entity _e, float _color)
 {
-       infection_coloridx = 0;
-       next_round = time + autocvar_g_infection_delay_round;
+       _e.infectioncolor = _color;
+       setcolor(_e, (_color << 4) | _color);
 }
 
-void infection_CheckWinner()
+string color_owner_green, color_owner_red;
+// find whose color a player is carrying, TRUE if it's his own, otherwise set color_owner_* to the other owner
+void infection_GetColorOwner(entity me)
 {
-       if (infection_players_count <= 1) return; // There can be no winner
-
-       // Check if only one color remains
-       float previnfectioncolor = -1;
-       float we_have_a_winner = TRUE; // TRUE until below loop proves us wrong
+       if (me.infectioncolor == me.infectioncolor_original)
+       {
+               color_owner_green = "^2your own";
+               color_owner_red = "^1their own";
+               return;
+       }
        entity e;
        FOR_EACH_PLAYER(e)
        {
-               // All infection colors are the same if we have a winner
-               if (previnfectioncolor != -1 && previnfectioncolor != e.infectioncolor)
+               if (me.infectioncolor == e.infectioncolor_original)
                {
-                       // In this case we still have more than one color alive
-                       we_have_a_winner = FALSE;
+                       color_owner_green = strcat(e.netname, "^2's");
+                       color_owner_red = strcat(e.netname, "^1's");
                        break;
                }
-               previnfectioncolor = e.infectioncolor;
        }
+}
 
-       if (!we_have_a_winner) return;
-
-       // Who is it?
-       entity winner = world;
-       FOR_EACH_PLAYER(e)
+void infection_Assign(float _late)
+{
+       entity e;
+       if (_late == 0)
        {
-               if (e.infectioncolor == e.infectioncolor_original)
+               float infection_coloridx = 0;
+               FOR_EACH_PLAYER(e)
                {
-                       winner = e;
-                       break;
+                       if (infection_coloridx < autocvar_g_infection_teams) // Limit alphas
+                               e.infectioncolor_original = infection_coloridx;
+                       infection_SetColor(e, infection_coloridx++ % bound(0, autocvar_g_infection_teams, 15));
                }
        }
-
-       if (winner.netname)
+       else
        {
-               UpdateFrags(winner, 1);
-
+               // Spawn too late, give player a random color
+               float color = 15;
+               float skip = random() * (infection_players_count - 1); // Ignore self
+               skip = rint(skip);
+               entity e;
                FOR_EACH_PLAYER(e)
                {
-                       centerprint(e, strcat(winner.netname, "^1 wins the round since their color survived.\n"));
+                       if (e == self || IS_OBSERVER(e)) continue;
+                       if (!skip --> 0) break;
                }
-               bprint(winner.netname, "^1 wins the round since their color survived.\n");
-       }
+               dprint(strcat("[INFECTION] copying ", e.netname, "'s color\n"));
+               color = e.infectioncolor;
+               self.infectioncolor_original = INFECTIONTEAM_NONE; // Can't win if player didn't spawn during the round delay
+               infection_SetColor(self, color);
+    }
+}
 
-       infection_Initialize();
+float infection_CheckTeams()
+{
+       return infection_players_count > 1;
 }
 
-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)
+float infection_CheckWinner()
 {
+       if (infection_players_count <= 1) return FALSE; // There can be no winner
+
+       if (0 < round_handler_GetEndTime() && round_handler_GetEndTime() <= time) // Round over
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
+               round_handler_Init(5, autocvar_g_infection_warmup, autocvar_g_infection_round_timelimit);
+               return TRUE;
+       }
+
+       // Check if only one color remains
+       float previnfectioncolor = -1;
+       float we_have_a_winner = TRUE; // TRUE until loop below proves us wrong
        entity e;
        FOR_EACH_PLAYER(e)
        {
-               if (e.infectioncolor_original == me.infectioncolor_original)
-               {
-                       return TRUE;
-               }
-               else if (e.infectioncolor_original == me.infectioncolor)
+               // All infection colors are the same if we have a winner
+               if (previnfectioncolor != -1 && previnfectioncolor != e.infectioncolor)
                {
-                       color_owner_green = strcat(e.netname, "^2's");
-                       color_owner_red = strcat(e.netname, "^1's");
+                       // In this case we still have more than one color alive
+                       we_have_a_winner = FALSE;
                        break;
                }
+               previnfectioncolor = e.infectioncolor;
        }
-       return FALSE;
-}
 
-MUTATOR_HOOKFUNCTION(infection_PlayerDies)
-{
-       // If this is the first time we die... (our infectioncolor remained unchanged)
-       if (frag_target.infectioncolor == frag_target.infectioncolor_original)
+       if (!we_have_a_winner) return FALSE;
+
+       // Who is it?
+       FOR_EACH_PLAYER(e)
        {
-               infection_GetColorOwner(frag_attacker);
-               entity e;
-               FOR_EACH_PLAYER(e) // check other players...
+               if (e.infectioncolor == e.infectioncolor_original)
                {
-                       if (e.infectioncolor == frag_target.infectioncolor) // And see if they have our original infection color
-                       {
-                               // 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;
-                               infection_SetColor(e, e.infectioncolor);
-                       }
+                       UpdateFrags(e, 10); // Bonus points
+                       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_PLAYER_WIN, e.netname);
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_PLAYER_WIN, e.netname);
                }
        }
-       else
-       {
-               frag_target.infectioncolor = frag_attacker.infectioncolor;
-               infection_SetColor(frag_target, frag_target.infectioncolor);
-       }
 
-       if (infection_GetColorOwner(frag_attacker))
-       {
-               color_owner_green = "^2your own";
-               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"));
+       round_handler_Init(5, autocvar_g_infection_warmup, autocvar_g_infection_round_timelimit);
+       return TRUE;
+}
 
-       bprint("^7", frag_target.netname, "^1 was infected by ^7", frag_attacker.netname, " ^1with ^7", color_owner_red, " ^1color.\n");
+void infection_RoundStart()
+{
+       infection_Assign(FALSE);
+       infection_CheckWinner();
+}
 
-       frag_target.health = cvar("g_balance_health_start"); // "respawn" the player
+void infection_Initialize()
+{
+       infection_players_count = 0;
+       round_handler_Spawn(infection_CheckTeams, infection_CheckWinner, infection_RoundStart);
+       round_handler_Init(5, autocvar_g_infection_warmup, autocvar_g_infection_round_timelimit);
+}
 
+MUTATOR_HOOKFUNCTION(infection_PlayerDies)
+{
        infection_CheckWinner();
-
        return TRUE;
 }
 
 MUTATOR_HOOKFUNCTION(infection_RemovePlayer)
 {
-       if (!self.infection_jointime)
-               return FALSE; // nothing to remove
+       if (!IS_PLAYER(self)) return TRUE; // Wasn't playing
 
        infection_players_count--;
 
-       // if other players have our color, randomize their color
-       // ... 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)
+       self.infectioncolor_original = INFECTIONTEAM_UNDEFINED;
+
+       // Grant alpha status to next of kin
+       entity e;
+       FOR_EACH_PLAYER(e)
        {
-               entity e;
-               FOR_EACH_PLAYER(e) // check other players...
+               if (e.infectioncolor == self.infectioncolor_original)
                {
-                       if (e.infectioncolor == self.infectioncolor_original) // and see if they have our original infection color
-                       {
-                               e.infectioncolor_original = self.infectioncolor;
-                               centerprint(frag_attacker, "^2You are now a master.\n");
-                               break;
-                       }
+                       e.infectioncolor_original = self.infectioncolor;
+                       centerprint(e, "^2You are now an alpha.\n");
+                       break;
                }
        }
 
-       if (infection_players_count > 1 && time >= next_round)
-               infection_CheckWinner();
-
+       infection_CheckWinner();
        return TRUE;
 }
 
 MUTATOR_HOOKFUNCTION(infection_PlayerSpawn)
 {
-       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 (self.infectioncolor_original != INFECTIONTEAM_UNDEFINED) return TRUE; // Wasn't observing
+       infection_players_count++;
+
+       infection_Assign(TRUE);
+
+       return TRUE;
+}
 
-       if (time >= next_round) // spawn too late, give player a random color
+MUTATOR_HOOKFUNCTION(infection_GiveFragsForKill)
+{
+       frag_score = 0;
+       infection_GetColorOwner(frag_attacker);
+       // If this is the first time we die... (our infectioncolor remained unchanged)
+       if (autocvar_g_infection_conversions && frag_target.infectioncolor == frag_target.infectioncolor_original)
        {
-               float skip = floor(random() * infection_players_count);
                entity e;
-               FOR_EACH_PLAYER(e)
+               FOR_EACH_PLAYER(e) // check other players...
                {
-                       if (skip--) continue;
-                       self.infectioncolor = e.infectioncolor;
-                       self.infectioncolor_original = -1; // can't win if player didn't spawn during the round delay
+                       if (e.infectioncolor == frag_target.infectioncolor) // And see if they have our original infection color
+                       {
+                               // 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 alpha ^7", frag_target.netname, "^1 was infected by ^7", frag_attacker.netname, " ^1with ^7", color_owner_red, " ^1color.\n"));
+                               infection_SetColor(e, frag_attacker.infectioncolor);
+                               frag_score++;
+                       }
                }
        }
-       else // we are still in the delay period before the round starts
+       else
        {
-               self.infectioncolor = infection_coloridx++;
-               self.infectioncolor_original = self.infectioncolor;
+               infection_SetColor(frag_target, frag_attacker.infectioncolor);
+               frag_score++;
        }
-       infection_SetColor(self, self.infectioncolor);
 
-       return TRUE;
-}
+       string target = frag_target.netname, attacker = frag_attacker.netname;
+
+       centerprint(frag_attacker, strcat("^2You infected ^7", target, " ^2with ^7", color_owner_green, " ^2color.\n"));
+       centerprint(frag_target, strcat("^1You were infected by ^7", attacker, " ^1with ^7", color_owner_red, " ^1color.\n"));
+
+       bprint("^7", frag_target.netname, "^1 was infected by ^7", attacker, " ^1with ^7", color_owner_red, " ^1color.\n");
 
-MUTATOR_HOOKFUNCTION(infection_GiveFragsForKill)
-{
-       frag_score = 0; // TODO: no frags counted in infection, maybe later
        return TRUE;
 }
 
 MUTATOR_HOOKFUNCTION(infection_PlayerPreThink)
 {
-       infection_SetColor(self, self.infectioncolor); // prevent cheating by changing player colors
+       if (IS_PLAYER(self))
+       {
+               // Prevent cheating by changing player colors
+               infection_SetColor(self, round_handler_IsRoundStarted()
+                       ? self.infectioncolor : 15
+               );
+       }
        return TRUE;
 }
 
@@ -215,11 +240,20 @@ MUTATOR_HOOKFUNCTION(infection_PlayerDamage_Calculate)
 
 MUTATOR_HOOKFUNCTION(infection_BotShouldAttack)
 {
-       return checkentity.infectioncolor == self.infectioncolor; // FIXME: Has reverse meaning
+       return checkentity.infectioncolor == self.infectioncolor;
+}
+
+MUTATOR_HOOKFUNCTION(infection_ClientConnect)
+{
+       self.infectioncolor_original = INFECTIONTEAM_UNDEFINED;
+       stuffcmd(self, "settemp cl_forceplayercolors 0\n");
+
+       return FALSE;
 }
 
 MUTATOR_DEFINITION(gamemode_infection)
 {
+       MUTATOR_HOOK(ClientConnect, infection_ClientConnect, CBC_ORDER_ANY);
        MUTATOR_HOOK(MakePlayerObserver, infection_RemovePlayer, CBC_ORDER_ANY);
        MUTATOR_HOOK(ClientDisconnect, infection_RemovePlayer, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerDies, infection_PlayerDies, CBC_ORDER_ANY);