set g_lms_start_ammo_cells 180
set g_lms_start_ammo_plasma 180
set g_lms_start_ammo_fuel 0
+set g_mayhem_start_health 200
+set g_mayhem_start_armor 200
+set g_mayhem_start_ammo_shells 60
+set g_mayhem_start_ammo_nails 320
+set g_mayhem_start_ammo_rockets 160
+set g_mayhem_start_ammo_cells 180
+set g_mayhem_start_ammo_plasma 180
+set g_mayhem_start_ammo_fuel 0
+set g_tmayhem_start_health 200
+set g_tmayhem_start_armor 200
+set g_tmayhem_start_ammo_shells 60
+set g_tmayhem_start_ammo_nails 320
+set g_tmayhem_start_ammo_rockets 160
+set g_tmayhem_start_ammo_cells 180
+set g_tmayhem_start_ammo_plasma 180
+set g_tmayhem_start_ammo_fuel 0
set g_balance_nix_roundtime 25
set g_balance_nix_incrtime 1.6
set g_balance_nix_ammo_shells 60
set g_balance_powerup_invincible_time 30
set g_balance_powerup_invisibility_alpha 0.15
set g_balance_powerup_invisibility_time 30
- set g_balance_powerup_speed_attackrate 0.8
- set g_balance_powerup_speed_highspeed 1.5
- set g_balance_powerup_speed_time 30
+ set g_balance_powerup_speed_attackrate 0.7692307692 // 1/1.3
+ set g_balance_powerup_speed_highspeed 1.3
+ set g_balance_powerup_speed_time 30 // q3 haste lasts 30 seconds unless count field set otherwise
set g_balance_powerup_strength_damage 3
set g_balance_powerup_strength_force 3
set g_balance_powerup_strength_time 30
// ===============================================
// menu_cmd (menu command) - menu/command/menu_cmd.qc
// ===============================================
+ alias menu_showwelcomedialog "menu_cmd directmenu Welcome"
alias menu_showteamselect "menu_cmd directmenu TeamSelect"
alias menu_showhudexit "menu_cmd directmenu HUDExit"
alias menu_showhudoptions "menu_cmd directpanelhudmenu ${* ?}"
alias menu_showsandboxtools "menu_cmd directmenu SandboxTools"
alias menu_showquitdialog "menu_cmd directmenu Quit"
- alias menu_showdisconnectdialog "menu_cmd directmenu Disconnect"
+ alias menu_showgamemenudialog "menu_cmd directmenu GameMenu"
alias menu_showmonstertools "menu_cmd directmenu MonsterTools"
// command executed before loading a map by the menu
alias team_blue "cmd selectteam blue; cmd join"
alias team_pink "cmd selectteam pink; cmd join"
alias team_yellow "cmd selectteam yellow; cmd join"
- alias team_auto "cmd selectteam auto; cmd join"
+ alias team_auto "togglemenu 0; cmd selectteam auto; cmd join"
alias spec "spectate ${* ?}"
alias warp "qc_cmd_sv warp ${* ?}" // Choose different level in campaign
// other aliases for server commands
- alias endmatch "timelimit -1"
+ set _endmatch 0 "if set to 1 ends the match immediately; use it instead of timelimit -1 (deprecated)"
+ alias endmatch "_endmatch 1"
alias bots "minplayers 4; minplayers_per_team 2"
alias nobots "minplayers 0; minplayers_per_team 0"
// ===================================
alias ban "qc_cmd_sv ban ${* ?}" // Ban an IP address or a range of addresses (like 1.2.3)
alias banlist "qc_cmd_sv banlist ${* ?}" // List all existing bans
+alias kickkick "qc_cmd_sv kickkick ${* ?}" // Disconnect a client
alias kickban "qc_cmd_sv kickban ${* ?}" // Disconnect a client and ban it at the same time
alias mute "qc_cmd_sv mute ${* ?}" // Disallow a client from talking by muting them
alias unban "qc_cmd_sv unban ${* ?}" // Remove an existing ban
alias sv_hook_gamestart_ft
alias sv_hook_gamestart_inv
alias sv_hook_gamestart_duel
+alias sv_hook_gamestart_mmm //LegendGuard adds mmm hook for MMM 20-02-2021
+alias sv_hook_gamestart_mayhem
+alias sv_hook_gamestart_tmayhem
// there is currently no hook for when the match is restarted
// see sv_hook_readyrestart for previous uses of this hook
//alias sv_hook_gamerestart
alias sv_vote_gametype_hook_rc
alias sv_vote_gametype_hook_tdm
alias sv_vote_gametype_hook_duel
+alias sv_vote_gametype_hook_mmm //LegendGuard adds mmm hook for MMM 20-02-2021
+alias sv_vote_gametype_hook_mayhem
+alias sv_vote_gametype_hook_tmayhem
// Example preset to allow 1v1ctf to be used for the gametype voting screen.
// Aliases can have max 31 chars so the gametype can have max 9 chars.
set g_duel_respawn_delay_max 0
set g_duel_respawn_waves 0
set g_duel_weapon_stay 0
+set g_mmm_respawn_delay_small 0 //LegendGuard adds mmm cvars for MMM 20-02-2021
+set g_mmm_respawn_delay_small_count 0
+set g_mmm_respawn_delay_large 0
+set g_mmm_respawn_delay_large_count 0
+set g_mmm_respawn_delay_max 0
+set g_mmm_respawn_waves 0
+set g_mmm_weapon_stay 0
+set g_mayhem_respawn_delay_small 0
+set g_mayhem_respawn_delay_small_count 0
+set g_mayhem_respawn_delay_large 0
+set g_mayhem_respawn_delay_large_count 0
+set g_mayhem_respawn_delay_max 0
+set g_mayhem_respawn_waves 0
+set g_mayhem_weapon_stay 0
+set g_tmayhem_respawn_delay_small 0
+set g_tmayhem_respawn_delay_small_count 0
+set g_tmayhem_respawn_delay_large 0
+set g_tmayhem_respawn_delay_large_count 0
+set g_tmayhem_respawn_delay_max 0
+set g_tmayhem_respawn_waves 0
+set g_tmayhem_weapon_stay 0
// =========
set g_lms_join_anytime 1 "1: new players can join, but get same amount of lives as the worst player; 0: new players can only join if the worst active player has (fraglimit - g_lms_last_join) or more lives"
set g_lms_items 0 "enables items to spawn, weaponarena still disables weapons and ammo (to force all items to spawn, use g_pickup_items 1 instead)"
set g_lms_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena"
+ set g_lms_forfeit_min_match_time 30 "end the match early if at least this many seconds have elapsed and less than 2 players are playing due to forfeits"
// =========
//set g_duel_warmup 180 "Have a short warmup period before beginning the actual duel"
set g_duel_with_powerups 0 "Enable powerups to spawn in the duel gamemode"
set g_duel_not_dm_maps 0 "when this is set, DM maps will NOT be listed in duel"
+
+//LegendGuard adds mmm cvars for MMM 20-02-2021
+// ==========
+// murder in megaerebus manor
+// ==========
+set g_mmm 0 "Murder in Megaerebus Manor: A group of space civilians have murderers among them. Murderers must kill civilians, while the civilians have to try to find and kill the murderers"
+set g_mmm_not_lms_maps 0 "when this is set, LMS maps will NOT be listed in mmm"
+set g_mmm_not_dm_maps 0 "when this is set, DM maps will NOT be listed in mmm"
+set g_mmm_murderer_count 0.25 "number of players who will become murderers, set between 0 and 0.9 to use a multiplier of the current players, or 1 and above to specify an exact number of players"
+set g_mmm_detective_count 0.125 "number of players who will become detectives, set between 0 and 0.9 to use a multiplier of the current players, or 1 and above, to specify an exact number of players. 0 = no detectives"
+set g_mmm_punish_teamkill 0 "enable option to kill the player when they kill an ally"
+set g_mmm_reward_civilian 1 "give a point to all civilian players if the round timelimit is reached, in addition to the points given for kills"
+set g_mmm_warmup 10 "how long the players will have time to run around the map before the round starts"
+set g_mmm_round_timelimit 180 "round time limit in seconds"
+set g_mmm_max_karma_points 1000 "limit of maximum number of karma points will have in the server"
+set g_mmm_min_karma_points 550 "limit where number of karma points can be reached when are being decreased"
+set g_mmm_karma_bankick_tool 1 "tool for strict rules when karma is low: '0' nothing does, '1' forces player to spec, '2' kicks player, '3' bans player"
+set g_mmm_karma_bantime 1800 "number of seconds to ban someone with very low karma"
+set g_mmm_karma_damageactive 1 "enable karma damage rule. If a player's karma is low, they will not do as much damage as a player who has high or full karma"
+set g_mmm_karma_damagepunishmentdeal 20 "punishment damage points when player kills an ally"
+set g_mmm_karma_severity 0.25 "how severe karma is to decrease karma points to the players [0.1 - 1.0]"
+set g_mmm_reward_sleuth 1 "give a point to all sleuth players if investigated corpses"
+set g_mmm_reward_detective 1 "give a point to all detective players if investigated corpses"
+
+// ==============================
+// free for all and team mayhem
+// ==============================
+set g_mayhem 0 "Mayhem: Compete for the most damage dealt and frags in this chaotic mayhem!"
+set g_tmayhem 0 "Team Mayhem: Compete with your team for the most damage dealt and frags in this chaotic mayhem!"
+
+set g_mayhem_scoringmethod 1 "1: By default 25% of the score is based on kills and 75% of it is based on damage. 2: 100% frags. 3: 100% damage."
+set g_tmayhem_scoringmethod 1 "1: By default 25% of the score is based on kills and 75% of it is based on damage. 2: 100% frags. 3: 100% damage."
+set g_mayhem_scoringmethod_1_damage_weight 0.75 "for the first scoring method how much is damage equal to player's spawning health worth in score"
+set g_tmayhem_scoringmethod_1_damage_weight 0.75 "for the first scoring method how much is damage equal to player's spawning health worth in score"
+set g_mayhem_scoringmethod_1_disable_selfdamage2score 0 "disable reducing score with self damage at the cost of full penalty for suicides regardless of how much health was lost suiciding"
+set g_tmayhem_scoringmethod_1_disable_selfdamage2score 0 "disable reducing score with self damage at the cost of full penalty for suicides regardless of how much health was lost suiciding"
+set g_mayhem_scoringmethod_1_frag_weight 0.25 "for the first scoring method how much is a frag worth in score"
+set g_tmayhem_scoringmethod_1_frag_weight 0.25 "for the first scoring method how much is a frag worth in score"
+
+set g_mayhem_fraglimit 30 "Team Mayhem basis for how many frags until the match ends, edit this over point_limit preferably"
+set g_tmayhem_fraglimit 50 "Team Mayhem basis for how many frags until the match ends, edit this over point_limit preferably"
+
+set g_mayhem_visual_score_limit 1000 "Mayhem visual score limit overriding the mapinfo specified one"
+set g_tmayhem_visual_score_limit 1000 "Team Mayhem visual score limit overriding the mapinfo specified one"
+
+set g_tmayhem_score_leadlimit -1 "Team Mayhem score lead limit(based on tmayhem_visual_score_limit, not tmayhem_fraglimit) overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+
+set g_mayhem_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena"
+set g_tmayhem_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena"
+
+set g_mayhem_powerups 1 "Allow powerups in mayhem. Only checked if g_powerups is -1 therefore this will be overridden by g_powerups 1 or 0"
+set g_tmayhem_powerups 1 "Allow powerups in team mayhem. Only checked if g_powerups is -1 therefore this will be overridden by g_powerups 1 or 0"
+set g_mayhem_pickup_items 0 "spawn pickup items in mayhem"
+set g_tmayhem_pickup_items 0 "spawn pickup items in team mayhem"
+set g_mayhem_pickup_items_remove_weapons_and_ammo 1 "when pickup items are enabled in mayhem still remove weapons and ammo pickups"
+set g_tmayhem_pickup_items_remove_weapons_and_ammo 1 "when pickup items are enabled in team mayhem still remove weapons and ammo pickups"
+
+set g_mayhem_selfdamage 0 "0 = disable selfdamage in mayhem, 1 = enable selfdamage in mayhem"
+set g_tmayhem_selfdamage 0 "0 = disable selfdamage in tmayhem, 1 = enable selfdamage in tmayhem"
+
+set g_mayhem_regenerate 0 "health and/or armor regeneration, according to g_balance_health_regen and g_balance_armor_regen"
+set g_tmayhem_regenerate 0 "health and/or armor regeneration, according to g_balance_health_regen and g_balance_armor_regen"
+set g_mayhem_rot 0 "health and/or armor rotting, according to g_balance_health_rot and g_balance_armor_rot"
+set g_tmayhem_rot 0 "health and/or armor rotting, according to g_balance_health_rot and g_balance_armor_rot"
+
+set g_tmayhem_teams 2 "how many teams are in team mayhem (set by mapinfo)"
+set g_tmayhem_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
+set g_tmayhem_teams_override 0 "how many teams are in team mayhem"
seta notification_INFO_SUPERWEAPON_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_TEAMCHANGE_LARGERTEAM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_TEAMCHANGE_NOTALLOWED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+
+//LegendGuard adds mmm notifications for MMM 20-02-2021
+seta notification_INFO_MMM_MURDERER_WIN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_MMM_CIVILIAN_WIN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+
seta notification_INFO_VERSION_BETA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_VERSION_OLD "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_VERSION_OUTDATED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_OBJ_DESTROYED "1" "0 = off, 1 = centerprint"
- seta notification_CENTER_CAMPAIGN_MESSAGE "1" "0 = off, 1 = centerprint"
seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint"
seta notification_CENTER_COINTOSS "1" "0 = off, 1 = centerprint"
seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint"
seta notification_CENTER_KEYHUNT_SCAN "1" "0 = off, 1 = centerprint"
seta notification_CENTER_KEYHUNT_START "1" "0 = off, 1 = centerprint"
seta notification_CENTER_LMS_NOLIVES "1" "0 = off, 1 = centerprint"
+ seta notification_CENTER_LMS_SPECWARN "1" "0 = off, 1 = centerprint"
seta notification_CENTER_MISSING_PLAYERS "1" "0 = off, 1 = centerprint"
seta notification_CENTER_MISSING_TEAMS "1" "0 = off, 1 = centerprint"
seta notification_CENTER_MOTD "1" "0 = off, 1 = centerprint"
seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "0 = off, 1 = centerprint"
seta notification_CENTER_TIMEOUT_BEGINNING "1" "0 = off, 1 = centerprint"
seta notification_CENTER_TIMEOUT_ENDING "1" "0 = off, 1 = centerprint"
+
+//LegendGuard adds mmm notification for MMM 20-02-2021
+seta notification_CENTER_MMM_MURDERER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MMM_MURDERER_WIN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MMM_CIVILIAN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MMM_CIVILIAN_WIN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MMM_DETECTIVE "1" "0 = off, 1 = centerprint"
+
seta notification_CENTER_VEHICLE_ENTER "1" "0 = off, 1 = centerprint"
seta notification_CENTER_VEHICLE_ENTER_GUNNER "1" "0 = off, 1 = centerprint"
seta notification_CENTER_VEHICLE_ENTER_STEAL "1" "0 = off, 1 = centerprint"
#include "announcer.qh"
+ #include <client/draw.qh>
#include <client/hud/panel/centerprint.qh>
#include <client/mutators/_mod.qh>
#include <common/notifications/all.qh>
#include <common/stats.qh>
#include <common/mapinfo.qh>
-
#include <common/ent_cs.qh>
- #include <common/gamemodes/gamemode/duel/duel.qh>
bool announcer_1min;
bool announcer_5min;
{
float starttime = STAT(GAMESTARTTIME);
float roundstarttime = STAT(ROUNDSTARTTIME);
- if(roundstarttime == -1)
+ bool game_timeout = (STAT(TIMEOUT_LAST) > 0);
+
+ if(roundstarttime == -1 || game_timeout)
{
Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_ROUNDSTOP);
delete(this);
return;
}
- if(starttime <= time && roundstarttime != starttime) // game start time has passed
- announcer_5min = announcer_1min = false; // reset maptime announcers now as well
-
bool inround = (roundstarttime && time >= starttime);
float countdown = (inround ? roundstarttime - time : starttime - time);
float countdown_rounded = floor(0.5 + countdown);
+ if(time >= starttime) centerprint_ClearTitle();
+
if(countdown <= 0) // countdown has finished, starttime is now
{
Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN);
{
if(inround)
{
- Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_ROUNDSTART, countdown_rounded);
+ Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_ROUNDSTART, STAT(ROUNDS_PLAYED) + 1, countdown_rounded);
Notification annce_num = Announcer_PickNumber(CNT_ROUNDSTART, countdown_rounded);
if(annce_num != NULL)
Local_Notification(MSG_ANNCE, annce_num);
* timelimit, fraglimit and game_starttime! Requires engine changes (remove STAT_TIMELIMIT
* and STAT_FRAGLIMIT to be auto-sent)
*/
- float previous_game_starttime;
+ float previous_game_starttime;
void Announcer_Gamestart()
{
float startTime = STAT(GAMESTARTTIME);
setthink(announcer_countdown, Announcer_Countdown);
}
- // z411 set title
- if(time < STAT(GAMESTARTTIME) && !warmup_stage) {
- if(gametype == MAPINFO_TYPE_DUEL) {
+ if(!warmup_stage && time < STAT(GAMESTARTTIME))
+ {
+ if (gametype.m_1v1)
+ {
entity pl1 = players.sort_next;
entity pl2 = pl1.sort_next;
-
- centerprint_SetTitle(strcat(entcs_GetName(pl1.sv_entnum), " vs ", entcs_GetName(pl2.sv_entnum)));
- } else {
- centerprint_SetTitle(MapInfo_Type_ToText(gametype));
+ string pl1_name = (pl1 && pl1.team != NUM_SPECTATOR ? entcs_GetName(pl1.sv_entnum) : "???");
+ string pl2_name = (pl2 && pl2.team != NUM_SPECTATOR ? entcs_GetName(pl2.sv_entnum) : "???");
+
+ float offset = stringwidth(pl2_name, true, hud_fontsize) - stringwidth(pl1_name, true, hud_fontsize) - 1;
+ centerprint_SetTitle(sprintf("^BG%s^BG%s%s", pl1_name, _(" vs "), pl2_name), offset / 2); // Show duelers in 1v1 game mode
}
- }
-
- if(time + 5.0 < startTime) // if connecting to server while restart was active don't always play prepareforbattle
- if(time > announcer_countdown.nextthink && !warmup_stage && time < STAT(GAMESTARTTIME)) { // don't play it again if countdown was already going
- if(teamplay)
- Local_Notification(MSG_ANNCE, ANNCE_PREPARE_TEAM);
else
- Local_Notification(MSG_ANNCE, ANNCE_PREPARE);
+ centerprint_SetTitle(strcat("^BG", MapInfo_Type_ToText(gametype)), 0); // Show game type as title
+
+ if(time + 5.0 < startTime) // if connecting to server while restart was active don't always play prepareforbattle
- Local_Notification(MSG_ANNCE, ANNCE_PREPARE);
++ if(teamplay)
++ Local_Notification(MSG_ANNCE, ANNCE_PREPARE_TEAM);
++ else
++ Local_Notification(MSG_ANNCE, ANNCE_PREPARE);
}
-
+
announcer_countdown.nextthink = startTime - floor(startTime - time + 0.5); //synchronize nextthink to startTime
}
}
void Announcer_Time()
{
+ static bool warmup_stage_prev;
+
if(intermission)
return;
+ if (warmup_stage != warmup_stage_prev)
+ {
+ announcer_5min = announcer_1min = false;
+ warmup_stage_prev = warmup_stage;
+ return;
+ }
+
+ float starttime = STAT(GAMESTARTTIME);
+ if(time < starttime)
+ {
+ announcer_5min = announcer_1min = false;
+ return;
+ }
+
float timeleft;
if(warmup_stage)
{
timeleft = 0;
}
else
- timeleft = max(0, STAT(TIMELIMIT) * 60 + STAT(GAMESTARTTIME) - time);
+ timeleft = max(0, STAT(TIMELIMIT) * 60 + starttime - time);
if(autocvar_cl_announcer_maptime >= 2)
ANNOUNCER_CHECKMINUTE(5);
const int CENTERPRINT_MAX_MSGS = 10;
const int CENTERPRINT_MAX_ENTRIES = 50;
- const float CENTERPRINT_SPACING = 0.7;
+ const float CENTERPRINT_BASE_SIZE = 1.4;
+ const float CENTERPRINT_SPACING = 0.5;
+ const float CENTERPRINT_TITLE_SPACING = 0.35;
int cpm_index;
string centerprint_messages[CENTERPRINT_MAX_MSGS];
int centerprint_msgID[CENTERPRINT_MAX_MSGS];
- bool centerprint_bold[CENTERPRINT_MAX_MSGS];
float centerprint_time[CENTERPRINT_MAX_MSGS];
+ float centerprint_start_time[CENTERPRINT_MAX_MSGS];
float centerprint_expire_time[CENTERPRINT_MAX_MSGS];
int centerprint_countdown_num[CENTERPRINT_MAX_MSGS];
bool centerprint_showing;
- bool centerprint_title_show;
+float centerprint_medal_expire_time;
+string centerprint_medal_icon;
+float centerprint_medal_times;
+
string centerprint_title;
-
- void centerprint_ClearTitle()
- {
- centerprint_title = string_null;
- centerprint_title_show = false;
- }
- void centerprint_SetTitle(string title)
- {
- if(title != centerprint_title) {
- if(centerprint_title)
- strunzone(centerprint_title);
- centerprint_title = strzone(title);
-
- centerprint_title_show = true;
- }
- }
-
- void centerprint_Medal(string icon, float times)
- {
- if(!autocvar_hud_panel_centerprint_medals) return;
-
- //LOG_INFOF("centerprint_Medal: icon: %s times: %d", icon, times);
- //centerprint_medal_expire_time = time + autocvar_hud_panel_centerprint_time;
- centerprint_medal_expire_time = time + MSG_MEDAL_TIME;
- centerprint_medal_times = times;
- if(centerprint_medal_icon)
- strunzone(centerprint_medal_icon);
- centerprint_medal_icon = strzone(strcat("gfx/medal/", icon));
-
- centerprint_showing = true;
- }
+ float centerprint_title_offset;
void centerprint_Add(int new_id, string strMessage, float duration, int countdown_num)
{
if(strMessage == "" && new_id == 0)
return;
- // strip BOLD_OPERATOR
- bool is_bold = (substring(strMessage, 0, 5) == BOLD_OPERATOR);
- if (is_bold)
- strMessage = substring(strMessage, 5, -1);
-
// strip trailing newlines
j = strlen(strMessage) - 1;
while(substring(strMessage, j, 1) == "\n" && j >= 0)
}
}
+ if (strMessage == "")
+ return;
+
if (i == CENTERPRINT_MAX_MSGS)
{
// a msg with the same id was not found, add the msg at the next position
j = cpm_index;
}
strcpy(centerprint_messages[j], strMessage);
- centerprint_bold[j] = is_bold;
+ centerprint_start_time[j] = time;
centerprint_msgID[j] = new_id;
if (duration < 0)
{
{
for (int i=0; i<CENTERPRINT_MAX_MSGS; ++i)
{
+ centerprint_start_time[i] = 0;
centerprint_expire_time[i] = 0;
centerprint_time[i] = 1;
centerprint_msgID[i] = 0;
- centerprint_bold[i] = false;
strfree(centerprint_messages[i]);
}
}
- if(centerprint_title)
- strfree(centerprint_title);
-
- centerprint_title = strzone(CCR(title));
++void centerprint_Medal(string icon, float times)
++{
++ if(!autocvar_hud_panel_centerprint_medals) return;
++
++ //LOG_INFOF("centerprint_Medal: icon: %s times: %d", icon, times);
++ //centerprint_medal_expire_time = time + autocvar_hud_panel_centerprint_time;
++ centerprint_medal_expire_time = time + MSG_MEDAL_TIME;
++ centerprint_medal_times = times;
++ if(centerprint_medal_icon)
++ strunzone(centerprint_medal_icon);
++ centerprint_medal_icon = strzone(strcat("gfx/medal/", icon));
++
++ centerprint_showing = true;
++}
++
+ void centerprint_ClearTitle()
+ {
+ strfree(centerprint_title);
+ centerprint_title_offset = 0;
+ }
+
+ void centerprint_SetTitle(string title, float offset)
+ {
+ if(title != centerprint_title) {
++ strcpy(centerprint_title, CCR(title));
+ centerprint_title_offset = offset;
+ }
+ }
+
float hud_configure_cp_generation_time;
void HUD_CenterPrint()
{
{
if(!autocvar_hud_panel_centerprint) return;
- if(hud_configure_prev)
+ if(hud_configure_prev) {
+ centerprint_ClearTitle();
centerprint_KillAll();
+ }
}
else
{
{
if(highlightedPanel == HUD_PANEL(CENTERPRINT))
{
+ centerprint_SetTitle(sprintf(_("Title at %s"), seconds_tostring(hud_configure_cp_generation_time)), 0);
+
float r;
r = random();
if (r > 0.8)
centerprint_Add(floor(r*1000), sprintf(_("^3Countdown message at time %s, seconds left: ^COUNT"), seconds_tostring(time)), 1, 10);
else if (r > 0.55)
- centerprint_Add(0, sprintf(_("^1Multiline message at time %s that\n^1lasts longer than normal"), seconds_tostring(time)), 20, 0);
+ centerprint_Add(0, sprintf(_("^1Multiline message at time %s that\n^BOLDlasts longer than normal"), seconds_tostring(time)), 20, 0);
else
centerprint_AddStandard(sprintf(_("Message at time %s"), seconds_tostring(time)));
hud_configure_cp_generation_time = time + 1 + random()*4;
panel_size -= '2 2 0' * panel_bg_padding;
}
- int entries;
- float height;
- vector fontsize;
-
int i, j, k, n, g;
- float a, sz, align, current_msg_posY = 0, msg_size;
- vector pos, mysize, newsize;
- string ts;
+ float a = 1, sz, align, current_msg_posY = 0, msg_size;
+ vector pos;
+ vector cp_fontsize = hud_fontsize * CENTERPRINT_BASE_SIZE;
+ string ts = "";
bool all_messages_expired = true;
pos = panel_pos;
- height = vid_conheight/50 * 4;
- pos.y -= height;
++
+ if (autocvar_hud_panel_centerprint_flip)
+ pos.y += panel_size.y;
+ align = bound(0, autocvar_hud_panel_centerprint_align, 1);
+
+ // z411 draw medals first
+ if (autocvar_hud_panel_centerprint_medals && time < centerprint_medal_expire_time) {
++ float height = vid_conheight/50 * 4;
++ pos.y -= height;
++
+ if(time < centerprint_medal_expire_time - MSG_MEDAL_FADE_TIME)
+ a = 1;
+ else
+ a = (centerprint_medal_expire_time - time) / MSG_MEDAL_FADE_TIME;
+
+ vector tmp_in = pos;
+
- mysize = draw_getimagesize(centerprint_medal_icon);
- newsize = vec2(height*(mysize.x/mysize.y), height);
- fontsize = '1 1 0' * (newsize.y/2);
++ vector mysize = draw_getimagesize(centerprint_medal_icon);
++ vector newsize = vec2(height*(mysize.x/mysize.y), height);
++ vector fontsize = '1 1 0' * (newsize.y/2);
+
+ tmp_in.x += (panel_size.x - newsize.x) / 2; // center medal icon
+
+ if(centerprint_medal_times < autocvar_hud_panel_centerprint_medals_max) {
+ tmp_in.x -= ((newsize.x * 1.1) * (centerprint_medal_times - 1) / 2);
+ for(int t = 0; t < centerprint_medal_times; t++) {
+ drawpic(tmp_in, centerprint_medal_icon, newsize, '1 1 1', a, DRAWFLAG_NORMAL);
+ tmp_in.x += newsize.x * 1.1;
+ }
+ } else {
+ drawpic(tmp_in, centerprint_medal_icon, newsize, '1 1 1', a, DRAWFLAG_NORMAL);
+ tmp_in.x += newsize.x + fontsize.x * 0.25; // draw times next to it
+ tmp_in.y += (newsize.y - fontsize.y) / 2;
+ drawstring(tmp_in, ftos(centerprint_medal_times), fontsize, '1 1 1', a, DRAWFLAG_NORMAL);
+ }
++
++ pos.y += height;
+
+ all_messages_expired = false;
+ }
-
- // continue with normal procedure
- pos.y += height;
-
- // z411 title
- if(centerprint_title_show) {
- fontsize = '1 1 0' * vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale * 1.5;
- drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(centerprint_title, true, fontsize)), centerprint_title, fontsize, 1, DRAWFLAG_NORMAL);
- pos.y += fontsize.y + (fontsize.y / 4);
-
+
+ // Show title if available
+ if(centerprint_title) {
+ vector fontsize = cp_fontsize * autocvar_hud_panel_centerprint_fontscale_title;
+ float width = stringwidth(centerprint_title, true, fontsize);
+
+ pos.x = panel_pos.x + (panel_size.x - width) * align;
+
+ if (autocvar_hud_panel_centerprint_flip)
+ pos.y -= fontsize.y;
+ if (centerprint_title_offset && align == 0.5)
+ pos.x += centerprint_title_offset * CENTERPRINT_BASE_SIZE * autocvar_hud_panel_centerprint_fontscale_title;
+
+ drawcolorcodedstring(pos, centerprint_title, fontsize, 1, DRAWFLAG_NORMAL);
+
+ if (autocvar_hud_panel_centerprint_flip)
+ pos.y -= cp_fontsize.y * CENTERPRINT_TITLE_SPACING;
+ else
+ pos.y += fontsize.y + (hud_fontsize.y * CENTERPRINT_TITLE_SPACING);
+
+ drawfill(pos, vec2(width, 1), '1 1 1', 1, DRAWFLAG_NORMAL);
+
+ if (autocvar_hud_panel_centerprint_flip)
+ pos.y -= cp_fontsize.y * CENTERPRINT_TITLE_SPACING;
+ else
+ pos.y += cp_fontsize.y * CENTERPRINT_TITLE_SPACING;
+
all_messages_expired = false;
}
-
- // continue with normal procedure this time
-
- if (autocvar_hud_panel_centerprint_flip)
- pos.y += panel_size.y;
- align = bound(0, autocvar_hud_panel_centerprint_align, 1);
+
for (g=0, i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
{
- bool is_bold = centerprint_bold[j];
-
- // entries = bound(1, floor(CENTERPRINT_MAX_ENTRIES * 4 * panel_size_y/panel_size_x), CENTERPRINT_MAX_ENTRIES);
- // height = panel_size_y/entries;
- // fontsize = '1 1 0' * height;
- height = (is_bold) ? vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale_bold : vid_conheight/50 * autocvar_hud_panel_centerprint_fontscale;
- fontsize = '1 1 0' * height;
- entries = bound(1, floor(panel_size.y/height), CENTERPRINT_MAX_ENTRIES);
-
if (j == CENTERPRINT_MAX_MSGS)
j = 0;
if (centerprint_expire_time[j] == -1)
all_messages_expired = false;
+ if (time < centerprint_start_time[j]) continue;
+
+ float fade_in_time = autocvar_hud_panel_centerprint_fade_in;
+ float fade_out_time = autocvar_hud_panel_centerprint_fade_out;
+
+ if (centerprint_countdown_num[j]) {
+ fade_in_time = 0;
+ fade_out_time = 0;
+ }
+
// fade
- //if(centerprint_time[j] < 0) // Expired but forced. Expire time is the fade-in time.
- // a = (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in);
- if(centerprint_time[j] < 0 || centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time) // Regularily printed. Not fading out yet.
+ if(fade_in_time && centerprint_start_time[j] && time < centerprint_start_time[j] + fade_in_time) // Fade in
+ a = (time - centerprint_start_time[j]) / fade_in_time;
+ else if(time < centerprint_expire_time[j] - fade_out_time || centerprint_time[j] < 0) // Regularily printed or forced
a = 1;
- else // Expiring soon, so fade it out.
- a = (centerprint_expire_time[j] - time) / max(0.0001, autocvar_hud_panel_centerprint_fade_out);
+ else if(fade_out_time) // Expiring soon, so fade it out.
+ a = (centerprint_expire_time[j] - time) / fade_out_time;
if(centerprint_msgID[j] == ORDINAL(CPID_TIMEIN))
a = 1;
// while counting down show it anyway in order to hold the current message position
if (a <= 0.5/255.0 && centerprint_countdown_num[j] == 0) // Guaranteed invisible - don't show.
continue;
- if (a > 1)
- a = 1;
-
- // set the size from fading in/out before subsequent fading
- //sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize);
// also fade it based on positioning
if(autocvar_hud_panel_centerprint_fade_subsequent)
}
a *= panel_fg_alpha;
- // finally set the size based on the new alpha from subsequent fading
- //sz = sz * (autocvar_hud_panel_centerprint_fade_subsequent_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_subsequent_minfontsize));
- sz = 1; // z411 disable ugly zoom shit
+ // finally set the size based on the alpha
+ sz = autocvar_hud_panel_centerprint_fade_minfontsize + a * (1 - autocvar_hud_panel_centerprint_fade_minfontsize);
drawfontscale = hud_scale * sz;
if (centerprint_countdown_num[j])
- n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
+ n = tokenizebyseparator(strreplace("^COUNT", ftos(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
else
n = tokenizebyseparator(centerprint_messages[j], "\n");
getWrappedLine_remaining = argv(k);
while(getWrappedLine_remaining)
{
+ bool is_bold = (substring(getWrappedLine_remaining, 0, 5) == BOLD_OPERATOR);
+ vector fontsize = cp_fontsize * (is_bold ? autocvar_hud_panel_centerprint_fontscale_bold : autocvar_hud_panel_centerprint_fontscale);
+
ts = getWrappedLine(panel_size.x * hud_scale.x * sz, fontsize, stringwidth_colors);
if (ts != "")
pos.y -= fontsize.y;
for(k = 0; k < n; ++k)
{
getWrappedLine_remaining = argv(k);
+
+ bool is_bold = (substring(getWrappedLine_remaining, 0, 5) == BOLD_OPERATOR);
+ vector fontsize = cp_fontsize * (is_bold ? autocvar_hud_panel_centerprint_fontscale_bold : autocvar_hud_panel_centerprint_fontscale);
+ if (is_bold)
+ getWrappedLine_remaining = substring(getWrappedLine_remaining, 5, -1);
+
while(getWrappedLine_remaining)
{
ts = getWrappedLine(panel_size.x * hud_scale.x * sz, fontsize, stringwidth_colors);
++g; // move next position number up
msg_size = pos.y - msg_size;
+
if (autocvar_hud_panel_centerprint_flip)
{
- pos.y = current_msg_posY - CENTERPRINT_SPACING * fontsize.y;
+ pos.y -= msg_size + CENTERPRINT_SPACING * cp_fontsize.y;
if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
- pos.y += (msg_size + CENTERPRINT_SPACING * fontsize.y) * (1 - sqrt(sz));
+ pos.y += (1 - sqrt(a));
if (pos.y < panel_pos.y) // check if the next message can be shown
{
}
else
{
- pos.y += CENTERPRINT_SPACING * fontsize.y;
+ pos.y += CENTERPRINT_SPACING * cp_fontsize.y;
if (a < 1 && centerprint_msgID[j] == 0) // messages with id can be replaced just after they are faded out, so never move over them the next messages
- pos.y -= (msg_size + CENTERPRINT_SPACING * fontsize.y) * (1 - sqrt(sz));
+ pos.y -= (1 - sqrt(a));
- if(pos.y > panel_pos.y + panel_size.y - fontsize.y) // check if the next message can be shown
+ if(pos.y > panel_pos.y + panel_size.y - cp_fontsize.y) // check if the next message can be shown
{
drawfontscale = hud_scale;
return;
bool autocvar_hud_panel_centerprint;
float autocvar_hud_panel_centerprint_align;
- //float autocvar_hud_panel_centerprint_fade_in = 0.15;
-float autocvar_hud_panel_centerprint_fade_in = 0.15;
++float autocvar_hud_panel_centerprint_fade_in = 0;
float autocvar_hud_panel_centerprint_fade_out = 0.15;
float autocvar_hud_panel_centerprint_fade_subsequent = 1;
float autocvar_hud_panel_centerprint_fade_subsequent_passone = 3;
float autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha = 0.5;
float autocvar_hud_panel_centerprint_fade_subsequent_passtwo = 10;
float autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha = 0.5;
- //float autocvar_hud_panel_centerprint_fade_subsequent_minfontsize = 0.75;
- //float autocvar_hud_panel_centerprint_fade_minfontsize = 0;
+ float autocvar_hud_panel_centerprint_fade_minfontsize = 1;
bool autocvar_hud_panel_centerprint_flip;
- float autocvar_hud_panel_centerprint_fontscale;
+ float autocvar_hud_panel_centerprint_fontscale = 1;
float autocvar_hud_panel_centerprint_fontscale_bold = 1.4;
- bool autocvar_hud_panel_centerprint_dynamichud = true;
+ float autocvar_hud_panel_centerprint_fontscale_title = 1.8;
+ bool autocvar_hud_panel_centerprint_dynamichud = true;
float autocvar_hud_panel_centerprint_time;
- void centerprint_ClearTitle();
- void centerprint_SetTitle(string title);
- void centerprint_Medal(string icon, int times);
-
+bool autocvar_hud_panel_centerprint_medals = true;
+int autocvar_hud_panel_centerprint_medals_max = 5;
+
void centerprint_Add(int new_id, string strMessage, float duration, int countdown_num);
void centerprint_AddStandard(string strMessage);
void centerprint_Kill(int id);
void centerprint_KillAll();
+
+ void centerprint_ClearTitle();
+ void centerprint_SetTitle(string title, float offset);
++void centerprint_Medal(string icon, int times);
#include <client/view.qh>
// Timer (#5)
+float last_timeleft;
+int autocvar_cl_timer_countdown = 3; // 0 = disabled, 1 = always on, 2 = only spec, 3 = as dictated by server
void HUD_Timer_Export(int fh)
{
// allow saving cvars that aesthetically change the panel into hud skin files
}
+ vector HUD_Timer_Color(float timeleft)
+ {
+ if(timeleft <= 60)
+ return '1 0 0'; // red
+ else if(timeleft <= 300)
+ return '1 1 0'; // yellow
+ else
+ return '1 1 1'; // white
+ }
+
+ float HUD_Timer_TimeElapsed(float curtime, float starttime)
+ {
+ float time_elapsed = curtime - starttime;
+ if (!autocvar_hud_panel_timer_unbound)
+ time_elapsed = max(0, time_elapsed);
+ return floor(time_elapsed);
+ }
+
+ float HUD_Timer_TimeLeft(float curtime, float starttime, float timelimit)
+ {
+ float timeleft = timelimit + starttime - curtime;
+ if (!autocvar_hud_panel_timer_unbound)
+ timeleft = bound(0, timeleft, timelimit);
+ return ceil(timeleft);
+ }
+
void HUD_Timer()
{
if(!autocvar__hud_configure)
HUD_Scale_Enable();
else
HUD_Scale_Disable();
- HUD_Panel_DrawBg();
if(panel_bg_padding)
{
pos += '1 1 0' * panel_bg_padding;
mySize -= '2 2 0' * panel_bg_padding;
}
- string timer_sub = "";
- float timelimit, timeleft, minutesLeft, overtimes, timeout_last;
-
- timelimit = STAT(TIMELIMIT);
- overtimes = STAT(OVERTIMESADDED);
- timeout_last = STAT(TIMEOUT_LAST);
+ string timer;
+ string subtimer = string_null;
+ string subtext = string_null;
+ float curtime, timelimit, timeleft;
+ vector timer_size, subtext_size, subtimer_size;
+ vector timer_color = '1 1 1';
+ vector subtimer_color = '1 1 1';
+ bool swap = (autocvar_hud_panel_timer_secondary == 2 && STAT(ROUNDSTARTTIME));
++ float timeout_last = STAT(TIMEOUT_LAST);
+
+ // Use real or frozen time and get the time limit
- curtime = (intermission_time ? intermission_time : time);
++ if(intermission_time)
++ curtime = intermission_time;
++ else if(timeout_last)
++ curtime = timeout_last;
++ else
++ curtime = time;
+
- if (autocvar_hud_panel_timer_unbound){
- timeleft = max(0, timelimit * 60 + STAT(GAMESTARTTIME) - time);
- } else {
- timeleft = bound(0, timelimit * 60 + STAT(GAMESTARTTIME) - time, timelimit * 60);
+ if(warmup_stage)
+ {
+ timelimit = STAT(WARMUP_TIMELIMIT);
+ if(timelimit == 0)
+ timelimit = STAT(TIMELIMIT) * 60;
+ }
+ else
+ {
+ timelimit = STAT(TIMELIMIT) * 60;
}
- timeleft = ceil(timeleft);
+
+ // Calculate time left
+ timeleft = HUD_Timer_TimeLeft(curtime, STAT(GAMESTARTTIME), timelimit);
+
+ // Timer color
+ if(!intermission_time && !warmup_stage && timelimit > 0)
+ timer_color = HUD_Timer_Color(timeleft);
- if(countdown_type && !warmup_stage && timeleft > 0 && timeleft != last_timeleft && timeleft <= 10)
+ // countdown sound
+ // if 3 use server dictated option, otherwise the client's
+ int countdown_type;
+ if(autocvar_cl_timer_countdown == 3)
+ countdown_type = sv_timer_countdown;
+ else
+ countdown_type = autocvar_cl_timer_countdown;
+
- minutesLeft = floor(timeleft / 60);
++ if(countdown_type && !warmup_stage && timeleft > 0 && timeleft != last_timeleft && timeleft <= 10 && !intermission_time)
+ {
+ if(countdown_type == 1 || (countdown_type == 2 && spectatee_status))
+ sound(NULL, CH_INFO, SND_ENDCOUNT, VOL_BASE, ATTN_NONE);
+
+ last_timeleft = timeleft;
+ }
+
+ // Timer text
+ if (autocvar_hud_panel_timer_increment || timelimit <= 0)
+ timer = seconds_tostring(HUD_Timer_TimeElapsed(curtime, STAT(GAMESTARTTIME)));
+ else
+ timer = seconds_tostring(timeleft);
- float warmup_timeleft = 0;
- if(warmup_stage)
+ // Secondary timer for round-based game modes
+ if(STAT(ROUNDSTARTTIME) && autocvar_hud_panel_timer_secondary)
{
- float warmup_timelimit = STAT(WARMUP_TIMELIMIT);
- if(warmup_timelimit > 0)
- warmup_timeleft = max(0, warmup_timelimit - time + STAT(GAMESTARTTIME));
- else if(warmup_timelimit == 0)
- warmup_timeleft = timeleft;
- warmup_timeleft = ceil(warmup_timeleft);
- }
+ if(STAT(ROUNDSTARTTIME) == -1) {
+ // Round can't start
+ subtimer = "--:--";
+ subtimer_color = '1 0 0';
+ } else {
+ float round_curtime, round_timelimit, round_timeleft;
- vector timer_color;
- if(intermission_time || minutesLeft >= 5 || warmup_stage || timelimit == 0)
- timer_color = '1 1 1'; //white
- else if(minutesLeft >= 1)
- timer_color = '1 1 0'; //yellow
- else
- timer_color = '1 0 0'; //red
-
- if (intermission_time) {
- timer = max(0, floor(intermission_time - STAT(GAMESTARTTIME)));
- timer_sub = "Intermission";
- } else if (timeout_last) {
- if(autocvar_hud_panel_timer_increment)
- timer = max(0, floor(timeout_last - STAT(GAMESTARTTIME)));
- else
- timer = ceil(max(0, timelimit * 60 + STAT(GAMESTARTTIME) - timeout_last));
- timer_sub = "Timeout";
- } else if (autocvar_hud_panel_timer_increment || timelimit == 0) {
- // Time elapsed timer
- if((warmup_stage && warmup_timeleft <= 0) || time < STAT(GAMESTARTTIME))
- timer = 0;
- else
- timer = floor(time - STAT(GAMESTARTTIME));
- } else {
- // Time left timer
- if(warmup_stage) {
- if(warmup_timeleft <= 0)
- timer = floor(timelimit * 60);
+ // Use real or frozen time and get the time limit
+ round_curtime = (game_stopped_time ? game_stopped_time : time);
+ round_timelimit = STAT(ROUND_TIMELIMIT);
+
+ // Calculate time left
+ round_timeleft = HUD_Timer_TimeLeft(round_curtime, STAT(ROUNDSTARTTIME), round_timelimit);
+
+ // Subtimer color
+ if(!intermission_time && round_timelimit > 0)
+ subtimer_color = HUD_Timer_Color(round_timeleft);
+
+ // Subtimer text
+ if (autocvar_hud_panel_timer_increment || round_timelimit <= 0)
+ subtimer = seconds_tostring(HUD_Timer_TimeElapsed(round_curtime, STAT(ROUNDSTARTTIME)));
else
- timer = warmup_timeleft;
- } else {
- timer = timeleft;
+ subtimer = seconds_tostring(round_timeleft);
}
}
-
- if(warmup_stage)
- timer_sub = "Warmup";
+
+ // Subtext
+ int overtimes = STAT(OVERTIMES);
+
+ if(warmup_stage || autocvar__hud_configure)
+ subtext = _("Warmup");
+ else if(STAT(TIMEOUT_STATUS) == 2)
+ subtext = _("Timeout");
+ else if (overtimes == -1)
+ subtext = _("Sudden Death");
else if(overtimes == 1)
- timer_sub = "Overtime";
- else if (overtimes > 1)
- timer_sub = sprintf("Overtime #%d", overtimes);
-
- drawstring_aspect(pos, seconds_tostring(timer), mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
-
- if(timer_sub != "") {
- pos.y += mySize.y;
- mySize.y = mySize.y / 2;
- drawstring_aspect(pos, timer_sub, mySize, '1 0 0', panel_fg_alpha, DRAWFLAG_NORMAL);
+ subtext = _("Overtime");
+ else if (overtimes >= 2)
+ subtext = sprintf(_("Overtime #%d"), overtimes);
+
+ subtext_size = vec2(mySize.x, mySize.y / 3);
+ timer_size = vec2(mySize.x, mySize.y - subtext_size.y);
+ subtimer_size = vec2(mySize.x / 3, mySize.y - subtext_size.y);
+
+ panel_size.y -= subtext_size.y;
+ HUD_Panel_DrawBg();
+
+ if(subtimer) {
+ float subtimer_padding = subtimer_size.y / 5;
+ timer_size.x -= subtimer_size.x;
+ drawstring_aspect(pos + eX * timer_size.x + eY * subtimer_padding, (swap ? timer : subtimer), subtimer_size - eY * subtimer_padding * 2, (swap ? timer_color : subtimer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
}
+ drawstring_aspect(pos, (swap ? subtimer : timer), timer_size, (swap ? subtimer_color : timer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ if(subtext)
+ drawstring_aspect(pos + eY * timer_size.y, subtext, subtext_size, '0 1 0', panel_fg_alpha, DRAWFLAG_NORMAL);
+
draw_endBoldFont();
}
registercvar("cl_weapon_switch_fallback_to_impulse", "1");
registercvar("cl_allow_uidranking", "1");
+
+ // z411
+ registercvar("cl_chat_sounds", "1");
if(autocvar_cl_lockview)
cvar_set("cl_lockview", "0");
if(override)
return true;
+ if(bInputType == 3 || bInputType == 2)
+ return false;
+
+ // at this point bInputType can only be 0 or 1 (key pressed or released)
+ bool key_pressed = (bInputType == 0);
+
+ if(key_pressed) {
+ if(nPrimary == K_ALT) hudShiftState |= S_ALT;
+ if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
+ if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
+ }
+ else {
+ if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
+ if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
+ if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
+ }
+
+ if (nPrimary == K_ESCAPE && !(hudShiftState & S_SHIFT) && key_pressed)
+ {
+ if (!isdemo() && cvar("_menu_gamemenu_dialog_available"))
+ {
+ localcmd("\nmenu_showgamemenudialog\n");
+ return true;
+ }
+ }
+
return false;
}
NET_HANDLE(ENT_CLIENT_ACCURACY, bool isnew)
{
make_pure(this);
+ float entnum = ReadByte();
+
int sf = ReadInt24_t();
if (sf == 0) {
for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w)
int f = 1;
for (int w = 0; w <= WEP_LAST - WEP_FIRST; ++w) {
if (sf & f) {
- int b = ReadByte();
- if (b == 0)
- weapon_accuracy[w] = -1;
- else if (b == 255)
- weapon_accuracy[w] = 1.0; // no better error handling yet, sorry
- else
- weapon_accuracy[w] = (b - 1.0) / 100.0;
+ if(entnum > 0) {
+ playerslots[entnum-1].accuracy_frags[w] = ReadByte();
+ playerslots[entnum-1].accuracy_hit[w] = ReadShort();
+ playerslots[entnum-1].accuracy_cnt_hit[w] = ReadShort();
+ playerslots[entnum-1].accuracy_cnt_fired[w] = ReadShort();
+
+ //LOG_INFOF("Duel stats ?/%d", playerslots[entnum-1].accuracy_cnt_fired[w]);
+ } else {
+ int b = ReadByte();
+ if (b == 0)
+ weapon_accuracy[w] = -1;
+ else if (b == 255)
+ weapon_accuracy[w] = 1.0; // no better error handling yet, sorry
+ else
+ weapon_accuracy[w] = (b - 1.0) / 100.0;
+ }
}
f = (f == 0x800000) ? 1 : f * 2;
}
localcmd(sprintf("\nfog %s\nr_fog_exp2 0\nr_drawfog 1\n", forcefog));
}
+ bool net_handle_ServerWelcome();
NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
{
make_pure(this);
strcpy(teamscores_label(i), ReadString());
teamscores_flags(i) = ReadByte();
}
+ bool welcome_msg_too = ReadByte();
+ if (welcome_msg_too)
+ net_handle_ServerWelcome();
return = true;
Scoreboard_InitScores();
Gamemode_Init();
serverflags = ReadByte();
g_trueaim_minrange = ReadCoord();
+
+ strcpy(hostname_full, ReadString());
+ strcpy(motd_permanent, ReadString());
+
+ sv_timer_countdown = ReadByte();
return = true;
if (!postinit) PostInit();
}
+NET_HANDLE(TE_CSQC_TEAMNAMES, bool isNew)
+{
+ teamname_red = strzone(ReadString());
+ teamname_blue = strzone(ReadString());
+ teamname_yellow = strzone(ReadString());
+ teamname_pink = strzone(ReadString());
+
+ return = true;
+}
+
+NET_HANDLE(TE_CSQC_CHATSOUND, bool isNew)
+{
+ string snd = ReadString();
+ snd = strcat("chat/", snd, ".ogg");
+
+ precache_sound(snd);
+ _sound(NULL, CH_INFO, snd, VOL_BASE, ATTN_NONE);
+
+ return = true;
+}
+
float GetSpeedUnitFactor(int speed_unit)
{
switch(speed_unit)
}
}
+ bool net_handle_ServerWelcome()
+ {
+ bool campaign = ReadByte();
+ if (campaign)
+ {
+ string campaign_title = ReadString();
+ int campaign_level = ReadByte();
+ string campaign_msg = ReadString();
+ string welcomedialog_args;
+ welcomedialog_args = strcat("HOSTNAME \"", campaign_title, "\"");
+ string key = getcommandkey(_("jump"), "+jump");
+ string msg = strcat(
+ CCR("^F1"), sprintf(_("Level %d:"), campaign_level),
+ sprintf(CCR(" ^BG%s\n^3\n"), campaign_msg),
+ sprintf(CCR(_("^BGPress ^F2%s^BG to enter the game")), key));
+ msg = MakeConsoleSafe(strreplace("\n", "\\n", msg));
+ welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\"");
+ localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
+ return true;
+ }
+
+ bool force_centerprint = ReadByte();
+ string hostname = ReadString();
+ string ver = ReadString();
+ string modifications = ReadString();
+ string cache_mutatormsg = ReadString();
+ string mutator_msg = ReadString();
+ string motd = ReadString();
+
+ string msg = "";
+ msg = strcat(msg, ver);
+ msg = strcat(msg, "^8\n\n", strcat(_("Gametype:"), " ^1", MapInfo_Type_ToText(gametype)), "^8\n");
+ if(modifications != "")
+ msg = strcat(msg, "^8\n", _("Active modifications:"), " ^3", modifications, "^8\n");
+ if (cache_mutatormsg != "")
+ msg = strcat(msg, "\n\n^8", _("Special gameplay tips:"), " ^7", cache_mutatormsg);
+ msg = strcat(msg, mutator_msg); // trust that the mutator will do proper formatting
+ if (motd != "")
+ msg = strcat(msg, "\n\n^8", _("MOTD:"), " ^7", motd);
+
+ if (!force_centerprint && !isdemo() && cvar("_menu_welcome_dialog_available") && autocvar_cl_welcome_in_menu_dialog)
+ {
+ string welcomedialog_args;
+ welcomedialog_args = strcat("HOSTNAME \"", hostname, "\"");
+ msg = MakeConsoleSafe(strreplace("\n", "\\n", msg));
+ welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\"");
+ localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n");
+ }
+ else
+ centerprint_Add(ORDINAL(CPID_MOTD), strcat(hostname, "\n\n\n", msg), -1, 0);
+ return true;
+ }
+
+ NET_HANDLE(TE_CSQC_SERVERWELCOME, bool isNew)
+ {
+ return net_handle_ServerWelcome();
+ }
+
string _getcommandkey(string cmd_name, string command, bool forcename)
{
string keys;
#include <common/constants.qh>
#include <common/weapons/_all.qh>
+#include <common/items/inventory.qh>
+
+// z411
+string hostname_full;
+string motd_permanent;
+int sv_timer_countdown;
bool autocvar_cl_db_saveasdump;
bool autocvar_cl_spawn_event_particles;
bool autocvar_developer_csqcentities;
bool autocvar_cl_race_cptimes_onlyself; // TODO: move to race gamemode
bool autocvar_cl_race_cptimes_showself = false;
+ bool autocvar_cl_welcome_in_menu_dialog = true;
// Map coordinate base calculations need these
vector mi_center;
.int enttype; // entity type sent from server
.int sv_entnum; // entity number sent from server
+// z411 accuracy info
+.float accuracy_frags[REGISTRY_MAX(Weapons)];
+.float accuracy_hit[REGISTRY_MAX(Weapons)];
+.float accuracy_cnt_hit[REGISTRY_MAX(Weapons)];
+.float accuracy_cnt_fired[REGISTRY_MAX(Weapons)];
+
.int team;
.int team_size;
+.int countrycode;
+.string rank;
int binddb;
float ticrate;
int serverflags;
+
float kill_time = STAT(KILL_TIME);
if (COMPARE_INCREASING(kill_time, kill_time_prev) > autocvar_cl_hitsound_antispam_time)
{
- sound(NULL, CH_INFO, SND_KILL, VOL_BASE, ATTN_NONE);
+ sound(NULL, CH_INFO, SND_KILL, VOL_BASE * 1.15, ATTN_NONE);
kill_time_prev = kill_time;
}
}
UpdateDamage();
HUD_Crosshair(this);
HitSound();
+ Local_Notification_Queue_Process();
}
void ViewLocation_Mouse()
myhealth_flash += autocvar_hud_damage_fade_rate * frametime; // dead
}
}
+
+ if(myhealth_prev > 1 && myhealth <= 0 && !intermission)
+ {
+ // Just died
+ sound(NULL, CH_INFO, SND_DEATH, VOL_BASE, ATTN_NONE);
+ }
if(spectatee_status == -1 || intermission)
{
if(intermission && !intermission_time)
intermission_time = time;
+ if(STAT(GAME_STOPPED) && !game_stopped_time)
+ game_stopped_time = time;
+ else if(game_stopped_time && !STAT(GAME_STOPPED))
+ game_stopped_time = 0;
+
if(intermission && !isdemo() && !(calledhooks & HOOK_END))
{
if(calledhooks & HOOK_START)
ENTCS_PROP(FRAGS, true, frags, frags, ENTCS_SET_NORMAL,
{ WriteShort(chan, ent.frags); },
{ ent.frags = ReadShort(); })
+
+ENTCS_PROP(COUNTRYCODE, true, countrycode, countrycode, ENTCS_SET_NORMAL,
+ { WriteByte(chan, ent.countrycode); },
+ { ent.countrycode = ReadByte(); })
+
+ENTCS_PROP(RANK, true, rank, rank, ENTCS_SET_NORMAL,
+ { WriteString(chan, ent.rank); },
+ { strcpy(ent.rank, ReadString()); })
// use sv_solid to avoid changing solidity state of entcs entities
ENTCS_PROP(SOLID, true, sv_solid, solid, ENTCS_SET_NORMAL,
{ WriteByte(chan, ent.sv_solid); },
{ ent.sv_solid = ReadByte(); })
- ENTCS_PROP(MMM_STATUS, true, mmm_status, mmm_status, ENTCS_SET_NORMAL,
- { WriteShort(chan, ent.mmm_status); },
- { ent.mmm_status = ReadShort(); })
+// z411 weapon
+ENTCS_PROP(ACTIVEWEPID, false, activewepid, activewepid, ENTCS_SET_NORMAL,
+ { WriteByte(chan, ent.activewepid); },
+ { ent.activewepid = ReadByte(); })
+
+//LegendGuard adds ENTCS_PROP for MMM 20-02-2021
+// gamemode specific player mmm status (independent of score and frags)
++//ENTCS_PROP(MMM_STATUS, true, mmm_status, mmm_status, ENTCS_SET_NORMAL,
++// { WriteShort(chan, ent.mmm_status); },
++// { ent.mmm_status = ReadShort(); })
+
#ifdef SVQC
int ENTCS_PUBLICMASK = 0, ENTCS_PRIVATEMASK = 0;
#include <common/gamemodes/gamemode/keepaway/_mod.inc>
#include <common/gamemodes/gamemode/keyhunt/_mod.inc>
#include <common/gamemodes/gamemode/lms/_mod.inc>
- #include <common/gamemodes/gamemode/mmm/_mod.inc> //LegendGuard adds _mod.inc for Murder in Megaerebus Manor 20-02-2021
++//#include <common/gamemodes/gamemode/mmm/_mod.inc>
+#include <common/gamemodes/gamemode/mayhem/_mod.inc>
#include <common/gamemodes/gamemode/nexball/_mod.inc>
#include <common/gamemodes/gamemode/onslaught/_mod.inc>
#include <common/gamemodes/gamemode/race/_mod.inc>
#include <common/gamemodes/gamemode/tdm/_mod.inc>
+#include <common/gamemodes/gamemode/tmayhem/_mod.inc>
#include <common/gamemodes/gamemode/keepaway/_mod.qh>
#include <common/gamemodes/gamemode/keyhunt/_mod.qh>
#include <common/gamemodes/gamemode/lms/_mod.qh>
- #include <common/gamemodes/gamemode/mmm/_mod.qh> //LegendGuard adds _mod.qh for Murder in Megaerebus Manor 20-02-2021
++//#include <common/gamemodes/gamemode/mmm/_mod.qh>
+#include <common/gamemodes/gamemode/mayhem/_mod.qh>
#include <common/gamemodes/gamemode/nexball/_mod.qh>
#include <common/gamemodes/gamemode/onslaught/_mod.qh>
#include <common/gamemodes/gamemode/race/_mod.qh>
#include <common/gamemodes/gamemode/tdm/_mod.qh>
+#include <common/gamemodes/gamemode/tmayhem/_mod.qh>
const int GAMETYPE_FLAG_PRIORITY = BIT(3); // priority selection when preferred gametype isn't available in random selections
const int GAMETYPE_FLAG_HIDELIMITS = BIT(4); // don't display a score limit needed for winning the match in the scoreboard
const int GAMETYPE_FLAG_WEAPONARENA = BIT(5); // gametype has a forced weapon arena, weapon arena mutators should disable themselves when this is set
+ const int GAMETYPE_FLAG_1V1 = BIT(6); // 1v1 gameplay
int MAPINFO_TYPE_ALL;
.int m_flags;
ATTRIB(Gametype, m_hidelimits, bool, false);
/** does this gametype enforce its own weapon arena? */
ATTRIB(Gametype, m_weaponarena, bool, false);
+ /** 1v1 gameplay? */
+ ATTRIB(Gametype, m_1v1, bool, false);
/** game type defaults */
ATTRIB(Gametype, model2, string);
/** game type description */
/** game type priority in random selections */
ATTRIB(Gametype, m_priority, int, 0);
#ifdef CSQC
- ATTRIB(Gametype, m_modicons, void(vector pos, vector mySize));
- ATTRIB(Gametype, m_modicons_reset, void());
- ATTRIB(Gametype, m_modicons_export, void(int fh));
+ //ATTRIB(Gametype, m_modicons, void(vector pos, vector mySize));
+ //ATTRIB(Gametype, m_modicons_reset, void());
+ //ATTRIB(Gametype, m_modicons_export, void(int fh));
+ ATTRIB(Gametype, m_modscores, int(int team));
#endif
/** DO NOT USE, this is compatibility for legacy maps! */
this.m_priority = ((gflags & GAMETYPE_FLAG_PREFERRED) ? 2 : ((gflags & GAMETYPE_FLAG_PRIORITY) ? 1 : 0));
this.m_hidelimits = (gflags & GAMETYPE_FLAG_HIDELIMITS);
this.m_weaponarena = (gflags & GAMETYPE_FLAG_WEAPONARENA);
+ this.m_1v1 = (gflags & GAMETYPE_FLAG_1V1);
// same as `1 << m_id`
MAPINFO_TYPE_ALL |= this.items = this.m_flags = (MAPINFO_TYPE_ALL + 1);
REGISTER_NET_TEMP(TE_CSQC_TEAMNAGGER)
REGISTER_NET_TEMP(TE_CSQC_PINGPLREPORT)
REGISTER_NET_TEMP(TE_CSQC_WEAPONCOMPLAIN)
+ REGISTER_NET_TEMP(TE_CSQC_SERVERWELCOME)
REGISTER_NET_TEMP(TE_CSQC_VEHICLESETUP)
+REGISTER_NET_TEMP(TE_CSQC_TEAMNAMES)
+REGISTER_NET_TEMP(TE_CSQC_CHATSOUND)
+REGISTER_NET_TEMP(TE_CSQC_WEAPONPICKUP)
+REGISTER_NET_TEMP(TE_CSQC_TOTALSHARDS) // for RJZ
+
const int RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
const int RACE_NET_CHECKPOINT_CLEAR = 1;
const int RACE_NET_CHECKPOINT_NEXT_QUALIFYING = 2; // byte nextcheckpoint, short recordtime, string recordholder
#define N___NEVER 0
#define N_GNTLOFF 1
#define N__ALWAYS 2
+#define ANNCE_DEFTIME 2
-#define MULTITEAM_ANNCE(prefix, defaultvalue, sound, channel, volume, position) \
+#define MULTITEAM_ANNCE(prefix, defaultvalue, sound, channel, volume, position, queuetime) \
NOTIF_ADD_AUTOCVAR(ANNCE_##prefix, defaultvalue) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_2, prefix##_BLUE, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_3, prefix##_YELLOW, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position) \
- MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position)
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_2, prefix##_BLUE, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_2)), channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_3, prefix##_YELLOW, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_3)), channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position, queuetime)
// MSG_ANNCE_NOTIFICATIONS
- MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_20, N_GNTLOFF, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_25, N_GNTLOFF, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_30, N_GNTLOFF, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(MULTIFRAG, N___NEVER, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_ASSIST, N_GNTLOFF, "assist", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_DAMAGE, N_GNTLOFF, "damage", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_DEFENSE, N_GNTLOFF, "defense", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_EXCELLENT, N_GNTLOFF, "excellent", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_PERFECT, N_GNTLOFF, "perfect", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_ACCURACY, N_GNTLOFF, "accuracy", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_TELEFRAG, N_GNTLOFF, "telefrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(HUMILIATION, N__ALWAYS, "humiliation", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(MULTIFRAG, N_GNTLOFF, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(FIRSTBLOOD, N_GNTLOFF, "firstblood", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_IDLE_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_IDLE_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(PREPARE_TEAM, N__ALWAYS, "prepareyourteam", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(OVERTIME, N__ALWAYS, "overtime", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(SUDDENDEATH, N__ALWAYS, "suddendeath", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(SUICIDE, N_GNTLOFF, "suicide", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+ MSG_ANNCE_NOTIF(ACCIDENT, N_GNTLOFF, "accident", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, -1)
+
+ MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(LEAD_GAINED, N__ALWAYS, "leadgained", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(LEAD_LOST, N__ALWAYS, "leadlost", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(LEAD_TIED, N__ALWAYS, "leadtied", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MULTITEAM_ANNCE(ROUND_TEAM_WIN, N__ALWAYS, "round_win_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(TEAM_SCORES_TEAM, N__ALWAYS, "scores_team", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(TEAM_SCORES_ENEMY, N__ALWAYS, "scores_enemy", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MULTITEAM_ANNCE(TEAM_SCORES, N__ALWAYS, "scores_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(TEAM_LEADS_TEAM, N__ALWAYS, "leads_team", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(TEAM_LEADS_ENEMY, N__ALWAYS, "leads_enemy", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MULTITEAM_ANNCE(TEAM_LEADS, N__ALWAYS, "leads_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MULTITEAM_ANNCE(TEAM_WINS, N__ALWAYS, "wins_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(TEAM_LEADS_TIED, N__ALWAYS, "teamstied", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ROUND_OVER, N__ALWAYS, "round_over", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ROUND_TIED, N__ALWAYS, "round_tied", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ALONE, N__ALWAYS, "alone", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(CTF_PICKUP_YOU, N__ALWAYS, "ctf_pickup_you", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(CTF_PICKUP_TEAM, N__ALWAYS, "ctf_pickup_team", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(CTF_PICKUP_ENEMY, N__ALWAYS, "ctf_pickup_enemy", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MULTITEAM_ANNCE(CTF_PICKUP, N__ALWAYS, "ctf_pickup_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(CTF_RETURN_TEAM, N__ALWAYS, "ctf_return_team", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(CTF_RETURN_ENEMY, N__ALWAYS, "ctf_return_enemy", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MULTITEAM_ANNCE(CTF_RETURN, N__ALWAYS, "ctf_return_%s", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+// MSG_MEDAL_NOTIFICATIONS
+
+#define MSG_MEDAL_TIME 2
+#define MSG_MEDAL_FADE_TIME 0.5
+
+ MSG_MEDAL_NOTIF(AIRSHOT, N__ALWAYS, "airshot", ANNCE_ACHIEVEMENT_AIRSHOT)
+ MSG_MEDAL_NOTIF(ASSIST, N__ALWAYS, "assist", ANNCE_ACHIEVEMENT_ASSIST)
+ MSG_MEDAL_NOTIF(DAMAGE, N__ALWAYS, "damage", ANNCE_ACHIEVEMENT_DAMAGE)
+ MSG_MEDAL_NOTIF(DEFENSE, N__ALWAYS, "defense", ANNCE_ACHIEVEMENT_DEFENSE)
+ MSG_MEDAL_NOTIF(ELECTROBITCH, N__ALWAYS, "electrobitch", ANNCE_ACHIEVEMENT_ELECTROBITCH)
+ MSG_MEDAL_NOTIF(EXCELLENT, N__ALWAYS, "excellent", ANNCE_ACHIEVEMENT_EXCELLENT)
+ MSG_MEDAL_NOTIF(FIRSTBLOOD, N__ALWAYS, "firstblood", ANNCE_FIRSTBLOOD)
+ MSG_MEDAL_NOTIF(HEADSHOT, N__ALWAYS, "headshot", ANNCE_HEADSHOT)
+ MSG_MEDAL_NOTIF(HUMILIATION, N__ALWAYS, "humiliation", ANNCE_HUMILIATION)
+ MSG_MEDAL_NOTIF(IMPRESSIVE, N__ALWAYS, "impressive", ANNCE_ACHIEVEMENT_IMPRESSIVE)
+ MSG_MEDAL_NOTIF(YODA, N__ALWAYS, "yoda", ANNCE_ACHIEVEMENT_YODA)
+ MSG_MEDAL_NOTIF(TELEFRAG, N__ALWAYS, "telefrag", ANNCE_ACHIEVEMENT_TELEFRAG)
+
+ MSG_MEDAL_NOTIF(CAPTURE, N__ALWAYS, "capture", NULL)
+ MSG_MEDAL_NOTIF(PERFECT, N__ALWAYS, "perfect", ANNCE_ACHIEVEMENT_PERFECT)
+ MSG_MEDAL_NOTIF(ACCURACY, N__ALWAYS, "accuracy", ANNCE_ACHIEVEMENT_ACCURACY)
+
+ MSG_MEDAL_NOTIF(KILLSTREAK_03, N__ALWAYS, "killstreak_03", ANNCE_KILLSTREAK_03)
+ MSG_MEDAL_NOTIF(KILLSTREAK_05, N__ALWAYS, "killstreak_05", ANNCE_KILLSTREAK_05)
+ MSG_MEDAL_NOTIF(KILLSTREAK_10, N__ALWAYS, "killstreak_10", ANNCE_KILLSTREAK_10)
+ MSG_MEDAL_NOTIF(KILLSTREAK_15, N__ALWAYS, "killstreak_15", ANNCE_KILLSTREAK_15)
+
#undef N___NEVER
#undef N_GNTLOFF
MSG_INFO_NOTIF(FREEZETAG_SELF, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "")
MULTITEAM_INFO(ROUND_TEAM_WIN, N_CONSOLE, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "", NAME)
+ MULTITEAM_INFO(ROUND_TEAM_SCORES, N_CONSOLE, 0, 0, "", "", "", _("^TC^TT^BG scores"), "", NAME)
MSG_INFO_NOTIF(ROUND_PLAYER_WIN, N_CONSOLE, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "")
MSG_INFO_NOTIF(ROUND_TIED, N_CONSOLE, 0, 0, "", "", "", _("^BGRound tied"), "")
MSG_INFO_NOTIF(ROUND_OVER, N_CONSOLE, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "")
MSG_INFO_NOTIF(POWERUP_STRENGTH, N_CONSOLE, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "")
MSG_INFO_NOTIF(QUIT_DISCONNECT, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "")
- MSG_INFO_NOTIF(QUIT_KICK_IDLING, N_CHATCON, 1, 1, "s1 f1", "", "", _("^BG%s^F3 was kicked after idling for %s seconds"), "")
- MSG_INFO_NOTIF(MOVETOSPEC_IDLING, N_CHATCON, 1, 1, "s1 f1", "", "", _("^BG%s^F3 was moved to^BG spectators^F3 after idling for %s seconds"), "")
+ MSG_INFO_NOTIF(QUIT_KICK, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked"), "")
+ MSG_INFO_NOTIF(QUIT_KICK_IDLING, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for idling"), "")
+ MSG_INFO_NOTIF(MOVETOSPEC_IDLING, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was moved to spectator for idling"), "")
MSG_INFO_NOTIF(QUIT_KICK_SPECTATING, N_CONSOLE, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "")
MSG_INFO_NOTIF(QUIT_KICK_TEAMKILL, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for excessive teamkilling"), "")
MSG_INFO_NOTIF(QUIT_SPECTATE, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 is now^BG spectating"), "")
MSG_INFO_NOTIF(TEAMCHANGE_LARGERTEAM, N_CONSOLE, 0, 0, "", "", "", _("^BGYou cannot change to a larger team"), "")
MSG_INFO_NOTIF(TEAMCHANGE_NOTALLOWED, N_CONSOLE, 0, 0, "", "", "", _("^BGYou are not allowed to change teams"), "")
+ //LegendGuard adds MSG_INFO_NOTIF for MMM 20-02-2021
+ //LegendGuard adds N_CHATCON option 20-03-2021
+ MSG_INFO_NOTIF(MMM_MURDERER, N_CHATCON, 0, 0, "", "", "", _("^BGYou are ^K1Murderer^BG!"), "")
+ MSG_INFO_NOTIF(MMM_MURDERER_WIN, N_CONSOLE, 0, 0, "", "", "", _("^K1Murderers^BG win the round"), "")
+
+ //LegendGuard adds N_CHATCON option 20-03-2021
+ MSG_INFO_NOTIF(MMM_CIVILIAN, N_CHATCON, 0, 0, "", "", "", _("^BGYou are ^F1Civilian^BG!"), "")
+ MSG_INFO_NOTIF(MMM_CIVILIAN_WIN, N_CONSOLE, 0, 0, "", "", "", _("^F1Civilians^BG win the round"), "")
+
+ //LegendGuard adds N_CHATCON option 20-03-2021
+ MSG_INFO_NOTIF(MMM_DETECTIVE, N_CHATCON, 0, 0, "", "", "", _("^BGYou are ^4Detective^BG!"), "")
+ MSG_INFO_NOTIF(MMM_WHOISDETECTIVE, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s is ^4Detective^BG!"), "")
+ MSG_INFO_NOTIF(MMM_CORPSEDETECTION, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s"), "")
+ MSG_INFO_NOTIF(MMM_KARMAWARNING, N_CHATCON, 0, 0, "", "", "", _("^K1KARMA WARNING! ^3Here, have the Rifle!"), "")
MSG_INFO_NOTIF(VERSION_BETA, N_CONSOLE, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "")
MSG_INFO_NOTIF(VERSION_OLD, N_CHATCON, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "")
MSG_CENTER_NOTIF(ASSAULT_DEFENDING, N_ENABLE, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are defending!"), "")
MSG_CENTER_NOTIF(ASSAULT_OBJ_DESTROYED, N_ENABLE, 0, 1, "f1time", CPID_ASSAULT_ROLE, "0 0", _("^BGObjective destroyed in ^F4%s^BG!"), "")
- MSG_CENTER_NOTIF(COUNTDOWN_BEGIN, N_ENABLE, 0, 0, "", CPID_ROUND, "2 0", _("^F4Begin!"), "")
- MSG_CENTER_NOTIF(COUNTDOWN_GAMESTART, N_ENABLE, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Game starts in ^COUNT"), "")
- MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTART, N_ENABLE, 0, 1, "", CPID_ROUND, "1 f1", _("^F4Round starts in ^COUNT"), "")
+ MSG_CENTER_NOTIF(COUNTDOWN_BEGIN, N_ENABLE, 0, 0, "", CPID_ROUND, "2 0", BOLD(_("^BGBegin!")), "")
+ MSG_CENTER_NOTIF(COUNTDOWN_GAMESTART, N_ENABLE, 0, 1, "", CPID_ROUND, "1 f1", strcat(_("^BGGame starts in"), "\n", BOLD("^COUNT")), "")
+ MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTART, N_ENABLE, 0, 2, "f1", CPID_ROUND, "1 f2", strcat(_("^BGRound %s starts in"), "\n", BOLD("^COUNT")), "")
MSG_CENTER_NOTIF(COUNTDOWN_ROUNDSTOP, N_ENABLE, 0, 0, "", CPID_ROUND, "2 0", _("^F4Round cannot start"), "")
MSG_CENTER_NOTIF(ROUND_TIED, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^BGRound tied"), "")
#define VERBOSE_MURDER(type) strcat(MURDER_##type, "^BG%s")
- #define MURDER_FRAG BOLD(_("^K3%sYou fragged ^BG%s"))
- #define MURDER_FRAG2 BOLD(_("^K3%sYou scored against ^BG%s"))
- #define MURDER_FRAGGED BOLD(_("^K1%sYou were fragged by ^BG%s"))
- #define MURDER_FRAGGED2 BOLD(_("^K1%sYou were scored against by ^BG%s"))
+ #define MURDER_FRAG strcat(BOLD_OPERATOR, _("^K3%sYou fragged ^BG%s"))
+ #define MURDER_FRAG2 strcat(BOLD_OPERATOR, _("^K3%sYou scored against ^BG%s"))
+ #define MURDER_FRAG3 strcat(BOLD_OPERATOR, _("^K3%sYou fragged ^BG%s"), "\n", "%s^BG place with %s")
+ #define MURDER_FRAG4 strcat(BOLD_OPERATOR, _("^K3%sYou fragged ^BG%s"), "\n", "%s^BG with %s")
+ #define MURDER_FRAGGED _("^K1%sYou were fragged by ^BG%s")
+ #define MURDER_FRAGGED2 _("^K1%sYou were scored against by ^BG%s")
MSG_CENTER_NOTIF(DEATH_MURDER_FRAG, N_ENABLE, 1, 1, "spree_cen s1", CPID_Null, "0 0", MURDER_FRAG, MURDER_FRAG2 )
+ MSG_CENTER_NOTIF(DEATH_MURDER_DM, N_ENABLE, 1, 2, "spree_cen s1 frag_pos f2", CPID_Null, "0 0", MURDER_FRAG3, "")
+ MSG_CENTER_NOTIF(DEATH_MURDER_DUEL, N_ENABLE, 2, 2, "spree_cen s1 s2 f2", CPID_Null, "0 0", MURDER_FRAG4, "")
MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED, N_ENABLE, 1, 1, "spree_cen s1", CPID_Null, "0 0", MURDER_FRAGGED, MURDER_FRAGGED2 )
MSG_CENTER_NOTIF(DEATH_MURDER_FRAGGED_VERBOSE, N_ENABLE, 1, 4, "spree_cen s1 frag_stats", CPID_Null, "0 0", VERBOSE_MURDER(FRAGGED), VERBOSE_MURDER(FRAGGED2) )
MSG_CENTER_NOTIF(DEATH_MURDER_FRAG_VERBOSE, N_ENABLE, 1, 2, "spree_cen s1 frag_ping", CPID_Null, "0 0", VERBOSE_MURDER(FRAG), VERBOSE_MURDER(FRAG2) )
MULTITEAM_CENTER(ROUND_TEAM_LOSS, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team loses the round"), "", NAME)
MULTITEAM_CENTER(ROUND_TEAM_WIN, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "", NAME)
+ MULTITEAM_CENTER(ROUND_TEAM_SCORES, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG scores"), "", NAME)
MSG_CENTER_NOTIF(ROUND_PLAYER_WIN, N_ENABLE, 1, 0, "s1", CPID_ROUND, "0 0", _("^BG%s^BG wins the round"), "")
MSG_CENTER_NOTIF(FREEZETAG_SELF, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^K1You froze yourself"), "")
MULTITEAM_CENTER(KEYHUNT_START, N_ENABLE, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "", KEY)
MSG_CENTER_NOTIF(LMS_NOLIVES, N_ENABLE, 0, 0, "", CPID_LMS, "0 0", _("^BGYou have no lives left, you must wait until the next match"), "")
+ MSG_CENTER_NOTIF(LMS_SPECWARN, N_ENABLE, 0, 0, "", CPID_LMS, "0 0", _("^F4WARNING:^BG you can't rejoin this match after spectating.\nUse the same command again to spectate anyway."), "")
MSG_CENTER_NOTIF(MISSING_TEAMS, N_ENABLE, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "")
MSG_CENTER_NOTIF(MISSING_PLAYERS, N_ENABLE, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "")
+ MSG_CENTER_NOTIF(MISSING_READY, N_ENABLE, 0, 0, "", CPID_MISSING_READY, "-1 0", _("^BGThe match will begin\nwhen more players are ready.\n\nPress ^F2F4^BG to get ready"), "")
MSG_CENTER_NOTIF(INSTAGIB_DOWNGRADE, N_ENABLE, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "5 0", _("^BGYour weapon has been downgraded until you find some ammo!"), "")
MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO, N_ENABLE, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 9", _("^F4^COUNT^BG left to find some ammo!"), "")
MSG_CENTER_NOTIF(INSTAGIB_FINDAMMO_FIRST, N_ENABLE, 0, 0, "", CPID_INSTAGIB_FINDAMMO, "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!"))
MSG_CENTER_NOTIF(INSTAGIB_LIVES_REMAINING, N_ENABLE, 0, 1, "f1", CPID_Null, "0 0", _("^F2Extra lives remaining: ^K1%s"), "")
- MSG_CENTER_NOTIF(CAMPAIGN_MESSAGE, N_ENABLE, 1, 1, "f1 s1 join_key", CPID_CAMPAIGN_MESSAGE, "-1 0", strcat(_("Level %s: "), "^BG%s\n^3\n", _("^BGPress ^F2%s^BG to enter the game")), "")
MSG_CENTER_NOTIF(MOTD, N_ENABLE, 1, 0, "s1", CPID_MOTD, "-1 0", "^BG%s", "")
MSG_CENTER_NOTIF(NIX_COUNTDOWN, N_ENABLE, 0, 2, "item_wepname", CPID_NIX, "1 f2", _("^F2^COUNT^BG until weapon change...\nNext weapon: ^F1%s"), "")
MSG_CENTER_NOTIF(TIMEOUT_BEGINNING, N_ENABLE, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "")
MSG_CENTER_NOTIF(TIMEOUT_ENDING, N_ENABLE, 0, 1, "", CPID_TIMEIN, "1 f1", _("^F4Timeout ends in ^COUNT"), "")
+ MSG_CENTER_NOTIF(TIMEOUT_ONGOING, N_ENABLE, 0, 0, "", CPID_TIMEIN, "1 f1", _("^F4Match paused"), "")
+ //LegendGuard adds MSG_CENTER_NOTIF for MMM 20-02-2021
+ MSG_CENTER_NOTIF(MMM_MURDERER, N_ENABLE, 0, 0, "", CPID_MMM, "5 0", strcat(BOLD_OPERATOR, _("^BGYou are ^K1Murderer^BG! Kill all the civilians without raising suspicion!")), "")
+ MSG_CENTER_NOTIF(MMM_MURDERER_WIN, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^K1Murderers^BG win the round"), "")
+
+ MSG_CENTER_NOTIF(MMM_CIVILIAN, N_ENABLE, 0, 0, "", CPID_MMM, "5 0", strcat(BOLD_OPERATOR, _("^BGYou are ^F1Civilian^BG! Try to find out who are murderers and survive until time is up!")), "")
+ MSG_CENTER_NOTIF(MMM_CIVILIAN_WIN, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^F1Civilians^BG win the round"), "")
+
+ MSG_CENTER_NOTIF(MMM_DETECTIVE, N_ENABLE, 0, 0, "", CPID_MMM, "5 0", strcat(BOLD_OPERATOR, _("^BGYou are ^4Detective^BG! Find out who are murderers and protect the civilians!")), "")
+ MSG_CENTER_NOTIF(MMM_CORPSEDETECTION, N_ENABLE, 1, 0, "s1", CPID_MMM, "4 0", strcat(BOLD_OPERATOR, _("^BG%s")), "")
MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^K1Cannot join given minigame session!"), "" )
CASE(MSG, CHOICE)
/** Kill centerprint message @deprecated */
CASE(MSG, CENTER_KILL)
+ /** Medal notification */
+ CASE(MSG, MEDAL)
ENUMCLASS_END(MSG)
string Get_Notif_TypeName(MSG net_type)
case MSG_CENTER: return "MSG_CENTER";
case MSG_MULTI: return "MSG_MULTI";
case MSG_CHOICE: return "MSG_CHOICE";
+ case MSG_MEDAL: return "MSG_MEDAL";
case MSG_CENTER_KILL: return "MSG_CENTER_KILL";
}
LOG_WARNF("Get_Notif_TypeName(%d): Improper net type!", ORDINAL(net_type));
return "";
}
-
+//LegendGuard adds CASE(CPID, MMM) after TIMEIN for MMM 20-02-2021
ENUMCLASS(CPID)
CASE(CPID, ASSAULT_ROLE)
CASE(CPID, ROUND)
CASE(CPID, LMS)
CASE(CPID, MISSING_TEAMS)
CASE(CPID, MISSING_PLAYERS)
+ CASE(CPID, MISSING_READY)
CASE(CPID, INSTAGIB_FINDAMMO)
- CASE(CPID, CAMPAIGN_MESSAGE)
CASE(CPID, MOTD)
CASE(CPID, NIX)
CASE(CPID, ONSLAUGHT)
CASE(CPID, TEAMCHANGE)
CASE(CPID, TIMEOUT)
CASE(CPID, TIMEIN)
+ CASE(CPID, MMM)
CASE(CPID, VEHICLES)
CASE(CPID, VEHICLES_OTHER)
/** always last */
float channel,
string snd,
float vol,
- float position);
+ float position,
+ float queuetime);
void Create_Notification_Entity_InfoCenter(entity notif,
float var_cvar,
Notification optiona,
Notification optionb);
+void Create_Notification_Entity_Medal(entity notif,
+ float var_cvar,
+ string namestring,
+ /* MSG_MEDAL */
+ string icon,
+ Notification anncename);
+
void Dump_Notifications(int fh, bool alsoprint);
#define DEFAULT_FILENAME "notifications_dump.cfg"
CASE(NOTIF, TEAM)
/** send only to X team and their spectators, except for Y person and their spectators */
CASE(NOTIF, TEAM_EXCEPT)
+ /** send only to X team; don't include spectators */
+ CASE(NOTIF, TEAM_ONLY)
+ /** send to team X team except for Y person; don't include spectators */
+ CASE(NOTIF, TEAM_ONLY_EXCEPT)
/** send to everyone */
CASE(NOTIF, ALL)
/** send to everyone except X person and their spectators */
CASE(NOTIF, ALL_EXCEPT)
+ /** send to all spectators **/
+ CASE(NOTIF, ALL_SPEC)
ENUMCLASS_END(NOTIF)
string Get_Notif_BroadcastName(NOTIF broadcast)
{
case NOTIF_ONE: return "NOTIF_ONE";
case NOTIF_ONE_ONLY: return "NOTIF_ONE_ONLY";
+ case NOTIF_ALL_SPEC: return "NOTIF_ALL_SPEC";
case NOTIF_ALL_EXCEPT: return "NOTIF_ALL_EXCEPT";
case NOTIF_ALL: return "NOTIF_ALL";
case NOTIF_TEAM: return "NOTIF_TEAM";
case NOTIF_TEAM_EXCEPT: return "NOTIF_TEAM_EXCEPT";
+ case NOTIF_TEAM_ONLY: return "NOTIF_TEAM_ONLY";
+ case NOTIF_TEAM_ONLY_EXCEPT: return "NOTIF_TEAM_ONLY_EXCEPT";
}
LOG_WARNF("Get_Notif_BroadcastName(%d): Improper broadcast!", broadcast);
return "";
const float NOTIF_MAX_HUDARGS = 2;
const float NOTIF_MAX_DURCNT = 2;
+#ifdef CSQC
+const int NOTIF_QUEUE_MAX = 10;
+entity notif_queue_entity[NOTIF_QUEUE_MAX];
+MSG notif_queue_type[NOTIF_QUEUE_MAX];
+float notif_queue_time[NOTIF_QUEUE_MAX];
+float notif_queue_f1[NOTIF_QUEUE_MAX];
+
+float notif_queue_next_time;
+int notif_queue_length;
+
+void Local_Notification_Queue_Process();
+#endif
+
string arg_slot[NOTIF_MAX_ARGS];
const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs
ARG_CASE(ARG_CS, "join_key", getcommandkey(_("jump"), "+jump")) \
ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(true, f2)) \
ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \
- /*ARG_CASE(ARG_CS, "frag_pos", ((Should_Print_Score_Pos(f1)) ? sprintf("\n^BG%s", Read_Score_Pos(f1)) : ""))*/ \
+ ARG_CASE(ARG_CS, "frag_pos", notif_arg_frag_pos(f2)) \
ARG_CASE(ARG_CS, "spree_cen", (autocvar_notification_show_sprees ? notif_arg_spree_cen(f1) : "")) \
ARG_CASE(ARG_CS_SV, "spree_inf", (autocvar_notification_show_sprees ? notif_arg_spree_inf(1, input, s2, f2) : "")) \
ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
SPREE_ITEM(5, 05, _("RAGE! "), _("%s^K1 unlocked RAGE! %s^BG"), _("%s^K1 made FIVE SCORES IN A ROW! %s^BG")) \
SPREE_ITEM(10, 10, _("MASSACRE! "), _("%s^K1 started a MASSACRE! %s^BG"), _("%s^K1 made TEN SCORES IN A ROW! %s^BG")) \
SPREE_ITEM(15, 15, _("MAYHEM! "), _("%s^K1 executed MAYHEM! %s^BG"), _("%s^K1 made FIFTEEN SCORES IN A ROW! %s^BG")) \
- SPREE_ITEM(20, 20, _("BERSERKER! "), _("%s^K1 is a BERSERKER! %s^BG"), _("%s^K1 made TWENTY SCORES IN A ROW! %s^BG")) \
- SPREE_ITEM(25, 25, _("CARNAGE! "), _("%s^K1 inflicts CARNAGE! %s^BG"), _("%s^K1 made TWENTY FIVE SCORES IN A ROW! %s^BG")) \
- SPREE_ITEM(30, 30, _("ARMAGEDDON! "), _("%s^K1 unleashes ARMAGEDDON! %s^BG"), _("%s^K1 made THIRTY SCORES IN A ROW! %s^BG"))
#ifdef CSQC
+// z411 TODO : This actually doesn't work very well.
+// This gets run before the client gets score updates so it works
+// fine when you're playing (because frags get updated first)
+// but it breaks a lot when you're spectating because
+// we sometimes get the new frag info at different times
+// (before or after we run this). A suggested fix would
+// be to do this sorting and comparison in the server.
+string notif_arg_frag_pos(int score)
+{
+ entity pl;
+ int place = 1;
+ string str, color, tail;
+ bool tied = false;
+
+ for(pl = players.sort_next; pl; pl = pl.sort_next) {
+ if(pl.team == NUM_SPECTATOR) continue;
+ if(pl.(scores(SP_SCORE)) == score) break;
+ ++place;
+ }
+
+ entity prev = pl.sort_prev;
+ entity next = pl.sort_next;
+ if(prev && prev.(scores(SP_SCORE)) == score) {
+ tied = true;
+ --place; // We're tied always for the best place
+ }
+ if(next && next.(scores(SP_SCORE)) == score) {
+ tied = true;
+ }
+
+ switch(place) {
+ case 1:
+ color = "^4";
+ break;
+ case 2:
+ color = "^1";
+ break;
+ case 3:
+ color = "^3";
+ break;
+ default:
+ color = "";
+ }
+
+ switch(place % 10) {
+ case 1:
+ tail = "st";
+ break;
+ case 2:
+ tail = "nd";
+ break;
+ case 3:
+ tail = "rd";
+ break;
+ default:
+ tail = "th";
+ }
+
+ str = strcat(color, ftos(place), tail);
+ if(tied)
+ return strcat("Tied for ", str);
+ else
+ return str;
+}
+
string notif_arg_frag_ping(bool newline, float fping)
{
string s = newline ? "\n" : " ";
.string nent_snd;
.float nent_vol;
.float nent_position;
+.float nent_queuetime;
// MSG_INFO and MSG_CENTER entity values
.string nent_args; // used by both
return it;
}
-#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \
- MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position)
+#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position, queuetime)
-#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position) \
+#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position, queuetime) \
NOTIF_ADD_AUTOCVAR(ANNCE_##name, defaultvalue) \
- MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position)
+ MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position, queuetime)
-#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \
+#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \
Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_ANNCE, strtoupper(#name), teamnum); \
Create_Notification_Entity_Annce(this, ACVNN(cvarname), strtoupper(#name), \
- channel, /* channel */ \
- sound, /* snd */ \
- volume, /* vol */ \
- position); /* position */ \
+ channel, /* channel */ \
+ sound, /* snd */ \
+ volume, /* vol */ \
+ position, /* position */ \
+ queuetime); /* queuetime */ \
}
#define MSG_INFO_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
optiona, /* optiona */ \
optionb); /* optionb */ \
}
+
+#define MSG_MEDAL_NOTIF(name, defaultvalue, icon, anncename) \
+ NOTIF_ADD_AUTOCVAR(MEDAL_##name, defaultvalue) \
+ MSG_MEDAL_NOTIF_(0, MEDAL_##name, MEDAL_##name, defaultvalue, icon, anncename)
+
+#define MSG_MEDAL_NOTIF_(teamnum, name, cvarname, defaultvalue, icon, anncename) \
+ REGISTER(Notifications, name, m_id, new_pure(msg_medal_notification)) { \
+ Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_MEDAL, strtoupper(#name), teamnum); \
+ Create_Notification_Entity_Medal(this, ACVNN(cvarname), strtoupper(#name), \
+ icon, \
+ anncename); \
+ }
REGISTRY_BEGIN(Notifications)
{
float game_stopped;
float game_starttime; //point in time when the countdown to game start is over
float round_starttime; //point in time when the countdown to round start is over
- float checkrules_overtimesadded; // z411 add
+float overtime_starttime; // z411 point in time where first overtime started
+
+float timeout_last;
+float timeout_total_time;
+bool game_timeout;
+
int autocvar_leadlimit;
+ int overtimes; // overtimes added (-1 = sudden death)
+ int timeout_status; // (values: 0, 1, 2) contains whether a timeout is not active (0), was called but still at leadtime (1) or is active (2)
+
// TODO: world.qh can't be included here due to circular includes!
#define autocvar_fraglimit cvar("fraglimit")
#define autocvar_fraglimit_override cvar("fraglimit_override")
#endif
REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this))
REGISTER_STAT(GAME_STOPPED, int, game_stopped)
+
+REGISTER_STAT(TIMEOUT_LAST, float, timeout_last)
+
REGISTER_STAT(GAMESTARTTIME, float, game_starttime)
/** arc heat in [0,1] */
REGISTER_STAT(PRESSED_KEYS, int)
REGISTER_STAT(VEHICLESTAT_RELOAD2, int)
REGISTER_STAT(VEHICLESTAT_W2MODE, int)
REGISTER_STAT(NADE_TIMER, float)
- //REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
- //REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
-REGISTER_STAT(SECRETS_TOTAL, int, secrets_total)
-REGISTER_STAT(SECRETS_FOUND, int, secrets_found)
REGISTER_STAT(RESPAWN_TIME, float)
REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime)
- REGISTER_STAT(OVERTIMESTARTTIME, float, overtime_starttime)
- REGISTER_STAT(OVERTIMESADDED, float, checkrules_overtimesadded)
- //REGISTER_STAT(MONSTERS_TOTAL, int)
- //REGISTER_STAT(MONSTERS_KILLED, int)
+ REGISTER_STAT(OVERTIMES, int, overtimes)
+ REGISTER_STAT(TIMEOUT_STATUS, int, timeout_status)
-REGISTER_STAT(MONSTERS_TOTAL, int)
-REGISTER_STAT(MONSTERS_KILLED, int)
REGISTER_STAT(NADE_BONUS, float)
REGISTER_STAT(NADE_BONUS_TYPE, int)
REGISTER_STAT(NADE_BONUS_SCORE, float)
REGISTER_STAT(KILL_TIME, float)
REGISTER_STAT(VEIL_ORB, float)
REGISTER_STAT(VEIL_ORB_ALPHA, float)
-
#ifdef SVQC
float autocvar_sv_showfps = 0;
#endif
#ifdef SVQC
#include "physics/movetypes/movetypes.qh"
float warmup_limit;
+ float round_limit;
+ int rounds_played;
#endif
#ifdef SVQC
REGISTER_STAT(FRAGLIMIT, float, autocvar_fraglimit)
REGISTER_STAT(TIMELIMIT, float, autocvar_timelimit)
REGISTER_STAT(WARMUP_TIMELIMIT, float, warmup_limit)
+ REGISTER_STAT(ROUNDS_PLAYED, int, rounds_played)
+ REGISTER_STAT(ROUND_TIMELIMIT, float, round_limit)
#ifdef SVQC
float autocvar_sv_wallfriction;
#define autocvar_sv_gravity cvar("sv_gravity")
#ifdef SVQC
SPECTATE_COPYFIELD(_STAT(GUNALIGN))
#endif
+
+REGISTER_STAT(MMM_ROUNDTIMER, float) //LegendGuard adds MMM_ROUNDTIMER for MMM 20-02-2021
if(!_Nex_ExtResponseSystem_Queried)
{
_Nex_ExtResponseSystem_Queried = 1;
- float startcnt;
- string uri;
-
- cvar_set("cl_startcount", ftos(startcnt = cvar("cl_startcount") + 1));
-
- // for privacy, munge the start count a little
- startcnt = floor((floor(startcnt / 10) + random()) * 10);
- uri = sprintf("http://update.xonotic.org/checkupdate.txt?version=%s&cnt=%d", uri_escape(cvar_string("g_xonoticversion")), startcnt);
- uri_get(uri, URI_GET_UPDATENOTIFICATION);
+ cvar_set("cl_startcount", ftos(cvar("cl_startcount") + 1));
+ uri_get("https://update.xonotic.org/checkupdate.txt", URI_GET_UPDATENOTIFICATION);
}
if(_Nex_ExtResponseSystem_PacksStep > 0)
GAMETYPE(MAPINFO_TYPE_CTF) \
GAMETYPE(MAPINFO_TYPE_CA) \
GAMETYPE(MAPINFO_TYPE_FREEZETAG) \
+ GAMETYPE(MAPINFO_TYPE_TEAM_MAYHEM) \
+ GAMETYPE(MAPINFO_TYPE_MAYHEM) \
GAMETYPE(MAPINFO_TYPE_KEEPAWAY) \
GAMETYPE(MAPINFO_TYPE_KEYHUNT) \
GAMETYPE(MAPINFO_TYPE_LMS) \
GAMETYPE(MAPINFO_TYPE_ASSAULT) \
/* GAMETYPE(MAPINFO_TYPE_DUEL) */ \
/* GAMETYPE(MAPINFO_TYPE_INVASION) */ \
- GAMETYPE(MAPINFO_TYPE_MMM) \
- //LegendGuard adds GAMETYPE for menu for MMM 20-02-2021
++ /* GAMETYPE(MAPINFO_TYPE_MMM) */ \
/**/
// hidden gametypes come last so indexing always works correctly
e.configureXonoticTextSliderValues(e);
}
+ bool isServerSingleplayer()
+ {
+ return (cvar_string("net_address") == "127.0.0.1" && cvar_string("net_address_ipv6") == "::1");
+ }
+
+ void makeServerSingleplayer()
+ {
+ // it doesn't allow clients to connect from different machines
+ localcmd("defer 0.1 \"sv_cmd settemp net_address 127.0.0.1\"\n");
+ localcmd("defer 0.1 \"sv_cmd settemp net_address_ipv6 ::1\"\n");
+ }
+
float getFadedAlpha(float currentAlpha, float startAlpha, float targetAlpha)
{
if(startAlpha < targetAlpha)
WriteHeader(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
}
+void send_TeamNames(int channel, entity to) {
+ msg_entity = to;
+
+ WriteHeader(channel, TE_CSQC_TEAMNAMES);
+ WriteString(channel, autocvar_g_teamnames_red);
+ WriteString(channel, autocvar_g_teamnames_blue);
+ WriteString(channel, autocvar_g_teamnames_yellow);
+ WriteString(channel, autocvar_g_teamnames_pink);
+}
+
int CountSpectators(entity player, entity to)
{
if(!player) { return 0; } // not sure how, but best to be safe
void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint)
{
bool mutator_returnvalue = MUTATOR_CALLHOOK(MakePlayerObserver, this, is_forced);
+ bool recount_ready = false;
PlayerState_detach(this);
if (IS_PLAYER(this))
if(IS_REAL_CLIENT(this))
{
if (vote_called) { VoteCount(false); }
- ReadyCount();
+ this.ready = false;
+ recount_ready = true;
}
entcs_update_players(this);
}
if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
+ TRANSMUTE(Observer, this);
+
+ if(recount_ready) ReadyCount();
+
WaypointSprite_PlayerDead(this);
+ accuracy_resend(this);
if (CS(this).killcount != FRAGS_SPECTATOR && !game_stopped && CHAT_NOSPECTATORS())
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
- accuracy_resend(this);
-
CS(this).spectatortime = time;
if(this.bot_attack)
IL_REMOVE(g_bot_targets, this);
IL_REMOVE(g_monster_targets, this);
this.monster_attack = false;
STAT(HUD, this) = HUD_NORMAL;
- TRANSMUTE(Observer, this);
this.iscreature = false;
this.teleportable = TELEPORT_SIMPLE;
if(this.damagedbycontents)
this.revival_time = 0;
this.draggable = drag_undraggable;
+ player_powerups_remove_all(this);
this.items = 0;
STAT(WEAPONS, this) = '0 0 0';
this.drawonlytoclient = this;
if (CS(this).just_joined)
CS(this).just_joined = false;
+
+ // for RJZ
+ if (autocvar_rjz_count_shards)
+ send_TotalShards(this);
}
int player_getspecies(entity this)
setcolor(player, stof(autocvar_sv_defaultplayercolors));
}
+void ResetPlayerResources(entity this)
+{
+ if (warmup_stage) {
+ SetResource(this, RES_SHELLS, warmup_start_ammo_shells);
+ SetResource(this, RES_BULLETS, warmup_start_ammo_nails);
+ SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets);
+ SetResource(this, RES_CELLS, warmup_start_ammo_cells);
+ SetResource(this, RES_PLASMA, warmup_start_ammo_plasma);
+ SetResource(this, RES_FUEL, warmup_start_ammo_fuel);
+ SetResource(this, RES_HEALTH, warmup_start_health);
+ SetResource(this, RES_ARMOR, warmup_start_armorvalue);
+ STAT(WEAPONS, this) = WARMUP_START_WEAPONS;
+ } else {
+ SetResource(this, RES_SHELLS, start_ammo_shells);
+ SetResource(this, RES_BULLETS, start_ammo_nails);
+ SetResource(this, RES_ROCKETS, start_ammo_rockets);
+ SetResource(this, RES_CELLS, start_ammo_cells);
+ SetResource(this, RES_PLASMA, start_ammo_plasma);
+ SetResource(this, RES_FUEL, start_ammo_fuel);
+ SetResource(this, RES_HEALTH, start_health);
+ SetResource(this, RES_ARMOR, start_armorvalue);
+ STAT(WEAPONS, this) = start_weapons;
+ if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false)
+ {
+ GiveRandomWeapons(this, random_start_weapons_count,
+ autocvar_g_random_start_weapons, random_start_ammo);
+ }
+ }
+}
+
void PutPlayerInServer(entity this)
{
if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE);
this.takedamage = DAMAGE_AIM;
this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
- if (warmup_stage) {
- SetResource(this, RES_SHELLS, warmup_start_ammo_shells);
- SetResource(this, RES_BULLETS, warmup_start_ammo_nails);
- SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets);
- SetResource(this, RES_CELLS, warmup_start_ammo_cells);
- SetResource(this, RES_PLASMA, warmup_start_ammo_plasma);
- SetResource(this, RES_FUEL, warmup_start_ammo_fuel);
- SetResource(this, RES_HEALTH, warmup_start_health);
- SetResource(this, RES_ARMOR, warmup_start_armorvalue);
- STAT(WEAPONS, this) = WARMUP_START_WEAPONS;
- } else {
- SetResource(this, RES_SHELLS, start_ammo_shells);
- SetResource(this, RES_BULLETS, start_ammo_nails);
- SetResource(this, RES_ROCKETS, start_ammo_rockets);
- SetResource(this, RES_CELLS, start_ammo_cells);
- SetResource(this, RES_PLASMA, start_ammo_plasma);
- SetResource(this, RES_FUEL, start_ammo_fuel);
- SetResource(this, RES_HEALTH, start_health);
- SetResource(this, RES_ARMOR, start_armorvalue);
- STAT(WEAPONS, this) = start_weapons;
- if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false)
- {
- GiveRandomWeapons(this, random_start_weapons_count,
- autocvar_g_random_start_weapons, random_start_ammo);
- }
- }
+ ResetPlayerResources(this);
+
SetSpectatee_status(this, 0);
PS(this).dual_weapons = '0 0 0';
} else if (IS_PLAYER(this)) {
PutPlayerInServer(this);
}
-
+ // send team names
+ if(teamplay && IS_REAL_CLIENT(this))
+ send_TeamNames(MSG_ONE, this);
bot_relinkplayerlist();
}
WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor
WriteByte(channel, serverflags);
WriteCoord(channel, autocvar_g_trueaim_minrange);
+
+ // z411 send full hostname
+ WriteString(channel, (autocvar_hostname_full != "" ? autocvar_hostname_full : autocvar_hostname));
+ WriteString(channel, autocvar_sv_motd_permanent);
+
+ // z411 send client countdown type
+ WriteByte(channel, autocvar_sv_timer_countdown);
}
void ClientInit_CheckUpdate(entity this)
}
}
- string getwelcomemessage(entity this)
+ void SendWelcomemessage(entity this, bool force_centerprint)
+ {
+ msg_entity = this;
+ WriteHeader(MSG_ONE, TE_CSQC_SERVERWELCOME);
+ SendWelcomemessage_msg_type(this, force_centerprint, MSG_ONE);
+ }
+
+ void SendWelcomemessage_msg_type(entity this, bool force_centerprint, int msg_type)
{
+ WriteByte(msg_type, boolean(autocvar_g_campaign));
+ if (boolean(autocvar_g_campaign))
+ {
+ WriteString(msg_type, Campaign_GetTitle());
+ WriteByte(msg_type, Campaign_GetLevelNum());
+ WriteString(msg_type, Campaign_GetMessage());
+ return;
+ }
+ WriteByte(msg_type, force_centerprint);
+ WriteString(msg_type, autocvar_hostname);
+ WriteString(msg_type, GetClientVersionMessage(this));
+
MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
string modifications = M_ARGV(0, string);
modifications = strcat(modifications, ", Jet pack");
modifications = substring(modifications, 2, strlen(modifications) - 2);
- //string versionmessage = GetClientVersionMessage(this);
- //string s = strcat(versionmessage, "^8\n^9", (autocvar_hostname_full ? autocvar_hostname_full : autocvar_hostname));
- string s = (autocvar_hostname_full != "" ? autocvar_hostname_full : autocvar_hostname);
-
- s = strcat(s, "^8\n^7", gamemode_name);
-
- if(modifications != "")
- s = strcat(s, "^7 | ^3", modifications);
+ WriteString(msg_type, modifications);
if(cache_lastmutatormsg != autocvar_g_mutatormsg)
{
strcpy(cache_mutatormsg, cache_lastmutatormsg);
}
- if (cache_mutatormsg != "") {
- s = strcat(s, "\n^8tips: ^7", cache_mutatormsg);
- }
+ WriteString(msg_type, cache_mutatormsg);
string mutator_msg = "";
MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
mutator_msg = M_ARGV(0, string);
- s = strcat(s, mutator_msg); // trust that the mutator will do proper formatting
-
- string motd = autocvar_sv_motd;
- if (motd != "") {
- s = strcat(s, "\n\n^7", strreplace("\\n", "\n", motd));
- }
-
- // It's been a work, I want some credit for a while. Might remove later.
- s = strcat(s, "\n\nUsing BaI mod by z411 - bienvenidoainternet.org");
- return s;
+ WriteString(msg_type, mutator_msg); // trust that the mutator will do proper formatting
+ WriteString(msg_type, strreplace("\\n", "\n", autocvar_sv_motd));
}
/**
else
CS(this).allowed_timeouts = autocvar_sv_timeout_number;
- if (autocvar_sv_eventlog)
+ if (autocvar_sv_eventlog) {
GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? GameLog_ProcessIP(this.netaddress) : "bot"), ":", playername(this.netname, this.team, false)));
+
+ /* z411 for RJZ */
+ if(autocvar_rjz_ranks) GameLogEcho(strcat(":idfp:", ftos(etof(this)), ":", this.crypto_idfp));
+ }
CS(this).just_joined = true; // stop spamming the eventlog with additional lines when the client connects
MUTATOR_CALLHOOK(ClientConnect, this);
- if (IS_REAL_CLIENT(this))
- {
- if (!autocvar_g_campaign && !IS_PLAYER(this))
- {
- CS(this).motd_actived_time = -1;
- Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
- }
- }
+ if (IS_REAL_CLIENT(this) && !IS_PLAYER(this) && !autocvar_g_campaign)
+ CS(this).motd_actived_time = -1; // the welcome message is shown by the client
}
/*
=============
void play_countdown(entity this, float finished, Sound samp)
{
TC(Sound, samp);
- if(IS_REAL_CLIENT(this))
- if(floor(finished - time - frametime) != floor(finished - time))
- if(finished - time < 6)
- sound (this, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
+ float time_left = finished - time;
+ if(IS_REAL_CLIENT(this) && time_left < 6 && floor(time_left - frametime) != floor(time_left))
+ sound(this, CH_INFO, samp, VOL_BASE, ATTEN_NORM);
}
+ // it removes special powerups not handled by StatusEffects
void player_powerups_remove_all(entity this)
{
- if (this.items & IT_SUPERWEAPON)
+ if (this.items & (IT_SUPERWEAPON | IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS))
{
// don't play the poweroff sound when the game restarts or the player disconnects
- if (time > game_starttime + 1 && IS_CLIENT(this))
+ if (time > game_starttime + 1 && IS_CLIENT(this)
+ && !(start_items & (IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS)))
+ {
sound(this, CH_INFO, SND_POWEROFF, VOL_BASE, ATTEN_NORM);
- stopsound(this, CH_TRIGGER_SINGLE); // get rid of the pickup sound
- this.items -= (this.items & IT_SUPERWEAPON);
+ }
+ if (this.items & (IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS))
+ stopsound(this, CH_TRIGGER_SINGLE); // get rid of the pickup sound
+ this.items -= (this.items & (IT_SUPERWEAPON | IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS));
}
}
else
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_JOIN_PLAY, this.netname);
this.team_selected = false;
+
+ // z411
+ // send constant ready notification
+ if(warmup_stage)
+ Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MISSING_READY);
}
int GetPlayerLimit()
if (autocvar_g_campaign) {
if ((IS_PLAYER(this) && PHYS_INPUT_BUTTON_INFO(this)) || (!IS_PLAYER(this))) {
CS(this).motd_actived_time = time;
- Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_CAMPAIGN_MESSAGE, Campaign_GetMessage(), Campaign_GetLevelNum());
+ SendWelcomemessage(this, false);
}
} else {
if (PHYS_INPUT_BUTTON_INFO(this)) {
CS(this).motd_actived_time = time;
- Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, getwelcomemessage(this));
+ SendWelcomemessage(this, true);
}
}
}
CS(this).motd_actived_time = time;
else if ((time - CS(this).motd_actived_time > 2) && IS_PLAYER(this)) { // hide it some seconds after BUTTON_INFO has been released
CS(this).motd_actived_time = 0;
- Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
+ Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
}
} else {
if (PHYS_INPUT_BUTTON_INFO(this))
{
// instantly hide MOTD
CS(this).motd_actived_time = 0;
- if (autocvar_g_campaign)
- Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
- else
- Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
+ Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
}
else if (IS_PLAYER(this) || IS_SPEC(this))
{
return false;
}
- if (timeout_status == TIMEOUT_ACTIVE) {
- // don't allow the player to turn around while game is paused
+ if (game_timeout) {
+ // don't allow the player to turn around while game is paused
// FIXME turn this into CSQC stuff
this.v_angle = this.lastV_angle;
this.angles = this.lastV_angle;
this.fixangle = true;
+ return false;
}
if (frametime) player_powerups(this);
string autocvar_hostname;
int autocvar_spawn_debug;
string autocvar_sv_motd;
+string autocvar_sv_motd_permanent;
int autocvar_sv_name_maxlength = 64;
bool autocvar_sv_servermodelsonly;
int autocvar_sv_spectate;
float autocvar_sv_player_scale;
bool autocvar_sv_showspectators;
+// z411
+string autocvar_hostname_full;
+string autocvar_g_teamnames_red;
+string autocvar_g_teamnames_blue;
+string autocvar_g_teamnames_yellow;
+string autocvar_g_teamnames_pink;
+
+void send_TeamNames(int channel, entity to);
+
+// Medals
+float autocvar_g_medals_excellent_time = 2;
+
+// Timer
+int autocvar_sv_timer_countdown = 1; // 0 = disabled, 1 = enabled, 2 = spect only
+
// WEAPONTODO
.string weaponorder_byimpulse;
ATTRIB(Client, colormap, int, this.colormap);
ATTRIB(Client, team, int, this.team);
ATTRIB(Client, clientcolors, int, this.clientcolors);
+ ATTRIB(Client, countrycode, int, this.countrycode);
+ ATTRIB(Client, rank, string, this.rank);
/** Client IP */
ATTRIB(Client, netaddress, string, this.netaddress);
ATTRIB(Client, playermodel, string, this.playermodel);
ATTRIB(Client, cvar_cl_pokenade_type, string, this.cvar_cl_pokenade_type);
ATTRIB(Client, cvar_cl_spawn_near_teammate, bool, this.cvar_cl_spawn_near_teammate);
ATTRIB(Client, cvar_cl_gunalign, int, this.cvar_cl_gunalign);
+ ATTRIB(Client, cvar_cl_chat_sounds, bool, this.cvar_cl_chat_sounds);
ATTRIB(Client, cvar_cl_handicap, float, this.cvar_cl_handicap);
ATTRIB(Client, cvar_cl_clippedspectating, bool, this.cvar_cl_clippedspectating);
ATTRIB(Client, cvar_cl_autoscreenshot, int, this.cvar_cl_autoscreenshot);
#define IS_INDEPENDENT_PLAYER(e) ((e).solid == SOLID_TRIGGER)
#define MAKE_INDEPENDENT_PLAYER(e) (((e).solid = SOLID_TRIGGER), ((e).frags = FRAGS_PLAYER_OUT_OF_GAME))
+.float lastkill;
+.int countrycode;
.int killcount;
+.string rank; // RJZ
//flood fields
.float nickspamtime; // time of last nick change
.float nickspamcount;
+ void SendWelcomemessage_msg_type(entity this, bool force_centerprint, int msg_type);
+
// respawning
.int respawn_flags;
.float respawn_time;
#define SPECTATE_COPYFIELD(fld) SPECTATE_COPY() { this.(fld) = spectatee.(fld); }
const int MAX_SPECTATORS = 7;
+
+float _medal_times;
+#define Give_Medal(entity,medalname) \
+ _medal_times = GameRules_scoring_add(entity, MEDAL_##medalname, 1); \
+ Send_Notification(NOTIF_ONE, entity, MSG_MEDAL, MEDAL_##medalname, _medal_times);
+
{
case CMD_REQUEST_COMMAND:
{
- if (!game_stopped && IS_CLIENT(caller) && !IS_PLAYER(caller))
+ if (!game_stopped && !game_timeout && IS_CLIENT(caller) && !IS_PLAYER(caller))
{
if (joinAllowed(caller))
Join(caller);
{
case CMD_REQUEST_COMMAND:
{
- if (IS_CLIENT(caller) && caller.last_ready < time - 3) // anti-spam
+ if (IS_CLIENT(caller) && caller.last_ready < time - 3)
{
if (warmup_stage || g_race_qualifying == 2)
{
{
caller.ready = false;
if (IS_PLAYER(caller) || INGAME_JOINED(caller))
- bprint(playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n");
+ bprint("\{1}", playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n");
}
else
{
caller.ready = true;
if (IS_PLAYER(caller) || INGAME_JOINED(caller))
- bprint(playername(caller.netname, caller.team, false), "^2 is ready\n");
+ bprint("\{1}", playername(caller.netname, caller.team, false), "^2 is ready\n");
}
caller.last_ready = time;
{
case CMD_REQUEST_COMMAND:
{
- if (!intermission_running && IS_CLIENT(caller))
+ if (!intermission_running && IS_CLIENT(caller) && !game_timeout)
{
if(argv(1) != "")
{
}
}
+void ClientCommand_sounds(entity caller, int request)
+{
+ switch (request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ sprint(caller, strcat("Available sounds: \n\n", autocvar_sv_chat_sounds_list, "\n"));
+ return; // never fall through to usage
+ }
+
+ default:
+ case CMD_REQUEST_USAGE:
+ {
+ sprint(caller, "\nUsage:^3 cmd sounds\n");
+ return;
+ }
+ }
+}
+
void ClientCommand_suggestmap(entity caller, int request, int argc)
{
switch (request)
CLIENT_COMMAND("selfstuff", ClientCommand_selfstuff(ent, request, command), "Stuffcmd a command to your own client") \
CLIENT_COMMAND("sentcvar", ClientCommand_sentcvar(ent, request, arguments), "New system for sending a client cvar to the server") \
CLIENT_COMMAND("spectate", ClientCommand_spectate(ent, request), "Become an observer") \
+ CLIENT_COMMAND("sounds", ClientCommand_sounds(ent, request), "Get list of commsnds") \
CLIENT_COMMAND("suggestmap", ClientCommand_suggestmap(ent, request, arguments), "Suggest a map to the mapvote at match end") \
CLIENT_COMMAND("tell", ClientCommand_tell(ent, request, arguments, command), "Send a message directly to a player") \
CLIENT_COMMAND("voice", ClientCommand_voice(ent, request, arguments, command), "Send voice message via sound") \
#include <server/client.qh>
#include <server/command/common.qh>
#include <server/mutators/_mod.qh>
+#include <server/round_handler.qh>
#include <server/scores.qh>
#include <server/world.qh>
if (timeout_time == autocvar_sv_timeout_resumetime) // play a warning sound when only <sv_timeout_resumetime> seconds are left
Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_PREPARE);
- this.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second
+ //this.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second
+ this.nextthink = time + 1;
timeout_time -= 1; // decrease the time counter
}
+ else if (timeout_time == -1) // infinite timer
+ {
+ Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_TIMEOUT_ONGOING);
+ this.nextthink = time + TIMEOUT_SLOWMO_VALUE;
+ }
else // time to end the timeout
{
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_TIMEIN);
timeout_status = TIMEOUT_INACTIVE;
+ float total_time = time - timeout_last;
// reset the slowmo value back to normal
- cvar_set("slowmo", ftos(orig_slowmo));
+ // z411 TODO
+ //cvar_set("slowmo", ftos(orig_slowmo));
+
+ // Disable timeout and fix times
+ game_timeout = false;
+ timeout_total_time += total_time;
+ game_starttime += total_time;
- round_starttime += total_time;
++ if(round_starttime)
++ round_starttime += total_time;
+ if(round_handler && round_handler_GetEndTime() > 0)
+ round_handler.round_endtime += total_time;
+
+ LOG_INFOF("Timeout lasted %d secs", total_time);
+ timeout_last = 0;
// unlock the view for players so they can move around again
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), {
timeout_status = TIMEOUT_ACTIVE;
// set the slowmo value to the timeout default slowmo value
- cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
+ //cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE));
+ game_timeout = true;
+ timeout_last = time;
+
+ // play timeout sound
+ sound(NULL, CH_INFO, SND_TIMEOUT, VOL_BASE, ATTN_NONE);
// reset all the flood variables
FOREACH_CLIENT(true, {
timeout_status = TIMEOUT_INACTIVE;
timeout_time = 0;
timeout_handler.nextthink = time; // timeout_handler has to take care of it immediately
+ Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_TIMEOUT);
bprint(strcat("^7The timeout was aborted by ", GetCallerName(caller), " !\n"));
return;
}
{
timeout_time = autocvar_sv_timeout_resumetime;
timeout_handler.nextthink = time; // timeout_handler has to take care of it immediately
- bprint(strcat("^1Attention: ^7", GetCallerName(caller), " resumed the game! Prepare for battle!\n"));
+ bprint(strcat("\{1}^1Attention: ^7", GetCallerName(caller), " resumed the game! Prepare for battle!\n"));
return;
}
{
if (caller) CS(caller).allowed_timeouts -= 1;
// write a bprint who started the timeout (and how many they have left)
- bprint(GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(CS(caller).allowed_timeouts), " timeout(s) left)") : ""), "!\n");
+ bprint("\{1}", GetCallerName(caller), " ^7called a timeout", (caller ? strcat(" (", ftos(CS(caller).allowed_timeouts), " timeout(s) left)") : ""), "!\n");
timeout_status = TIMEOUT_LEADTIME;
timeout_caller = caller;
timeout_handler = new(timeout_handler);
setthink(timeout_handler, timeout_handler_think);
timeout_handler.nextthink = time; // always let the entity think asap
-
+
Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_TIMEOUT);
}
}
}
}
+void GameCommand_teamname(int request, int argc)
+{
+ switch (request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ if (argv(1) == "")
+ {
+ return;
+ }
+ if (!teamplay)
+ {
+ LOG_INFO("selectteam can only be used in teamgames");
+ return;
+ }
+
+ switch (argv(1))
+ {
+ case "red":
+ case "blue":
+ case "yellow":
+ case "pink":
+ {
+ int tm = Team_ColorToTeam(argv(1));
+ if(argv(2) != "") {
+ cvar_set(strcat("g_teamnames_", argv(1)), argv(2));
+ bprintf("\{1}%s%s^7 team is now known as %s^7\n", Team_ColorCode(tm), Team_ColorName(tm), argv(2));
+ } else {
+ cvar_set(strcat("g_teamnames_", argv(1)), "");
+ bprintf("\{1}%s%s^7 team now doesn't have a team name\n", Team_ColorCode(tm), Team_ColorName(tm), argv(2));
+ }
+
+ break;
+ }
+ default:
+ {
+ return;
+ }
+ }
+
+ send_TeamNames(MSG_BROADCAST, NULL);
+ return;
+ }
+
+ default:
+ LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+ case CMD_REQUEST_USAGE:
+ {
+ LOG_HELP("Usage:^3 sv_cmd sendteams");
+ LOG_HELP(" No arguments required.");
+ return;
+ }
+ }
+}
+
void GameCommand_allready(int request)
{
switch (request)
cvar_settemp("minplayers", "0");
cvar_settemp("minplayers_per_team", "0");
cvar_settemp("bot_number", "0");
- bot_fixcount();
+ bot_fixcount(false); // Kill all bots.
cvar_settemp("bot_number", argv(2));
- if (!bot_fixcount()) LOG_INFO("Sorry, could not set requested bot count");
+ if (!bot_fixcount(true)) LOG_INFO("Sorry, could not set requested bot count");
return;
}
else if (argv(1) == "load" && argc == 3)
cvar_settemp("minplayers", "0");
cvar_settemp("minplayers_per_team", "0");
cvar_settemp("bot_number", "0");
- bot_fixcount();
+ bot_fixcount(false); // Kill all bots.
cvar_settemp("bot_number", argv(3));
- if (!bot_fixcount()) LOG_INFO("Sorry, could not set requested bot count");
+ if (!bot_fixcount(true)) LOG_INFO("Sorry, could not set requested bot count");
}
else
{
}
}
+void GameCommand_ircmsg(int request, int argc, string command)
+{
+ /* IRCSay from the SMB Modpack */
+ switch (request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ string msgstr = substring(command, strlen(argv(0))+1, strlen(command));
+
+ if(msgstr == "")
+ return;
+
+ string prefix;
+ if(substring(msgstr, 0, 3) == "^4*") // actions
+ prefix = "\{3}";
+ else
+ prefix = "\{1}";
+
+ msgstr = strcat(prefix, strreplace("\n", " ", msgstr), "\n"); // newlines only are good for centerprint
+
+ FOREACH_CLIENTSLOT(true,
+ {
+ if(!intermission_running)
+ if((autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(warmup_stage || game_stopped)))
+ if(IS_PLAYER(it))
+ continue;
+ if(IS_REAL_CLIENT(it))
+ sprint(it, msgstr);
+ });
+ }
+
+ default:
+ case CMD_REQUEST_USAGE:
+ {
+ LOG_HELP("Usage:^3 sv_cmd ircmsg message");
+ return;
+ }
+ }
+}
+
void GameCommand_lockteams(int request)
{
switch (request)
if (teamplay)
{
lockteams = 1;
- bprint("^1The teams are now locked.\n");
+ bprint("\{1}^1The teams are now locked.\n");
}
else
{
}
}
+void GameCommand_setflag(int request, int argc)
+{
+ switch (request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ entity client;
+ float accepted;
+
+ client = GetFilteredEntity(argv(1));
+ accepted = VerifyClientEntity(client, false, false);
+
+ if (accepted <= 0)
+ {
+ LOG_INFO("^1ERROR^7: Couldn't set country flag");
+ LOG_HELP("Usage:^3 sv_cmd setflag #client_id countrycode[0-249]");
+ return;
+ }
+
+ client.countrycode = stof(argv(2));
+ LOG_INFO("^2SUCCESS^7: Country flag set!");
+ return;
+ }
+ default:
+ LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+ case CMD_REQUEST_USAGE:
+ {
+ LOG_HELP("Usage:^3 sv_cmd setflag #client_id countrycode[0-249]");
+ return;
+ }
+ }
+}
+
+void GameCommand_setrank(int request, int argc)
+{
+ switch (request)
+ {
+ case CMD_REQUEST_COMMAND:
+ {
+ entity client;
+ float accepted;
+
+ client = GetFilteredEntity(argv(1));
+ accepted = VerifyClientEntity(client, false, false);
+
+ if (accepted <= 0)
+ {
+ LOG_INFO("^1ERROR^7: Couldn't set player rank");
+ LOG_HELP("Usage:^3 sv_cmd setrank #client_id rank");
+ return;
+ }
+
+ client.rank = strzone(argv(2));
+ LOG_INFO("^2SUCCESS^7: Player rank set!");
+ return;
+ }
+ default:
+ LOG_INFOF("Incorrect parameters for ^2%s^7", argv(0));
+ case CMD_REQUEST_USAGE:
+ {
+ LOG_HELP("Usage:^3 sv_cmd setrank #client_id #rank");
+ return;
+ }
+ }
+}
+
void GameCommand_moveplayer(int request, int argc)
{
switch (request)
cvar_settemp("minplayers", "0");
cvar_settemp("minplayers_per_team", "0");
cvar_settemp("bot_number", argv(1));
- bot_fixcount();
+ bot_fixcount(true);
return;
}
}
if (teamplay)
{
lockteams = 0;
- bprint("^1The teams are now unlocked.\n");
+ bprint("\{1}^1The teams are now unlocked.\n");
}
else
{
SERVER_COMMAND(gametype, "Simple command to change the active gametype") { GameCommand_gametype(request, arguments); }
SERVER_COMMAND(gettaginfo, "Get specific information about a weapon model") { GameCommand_gettaginfo(request, arguments); }
SERVER_COMMAND(gotomap, "Simple command to switch to another map") { GameCommand_gotomap(request, arguments); }
+SERVER_COMMAND(ircmsg, "Chat message to be sent by IRC bots") { GameCommand_ircmsg(request, arguments, command); }
SERVER_COMMAND(lockteams, "Disable the ability for players to switch or enter teams") { GameCommand_lockteams(request); }
SERVER_COMMAND(make_mapinfo, "Automatically rebuild mapinfo files") { GameCommand_make_mapinfo(request); }
SERVER_COMMAND(moveplayer, "Change the team/status of a player") { GameCommand_moveplayer(request, arguments); }
SERVER_COMMAND(reducematchtime, "Decrease the timelimit value incrementally") { GameCommand_reducematchtime(request); }
SERVER_COMMAND(resetmatch, "Soft restart the game without changing teams; goes back to warmup if enabled") { GameCommand_resetmatch(request); }
SERVER_COMMAND(setbots, "Adjust how many bots are in the match") { GameCommand_setbots(request, arguments); }
+SERVER_COMMAND(setflag, "Set client flag") { GameCommand_setflag(request, arguments); }
+SERVER_COMMAND(setrank, "Set client rank") { GameCommand_setrank(request, arguments); }
SERVER_COMMAND(shuffleteams, "Randomly move players to different teams") { GameCommand_shuffleteams(request); }
SERVER_COMMAND(stuffto, "Send a command to be executed on a client") { GameCommand_stuffto(request, arguments); }
+SERVER_COMMAND(teamname, "Set team name") { GameCommand_teamname(request, arguments); }
SERVER_COMMAND(trace, "Various debugging tools with tracing") { GameCommand_trace(request, arguments); }
SERVER_COMMAND(unlockteams, "Enable the ability for players to switch or enter teams") { GameCommand_unlockteams(request); }
SERVER_COMMAND(warp, "Choose different level in campaign") { GameCommand_warp(request, arguments); }
// add up all the votes from each connected client
FOREACH_CLIENT(IS_REAL_CLIENT(it) && IS_CLIENT(it), {
+ // z411
+ if(vote_target_type == VOTE_TARGET_TEAM && it.team != vote_caller.team) continue;
+ if(vote_target_type == VOTE_TARGET_SINGLE && it != vote_target) continue;
+
++vote_player_count;
if (IS_PLAYER(it)) ++vote_real_player_count;
switch (it.vote_selection)
if (round_handler_IsActive())
round_handler_Reset(game_starttime);
}
+
+ // for RJZ
+ if (autocvar_rjz_count_shards) {
+ total_shards = 0;
+ send_TotalShardsAll();
+ }
if (shuffleteams_on_reset_map)
{
// clear overtime, we have to decrease timelimit to its original value again.
if (checkrules_overtimesadded > 0 && g_race_qualifying != 2)
cvar_set("timelimit", ftos(autocvar_timelimit - (checkrules_overtimesadded * autocvar_timelimit_overtime)));
- checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = 0;
+ checkrules_suddendeathend = checkrules_overtimesadded = checkrules_suddendeathwarning = overtimes = 0;
if(warmup_stage)
game_starttime = time; // Warmup: No countdown in warmup
localcmd("\nsv_hook_warmupend\n");
// reset the .ready status of all players (also spectators)
- FOREACH_CLIENT(IS_REAL_CLIENT(it), { it.ready = false; });
+ FOREACH_CLIENT(IS_REAL_CLIENT(it), {
+ it.ready = false;
+ Kill_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CPID_MISSING_READY);
+ });
readycount = 0;
Nagger_ReadyCounted(); // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { CS(it).allowed_timeouts = autocvar_sv_timeout_number; });
}
+ round_handler_Activate(!warmup_stage);
if (!sv_ready_restart_after_countdown || warmup_stage)
reset_map(true, is_fake_round_start);
case MUT_VOTEPARSE_UNACCEPTABLE: { return 0; }
}
+ vote_target_type = VOTE_TARGET_ALL;
+
switch (first_command) // now go through and parse the proper commands to adjust as needed.
{
case "kick":
if (first_command == "kickban")
command_arguments = strcat(ftos(autocvar_g_ban_default_bantime), " ", ftos(autocvar_g_ban_default_masksize), " ~");
- vote_parsed_command = strcat(first_command, " # ", ftos(etof(victim)), " ", command_arguments);
+ if (first_command == "kick") // z411 : Use our kick implementation - kind of hacky...
+ vote_parsed_command = strcat("defer 2 \"sv_cmd kickkick # ", ftos(etof(victim)), " ", command_arguments, "\"");
+ else
+ vote_parsed_command = strcat("defer 2 \"", first_command, " # ", ftos(etof(victim)), " ", command_arguments, "\"");
+
vote_parsed_display = sprintf("^1%s #%d ^7%s^1 %s", first_command, etof(victim), victim.netname, reason);
}
else
{
vote_command = ValidateMap(argv(startpos + 1), caller);
if (!vote_command) return -1;
- vote_parsed_command = strcat("gotomap ", vote_command);
- vote_parsed_display = strzone(strcat("^1", vote_parsed_command));
+ vote_parsed_command = strcat("defer 2 \"gotomap ", vote_command, "\"");
+ vote_parsed_display = strzone(strcat("^1gotomap ", vote_command));
break;
}
+
+ // z411 team calls
+ case "teamname":
+ {
+ if (teamplay && Team_IsValidTeam(caller.team)) {
+ vote_target_type = VOTE_TARGET_TEAM;
+
+ string tmname = strtolower(Static_Team_ColorName(caller.team));
+ string newname = argv(startpos + 1);
+
+ vote_parsed_command = strcat(first_command, " ", tmname, " \"", newname, "\"");
+ vote_parsed_display = strzone(strcat("^3(Team) ^1", first_command, " ^2", newname));
+ } else { print_to(caller, "vcall: Not in a team\n"); return 0; }
+
+ break;
+ }
// TODO: replicate the old behaviour of being able to vote for maps from different modes on multimode servers (possibly support it in gotomap too)
// maybe fallback instead of aborting if map name is invalid?
break;
}
- case "restart":
+ case "gg":
+ case "shuffleteams":
+ case "endmatch":
{
// add a delay so that vote result can be seen and announcer can be heard
// if the vote is accepted
- vote_parsed_command = strcat("defer 1 ", vote_command);
+ vote_parsed_command = strcat("defer 2 ", vote_command);
+ vote_parsed_display = strzone(strcat("^1", vote_command));
+
+ break;
+ }
+
+ case "reset":
+ case "restart": // re-direct all match restarting to resetmatch
+ vote_command = "resetmatch"; // fall-through
+ case "resetmatch":
+ {
+ vote_parsed_command = strcat("defer 2 ", vote_command);
vote_parsed_display = strzone(strcat("^1", vote_command));
break;
return -1;
}
- vote_parsed_command = vote_command;
+ vote_parsed_command = strcat("defer 2 ", vote_command);
vote_parsed_display = strzone(strcat("^1", vote_command));
break;
}
const float VOTE_NORMAL = 1;
const float VOTE_MASTER = 2;
+// z411 vote targets
+const float VOTE_TARGET_ALL = 0;
+const float VOTE_TARGET_TEAM = 1;
+const float VOTE_TARGET_SINGLE = 2;
+
// global vote information declarations
entity vote_caller; // original caller of the current vote
string vote_caller_name; // name of the vote caller
float vote_reject_count; // same as above, but rejected
float vote_abstain_count; // same as above, but abstained
float vote_needed_overall; // total amount of players NEEDED for a vote to pass (based on sv_vote_majority_factor)
+float vote_target_type; // z411
+entity vote_target; // z411
.float vote_master; // flag for if the player has vote master privelages
.float vote_waittime; // flag for how long the player must wait before they can vote again
.float vote_selection; // flag for which vote selection the player has made (See VOTE_SELECT_*)
entity nagger;
float readycount; // amount of players who are ready
.float ready; // flag for if a player is ready
- .float last_ready; // z411 time of the last readyup for anti-spam
+ .float last_ready; // last ready time for anti-spam
.int team_saved; // team number to restore upon map reset
.void(entity this) reset; // if set, an entity is reset using this
.void(entity this) reset2; // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
void Obituary_SpecialDeath(
entity notif_target,
+ entity attacker,
float murder,
int deathtype,
string s1, string s2, string s3,
f1, f2, f3, 0
);
}
+
+ if(deathtype == DEATH_TELEFRAG.m_id) {
+ Give_Medal(attacker, TELEFRAG);
+ }
}
float Obituary_WeaponDeath(
entity notif_target,
+ entity attacker,
float murder,
int deathtype,
string s1, string s2, string s3,
s1, s2, s3, "",
f1, f2, 0, 0
);
+
+ // z411 special medals
+ if(attacker) {
+ switch(death_message) {
+ case WEAPON_SHOTGUN_MURDER_SLAP:
+ if(!cvar("g_melee_only")) { // don't spam humiliation if we're in melee_only mode
+ Give_Medal(attacker, HUMILIATION);
+ }
+ break;
+ case WEAPON_ELECTRO_MURDER_COMBO:
+ Give_Medal(attacker, ELECTROBITCH);
+ break;
+ }
+ }
}
else
{
notif_anonymous = M_ARGV(5, bool);
if(notif_anonymous)
- attacker_name = "Anonymous player";
+ attacker_name = "???";
#ifdef NOTIFICATIONS_DEBUG
Debug_Notification(
{
if(deathtype == DEATH_TEAMCHANGE.m_id || deathtype == DEATH_AUTOTEAMCHANGE.m_id)
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
+ Obituary_SpecialDeath(targ, NULL, false, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
}
else
{
{
case DEATH_MIRRORDAMAGE:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+ Obituary_SpecialDeath(targ, NULL, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
case DEATH_HURTTRIGGER:
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, inflictor.message, deathlocation, CS(targ).killcount, 0, 0);
+ Obituary_SpecialDeath(targ, NULL, false, deathtype, targ.netname, inflictor.message, deathlocation, CS(targ).killcount, 0, 0);
break;
default:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+ Obituary_SpecialDeath(targ, NULL, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
}
}
}
- else if (!Obituary_WeaponDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
+ else if (!Obituary_WeaponDeath(targ, NULL, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0))
{
backtrace("SUICIDE: what the hell happened here?\n");
return;
}
LogDeath("suicide", deathtype, targ, targ);
+ Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_SUICIDE);
if(deathtype != DEATH_AUTOTEAMCHANGE.m_id) // special case: don't negate frags if auto switched
GiveFrags(attacker, targ, -1, deathtype, weaponentity);
}
Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker_name);
- Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL), targ.netname, attacker_name, deathlocation, CS(targ).killcount);
+ Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(targ.team, INFO_DEATH_TEAMKILL),
+ playername(targ.netname, targ.team, true), playername(attacker_name, attacker.team, true),
+ deathlocation, CS(targ).killcount);
// In this case, the death message will ALWAYS be "foo was betrayed by bar"
// No need for specific death/weapon messages...
CS(attacker).killcount = CS(attacker).killcount + 1;
attacker.killsound += 1;
-
+
// TODO: improve SPREE_ITEM and KILL_SPREE_LIST
// these 2 macros are spread over multiple files
#define SPREE_ITEM(counta,countb,center,normal,gentle) \
case counta: \
- Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
+ Give_Medal(attacker, KILLSTREAK_##countb); \
if (!warmup_stage) \
PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
break;
{
checkrules_firstblood = true;
notif_firstblood = true; // modify the current messages so that they too show firstblood information
+ Give_Medal(attacker, FIRSTBLOOD);
PlayerStats_GameReport_Event_Player(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
PlayerStats_GameReport_Event_Player(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
kill_count_to_attacker = CS(attacker).killcount;
kill_count_to_target = 0;
}
+
+ // Excellent check
+ if(attacker.lastkill && attacker.lastkill > time - autocvar_g_medals_excellent_time) {
+ Give_Medal(attacker, EXCELLENT);
+ }
+ attacker.lastkill = time;
if(targ.istypefrag)
{
if(deathtype == DEATH_BUFF.m_id)
f3 = buff_FirstFromFlags(attacker).m_id;
- if (!Obituary_WeaponDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker))
- Obituary_SpecialDeath(targ, true, deathtype, targ.netname, attacker_name, deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
+ if (!Obituary_WeaponDeath(targ, attacker, true, deathtype, playername(targ.netname, targ.team, true), playername(attacker_name, attacker.team, true), deathlocation, CS(targ).killcount, kill_count_to_attacker))
+ Obituary_SpecialDeath(targ, attacker, true, deathtype, playername(targ.netname, targ.team, true), playername(attacker_name, attacker.team, true), deathlocation, CS(targ).killcount, kill_count_to_attacker, f3);
}
}
// and there will be a REAL DEATH_VOID implementation which mappers will use.
case DEATH_HURTTRIGGER:
{
- Obituary_SpecialDeath(targ, false, deathtype,
- targ.netname,
+ Obituary_SpecialDeath(targ, NULL, false, deathtype,
+ playername(targ.netname, targ.team, true),
inflictor.message,
deathlocation,
CS(targ).killcount,
case DEATH_CUSTOM:
{
- Obituary_SpecialDeath(targ, false, deathtype,
- targ.netname,
+ Obituary_SpecialDeath(targ, NULL, false, deathtype,
+ playername(targ.netname, targ.team, true),
((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
deathlocation,
CS(targ).killcount,
default:
{
- Obituary_SpecialDeath(targ, false, deathtype, targ.netname, deathlocation, "", CS(targ).killcount, 0, 0);
+ Obituary_SpecialDeath(targ, NULL, false, deathtype, playername(targ.netname, targ.team, true), deathlocation, "", CS(targ).killcount, 0, 0);
break;
}
}
LogDeath("accident", deathtype, targ, targ);
+ Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACCIDENT);
GiveFrags(targ, targ, -1, deathtype, weaponentity);
if(GameRules_scoring_add(targ, SCORE, 0) == -5)
return 0;
}
+ if (rad < 0) rad = 0;
+
RadiusDamage_running = 1;
tfloordmg = autocvar_g_throughfloor_damage;
if (((cantbe != targ) && !mustbe) || (mustbe == targ))
if (targ.takedamage)
{
- vector nearest;
- vector diff;
- float power;
-
- // LordHavoc: measure distance to nearest point on target (not origin)
- // (this guarentees 100% damage on a touch impact)
- nearest = targ.WarpZone_findradius_nearest;
- diff = targ.WarpZone_findradius_dist;
+ // measure distance from nearest point on target (not origin)
+ // to nearest point on inflictor (not origin)
+ vector nearest = targ.WarpZone_findradius_nearest;
+ vector inflictornearest = NearestPointOnBoundingBox(
+ inflictororigin - (inflictor.maxs - inflictor.mins) * 0.5,
+ inflictororigin + (inflictor.maxs - inflictor.mins) * 0.5,
+ nearest);
+ vector diff = inflictornearest - nearest;
+
// round up a little on the damage to ensure full damage on impacts
// and turn the distance into a fraction of the radius
- power = 1 - ((vlen (diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad);
- //bprint(" ");
- //bprint(ftos(power));
- //if (targ == attacker)
- // print(ftos(power), "\n");
- if (power > 0)
+ float dist = max(0, vlen(diff) - bound(MIN_DAMAGEEXTRARADIUS, targ.damageextraradius, MAX_DAMAGEEXTRARADIUS));
+ if (dist <= rad)
{
- float finaldmg;
- if (power > 1)
- power = 1;
- finaldmg = coredamage * power + edgedamage * (1 - power);
+ float power = 1;
+ if (rad > 0)
+ power -= (dist / rad);
+ // at this point power can't be < 0 or > 1
+ float finaldmg = coredamage * power + edgedamage * (1 - power);
if (finaldmg > 0)
{
float a;
.float spawnshieldtime;
.int totalfrags;
+.float lastkill;
.bool canteamdamage;
void Obituary_SpecialDeath(
entity notif_target,
+ entity attacker,
float murder,
int deathtype,
string s1, string s2, string s3,
float w_deathtype;
float Obituary_WeaponDeath(
entity notif_target,
+ entity target,
float murder,
int deathtype,
string s1, string s2, string s3,
float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype, .entity weaponentity, entity directhitentity);
.float damageforcescale;
- const float MIN_DAMAGEEXTRARADIUS = 2;
+ const float MIN_DAMAGEEXTRARADIUS = 0.1;
const float MAX_DAMAGEEXTRARADIUS = 16;
.float damageextraradius;
.float fire_deathtype;
.entity fire_owner;
.float fire_hitsound;
- .entity fire_burner;
float Fire_AddDamage(entity e, entity o, float d, float t, float dt);
#include <common/mutators/mutator/buffs/sv_buffs.qh>
#include <common/mutators/mutator/powerups/_mod.qh>
#include <common/mutators/mutator/status_effects/_mod.qh>
+#include <common/net_linked.qh>
#include <common/notifications/all.qh>
#include <common/resources/resources.qh>
#include <common/util.qh>
void Item_RespawnCountdown(entity this)
{
+ if(game_timeout) { this.nextthink = time + 1; return; }
+
if(this.item_respawncounter >= ITEM_RESPAWN_TICKS)
{
if(this.waypointsprite_attached)
else
{
this.nextthink = time + 1;
- this.item_respawncounter += 1;
+ this.item_respawncounter = floor((time - game_starttime) - (this.scheduledrespawntime - ITEM_RESPAWN_TICKS)) + 1;
+ //this.item_respawncounter += 1;
+ //LOG_INFOF("Respawncounter: %d", this.item_respawncounter);
+ if(this.item_respawncounter < 1) return;
+
if(this.item_respawncounter == 1)
{
do {
void Item_RespawnThink(entity this)
{
- this.nextthink = time;
+ this.nextthink = time + 1;
if(this.origin != this.oldorigin)
ItemUpdate(this);
-
- if(time >= this.wait)
+
+ if(!game_timeout && time - game_starttime >= this.wait)
Item_Respawn(this);
+
+ //LOG_INFOF("time until respawn %d", (this.wait) - (time - game_starttime));
}
void Item_ScheduleRespawnIn(entity e, float t)
if ((Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS) || MUTATOR_CALLHOOK(Item_ScheduleRespawn, e, t)) && (t - ITEM_RESPAWN_TICKS) > 0)
{
setthink(e, Item_RespawnCountdown);
- e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS);
- e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
+ //e.nextthink = time - timeout_total_time + max(0, t - ITEM_RESPAWN_TICKS);
+ //e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
+ e.nextthink = time;
+ e.scheduledrespawntime = time - game_starttime + t;
e.item_respawncounter = 0;
+
if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
{
t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime);
{
setthink(e, Item_RespawnThink);
e.nextthink = time;
- e.scheduledrespawntime = time + t;
- e.wait = time + t;
+ e.scheduledrespawntime = time - game_starttime + t;
+ e.wait = time - game_starttime + t;
if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
{
return true;
}
+void Item_NotifyWeapon(entity player, int wep)
+{
+ if(IS_REAL_CLIENT(player)) {
+ msg_entity = player;
+ WriteHeader(MSG_ONE, TE_CSQC_WEAPONPICKUP);
+ WriteByte(MSG_ONE, wep);
+ }
+}
+
bool Item_GiveTo(entity item, entity player)
{
// if nothing happens to player, just return without taking the item
pickedup |= Item_GiveAmmoTo(item, player, RES_CELLS, g_pickup_cells_max);
pickedup |= Item_GiveAmmoTo(item, player, RES_PLASMA, g_pickup_plasma_max);
pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max);
+
+ // for RJZ
+ if (autocvar_rjz_count_shards && !warmup_stage && item.itemdef == ITEM_ArmorSmall) {
+ total_shards++;
+ send_TotalShardsAll();
+ }
+
if (item.itemdef.instanceOfWeaponPickup)
{
- WepSet w;
+ WepSet w, wp;
w = STAT(WEAPONS, item);
- w &= ~STAT(WEAPONS, player);
+ wp = w & ~STAT(WEAPONS, player);
if (w || (item.spawnshieldtime && item.pickup_anyway > 0))
{
pickedup = true;
FOREACH(Weapons, it != WEP_Null, {
- if(w & (it.m_wepset))
+ Weapon wep = it;
+
+ if(w & (wep.m_wepset)) {
+ // z411 Seriously find a better way to do this
+ Item_NotifyWeapon(player, wep.m_id);
+ FOREACH_CLIENT(IS_SPEC(it) && it.enemy == player, { Item_NotifyWeapon(it, wep.m_id); });
+ }
+
+ if(wp & (wep.m_wepset))
{
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
.entity weaponentity = weaponentities[slot];
if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
- W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
+ W_DropEvent(wr_pickup, player, wep.m_id, item, weaponentity);
}
- W_GiveWeapon(player, it.m_id);
+ W_GiveWeapon(player, wep.m_id);
}
});
}
if(v1 <= v0 - t)
{
if(snd_decr != NULL)
- sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
+ sound(e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
}
else if(v0 >= v0 + t)
{
if(snd_incr != NULL)
- sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTEN_NORM);
+ sound(e, ((snd_incr == SND_POWERUP) ? CH_TRIGGER_SINGLE : CH_TRIGGER), snd_incr, VOL_BASE, ATTEN_NORM);
}
}
/**/
MUTATOR_HOOKABLE(ItemTouched, EV_ItemTouched);
+ // The Resource hooks are often called by other hooks and to avoid conflicts
+ // as much as possible their args start from ARGV_7
+
/** Called when the amount of entity resources changes. Can be used to override
resource limit. */
#define EV_GetResourceLimit(i, o) \
- /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /** limit */ i(float, MUTATOR_ARGV_2_float) \
- /**/ o(float, MUTATOR_ARGV_2_float) \
+ /** checked entity */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /** limit */ i(float, MUTATOR_ARGV_9_float) \
+ /**/ o(float, MUTATOR_ARGV_9_float) \
/**/
MUTATOR_HOOKABLE(GetResourceLimit, EV_GetResourceLimit);
/** Called when the amount of resource of an entity changes. See RES_*
constants for resource types. Return true to forbid the change. */
#define EV_SetResource(i, o) \
- /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /**/ o(entity, MUTATOR_ARGV_1_entity) \
- /** amount */ i(float, MUTATOR_ARGV_2_float) \
- /**/ o(float, MUTATOR_ARGV_2_float) \
+ /** checked entity */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /**/ o(entity, MUTATOR_ARGV_8_entity) \
+ /** amount */ i(float, MUTATOR_ARGV_9_float) \
+ /**/ o(float, MUTATOR_ARGV_9_float) \
/**/
MUTATOR_HOOKABLE(SetResource, EV_SetResource);
constants for resource types. Amount wasted is the amount of resource that is
above resource limit so it was not given. */
#define EV_ResourceAmountChanged(i, o) \
- /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /** amount */ i(float, MUTATOR_ARGV_2_float) \
+ /** checked entity */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /** amount */ i(float, MUTATOR_ARGV_9_float) \
/**/
MUTATOR_HOOKABLE(ResourceAmountChanged, EV_ResourceAmountChanged);
limit. See RES_* constants for resource types. Amount wasted is the amount
of resource that is above resource limit so it was not given. */
#define EV_ResourceWasted(i, o) \
- /** checked entity */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /** amount wasted */ i(float, MUTATOR_ARGV_2_float) \
+ /** checked entity */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /** amount wasted */ i(float, MUTATOR_ARGV_9_float) \
/**/
MUTATOR_HOOKABLE(ResourceWasted, EV_ResourceWasted);
for resource types. Return true to forbid giving.
NOTE: This hook is also called by GiveResourceWithLimit */
#define EV_GiveResource(i, o) \
- /** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /**/ o(entity, MUTATOR_ARGV_1_entity) \
- /** amount */ i(float, MUTATOR_ARGV_2_float) \
- /**/ o(float, MUTATOR_ARGV_2_float) \
+ /** receiver */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /**/ o(entity, MUTATOR_ARGV_8_entity) \
+ /** amount */ i(float, MUTATOR_ARGV_9_float) \
+ /**/ o(float, MUTATOR_ARGV_9_float) \
/**/
MUTATOR_HOOKABLE(GiveResource, EV_GiveResource);
/** Called when entity is being given some resource with specified limit. See
RES_* constants for resource types. Return true to forbid giving. */
#define EV_GiveResourceWithLimit(i, o) \
- /** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /**/ o(entity, MUTATOR_ARGV_1_entity) \
- /** amount */ i(float, MUTATOR_ARGV_2_float) \
- /**/ o(float, MUTATOR_ARGV_2_float) \
- /** limit */ i(float, MUTATOR_ARGV_3_float) \
- /**/ o(float, MUTATOR_ARGV_3_float) \
+ /** receiver */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /**/ o(entity, MUTATOR_ARGV_8_entity) \
+ /** amount */ i(float, MUTATOR_ARGV_9_float) \
+ /**/ o(float, MUTATOR_ARGV_9_float) \
+ /** limit */ i(float, MUTATOR_ARGV_10_float) \
+ /**/ o(float, MUTATOR_ARGV_10_float) \
/**/
MUTATOR_HOOKABLE(GiveResourceWithLimit, EV_GiveResourceWithLimit);
for resource types. Return true to forbid giving.
NOTE: This hook is also called by TakeResourceWithLimit */
#define EV_TakeResource(i, o) \
- /** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /**/ o(entity, MUTATOR_ARGV_1_entity) \
- /** amount */ i(float, MUTATOR_ARGV_2_float) \
- /**/ o(float, MUTATOR_ARGV_2_float) \
+ /** receiver */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /**/ o(entity, MUTATOR_ARGV_8_entity) \
+ /** amount */ i(float, MUTATOR_ARGV_9_float) \
+ /**/ o(float, MUTATOR_ARGV_9_float) \
/**/
MUTATOR_HOOKABLE(TakeResource, EV_TakeResource);
/** Called when some resource is being taken from an entity, with a limit. See
RES_* constants for resource types. Return true to forbid giving. */
#define EV_TakeResourceWithLimit(i, o) \
- /** receiver */ i(entity, MUTATOR_ARGV_0_entity) \
- /** resource type */ i(entity, MUTATOR_ARGV_1_entity) \
- /**/ o(entity, MUTATOR_ARGV_1_entity) \
- /** amount */ i(float, MUTATOR_ARGV_2_float) \
- /**/ o(float, MUTATOR_ARGV_2_float) \
- /** limit */ i(float, MUTATOR_ARGV_3_float) \
- /**/ o(float, MUTATOR_ARGV_3_float) \
+ /** receiver */ i(entity, MUTATOR_ARGV_7_entity) \
+ /** resource type */ i(entity, MUTATOR_ARGV_8_entity) \
+ /**/ o(entity, MUTATOR_ARGV_8_entity) \
+ /** amount */ i(float, MUTATOR_ARGV_9_float) \
+ /**/ o(float, MUTATOR_ARGV_9_float) \
+ /** limit */ i(float, MUTATOR_ARGV_10_float) \
+ /**/ o(float, MUTATOR_ARGV_10_float) \
/**/
MUTATOR_HOOKABLE(TakeResourceWithLimit, EV_TakeResourceWithLimit);
+ // END Resource hooks
+
/** called at when a player connect */
#define EV_ClientConnect(i, o) \
/** player */ i(entity, MUTATOR_ARGV_0_entity) \
MUTATOR_HOOKABLE(FixPlayermodel, EV_FixPlayermodel);
/** Return error to play frag remaining announcements */
+MUTATOR_HOOKABLE(Scores_AnnounceLeads, EV_NO_ARGS);
MUTATOR_HOOKABLE(Scores_CountFragsRemaining, EV_NO_ARGS);
#define EV_GrappleHookThink(i, o) \
#include <common/util.qh>
#include <server/campaign.qh>
#include <server/command/vote.qh>
+#include <server/weapons/accuracy.qh>
#include <server/world.qh>
void round_handler_Think(entity this)
{
+ if (!this.isactive) return;
+ if (game_timeout) { this.nextthink = time + 1; return; }
+
if (intermission_running)
{
round_handler_Reset(0);
this.cnt = 0;
this.round_endtime = (this.round_timelimit) ? time + this.round_timelimit : 0;
this.nextthink = time;
+ FOREACH_CLIENT(IS_PLAYER(it), { roundaccuracy_clear(it); });
+ rounds_played++;
if (this.roundStart) this.roundStart();
return;
}
else
{
round_handler_Reset(0);
+ round_starttime = -1; // can't start
}
this.nextthink = time + 1; // canRoundStart every second
}
this.count = fabs(floor(the_count));
this.cnt = this.count + 1;
this.round_timelimit = (the_round_timelimit > 0) ? the_round_timelimit : 0;
+ round_limit = the_round_timelimit;
}
// NOTE: this is only needed because if round_handler spawns at time 1
return;
}
entity this = round_handler = new_pure(round_handler);
-
- setthink(this, round_handler_FirstThink);
+
this.canRoundStart = canRoundStart_func;
this.canRoundEnd = canRoundEnd_func;
this.roundStart = roundStart_func;
this.wait = false;
round_handler_Init(5, 5, 180);
- this.nextthink = time;
+}
+
+void round_handler_Activate(bool active) {
+ if (round_handler) {
+ entity this = round_handler;
+
+ this.isactive = active;
+ if(active) {
+ setthink(this, round_handler_FirstThink);
+ this.nextthink = time;
+ } else {
+ round_starttime = -1;
+ }
+ }
}
void round_handler_Reset(float next_think)
if (this.count)
if (this.cnt < this.count + 1) this.cnt = this.count + 1;
this.nextthink = next_think;
- round_starttime = (next_think) ? (next_think + this.count) : -1;
+ if (next_think)
+ {
+ if (next_think <= game_starttime) rounds_played = 0;
+ round_starttime = next_think + this.count;
+ }
}
void round_handler_Remove()
}
}
+ .bool welcome_msg_already_sent_on_connection;
bool ScoreInfo_SendEntity(entity this, entity to, int sf)
{
float i;
WriteString(MSG_ENTITY, teamscores_label(i));
WriteByte(MSG_ENTITY, teamscores_flags(i));
}
+ bool welcome_msg_too = (!to.welcome_msg_already_sent_on_connection);
+ WriteByte(MSG_ENTITY, welcome_msg_too);
+ // welcome message is sent here because it needs to know the gametype
+ if (welcome_msg_too)
+ {
+ SendWelcomemessage_msg_type(this, false, MSG_ENTITY);
+ to.welcome_msg_already_sent_on_connection = true;
+ }
return true;
}
sk = CS(player).scorekeeper;
FOREACH(Scores, true, {
if(sk.(scores(it)) != 0)
- if(scores_label(it) != "")
- sk.SendFlags |= BIT(i % 16);
+ //if(scores_label(it) != "")
+ sk.SendFlags |= (2 ** (i % 16));
if(i != SP_ELO.m_id)
sk.(scores(it)) = 0;
});
if (!sk) continue;
FOREACH(Scores, true, {
if(sk.(scores(it)) != 0)
- if(scores_label(it) != "")
- sk.SendFlags |= BIT(i % 16);
+ //if(scores_label(it) != "")
+ sk.SendFlags |= (2 ** (i % 16));
if(i != SP_ELO.m_id)
sk.(scores(it)) = 0;
});
for(int j = 0; j < MAX_TEAMSCORE; ++j)
{
if(sk.(teamscores(j)) != 0)
- if(teamscores_label(j) != "")
- sk.SendFlags |= BIT(j);
+ //if(teamscores_label(j) != "")
+ sk.SendFlags |= (2 ** j);
sk.(teamscores(j)) = 0;
}
}
{
return s.(scores(scorefield));
}
- if(scores_label(scorefield) != "")
- s.SendFlags |= BIT(scorefield.m_id % 16);
+ //if(scores_label(scorefield) != "")
+ s.SendFlags |= (2 ** (scorefield.m_id % 16));
if(!warmup_stage)
PlayerStats_GameReport_Event_Player(s.owner, strcat(PLAYERSTATS_TOTAL, scores_label(scorefield)), score);
s.(scores(scorefield)) += score;
return result.x;
}
+bool Score_NewLeader()
+{
+ if(teamplay) {
+ if (WinningConditionHelper_winnerteam != WinningConditionHelper_winnerteam_last && (WinningConditionHelper_secondteam || WinningConditionHelper_equality))
+ {
+ WinningConditionHelper_winnerteam_last = WinningConditionHelper_winnerteam;
+ return true;
+ }
+ } else {
+ if (WinningConditionHelper_winner != WinningConditionHelper_winner_last && (WinningConditionHelper_second || WinningConditionHelper_equality))
+ {
+ WinningConditionHelper_winner_last = WinningConditionHelper_winner;
+ return true;
+ }
+ }
+ return false;
+}
+
void WinningConditionHelper(entity this)
{
float c;
WinningConditionHelper_equality = (PlayerScore_Compare(winnerscorekeeper, secondscorekeeper, false) == 0);
if(WinningConditionHelper_equality)
+ {
+ WinningConditionHelper_equality_one = WinningConditionHelper_winner;
+ WinningConditionHelper_equality_two = WinningConditionHelper_second;
WinningConditionHelper_winner = WinningConditionHelper_second = NULL;
+ }
+ else
+ {
+ WinningConditionHelper_equality_one = WinningConditionHelper_equality_two = NULL;
+ }
WinningConditionHelper_topscore = winnerscorekeeper.scores_primary;
WinningConditionHelper_secondscore = secondscorekeeper.scores_primary;
const float SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS = 1;
+void send_TotalShards(entity to) {
+ // for RJZ
+ // Send total number of picked up shards
+ if(!autocvar_rjz_count_shards) return;
+ if(!IS_REAL_CLIENT(to)) return;
+
+ msg_entity = to;
+ WriteHeader(MSG_ONE, TE_CSQC_TOTALSHARDS);
+ WriteInt24_t(MSG_ONE, total_shards);
+}
+
+void send_TotalShardsAll() {
+ // for RJZ
+ // Send total number of picked up shards
+ if(!autocvar_rjz_count_shards) return;
+
+ FOREACH_CLIENT(IS_REAL_CLIENT(it) && (IS_SPEC(it) || IS_OBSERVER(it)), {
+ send_TotalShards(it);
+ });
+}
+
void SetDefaultAlpha()
{
if (!MUTATOR_CALLHOOK(SetDefaultAlpha))
BADCVAR("g_keyhunt");
BADCVAR("g_keyhunt_teams");
BADCVAR("g_lms");
+ BADCVAR("g_mayhem");
BADCVAR("g_nexball");
BADCVAR("g_onslaught");
BADCVAR("g_race");
BADCVAR("g_tdm");
BADCVAR("g_tdm_on_dm_maps");
BADCVAR("g_tdm_teams");
+ BADCVAR("g_mmm");
+ BADCVAR("g_mmm_not_dm_maps");
+ BADCVAR("g_tmayhem");
+ BADCVAR("g_tmayhem_teams");
BADCVAR("g_vip");
BADCVAR("leadlimit");
BADCVAR("nextmap");
BADCVAR("g_mapinfo_ignore_warnings");
BADCVAR("g_maplist_ignore_sizes");
BADCVAR("g_maplist_sizes_count_bots");
+ //LegendGuard adds BADCVAR(g_*) for MMM 20-02-2021
// long
BADCVAR("hostname");
+ BADCVAR("hostname_full");
BADCVAR("g_maplist");
BADCVAR("g_maplist_mostrecent");
BADCVAR("sv_motd");
+ BADCVAR("sv_motd_permanent");
+
+ BADPREFIX("g_teamnames_");
v = cvar_string(k);
d = cvar_defstring(k);
BADCVAR("g_forced_respawn");
BADCVAR("g_freezetag_point_leadlimit");
BADCVAR("g_freezetag_point_limit");
+ BADCVAR("g_freezetag_revive_respawn");
+ BADCVAR("g_freezetag_round_stop");
+ BADCVAR("g_freezetag_round_respawn");
BADCVAR("g_glowtrails");
BADCVAR("g_hats");
BADCVAR("g_casings");
BADCVAR("g_spawn_alloweffects");
BADCVAR("g_tdm_point_leadlimit");
BADCVAR("g_tdm_point_limit");
+ BADCVAR("g_mayhem_fraglimit");
+ BADCVAR("g_tmayhem_fraglimit");
+ BADCVAR("g_mayhem_visual_score_limit");
+ BADCVAR("g_tmayhem_visual_score_limit");
+ BADCVAR("g_tmayhem_score_leadlimit");
BADCVAR("leadlimit_and_fraglimit");
BADCVAR("leadlimit_override");
+ BADCVAR("g_mayhem_scoringmethod");
+ BADCVAR("g_mayhem_scoringmethod_damage_weight");
+ BADCVAR("g_mayhem_scoringmethod_frag_weight");
+ BADCVAR("g_tmayhem_scoringmethod");
+ BADCVAR("g_tmayhem_scoringmethod_damage_weight");
+ BADCVAR("g_tmayhem_scoringmethod_frag_weight");
BADCVAR("pausable");
BADCVAR("sv_announcer");
BADCVAR("sv_checkforpacketsduringsleep");
BADPREFIX("sv_timeout_");
BADPREFIX("sv_vote_");
BADPREFIX("timelimit_");
+ BADPREFIX("sv_chat_");
+ BADPREFIX("sv_jingle_");
// allowed changes to server admins (please sync this to server.cfg)
// vi commands:
BADCVAR("g_keyhunt_point_limit");
BADCVAR("g_keyhunt_teams_override");
BADCVAR("g_lms_lives_override");
+ BADCVAR("g_mayhem_powerups");
BADCVAR("g_maplist");
BADCVAR("g_maxplayers");
BADCVAR("g_mirrordamage");
BADCVAR("g_start_delay");
BADCVAR("g_superspectate");
BADCVAR("g_tdm_teams_override");
+ BADCVAR("g_tmayhem_teams_override");
+ BADCVAR("g_tmayhem_powerups");
BADCVAR("g_warmup");
BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
BADCVAR("hostname");
BADCVAR("g_ca_weaponarena");
BADCVAR("g_freezetag_weaponarena");
BADCVAR("g_lms_weaponarena");
+ BADCVAR("g_mayhem_weaponarena");
+ BADCVAR("g_tmayhem_weaponarena");
BADCVAR("g_ctf_stalemate_time");
#undef BADPRESUFFIX
WinningConditionHelper(this); // set worldstatus
+ if(!warmup_stage)
+ round_handler_Activate(true);
+
+ // for RJZ
+ if (autocvar_rjz_count_shards && warmup_stage) {
+ total_shards = -2;
+ send_TotalShardsAll();
+ }
+
world_initialized = 1;
__spawnfunc_spawn_all();
}
*/
void NextLevel()
{
+ cvar_set("_endmatch", "0");
game_stopped = true;
intermission_running = true; // game over
*/
//pos = FindIntermission ();
+
+ sound(NULL, CH_INFO, SND_ENDMATCH, VOL_BASE, ATTN_NONE);
VoteReset();
WeaponStats_Shutdown();
Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_Null); // kill all centerprints now
+
+ // send winner notification
+ if(teamplay) {
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, APP_TEAM_NUM(WinningConditionHelper_winnerteam, ANNCE_TEAM_WINS));
+ }
if(autocvar_sv_eventlog)
GameLogEcho(":gameover");
});
target_music_kill();
+
+ // z411
+ if(autocvar_sv_jingle_end) {
+ int jingles_len = 0;
+ string jingles[32];
+ jingles[0] = "";
+
+ FOREACH_WORD(autocvar_sv_jingle_end_list, it,
+ {
+ jingles[jingles_len] = it;
+ jingles_len++;
+ });
+
+ if(jingles_len) {
+ int song_to_play = rint(random() * (jingles_len - 1));
+
+ FOREACH_CLIENT(IS_REAL_CLIENT(it),
+ {
+ stuffcmd(it, "cd stop\n");
+ _sound(it, CH_INFO, strcat("jingle/", jingles[song_to_play], ".ogg"), VOL_BASE * autocvar_sv_jingle_end_volume, ATTEN_NORM);
+ });
+ }
+ }
if(autocvar_g_campaign)
CampaignPreIntermission();
}
- float InitiateSuddenDeath()
+ int InitiateSuddenDeath()
{
// Check first whether normal overtimes could be added before initiating suddendeath mode
// - for this timelimit_overtime needs to be >0 of course
if(!checkrules_suddendeathend)
{
if(autocvar_g_campaign)
+ {
checkrules_suddendeathend = time; // no suddendeath in campaign
+ }
else
+ {
checkrules_suddendeathend = time + 60 * autocvar_timelimit_suddendeath;
+ overtimes = -1;
+ }
if(g_race && !g_race_qualifying)
race_StartCompleting();
}
void InitiateOvertime() // ONLY call this if InitiateSuddenDeath returned true
{
++checkrules_overtimesadded;
+ overtimes = checkrules_overtimesadded;
//add one more overtime by simply extending the timelimit
cvar_set("timelimit", ftos(autocvar_timelimit + autocvar_timelimit_overtime));
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime * 60);
+
+ sound(NULL, CH_INFO, SND_OVERTIME, VOL_BASE, ATTN_NONE);
+ if(checkrules_overtimesadded == 1) {
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_OVERTIME);
+ overtime_starttime = time;
+ }
}
float GetWinningCode(float fraglimitreached, float equality)
FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { it.winning = 0; });
}
-int fragsleft_last;
+void AnnounceNewLeader()
+{
+ if(teamplay) {
+ if (WinningConditionHelper_equality)
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_TEAM_LEADS_TIED);
+ else
+ FOREACH_CLIENT(IS_PLAYER(it), {
+ if(it.team == WinningConditionHelper_winnerteam)
+ Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_LEADS_TEAM);
+ else
+ Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_LEADS_ENEMY);
+ });
+ Send_Notification(NOTIF_ALL_SPEC, NULL, MSG_ANNCE, APP_TEAM_NUM(WinningConditionHelper_winnerteam, ANNCE_TEAM_LEADS));
+ } else {
+ if (WinningConditionHelper_equality)
+ {
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_equality_one, MSG_ANNCE, ANNCE_LEAD_TIED);
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_equality_two, MSG_ANNCE, ANNCE_LEAD_TIED);
+ }
+ else
+ {
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_winner, MSG_ANNCE, ANNCE_LEAD_GAINED);
+ Send_Notification(NOTIF_ONE, WinningConditionHelper_second, MSG_ANNCE, ANNCE_LEAD_LOST);
+ }
+ }
+}
+
+void AnnounceScores(float tm)
+{
+ WinningConditionHelper(NULL);
+ if (Score_NewLeader()) {
+ AnnounceNewLeader();
+ } else {
+ FOREACH_CLIENT(IS_PLAYER(it), {
+ if(it.team == tm)
+ Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_SCORES_TEAM);
+ else
+ Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_SCORES_ENEMY);
+ });
+ Send_Notification(NOTIF_ALL_SPEC, NULL, MSG_ANNCE, APP_TEAM_NUM(tm, ANNCE_TEAM_SCORES));
+ }
+}
+
float WinningCondition_Scores(float limit, float leadlimit)
{
// TODO make everything use THIS winning condition (except LMS)
if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining))
{
- float fragsleft;
if (checkrules_suddendeathend && time >= checkrules_suddendeathend)
{
fragsleft = 1;
fragsleft_last = fragsleft;
}
}
-
+
+ // z411 - lead announcer
+ if(MUTATOR_CALLHOOK(Scores_AnnounceLeads)) {
+ if (Score_NewLeader())
+ AnnounceNewLeader();
+ }
+
bool fraglimit_reached = (limit && WinningConditionHelper_topscore >= limit);
bool leadlimit_reached = (leadlimit && WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit);
// again, but this shouldn't hurt
return;
}
+
+ // z411 don't check rules if we're in a timeout
+ if (game_timeout) return;
float timelimit = autocvar_timelimit * 60;
float fraglimit = autocvar_fraglimit;
leadlimit = 0; // no leadlimit for now
}
- if(timelimit > 0)
- {
- timelimit += game_starttime;
- }
- else if (timelimit < 0)
+ if (autocvar__endmatch || timelimit < 0)
{
// endmatch
NextLevel();
return;
}
- float wantovertime;
- wantovertime = 0;
+ if(timelimit > 0)
+ timelimit += game_starttime;
+
+ int overtimes_prev = overtimes;
+ int wantovertime = 0;
if(checkrules_suddendeathend)
{
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_RACE_FINISHLAP);
else
Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_OVERTIME_FRAG);
+ checkrules_overtimesadded = 1;
+ sound(NULL, CH_INFO, SND_OVERTIME, VOL_BASE, ATTN_NONE);
+ Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_OVERTIME);
}
}
else
if(checkrules_status == WINNING_YES)
{
+ if (overtimes == -1 && overtimes != overtimes_prev)
+ {
+ // if suddendeathend overtime has just begun, revert it
+ checkrules_suddendeathend = 0;
+ overtimes = overtimes_prev;
+ }
//print("WINNING\n");
NextLevel();
}
{
if(cvar("sv_allow_fullbright"))
serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
+ if(cvar("sv_forbid_pickuptimer"))
+ serverflags |= SERVERFLAG_FORBID_PICKUPTIMER;
sv_ready_restart_after_countdown = cvar("sv_ready_restart_after_countdown");
bool autocvar_sv_freezenonclients;
void Physics_Frame()
{
- if(autocvar_sv_freezenonclients)
+ if(autocvar_sv_freezenonclients || game_timeout)
return;
IL_EACH(g_moveables, true,
#include <common/weapons/_all.qh>
bool autocvar__sv_init;
+ bool autocvar__endmatch;
bool autocvar_g_use_ammunition;
bool autocvar_g_jetpack;
bool autocvar_g_warmup_allguns;
int autocvar_timelimit_overtimes;
float autocvar_timelimit_suddendeath;
+// z411
+bool autocvar_sv_jingle_end;
+string autocvar_sv_jingle_end_list;
+float autocvar_sv_jingle_end_volume;
+
+float fragsleft;
+int fragsleft_last;
+
float checkrules_equality;
float checkrules_suddendeathwarning;
float checkrules_suddendeathend;
- //float checkrules_overtimesadded; //how many overtimes have been already added
+ int checkrules_overtimesadded; //how many overtimes have been already added
// flag set on worldspawn so that the code knows if it is dedicated or not
bool server_is_dedicated;
.vector dropped_origin;
void droptofloor(entity this);
+/* z411 for RJZ */
+bool autocvar_rjz_count_shards = false;
+bool autocvar_rjz_ranks = false;
+int total_shards = 0;
+void send_TotalShards(entity to);
+void send_TotalShardsAll();
+
IntrusiveList g_moveables;
STATIC_INIT(g_moveables) { g_moveables = IL_NEW(); }