From: terencehill Date: Thu, 7 Mar 2013 00:11:34 +0000 (+0100) Subject: Merge branch 'master' into terencehill/ca_arena_mutators X-Git-Tag: xonotic-v0.7.0~61^2~24 X-Git-Url: http://git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=3aed354c1125db3e6e862f552c253b06b09d5d86 Merge branch 'master' into terencehill/ca_arena_mutators Conflicts: qcsrc/client/announcer.qc qcsrc/common/constants.qh qcsrc/server/arena.qc qcsrc/server/cl_client.qc qcsrc/server/defs.qh qcsrc/server/mutators/gamemode_freezetag.qc --- 3aed354c1125db3e6e862f552c253b06b09d5d86 diff --cc qcsrc/client/announcer.qc index 5ca75123cd,240d424c6a..51c67ccabe --- a/qcsrc/client/announcer.qc +++ b/qcsrc/client/announcer.qc @@@ -22,36 -22,23 +22,36 @@@ void Announcer_Play(string announcement void Announcer_Countdown() { float starttime = getstatf(STAT_GAMESTARTTIME); + float roundstarttime = getstatf(STAT_ROUNDSTARTTIME); + if(roundstarttime == -1) + { + // stop countdown immediately + centerprint_generic(CPID_GAME_STARTING, "", 1, 0); + remove(self); + return; + } + if(roundstarttime >= starttime) + starttime = roundstarttime; + if(starttime <= time && roundstarttime != starttime) // game start time has passed + announcer_5min = announcer_1min = FALSE; // reset maptime announcers now as well + float countdown = (starttime - time); float countdown_rounded = floor(0.5 + countdown); - + if(countdown <= 0) // countdown has finished, starttime is now { - centerprint_generic(CPID_GAME_STARTING, _("^1Begin!"), 1, 0); - if (!spectatee_status) - Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN); ++ Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN); Announcer_Play("begin"); - announcer_5min = announcer_1min = FALSE; // reset maptime announcers now as well remove(self); return; } else // countdown is still going { - if (!spectatee_status) + if(roundstarttime == starttime) + centerprint_generic(CPID_GAME_STARTING, _("^1Round starts in %d seconds"), 1, countdown_rounded); + else - centerprint_generic(CPID_GAME_STARTING, _("^1Game starts in %d seconds"), 1, countdown_rounded); + Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_GAMESTART, countdown_rounded); if(countdown_rounded <= 3 && countdown_rounded >= 1) Announcer_Play(ftos(countdown_rounded)); diff --cc qcsrc/server/cl_client.qc index 4ee8bcb513,356d444c0c..67190df2d9 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@@ -1046,8 -1082,10 +1048,8 @@@ void ClientKill_Now_TeamChange( } else if(self.killindicator_teamchange == -2) { - if(g_ca) - self.caplayer = 0; if(blockSpectators) - sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n")); + Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); PutObserverInServer(); } else @@@ -2253,46 -2321,34 +2263,37 @@@ void ShowRespawnCountdown( } } - .float prevent_join_msgtime; void LeaveSpectatorMode() { + if(self.caplayer) + return; - if(nJoinAllowed(self)) { - if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) { + if(nJoinAllowed(self)) + { + if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) + { self.classname = "player"; if(autocvar_g_campaign || autocvar_g_balance_teams) - JoinBestTeam(self, FALSE, TRUE); + { JoinBestTeam(self, FALSE, TRUE); } if(autocvar_g_campaign) - campaign_bots_may_start = 1; + { campaign_bots_may_start = 1; } + else + { Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); } + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN); + PutClientInServer(); - if(self.classname == "player") - bprint ("^4", self.netname, "^4 is playing now\n"); - - if(!autocvar_g_campaign) - if (time < self.jointime + autocvar_welcome_message_time) - Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD - - if (self.prevent_join_msgtime) - { - Send_CSQC_Centerprint_Generic_Expire(self, CPID_PREVENT_JOIN); - self.prevent_join_msgtime = 0; - } - } else { - stuffcmd(self, "menu_showteamselect\n"); + if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); } } - else if not(g_ca && self.caplayer) { stuffcmd(self, "menu_showteamselect\n"); } ++ else ++ stuffcmd(self, "menu_showteamselect\n"); } - else { - //player may not join because of g_maxplayers is set - if (time - self.prevent_join_msgtime > 2) - { - Send_CSQC_Centerprint_Generic(self, CPID_PREVENT_JOIN, PREVENT_JOIN_TEXT, 0, 0); - self.prevent_join_msgtime = time; - } + else + { + // Player may not join because g_maxplayers is set + Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN); } } diff --cc qcsrc/server/cl_weapons.qc index 2715d475c8,2a1297dc2b..57b1cf4f4d --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@@ -357,27 -349,12 +347,24 @@@ void W_ThrowWeapon(vector velo, vector W_SwitchWeapon_Force(self, w_getbestweapon(self)); a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo); - if not(a) - return; - if(a == "") - sprint(self, strcat("You dropped the ^2", W_Name(w), "\n")); - else - sprint(self, strcat("You dropped the ^2", W_Name(w), " with ", a, "\n")); + + if not(a) return; + Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_WEAPON_DROP, a, w); } -// Bringed back weapon frame +float forbidWeaponUse() +{ + if(time < game_starttime && !autocvar_sv_ready_restart_after_countdown) + return 1; + if(round_handler_IsActive() && !round_handler_IsRoundStarted()) + return 1; + if(self.player_blocked) + return 1; + if(self.freezetag_frozen) + return 1; + return 0; +} + void W_WeaponFrame() { vector fo, ri, up; diff --cc qcsrc/server/command/cmd.qc index 96f3606021,6c1e0ed56f..4cb6650896 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@@ -154,11 -154,14 +154,13 @@@ void ClientCommand_join(float request { if(nJoinAllowed(self)) { - if(g_ca) { self.caplayer = 1; } if(autocvar_g_campaign) { campaign_bots_may_start = 1; } - + self.classname = "player"; PlayerScore_Clear(self); - bprint ("^4", self.netname, "^4 is playing now\n"); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); PutClientInServer(); } else diff --cc qcsrc/server/defs.qh index 80bf9a1c4a,5eaafe4f10..3281218ccb --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@@ -586,12 -588,8 +590,6 @@@ string deathmessage .void (float act_state) setactive; .entity realowner; - .float nex_charge; - .float nex_charge_rottime; - .float nex_chargepool_ammo; - - .float hagar_load; -float allowed_to_spawn; // boolean variable used by the clan arena code to determine if a player can spawn (after the round has ended) -- float serverflags; .float team_forced; // can be a team number to force a team, or 0 for default action, or -1 for forced spectator diff --cc qcsrc/server/mutators/gamemode_freezetag.qc index df3ad10a11,c43a398754..3853d49f27 --- a/qcsrc/server/mutators/gamemode_freezetag.qc +++ b/qcsrc/server/mutators/gamemode_freezetag.qc @@@ -1,143 -1,46 +1,141 @@@ -void freezetag_Initialize() +.float freezetag_frozen_time; +.float freezetag_frozen_timeout; +.float freezetag_revive_progress; +.entity freezetag_ice; +#define ICE_MAX_ALPHA 1 +#define ICE_MIN_ALPHA 0.1 +float freezetag_teams; + +void freezetag_count_alive_players() { - precache_model("models/ice/ice.md3"); - warmup = time + autocvar_g_start_delay + autocvar_g_freezetag_warmup; - ScoreRules_freezetag(); + entity e; + total_players = redalive = bluealive = yellowalive = pinkalive = 0; + FOR_EACH_PLAYER(e) { + if(e.team == COLOR_TEAM1 && e.health >= 1) + { + ++total_players; + if (!e.freezetag_frozen) ++redalive; + } + else if(e.team == COLOR_TEAM2 && e.health >= 1) + { + ++total_players; + if (!e.freezetag_frozen) ++bluealive; + } + else if(e.team == COLOR_TEAM3 && e.health >= 1) + { + ++total_players; + if (!e.freezetag_frozen) ++yellowalive; + } + else if(e.team == COLOR_TEAM4 && e.health >= 1) + { + ++total_players; + if (!e.freezetag_frozen) ++pinkalive; + } + } + FOR_EACH_REALCLIENT(e) { + e.redalive_stat = redalive; + e.bluealive_stat = bluealive; + e.yellowalive_stat = yellowalive; + e.pinkalive_stat = pinkalive; + } } +#define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0)) +#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams) -void freezetag_CheckWinner() +float prev_total_players; +float freezetag_CheckTeams() { - if(time <= game_starttime) // game didn't even start yet! nobody can win in that case. - return; - - if(next_round || (time > warmup - autocvar_g_freezetag_warmup && time < warmup)) - return; // already waiting for next round to start - - if((redalive >= 1 && bluealive >= 1) - || (redalive >= 1 && yellowalive >= 1) - || (redalive >= 1 && pinkalive >= 1) - || (bluealive >= 1 && yellowalive >= 1) - || (bluealive >= 1 && pinkalive >= 1) - || (yellowalive >= 1 && pinkalive >= 1)) - return; // we still have active players on two or more teams, nobody won yet - - entity e, winner; - winner = world; - - FOR_EACH_PLAYER(e) + entity e; + if(FREEZETAG_ALIVE_TEAMS_OK()) { - if(e.freezetag_frozen == 0 && e.health >= 1) // here's one player from the winning team... good + if(prev_total_players != -1) { - winner = e; - break; // break, we found the winner + FOR_EACH_REALCLIENT(e) + Send_CSQC_Centerprint_Generic_Expire(e, CPID_WAITING_PLAYERS); } + prev_total_players = -1; + return 1; + } + if(prev_total_players != total_players) + { + string teams_missing = ""; + if(!redalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM1), ", "); + if(!bluealive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM2), ", "); + if(freezetag_teams >= 3) + if(!yellowalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM3), ", "); + if(freezetag_teams == 4) + if(!pinkalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM4), ", "); + teams_missing = substring(teams_missing, 0, strlen(teams_missing)-2); + + FOR_EACH_REALCLIENT(e) + Send_CSQC_Centerprint_Generic(e, CPID_WAITING_PLAYERS, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, 0); + prev_total_players = total_players; + } + return 0; +} + +float freezetag_getWinnerTeam() +{ + float winner_team = 0; + if(redalive >= 1) + winner_team = COLOR_TEAM1; + if(bluealive >= 1) + { + if(winner_team) return 0; + winner_team = COLOR_TEAM2; + } + if(yellowalive >= 1) + { + if(winner_team) return 0; + winner_team = COLOR_TEAM3; + } + if(pinkalive >= 1) + { + if(winner_team) return 0; + winner_team = COLOR_TEAM4; + } + if(winner_team) + return winner_team; + return -1; // no player left +} + +float freezetag_CheckWinner() +{ + entity e; + if(round_handler_GetTimeLeft() <= 0) + { + FOR_EACH_REALCLIENT(e) + centerprint(e, "Round over, there's no winner"); + bprint("Round over, there's no winner.\n"); + FOR_EACH_PLAYER(e) + e.freezetag_frozen_timeout = 0; + round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit); + return 1; } - if(winner != world) // just in case a winner wasn't found + if(FREEZETAG_ALIVE_TEAMS() > 1) + return 0; + + float winner_team; + string teamname; + winner_team = freezetag_getWinnerTeam(); + if(winner_team > 0) { - teamname = ColoredTeamName(winner_team); - FOR_EACH_REALCLIENT(e) - centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen.")); - bprint(teamname, "^5 wins the round since all the other teams were frozen.\n"); + Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner.team, CENTER_FREEZETAG_ROUND_WIN_)); + Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner.team, INFO_FREEZETAG_ROUND_WIN_)); - TeamScore_AddToTeam(winner.team, ST_SCORE, +1); + TeamScore_AddToTeam(winner_team, ST_SCORE, +1); + } + else if(winner_team == -1) + { + FOR_EACH_REALCLIENT(e) + centerprint(e, "^5Round tied! All teams were frozen."); + bprint("^5Round tied! All teams were frozen.\n"); } - next_round = time + 5; + FOR_EACH_PLAYER(e) + e.freezetag_frozen_timeout = 0; + round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit); + return 1; } // this is needed to allow the player to turn his view around (fixangle can't @@@ -388,21 -291,17 +386,21 @@@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDi MUTATOR_HOOKFUNCTION(freezetag_PlayerSpawn) { - freezetag_Unfreeze(world); // start by making sure that all ice blocks are removed + if(self.freezetag_frozen_timeout == -1) // if PlayerSpawn is called by reset_map_players + return 1; // do nothing, round is starting right now - if(total_players == 1 && time > game_starttime) // only one player active on server, start a new match immediately - if(!next_round && warmup && (time < warmup - autocvar_g_freezetag_warmup || time > warmup)) // not awaiting next round + if(self.freezetag_frozen_timeout == -2) // player was dead { - next_round = time; + freezetag_Freeze(world); return 1; } - if(warmup && time > warmup) // spawn too late, freeze player + + freezetag_count_alive_players(); + + if(round_handler_IsActive()) + if(round_handler_IsRoundStarted()) { - centerprint(self, "^1Round already started, you spawn as frozen."); + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_SPAWN_LATE); freezetag_Freeze(world); } @@@ -505,23 -365,21 +503,17 @@@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPr } } - if(n > 1) - centerprint(self, strcat("^5You were revived by ^7", o.netname, "^5 et al.\n")); - else - centerprint(self, strcat("^5You were revived by ^7", o.netname, "^5.\n")); - centerprint(o, strcat("^5You revived ^7", self.netname, "^5.\n")); - if(n > 1) - bprint("^7", o.netname, "^5 et al revived ^7", self.netname, "^5.\n"); - else - bprint("^7", o.netname, "^5 revived ^7", self.netname, "^5.\n"); + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname); + Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname); + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVE, self.netname, o.netname); } - // now find EVERY teammate within reviving radius, set their revive_progress values correct - FOR_EACH_PLAYER(other) if(self != other) + FOR_EACH_PLAYER(other) { - if(other.freezetag_frozen == 0) + if(other.reviving) { - if(other.team == self.team) - { - if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax)) - other.freezetag_revive_progress = self.freezetag_revive_progress; - } + other.freezetag_revive_progress = self.freezetag_revive_progress; + other.reviving = FALSE; } } } diff --cc qcsrc/server/mutators/gamemode_keyhunt.qh index 55614ff8ef,bda701f96a..611f7f065e --- a/qcsrc/server/mutators/gamemode_keyhunt.qh +++ b/qcsrc/server/mutators/gamemode_keyhunt.qh @@@ -6,6 -6,7 +6,6 @@@ float kh_tracking_enabled .entity kh_next; float kh_Key_AllOwnedByWhichTeam(); -// used by arena.qc ready-restart: typedef void(void) kh_Think_t; void kh_StartRound(); - void kh_Controller_SetThink_NoMsg(float t, kh_Think_t func); + void kh_Controller_SetThink(float t, kh_Think_t func); diff --cc qcsrc/server/progs.src index fcc82ed085,a00fd32c5e..03326da843 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@@ -28,10 -30,11 +30,13 @@@ autocvars.q constants.qh defs.qh // Should rename this, it has fields and globals + ../common/notifications.qh // must be after autocvars + ../common/deathtypes.qh // must be after notifications + mutators/base.qh mutators/mutators.qh +mutators/gamemode_arena.qh +mutators/gamemode_ca.qh mutators/gamemode_ctf.qh mutators/gamemode_domination.qh mutators/gamemode_keyhunt.qh // TODO fix this