seta hud_panel_notify_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
seta hud_panel_notify_flip "" "order the list top to bottom instead of bottom to top"
seta hud_panel_notify_fontsize "" "multiplier for the font size used for player names in the panel"
- seta hud_panel_notify_print "" "also con_notify print the messages that are shown on the notify panel"
seta hud_panel_notify_fadetime "" "fade out time"
seta hud_panel_notify_time "" "time that a new entry stays until it fades out"
seta hud_panel_radar_scale "" "distance you can see on the team radar"
seta hud_panel_radar_maximized_scale "" "distance you can see on the radar when maximized"
seta hud_panel_radar_maximized_size "" "size of the radar when maximized"
+ seta hud_panel_radar_maximized_rotation "" "rotation mode: you set what points up. 0 = player, 1 = west, 2 = south, 3 = east, 4 = north"
+ seta hud_panel_radar_maximized_zoommode "" "zoom mode: 0 = zoomed by default, 1 = zoomed when +zoom, 2 = always zoomed, 3 = always zoomed out"
seta hud_panel_score "" "enable/disable this panel"
seta hud_panel_score_pos "" "position of this base of the panel"
seta hud_panel_modicons_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
seta hud_panel_modicons_bg_border "" "if set to something else than \"\" = override default size of border around the background"
seta hud_panel_modicons_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
+seta hud_panel_modicons_ca_layout "" "2 possible layouts: 0) number of alive players; 1) icons and number of alive players"
seta hud_panel_modicons_dom_layout "" "3 possible layouts: 0) only icons; 1) icons and percentage of average pps (points per second); 2) icons and average pps"
+seta hud_panel_modicons_freezetag_layout "" "2 possible layouts: 0) number of alive players; 1) icons and number of alive players"
seta hud_panel_pressedkeys "" "enable/disable this panel, 1 = show only when spectating other players, 2 = show always"
seta hud_panel_pressedkeys_pos "" "position of this base of the panel"
set g_arena 0 "Arena: many one-on-one rounds are played to find the winner"
set g_arena_maxspawned 2 "maximum number of players to spawn at once (the rest is spectating, waiting for their turn)"
set g_arena_roundbased 1 "if disabled, the next player will spawn as soon as someone dies"
+set g_arena_round_timelimit 180
set g_arena_warmup 5 "time, newly spawned players have to prepare themselves in round based matches"
set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
set g_ca_damage2score_multiplier 0.01
set g_ca_round_timelimit 180
+seta g_ca_teams_override 0
+set g_ca_teams 0
+
// ==================
set g_ctf_flag_health 0
set g_ctf_flag_dropped_waypoint 2 "show dropped flag waypointsprite when a flag is lost. 1 = team only, 2 = for all players"
set g_ctf_flag_dropped_floatinwater 200 "move upwards while in water at this velocity"
- set g_ctf_flag_pickup_verbosename 0 "show the name of the person who picked up the flag too"
set g_ctf_throw 1 "throwing allows circumventing carrierkill score, so enable this with care!"
set g_ctf_throw_angle_max 90 "maximum upwards angle you can throw the flag"
set g_ctf_throw_angle_min -90 "minimum downwards angle you can throw the flag"
// freezetag
// ===========
set g_freezetag 0 "Freeze Tag: Freeze the opposing team(s) to win, unfreeze teammates by standing next to them"
-seta g_freezetag_warmup 5 "Time players get to run around before the round starts"
+set g_freezetag_warmup 5 "Time players get to run around before the round starts"
seta g_freezetag_point_limit -1 "Freeze Tag point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
seta g_freezetag_point_leadlimit -1 "Freeze Tag point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
-seta g_freezetag_revive_speed 0.4 "Speed for reviving a frozen teammate"
-seta g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets lost when out of range"
-seta g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
-seta g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen player with"
+set g_freezetag_revive_speed 0.4 "Speed for reviving a frozen teammate"
+set g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets lost when out of range"
+set g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
+set g_freezetag_round_timelimit 180
+set g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen player with"
+set g_freezetag_frozen_maxtime 60 "frozen players will be automatically unfrozen after this time in seconds"
+seta g_freezetag_teams_override 0
+set g_freezetag_teams 0
// ==========
set g_lms_lives_override -1
set g_lms_regenerate 0
set g_lms_campcheck_interval 10
- set g_lms_campcheck_message "^1Don't camp!"
set g_lms_campcheck_damage 100
set g_lms_campcheck_distance 1800
set g_lms_last_join 3 "if g_lms_join_anytime is false, new players can only join if the worst active player has more than (fraglimit - g_lms_last_join) lives"
set g_onslaught_cp_buildhealth 100
set g_onslaught_cp_buildtime 5
set g_onslaught_cp_regen 20
+ set g_onslaught_cp_proxydecap 0 "de-capture controlpoints by standing close to them"
+ set g_onslaught_cp_proxydecap_distance 512
+ set g_onslaught_cp_proxydecap_dps 100
+ set g_onslaught_spawn_at_controlpoints 0
+ set g_onslaught_spawn_at_generator 0
// ======
seta hud_panel_weapons_accuracy "1"
seta hud_panel_weapons_label "1"
seta hud_panel_weapons_complainbubble "1"
- seta hud_panel_weapons_complainbubble_padding "2"
- seta hud_panel_weapons_complainbubble_time "4"
- seta hud_panel_weapons_complainbubble_fadetime "2"
+ seta hud_panel_weapons_complainbubble_padding "-1"
+ seta hud_panel_weapons_complainbubble_time "0"
+ seta hud_panel_weapons_complainbubble_fadetime "1"
seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
seta hud_panel_notify_bg_padding ""
seta hud_panel_notify_flip "0"
seta hud_panel_notify_fontsize "0.8"
- seta hud_panel_notify_print "1"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
seta hud_panel_radar_scale "4096"
seta hud_panel_radar_maximized_scale "8192"
seta hud_panel_radar_maximized_size "0.5 0.5"
+ seta hud_panel_radar_maximized_rotation "1"
+ seta hud_panel_radar_maximized_zoommode "3"
seta hud_panel_score 1
seta hud_panel_score_pos "0.890000 0.030000"
seta hud_panel_modicons_bg_alpha ""
seta hud_panel_modicons_bg_border ""
seta hud_panel_modicons_bg_padding "0"
+seta hud_panel_modicons_ca_layout "1"
seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
seta hud_panel_pressedkeys 1
seta hud_panel_pressedkeys_pos "0.450000 0.720000"
seta hud_panel_weapons_accuracy "1"
seta hud_panel_weapons_label "1"
seta hud_panel_weapons_complainbubble "1"
- seta hud_panel_weapons_complainbubble_padding "-10"
- seta hud_panel_weapons_complainbubble_time "1"
- seta hud_panel_weapons_complainbubble_fadetime "0.25"
+ seta hud_panel_weapons_complainbubble_padding "-1"
+ seta hud_panel_weapons_complainbubble_time "0"
+ seta hud_panel_weapons_complainbubble_fadetime "1"
seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
seta hud_panel_notify_bg_padding ""
seta hud_panel_notify_flip "1"
seta hud_panel_notify_fontsize "0.8"
- seta hud_panel_notify_print "0"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
seta hud_panel_radar_scale "4096"
seta hud_panel_radar_maximized_scale "8192"
seta hud_panel_radar_maximized_size "0.5 0.5"
+ seta hud_panel_radar_maximized_rotation "1"
+ seta hud_panel_radar_maximized_zoommode "3"
seta hud_panel_score 1
seta hud_panel_score_pos "0.465000 0.045000"
seta hud_panel_modicons_bg_alpha ""
seta hud_panel_modicons_bg_border ""
seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
seta hud_panel_pressedkeys 1
seta hud_panel_pressedkeys_pos "0.450000 0.650000"
seta hud_panel_weapons_accuracy "1"
seta hud_panel_weapons_label "1"
seta hud_panel_weapons_complainbubble "1"
- seta hud_panel_weapons_complainbubble_padding "-10"
- seta hud_panel_weapons_complainbubble_time "1"
- seta hud_panel_weapons_complainbubble_fadetime "0.25"
+ seta hud_panel_weapons_complainbubble_padding "-1"
+ seta hud_panel_weapons_complainbubble_time "0"
+ seta hud_panel_weapons_complainbubble_fadetime "1"
seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
seta hud_panel_notify_bg_padding ""
seta hud_panel_notify_flip "1"
seta hud_panel_notify_fontsize "0.8"
- seta hud_panel_notify_print "0"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
seta hud_panel_radar_scale "4096"
seta hud_panel_radar_maximized_scale "8192"
seta hud_panel_radar_maximized_size "0.5 0.5"
+ seta hud_panel_radar_maximized_rotation "1"
+ seta hud_panel_radar_maximized_zoommode "3"
seta hud_panel_score 1
seta hud_panel_score_pos "0.465000 0.045000"
seta hud_panel_modicons_bg_alpha ""
seta hud_panel_modicons_bg_border ""
seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
seta hud_panel_pressedkeys 1
seta hud_panel_pressedkeys_pos "0.450000 0.690000"
seta hud_panel_weapons_accuracy "1"
seta hud_panel_weapons_label "1"
seta hud_panel_weapons_complainbubble "1"
- seta hud_panel_weapons_complainbubble_padding "-10"
- seta hud_panel_weapons_complainbubble_time "1"
- seta hud_panel_weapons_complainbubble_fadetime "0.25"
+ seta hud_panel_weapons_complainbubble_padding "-1"
+ seta hud_panel_weapons_complainbubble_time "0"
+ seta hud_panel_weapons_complainbubble_fadetime "1"
seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
seta hud_panel_notify_bg_padding ""
seta hud_panel_notify_flip "0"
seta hud_panel_notify_fontsize "0.8"
- seta hud_panel_notify_print "1"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
seta hud_panel_radar_scale "4096"
seta hud_panel_radar_maximized_scale "8192"
seta hud_panel_radar_maximized_size "0.5 0.5"
+ seta hud_panel_radar_maximized_rotation "1"
+ seta hud_panel_radar_maximized_zoommode "3"
seta hud_panel_score 1
seta hud_panel_score_pos "0.020000 0.920000"
seta hud_panel_modicons_bg_alpha ""
seta hud_panel_modicons_bg_border ""
seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
seta hud_panel_pressedkeys 1
seta hud_panel_pressedkeys_pos "0.410000 0.710000"
seta hud_panel_weapons_accuracy "1"
seta hud_panel_weapons_label "1"
seta hud_panel_weapons_complainbubble "1"
- seta hud_panel_weapons_complainbubble_padding "-10"
- seta hud_panel_weapons_complainbubble_time "1"
- seta hud_panel_weapons_complainbubble_fadetime "0.25"
+ seta hud_panel_weapons_complainbubble_padding "-1"
+ seta hud_panel_weapons_complainbubble_time "0"
+ seta hud_panel_weapons_complainbubble_fadetime "1"
seta hud_panel_weapons_complainbubble_color_outofammo "0.8 0 0"
seta hud_panel_weapons_complainbubble_color_donthave "0.8 0.5 0"
seta hud_panel_weapons_complainbubble_color_unavailable "0 0.3 0.8"
seta hud_panel_notify_bg_padding ""
seta hud_panel_notify_flip "0"
seta hud_panel_notify_fontsize "1"
- seta hud_panel_notify_print "1"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
seta hud_panel_radar_scale "4096"
seta hud_panel_radar_maximized_scale "8192"
seta hud_panel_radar_maximized_size "0.5 0.5"
+ seta hud_panel_radar_maximized_rotation "1"
+ seta hud_panel_radar_maximized_zoommode "3"
seta hud_panel_score 1
seta hud_panel_score_pos "0.760000 0.910000"
seta hud_panel_modicons_bg_alpha ""
seta hud_panel_modicons_bg_border ""
seta hud_panel_modicons_bg_padding ""
+seta hud_panel_modicons_ca_layout "1"
seta hud_panel_modicons_dom_layout "1"
+seta hud_panel_modicons_freezetag_layout "1"
seta hud_panel_pressedkeys 1
seta hud_panel_pressedkeys_pos "0.440000 0.760000"
if(teamplay)
if(t == myteam)
return SHOTTYPE_HITTEAM;
- if(t == COLOR_SPECTATOR)
+ if(t == NUM_SPECTATOR)
return SHOTTYPE_HITWORLD;
return SHOTTYPE_HITENEMY;
}
}
}
}
-
- if(autocvar_hud_damage)
+
+ if(autocvar_hud_damage && !getstati(STAT_FROZEN))
{
splash_size_x = max(vid_conwidth, vid_conheight);
splash_size_y = max(vid_conwidth, vid_conheight);
void Announcer_Countdown()
{
float starttime = getstatf(STAT_GAMESTARTTIME);
+ float roundstarttime = getstatf(STAT_ROUNDSTARTTIME);
+ if(roundstarttime == -1)
+ {
+ // stop countdown immediately
+ centerprint_generic(CPID_GAME_STARTING, "", 1, 0);
+ remove(self);
+ return;
+ }
+ if(roundstarttime >= starttime)
+ starttime = roundstarttime;
+ if(starttime <= time && roundstarttime != starttime) // game start time has passed
+ announcer_5min = announcer_1min = FALSE; // reset maptime announcers now as well
+
float countdown = (starttime - time);
float countdown_rounded = floor(0.5 + countdown);
-
+
if(countdown <= 0) // countdown has finished, starttime is now
{
- centerprint_generic(CPID_GAME_STARTING, _("^1Begin!"), 1, 0);
- if (!spectatee_status)
- Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN);
++ Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN);
Announcer_Play("begin");
- announcer_5min = announcer_1min = FALSE; // reset maptime announcers now as well
remove(self);
return;
}
else // countdown is still going
{
- if (!spectatee_status)
+ if(roundstarttime == starttime)
+ centerprint_generic(CPID_GAME_STARTING, _("^1Round starts in %d seconds"), 1, countdown_rounded);
+ else
- centerprint_generic(CPID_GAME_STARTING, _("^1Game starts in %d seconds"), 1, countdown_rounded);
+ Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_GAMESTART, countdown_rounded);
if(countdown_rounded <= 3 && countdown_rounded >= 1)
Announcer_Play(ftos(countdown_rounded));
void Announcer_Gamestart()
{
float startTime = getstatf(STAT_GAMESTARTTIME);
-
+ float roundstarttime = getstatf(STAT_ROUNDSTARTTIME);
+ if(roundstarttime > startTime)
+ startTime = roundstarttime;
+
if(previous_game_starttime != startTime)
{
if((time + 5.0) < startTime) // if connecting to server while restart was active don't always play prepareforbattle
Announcer_Play("prepareforbattle");
-
+
if(time < startTime)
{
entity e;
float autocvar_hud_panel_infomessages;
float autocvar_hud_panel_infomessages_flip;
float autocvar_hud_panel_modicons;
+float autocvar_hud_panel_modicons_ca_layout;
float autocvar_hud_panel_modicons_dom_layout;
+float autocvar_hud_panel_modicons_freezetag_layout;
float autocvar_hud_panel_notify;
float autocvar_hud_panel_notify_fadetime;
float autocvar_hud_panel_notify_flip;
float autocvar_hud_panel_notify_fontsize;
- float autocvar_hud_panel_notify_print;
float autocvar_hud_panel_notify_time;
float autocvar_hud_panel_physics;
float autocvar_hud_panel_physics_acceleration_progressbar_mode;
float autocvar_hud_panel_radar_rotation;
float autocvar_hud_panel_radar_scale;
float autocvar_hud_panel_radar_zoommode;
+ float autocvar_hud_panel_radar_maximized_rotation;
+ float autocvar_hud_panel_radar_maximized_zoommode;
float autocvar_hud_panel_score;
float autocvar_hud_panel_score_rankings;
float autocvar_hud_panel_timer;
drawstring(position, text, scale, rgb, theAlpha, flag);
}
- // return the string of the given race place
- string race_PlaceName(float pos) {
- if(pos == 1)
- return _("1st");
- else if(pos == 2)
- return _("2nd");
- else if(pos == 3)
- return _("3rd");
- else
- return sprintf(_("%dth"), pos);
- }
-
// return the string of the onscreen race timer
string MakeRaceString(float cp, float mytime, float histime, float lapdelta, string hisname)
{
return 0;
}
+ float GetPlayerColorForce(float i)
+ {
+ if(!teamplay)
+ return 0;
+ else
+ return stof(getplayerkeyvalue(i, "colors")) & 15;
+ }
+
+ float GetPlayerColor(float i)
+ {
+ if not(playerslots[i].gotscores) // unconnected
+ return NUM_SPECTATOR;
+ else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
+ return NUM_SPECTATOR;
+ else
+ return GetPlayerColorForce(i);
+ }
+
+ string GetPlayerName(float i)
+ {
+ return ColorTranslateRGB(getplayerkeyvalue(i, "name"));
+ }
+
+
/*
==================
HUD panels
float i, f, a;
float screen_ar, center_x = 0, center_y;
float weapon_count, weapon_id;
- float row, column, rows, columns;
+ float row, column, rows = 0, columns;
float aspect = autocvar_hud_panel_weapons_aspect;
float panel_weapon_accuracy;
vector ammo_color = '1 0 1';
float ammo_alpha = 1;
- float when = autocvar_hud_panel_weapons_complainbubble_time;
- float fadetime = autocvar_hud_panel_weapons_complainbubble_fadetime;
+ float when = max(1, autocvar_hud_panel_weapons_complainbubble_time);
+ float fadetime = max(0, autocvar_hud_panel_weapons_complainbubble_fadetime);
- vector weapon_pos, weapon_size;
+ vector weapon_pos, weapon_size = '0 0 0';
local noref vector old_panel_size; // fteqcc sucks
vector color;
weaponorder_cmp_str = string_null;
}
+ if(autocvar_hud_panel_weapons_complainbubble)
+ if(autocvar__hud_configure || time - complain_weapon_time >= when + fadetime)
+ complain_weapon = 0;
+
// determine which weapons are going to be shown
if (autocvar_hud_panel_weapons_onlyowned)
{
++weapon_count;
// add it anyway if weaponcomplain is shown
- if((!autocvar__hud_configure)
- && (autocvar_hud_panel_weapons_complainbubble
- && time - complain_weapon_time < when + fadetime))
- ++weapon_count;
+ if(complain_weapon)
+ ++weapon_count;
// might as well commit suicide now, no reason to live ;)
- if (weapon_count == 0) { return; }
-
- // reduce size of the panel
- if (panel_size_y > panel_size_x)
+ if (weapon_count == 0)
{
- old_panel_size_y = panel_size_y;
- panel_size_y *= weapon_count / WEP_COUNT;
- panel_pos_y += (old_panel_size_y - panel_size_y) / 2;
+ draw_endBoldFont();
+ return;
}
- else
+
+ old_panel_size = panel_size;
+ if(panel_bg_padding)
+ old_panel_size -= '2 2 0' * panel_bg_padding;
+
+ // first find values for the standard table (with all the weapons)
+ rows = old_panel_size_y/old_panel_size_x;
+ rows = bound(1, floor((sqrt(4 * aspect * rows * WEP_COUNT + rows * rows) + rows + 0.5) / 2), WEP_COUNT);
+ columns = ceil(WEP_COUNT/rows);
+ weapon_size_x = old_panel_size_x / columns;
+ weapon_size_y = old_panel_size_y / rows;
+
+ // change table values to include only the owned weapons
+ // weapon_size won't be changed
+ if(weapon_count <= rows)
{
- old_panel_size_x = panel_size_x;
- panel_size_x *= weapon_count / WEP_COUNT;
- panel_pos_x += (old_panel_size_x - panel_size_x) / 2;
+ rows = weapon_count;
+ columns = 1;
}
+ else
+ columns = ceil(weapon_count / rows);
+
+ // reduce size of the panel
+ panel_size_x = columns * weapon_size_x;
+ panel_size_y = rows * weapon_size_y;
+ panel_pos_x += (old_panel_size_x - panel_size_x) / 2;
+ panel_pos_y += (old_panel_size_y - panel_size_y) / 2;
+ if(panel_bg_padding)
+ panel_size += '2 2 0' * panel_bg_padding;
}
else
weapon_count = WEP_COUNT;
HUD_Panel_DrawBg(1);
if(center_x == -1)
+ {
+ draw_endBoldFont();
return;
+ }
if(panel_bg_padding)
{
}
// after the sizing and animations are done, update the other values
- rows = panel_size_y/panel_size_x;
- rows = bound(1, floor((sqrt(4 * aspect * rows * weapon_count + rows * rows) + rows + 0.5) / 2), weapon_count);
- columns = ceil(weapon_count/rows);
- weapon_size = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
+
+ if(!rows) // if rows is > 0 onlyowned code has already updated these vars
+ {
+ rows = panel_size_y/panel_size_x;
+ rows = bound(1, floor((sqrt(4 * aspect * rows * weapon_count + rows * rows) + rows + 0.5) / 2), weapon_count);
+ columns = ceil(weapon_count/rows);
+ weapon_size = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
+ }
// calculate position/size for visual bar displaying ammount of ammo status
if (autocvar_hud_panel_weapons_ammo)
if (!self || self.impulse < 0) { continue; }
// skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon
- if (autocvar_hud_panel_weapons_onlyowned
- && !(WEPSET_CONTAINS_AW(weapons_stat, self.weapon)
- || (self.weapon == complain_weapon
- && time - complain_weapon_time < when + fadetime
- && autocvar_hud_panel_weapons_complainbubble)))
- continue;
+ if(autocvar_hud_panel_weapons_onlyowned)
+ if not(WEPSET_CONTAINS_AW(weapons_stat, self.weapon) || (self.weapon == complain_weapon))
+ continue;
// figure out the drawing position of weapon
weapon_pos = (panel_pos
}
// draw the complain message
- if(time - complain_weapon_time < when + fadetime && self.weapon == complain_weapon && autocvar_hud_panel_weapons_complainbubble)
+ if(self.weapon == complain_weapon)
{
if(fadetime)
a = ((complain_weapon_time + when > time) ? 1 : bound(0, (complain_weapon_time + when + fadetime - time) / fadetime, 1));
else
a = ((complain_weapon_time + when > time) ? 1 : 0);
-
string s;
if(complain_weapon_type == 0) {
s = _("Out of ammo");
// Notification area (#4)
//
- string Weapon_SuicideMessage(float deathtype)
+ void HUD_Notify_Push(string icon, string attacker, string victim)
{
- w_deathtype = deathtype;
- get_weaponinfo(DEATH_WEAPONOF(deathtype)).weapon_func(WR_SUICIDEMESSAGE);
- return w_deathtypestring;
- }
-
- string Weapon_KillMessage(float deathtype)
- {
- w_deathtype = deathtype;
- get_weaponinfo(DEATH_WEAPONOF(deathtype)).weapon_func(WR_KILLMESSAGE);
- return w_deathtypestring;
- }
+ if(icon != "")
+ {
+ --kn_index;
+ if (kn_index == -1) { kn_index = KN_MAX_ENTRIES-1; }
+ notify_times[kn_index] = time;
- #define KN_MAX_ENTRIES 10
- float kn_index;
- float killnotify_times[KN_MAX_ENTRIES];
- float killnotify_deathtype[KN_MAX_ENTRIES];
- float killnotify_actiontype[KN_MAX_ENTRIES]; // 0 = "Y [used by] X", 1 = "X [did action to] Y"
- string killnotify_attackers[KN_MAX_ENTRIES];
- string killnotify_victims[KN_MAX_ENTRIES];
- void HUD_KillNotify_Push(string attacker, string victim, float actiontype, float wpn)
- {
- --kn_index;
- if (kn_index == -1)
- kn_index = KN_MAX_ENTRIES-1;
- killnotify_times[kn_index] = time;
- killnotify_deathtype[kn_index] = wpn;
- killnotify_actiontype[kn_index] = actiontype;
- if(killnotify_attackers[kn_index])
- strunzone(killnotify_attackers[kn_index]);
- killnotify_attackers[kn_index] = strzone(attacker);
- if(killnotify_victims[kn_index])
- strunzone(killnotify_victims[kn_index]);
- killnotify_victims[kn_index] = strzone(victim);
- }
+ // icon
+ if(notify_icon[kn_index]) { strunzone(notify_icon[kn_index]); }
+ notify_icon[kn_index] = strzone(icon);
- void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s1 = attacker, s2 = victim
- {
- float w;
- float alsoprint, gentle;
- alsoprint = (autocvar_hud_panel_notify_print || !panel_enabled); // print message to console if: notify panel disabled, or cvar to do so enabled
- gentle = (autocvar_cl_gentle || autocvar_cl_gentle_messages);
-
- if ((msg == MSG_SUICIDE || msg == MSG_KILL || msg == MSG_KILL_ACTION) && gametype == MAPINFO_TYPE_CTS) // selfkill isn't interesting in CTS and only spams up the notify panel
- return;
+ // attacker
+ if(notify_attackers[kn_index]) { strunzone(notify_attackers[kn_index]); }
+ notify_attackers[kn_index] = strzone(attacker);
- if(msg == MSG_SUICIDE) {
- w = DEATH_WEAPONOF(type);
- if(WEP_VALID(w)) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if (alsoprint)
- print("^1", sprintf(Weapon_SuicideMessage(type), strcat(s1, "^1")), "\n");
- } else if (type == DEATH_KILL) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_KILL);
- if (alsoprint)
- print (sprintf(_("^1%s^1 couldn't take it anymore\n"), s1));
- } else if (type == DEATH_ROT) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if (alsoprint)
- print (sprintf(_("^1%s^1 died\n"), s1));
- } else if (type == DEATH_NOAMMO) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_NOAMMO);
- if (alsoprint)
- print (sprintf(_("^7%s^7 committed suicide. What's the point of living without ammo?\n"), s1));
- } else if (type == DEATH_CAMP) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_CAMP);
- if (alsoprint)
- print (sprintf(_("^1%s^1 thought they found a nice camping ground\n"), s1));
- } else if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
- HUD_KillNotify_Push(s1, "", 0, type);
- if (alsoprint)
- print (sprintf(_("^1%s^1 didn't become friends with the Lord of Teamplay\n"), s1));
- } else if (type == DEATH_CHEAT) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if (alsoprint)
- print (sprintf(_("^1%s^1 unfairly eliminated themself\n"), s1));
- } else if (type == DEATH_FIRE) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if (alsoprint)
- print (sprintf(_("^1%s^1 burned to death\n"), s1));
- } else if (type != DEATH_TEAMCHANGE && type != DEATH_QUIET) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if (alsoprint)
- print (sprintf(_("^1%s^1 couldn't resist the urge to self-destruct\n"), s1));
- }
-
- if (stof(s2) > 2) // killcount > 2
- print (sprintf(_("^1%s^1 ended it all after a %d kill spree\n"), s1, stof(s2)));
- } else if(msg == MSG_KILL) {
- w = DEATH_WEAPONOF(type);
- if(WEP_VALID(w)) {
- HUD_KillNotify_Push(s1, s2, 1, type);
- if (alsoprint)
- print("^1", sprintf(Weapon_KillMessage(type), strcat(s2, "^1"), strcat(s1, "^1")), "\n"); // default order: victim, killer
- }
- else if(type == KILL_TEAM_RED || type == KILL_TEAM_BLUE || type == KILL_TEAM_SPREE) {
- HUD_KillNotify_Push(s1, s2, 1, type);
- if(alsoprint)
- {
- if(gentle) {
- print (sprintf(_("^1%s^1 took action against a team mate\n"), s1));
- } else {
- print (sprintf(_("^1%s^1 mows down a team mate\n"), s1));
- }
- }
- if (stof(s2) > 2 && type == KILL_TEAM_SPREE) {
- if(gentle)
- print (sprintf(_("^1%s^1 ended a %d scoring spree by going against a team mate\n"), s1, stof(s3)));
- else
- print (sprintf(_("^1%s^1 ended a %d kill spree by killing a team mate\n"), s1, stof(s3)));
- }
- else if (stof(s2) > 2) {
- if(gentle)
- print (sprintf(_("^1%s^1's %s scoring spree was ended by a team mate!\n"), s1, stof(s3)));
- else
- print (sprintf(_("^1%s^1's %s kill spree was ended by a team mate!\n"), s1, stof(s3)));
- }
- }
- else if(type == KILL_FIRST_BLOOD)
- print(sprintf(_("^1%s^1 drew first blood\n"), s1));
- else if (type == DEATH_TELEFRAG) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_TELEFRAG);
- if(gentle)
- print (sprintf(_("^1%s^1 tried to occupy %s^1's teleport destination space\n"), s2, s1));
- else
- print (sprintf(_("^1%s^1 was telefragged by %s\n"), s2, s1));
- }
- else if (type == DEATH_DROWN) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_DROWN);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was drowned by %s\n"), s2, s1));
- }
- else if (type == DEATH_SLIME) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_SLIME);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was slimed by %s\n"), s2, s1));
- }
- else if (type == DEATH_LAVA) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_LAVA);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was cooked by %s\n"), s2, s1));
- }
- else if (type == DEATH_FALL) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_FALL);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was grounded by %s\n"), s2, s1));
- }
- else if (type == DEATH_SHOOTING_STAR) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_SHOOTING_STAR);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was shot into space by %s\n"), s2, s1));
- }
- else if (type == DEATH_SWAMP) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was conserved by %s\n"), s2, s1));
- }
- else if (type == DEATH_HURTTRIGGER)
- {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER);
- if(alsoprint)
- print(sprintf(_("^1%s^1 was thrown into a world of hurt by %s\n"), s2, s1));
- } else if(type == DEATH_VHCRUSH) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was crushed by %s\n"), s2, s1));
- } else if(type == DEATH_SBMINIGUN) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 got shredded by %s\n"), s2, s1));
- } else if(type == DEATH_SBROCKET) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was blasted to bits by %s\n"), s2, s1));
- } else if(type == DEATH_SBBLOWUP) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 got caught in the blast when %s^1's destroys a vehicle\n"), s2, s1));
- } else if(type == DEATH_WAKIGUN) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was bolted down by %s\n"), s2, s1));
- } else if(type == DEATH_BUMB_GUN) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 saw %s's preddy lights.\n"), s2, s1));
- } else if(type == DEATH_WAKIROCKET) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 could find no shelter from %s^1's rockets\n"), s2, s1));
- } else if(type == DEATH_WAKIBLOWUP) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 got caught in the blast when %s^1's destroys a vehicle\n"), s2, s1));
- } else if(type == DEATH_RAPTOR_CANNON) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 nailed to hell by %s\n"), s2, s1));
- } else if(type == DEATH_RAPTOR_BOMB) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 cluster crushed by %s\n"), s2, s1));
- } else if(type == DEATH_RAPTOR_DEATH) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 got caught in the blast when %s^1's destroys a vehicle\n"), s2, s1));
- } else if(type == DEATH_TURRET) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was pushed into the line of fire by %s\n"), s2, s1));
- } else if(type == DEATH_TOUCHEXPLODE) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was pushed into an accident by %s\n"), s2, s1));
- } else if(type == DEATH_CHEAT) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was unfairly eliminated by %s\n"), s2, s1));
- } else if (type == DEATH_FIRE) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was burnt to death by %s\n"), s2, s1));
- } else if (type == DEATH_CUSTOM) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_CUSTOM);
- if(alsoprint)
- print("^1", sprintf(s3, strcat(s2, "^1"), strcat(s1, "^1")), "\n");
- } else if (type == DEATH_HURTTRIGGER) {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_HURTTRIGGER);
- if(alsoprint)
- print("^1", sprintf(s3, strcat(s2, "^1"), strcat(s1, "^1")), "\n");
- } else {
- HUD_KillNotify_Push(s1, s2, 1, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was fragged by %s\n"), s2, s1));
- }
- } else if(msg == MSG_SPREE) {
- if(type == KILL_END_SPREE) {
- if(gentle)
- print (sprintf(_("^1%s^1's %s scoring spree was ended by %s\n"), s1, s2, s3));
- else
- print (sprintf(_("^1%s^1's %s kill spree was ended by %s\n"), s1, s2, s3));
- } else if(type == KILL_SPREE) {
- if(gentle)
- print (sprintf(_("^1%s^1 made %s scores in a row\n"), s1, s2));
- else
- print (sprintf(_("^1%s^1 has %s frags in a row\n"), s1, s2));
- } else if(type == KILL_SPREE_3) {
- if(gentle)
- print (sprintf(_("%s^7 made a ^1TRIPLE SCORE\n"), s1));
- else
- print (sprintf(_("%s^7 made a ^1TRIPLE FRAG\n"), s1));
- } else if(type == KILL_SPREE_5) {
- if(gentle)
- print (sprintf(_("%s^7 unleashes ^1SCORING RAGE\n"), s1));
- else
- print (sprintf(_("%s^7 unleashes ^1RAGE\n"), s1));
- } else if(type == KILL_SPREE_10) {
- if(gentle)
- print (sprintf(_("%s^7 made ^1TEN SCORES IN A ROW!\n"), s1));
- else
- print (sprintf(_("%s^7 starts the ^1MASSACRE!\n"), s1));
- } else if(type == KILL_SPREE_15) {
- if(gentle)
- print (sprintf(_("%s^7 made ^1FIFTEEN SCORES IN A ROW!\n"), s1));
- else
- print (sprintf(_("%s^7 executes ^1MAYHEM!\n"), s1));
- } else if(type == KILL_SPREE_20) {
- if(gentle)
- print (sprintf(_("%s^7 made ^1TWENTY SCORES IN A ROW!\n"), s1));
- else
- print (sprintf(_("%s^7 is a ^1BERSERKER!\n"), s1));
- } else if(type == KILL_SPREE_25) {
- if(gentle)
- print (sprintf(_("%s^7 made ^1TWENTY FIVE SCORES IN A ROW!\n"), s1));
- else
- print (sprintf(_("%s^7 inflicts ^1CARNAGE!\n"), s1));
- } else if(type == KILL_SPREE_30) {
- if(gentle)
- print (sprintf(_("%s^7 made ^1THIRTY SCORES IN A ROW!\n"), s1));
- else
- print (sprintf(_("%s^7 unleashes ^1ARMAGEDDON!\n"), s1));
- }
- } else if(msg == MSG_KILL_ACTION) { // wtf is this? isnt it basically the same as MSG_SUICIDE?
- if (type == DEATH_DROWN) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_DROWN);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 was in the water for too long\n"), s1));
- else
- print (sprintf(_("^1%s^1 drowned\n"), s1));
- }
- } else if (type == DEATH_SLIME) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_SLIME);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was slimed\n"), s1));
- } else if (type == DEATH_LAVA) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_LAVA);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 found a hot place\n"), s1));
- else
- print (sprintf(_("^1%s^1 turned into hot slag\n"), s1));
- }
- } else if (type == DEATH_FALL) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 tested gravity (and it worked)\n"), s1));
- else
- print (sprintf(_("^1%s^1 hit the ground with a crunch\n"), s1));
- }
- } else if (type == DEATH_SHOOTING_STAR) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_SHOOTING_STAR);
- if(alsoprint)
- print (sprintf(_("^1%s^1 became a shooting star\n"), s1));
- } else if (type == DEATH_SWAMP) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 discovered a swamp\n"), s1));
- else
- print (sprintf(_("^1%s^1 is now conserved for centuries to come\n"), s1));
- }
- } else if(DEATH_ISTURRET(type)) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 ran into a turret\n"), s1));
- else
- {
- switch(type)
- {
- case DEATH_TURRET_EWHEEL:
- print (sprintf(_("^1%s^1 was laserd down by a eWheel turret \n"), s1));
- break;
- case DEATH_TURRET_FLAC:
- print (sprintf(_("^1%s^1 got caught in the flac \n"), s1));
- break;
- case DEATH_TURRET_MACHINEGUN:
- print (sprintf(_("^1%s^1 was riddeld full of riddled by a machinegun turret \n"), s1));
- break;
- case DEATH_TURRET_WALKER_GUN:
- print (sprintf(_("^1%s^1 got served a led enrichment by a walker turret \n"), s1));
- break;
- case DEATH_TURRET_WALKER_MEELE:
- print (sprintf(_("^1%s^1 was impaled by a walker turret \n"), s1));
- break;
- case DEATH_TURRET_WALKER_ROCKET:
- print (sprintf(_("^1%s^1 was rocketed to hell by a walker turret \n"), s1));
- break;
- case DEATH_TURRET_HELLION:
- print (sprintf(_("^1%s^1 was blasted away hellion turret \n"), s1));
- break;
- case DEATH_TURRET_HK:
- print (sprintf(_("^1%s^1 could not hide from the hunter turret \n"), s1));
- break;
- case DEATH_TURRET_MLRS:
- print (sprintf(_("^1%s^1 got turned into smoldering gibs by a mlrs turret \n"), s1));
- break;
- case DEATH_TURRET_PLASMA:
- print (sprintf(_("^1%s^1 got served some superheated plasma from a plasma turret \n"), s1));
- break;
- case DEATH_TURRET_PHASER:
- print (sprintf(_("^1%s^1 was phased out \n"), s1));
- break;
- case DEATH_TURRET_TESLA:
- print (sprintf(_("^1%s^1 was electrocuted by a tesla turret \n"), s1));
- break;
- }
- }
- }
- } else if (type == DEATH_CUSTOM) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_CUSTOM);
- if(alsoprint)
- print("^1", sprintf(s2, strcat(s1, "^1")), "\n");
- } else if (type == DEATH_HURTTRIGGER) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_HURTTRIGGER);
- if(alsoprint)
- print("^1", sprintf(s2, strcat(s1, "^1")), "\n");
- } else if(type == DEATH_TOUCHEXPLODE) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 died in an accident\n"), s1));
- } else if(type == DEATH_CHEAT) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- print (sprintf(_("^1%s^1 was unfairly eliminated\n"), s1));
- } else if(type == DEATH_FIRE) {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 felt a little hot\n"), s1));
- else
- print (sprintf(_("^1%s^1 burnt to death\n"), s1));
- }
- } else {
- HUD_KillNotify_Push(s1, "", 0, DEATH_GENERIC);
- if(alsoprint)
- {
- if(gentle)
- print (sprintf(_("^1%s^1 needs a restart\n"), s1));
- else
- print (sprintf(_("^1%s^1 died\n"), s1));
- }
- }
- } else if(msg == MSG_KILL_ACTION_SPREE) {
- if(gentle)
- print (sprintf(_("^1%s^1 needs a restart after a %d scoring spree\n"), s1, stof(s2)));
- else
- print (sprintf(_("^1%s^1 died with a %d kill spree\n"), s1, stof(s2)));
- } else if(msg == MSG_INFO) {
- if(type == INFO_GOTFLAG) { // here, s2 is the flag name
- HUD_KillNotify_Push(s1, s2, 0, INFO_GOTFLAG);
- print(sprintf(_("%s^7 got the %s\n"), s1, s2));
- } else if(type == INFO_LOSTFLAG) {
- HUD_KillNotify_Push(s1, s2, 0, INFO_LOSTFLAG);
- print(sprintf(_("%s^7 lost the %s\n"), s1, s2));
- } else if(type == INFO_PICKUPFLAG) {
- HUD_KillNotify_Push(s1, s2, 0, INFO_GOTFLAG);
- print(sprintf(_("%s^7 picked up the %s\n"), s1, s2));
- } else if(type == INFO_RETURNFLAG) {
- HUD_KillNotify_Push(s1, s2, 0, INFO_RETURNFLAG);
- print(sprintf(_("%s^7 returned the %s\n"), s1, s2));
- } else if(type == INFO_CAPTUREFLAG) {
- HUD_KillNotify_Push(s1, s2, 0, INFO_CAPTUREFLAG);
- print(sprintf(_("%s^7 captured the %s%s\n"), s1, s2, s3));
- }
- } else if(msg == MSG_RACE) {
- if(type == RACE_SERVER_RECORD) {
- HUD_KillNotify_Push(s1, s2, 1, RACE_SERVER_RECORD);
- }
- else if(type == RACE_NEW_RANK) {
- HUD_KillNotify_Push(s1, s2, 1, RACE_NEW_RANK);
- }
- else if(type == RACE_NEW_TIME) {
- HUD_KillNotify_Push(s1, s2, 1, RACE_NEW_TIME);
- }
- else if(type == RACE_FAIL) {
- HUD_KillNotify_Push(s1, s2, 1, RACE_FAIL);
- }
- } else if(msg == MSG_KA) {
- if(type == KA_PICKUPBALL) {
- HUD_KillNotify_Push(s1, s2, 0, KA_PICKUPBALL);
- if(alsoprint)
- print (sprintf(_("%s^7 has picked up the ball!\n"), s1));
- }
- else if(type == KA_DROPBALL) {
- HUD_KillNotify_Push(s1, s2, 0, KA_DROPBALL);
- if(alsoprint)
- print(sprintf(_("%s^7 has dropped the ball!\n"), s1));
- }
- }
- }
-
- void HUD_KillCenterprint(string s1, string s2, float type, float msg)
- {
- float gentle;
- gentle = (autocvar_cl_gentle || autocvar_cl_gentle_messages);
- if(msg == MSG_SUICIDE) {
- if (type == DEATH_TEAMCHANGE) {
- centerprint_hud(sprintf(_("You are now on: %s"), s1));
- } else if (type == DEATH_AUTOTEAMCHANGE) {
- centerprint_hud(sprintf(_("You have been moved into a different team to improve team balance\nYou are now on: %s"), s1));
- } else if (type == DEATH_CAMP) {
- if(gentle)
- centerprint_hud(_("^1Reconsider your tactics, camper!"));
- else
- centerprint_hud(_("^1Die camper!"));
- } else if (type == DEATH_NOAMMO) {
- if(gentle)
- centerprint_hud(_("^1You are reinserted into the game for running out of ammo..."));
- else
- centerprint_hud(_("^1You were killed for running out of ammo..."));
- } else if (type == DEATH_ROT) {
- if(gentle)
- centerprint_hud(_("^1You need to preserve your health"));
- else
- centerprint_hud(_("^1You grew too old without taking your medicine"));
- } else if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
- if(gentle)
- centerprint_hud(_("^1Don't go against team mates!"));
- else
- centerprint_hud(_("^1Don't shoot your team mates!"));
- } else if (type == DEATH_QUIET) {
- // do nothing
- } else { // generic message
- if(gentle)
- centerprint_hud(_("^1You need to be more careful!"));
- else
- centerprint_hud(_("^1You killed your own dumb self!"));
- }
- } else if(msg == MSG_KILL) {
- if (type == KILL_TEAM_RED || type == KILL_TEAM_BLUE) {
- if(gentle) {
- centerprint_hud(sprintf(_("^1Moron! You went against ^7%s^1, a team mate!"), s1));
- } else {
- centerprint_hud(sprintf(_("^1Moron! You fragged ^7%s^1, a team mate!"), s1));
- }
- } else if (type == KILL_FIRST_BLOOD) {
- if(gentle) {
- centerprint_hud(_("^1First score"));
- } else {
- centerprint_hud(_("^1First blood"));
- }
- } else if (type == KILL_FIRST_VICTIM) {
- if(gentle) {
- centerprint_hud(_("^1First casualty"));
- } else {
- centerprint_hud(_("^1First victim"));
- }
- } else if (type == KILL_TYPEFRAG) { // s2 contains "advanced kill messages" such as ping, handicap...
- if(gentle) {
- centerprint_hud(strcat(sprintf(_("^1You scored against ^7%s^1 who was typing!"), s1), s2));
- } else {
- centerprint_hud(strcat(sprintf(_("^1You typefragged ^7%s"), s1), s2));
- }
- } else if (type == KILL_TYPEFRAGGED) {
- if(gentle) {
- centerprint_hud(strcat(sprintf(_("^1You were scored against by ^7%s^1 while you were typing!"), s1), s2));
- } else {
- centerprint_hud(strcat(sprintf(_("^1You were typefragged by ^7%s"), s1), s2));
- }
- } else if (type == KILL_FRAG) {
- if(gentle) {
- centerprint_hud(strcat(sprintf(_("^4You scored against ^7%s"), s1), s2));
- } else {
- centerprint_hud(strcat(sprintf(_("^4You fragged ^7%s"), s1), s2));
- }
- } else { // generic message
- if(gentle) {
- centerprint_hud(strcat(sprintf(_("^1You were scored against by ^7%s"), s1), s2));
- } else {
- centerprint_hud(strcat(sprintf(_("^1You were fragged by ^7%s"), s1), s2));
- }
- }
- } else if(msg == MSG_KILL_ACTION) {
- // TODO: invent more centerprints here?
- centerprint_hud(_("^1Watch your step!"));
+ // victim
+ if(notify_victims[kn_index]) { strunzone(notify_victims[kn_index]); }
+ notify_victims[kn_index] = strzone(victim);
}
}
- void HUD_Notify (void)
+ void HUD_Notify(void)
{
if(!autocvar__hud_configure)
{
float fadetime;
fadetime = autocvar_hud_panel_notify_fadetime;
- string s;
-
- vector pos_attacker, pos_victim;
- vector weap_pos;
+ vector pos_attacker, pos_victim, pos_icon;
float width_attacker;
- string attacker, victim;
+ string attacker, victim, icon;
- float i, j, w, type, step, limit;
+ float i, j, step, limit;
if(autocvar_hud_panel_notify_flip) //order items from the top down
{
i = 0;
a = entries - 1 - i;
attacker = textShortenToWidth(sprintf(_("Player %d"), a+1), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
victim = textShortenToWidth(sprintf(_("Player %d"), a+2), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
- s = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
+ icon = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
a = bound(0, (when - a) / 4, 1);
goto hud_config_notifyprint;
}
-
- if (j == KN_MAX_ENTRIES)
- j = 0;
-
- if(killnotify_times[j] + when > time)
- a = 1;
- else if(fadetime)
- {
- a = bound(0, (killnotify_times[j] + when + fadetime - time) / fadetime, 1);
- if(!a)
- {
- break;
- }
- }
else
{
- break;
- }
-
- s = "";
+ if (j == KN_MAX_ENTRIES)
+ j = 0;
- type = killnotify_deathtype[j];
- w = DEATH_WEAPONOF(type);
-
- // TODO: maybe print in team colors?
- //
- // Y [used by] X
- if(killnotify_actiontype[j] == 0)
- {
- if(type == DEATH_GENERIC)
- {
- s = "notify_death";
- }
- else if(type == DEATH_NOAMMO)
- {
- s = "notify_outofammo";
- }
- else if(type == DEATH_KILL)
- {
- s = "notify_selfkill";
- }
- else if(type == DEATH_CAMP)
- {
- s = "notify_camping";
- }
- else if(type == KILL_TEAM_RED)
- {
- s = "notify_teamkill_red";
- }
- else if(type == KILL_TEAM_BLUE)
- {
- s = "notify_teamkill_blue";
- }
- else if(type == DEATH_DROWN)
- {
- s = "notify_water";
- }
- else if(type == DEATH_SLIME)
- {
- s = "notify_slime";
- }
- else if(type == DEATH_LAVA)
- {
- s = "notify_lava";
- }
- else if(type == DEATH_FALL)
- {
- s = "notify_fall";
- }
- else if(type == DEATH_SHOOTING_STAR)
- {
- s = "notify_shootingstar";
- }
- else if(type == DEATH_HURTTRIGGER || type == DEATH_CUSTOM)
- {
- s = "notify_death";
- }
- else if(type == INFO_GOTFLAG)
- {
- if(killnotify_victims[j] == "^1RED^7 flag")
- {
- s = "notify_red_taken";
- }
- else
- {
- s = "notify_blue_taken";
- }
- }
- else if(type == INFO_RETURNFLAG)
- {
- if(killnotify_victims[j] == "^1RED^7 flag")
- {
- s = "notify_red_returned";
- }
- else
- {
- s = "notify_blue_returned";
- }
- }
- else if(type == INFO_LOSTFLAG)
- {
- if(killnotify_victims[j] == "^1RED^7 flag")
- {
- s = "notify_red_lost";
- }
- else
- {
- s = "notify_blue_lost";
- }
- }
- else if(type == INFO_CAPTUREFLAG)
+ if(notify_times[j] + when > time)
+ a = 1;
+ else if(fadetime)
{
- if(killnotify_victims[j] == "^1RED^7 flag")
- {
- s = "notify_red_captured";
- }
- else
+ a = bound(0, (notify_times[j] + when + fadetime - time) / fadetime, 1);
+ if(!a)
{
- s = "notify_blue_captured";
+ break;
}
}
- else if(type == KA_DROPBALL)
- {
- s = "notify_balldropped";
- }
- else if(type == KA_PICKUPBALL)
+ else
{
- s = "notify_ballpickedup";
+ break;
}
- attacker = textShortenToWidth(killnotify_attackers[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
- pos_attacker = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
- weap_pos = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
-
- if(s != "")
- {
- drawpic_aspect_skin(weap_pos, s, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- }
+ attacker = notify_attackers[j];
+ victim = notify_victims[j];
+ icon = notify_icon[j];
}
- // X [did action to] Y
- else
+
+ //type = notify_deathtype[j];
+ //w = DEATH_WEAPONOF(type);
+
+ if(icon != "")
{
- if(type & HITTYPE_SECONDARY && w == WEP_LASER)
- {
- s = "notify_melee_laser";
- }
- else if(type & HITTYPE_SECONDARY && w == WEP_SHOTGUN)
- {
- s = "notify_melee_shotgun";
- }
- else if(WEP_VALID(w))
- {
- self = get_weaponinfo(w);
- s = strcat("weapon", self.netname);
- }
- else if(type == KILL_TEAM_RED)
- {
- s = "notify_teamkill_red";
- }
- else if(type == KILL_TEAM_BLUE)
- {
- s = "notify_teamkill_red";
- }
- else if(type == DEATH_TELEFRAG)
+ if((attacker != "") && (victim == ""))
{
- s = "notify_telefrag";
- }
- else if(type == DEATH_DROWN)
- {
- s = "notify_water";
- }
- else if(type == DEATH_SLIME)
- {
- s = "notify_slime";
- }
- else if(type == DEATH_LAVA)
- {
- s = "notify_lava";
- }
- else if(type == DEATH_FALL)
- {
- s = "notify_fall";
- }
- else if(type == DEATH_SHOOTING_STAR)
- {
- s = "notify_shootingstar";
- }
- else if(type == DEATH_HURTTRIGGER || type == DEATH_CUSTOM) // DEATH_CUSTOM is also void, right?
- {
- s = "notify_void";
- }
- else if(type == RACE_SERVER_RECORD)
- {
- s = "race_newrecordserver";
- }
- else if(type == RACE_NEW_RANK)
- {
- s = "race_newrankyellow";
- }
- else if(type == RACE_NEW_TIME)
- {
- s = "race_newtime";
+ // Y [used by] X
+ attacker = textShortenToWidth(attacker, 0.73 * mySize_x - height, fontsize, stringwidth_colors);
+ pos_attacker = pos + eX * (0.27 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
+ pos_icon = pos + eX * 0.25 * mySize_x - eX * height + eY * i * height;
+
+ drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
- else if(type == RACE_FAIL)
+ else if((attacker != "") && (victim != ""))
{
- s = "race_newfail";
- }
-
- attacker = textShortenToWidth(killnotify_attackers[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
- victim = textShortenToWidth(killnotify_victims[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
+ // X [did action to] Y
+ attacker = textShortenToWidth(attacker, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
+ victim = textShortenToWidth(victim, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
:hud_config_notifyprint
- width_attacker = stringwidth(attacker, TRUE, fontsize);
- pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
- pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
- weap_pos = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
+ width_attacker = stringwidth(attacker, TRUE, fontsize);
+ pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
+ pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
+ pos_icon = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
- if(s != "")
- {
- drawpic_aspect_skin(weap_pos, s, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
drawcolorcodedstring(pos_victim, victim, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
HUD_Panel_UpdateCvars(radar);
HUD_Panel_ApplyFadeAlpha();
+
+ float f = 0;
if (hud_panel_radar_maximized && !autocvar__hud_configure)
{
panel_bg = strcat(hud_skin_path, "/border_default"); // always use the default border when maximized
if(precache_pic(panel_bg) == "") { panel_bg = "gfx/hud/default/border_default"; } // fallback
+
+ switch(hud_panel_radar_maximized_zoommode)
+ {
+ default:
+ case 0:
+ f = current_zoomfraction;
+ break;
+ case 1:
+ f = 1 - current_zoomfraction;
+ break;
+ case 2:
+ f = 0;
+ break;
+ case 3:
+ f = 1;
+ break;
+ }
+
+ switch(hud_panel_radar_maximized_rotation)
+ {
+ case 0:
+ teamradar_angle = view_angles_y - 90;
+ break;
+ default:
+ teamradar_angle = 90 * hud_panel_radar_maximized_rotation;
+ break;
+ }
+ }
+ if (!hud_panel_radar_maximized && !autocvar__hud_configure)
+ {
+ switch(hud_panel_radar_zoommode)
+ {
+ default:
+ case 0:
+ f = current_zoomfraction;
+ break;
+ case 1:
+ f = 1 - current_zoomfraction;
+ break;
+ case 2:
+ f = 0;
+ break;
+ case 3:
+ f = 1;
+ break;
+ }
+
+ switch(hud_panel_radar_rotation)
+ {
+ case 0:
+ teamradar_angle = view_angles_y - 90;
+ break;
+ default:
+ teamradar_angle = 90 * hud_panel_radar_rotation;
+ break;
+ }
}
vector pos, mySize;
float color2;
entity tm;
float scale2d, normalsize, bigsize;
- float f;
teamradar_origin2d = pos + 0.5 * mySize;
teamradar_size2d = mySize;
teamradar_loadcvars();
- switch(hud_panel_radar_zoommode)
- {
- default:
- case 0:
- f = current_zoomfraction;
- break;
- case 1:
- f = 1 - current_zoomfraction;
- break;
- case 2:
- f = 0;
- break;
- case 3:
- f = 1;
- break;
- }
-
- switch(hud_panel_radar_rotation)
- {
- case 0:
- teamradar_angle = view_angles_y - 90;
- break;
- default:
- teamradar_angle = 90 * hud_panel_radar_rotation;
- break;
- }
-
scale2d = vlen_maxnorm2d(mi_picmax - mi_picmin);
teamradar_size2d = mySize;
teamradar_extraclip_mins = teamradar_extraclip_maxs = '0 0 0'; // we always center
// pixels per world qu to match the teamradar_size2d_x range in the longest dimension
- if(hud_panel_radar_rotation == 0)
+ if((hud_panel_radar_rotation == 0 && !hud_panel_radar_maximized) || (hud_panel_radar_maximized_rotation == 0 && hud_panel_radar_maximized))
{
// max-min distance must fit the radar in any rotation
bigsize = vlen_minnorm2d(teamradar_size2d) * scale2d / (1.05 * vlen2d(mi_scale));
for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
{
color2 = GetPlayerColor(tm.sv_entnum);
- //if(color == COLOR_SPECTATOR || color == color2)
- draw_teamradar_player(tm.origin, tm.angles, GetTeamRGB(color2));
+ //if(color == NUM_SPECTATOR || color == color2)
+ draw_teamradar_player(tm.origin, tm.angles, Team_ColorRGB(color2));
}
draw_teamradar_player(view_origin, view_angles, '1 1 1');
for(i=0; i<team_count; ++i) {
if (i == floor((entries - 2) / players_per_team) || (entries == 1 && i == 0))
HUD_Panel_DrawHighlight(pos + eX * score_size * i, eX * score_size + eY * fontsize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eX * score_size * i, ftos(175 - 23*i), eX * score_size + eY * fontsize_y, GetTeamRGB(ColorByTeam(i)) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(pos + eX * score_size * i, ftos(175 - 23*i), eX * score_size + eY * fontsize_y, Team_ColorRGB(ColorByTeam(i)) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
}
first_pl = 1;
pos_y += fontsize_y;
}
if (team_count)
- score_color = GetTeamRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
+ score_color = Team_ColorRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
s = textShortenToWidth(s, name_size, fontsize, stringwidth_colors);
drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, TRUE, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
drawstring(pos + eX * (name_size + spacing_size), ftos(score), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
// show team scores in the first line
float score_size = mySize_x / team_count;
for(tm = teams.sort_next; tm; tm = tm.sort_next) {
- if(tm.team == COLOR_SPECTATOR)
+ if(tm.team == NUM_SPECTATOR)
continue;
if (tm.team == myteam)
drawfill(pos + eX * score_size * i, eX * score_size + eY * fontsize_y, '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores[ts_primary])), eX * score_size + eY * fontsize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores[ts_primary])), eX * score_size + eY * fontsize_y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
++i;
}
first_pl = 1;
do
for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
{
- if ((team_count && pl.team != tm.team) || pl.team == COLOR_SPECTATOR)
+ if ((team_count && pl.team != tm.team) || pl.team == NUM_SPECTATOR)
continue;
if (i == entries-1 && !me_printed && pl != me)
if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
{
for (pl = me.sort_next; pl; pl = pl.sort_next)
- if (pl.team != COLOR_SPECTATOR)
+ if (pl.team != NUM_SPECTATOR)
break;
if (pl)
drawfill(pos, eX * mySize_x + eY * fontsize_y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
}
if (team_count)
- score_color = GetTeamRGB(pl.team) * 0.8;
+ score_color = Team_ColorRGB(pl.team) * 0.8;
s = textShortenToWidth(GetPlayerName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, TRUE, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores[ps_primary])), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
pos_y += fontsize_y;
++i;
}
- while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != COLOR_SPECTATOR || (tm = tm.sort_next)));
+ while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != NUM_SPECTATOR || (tm = tm.sort_next)));
}
void HUD_Score(void)
vector score_pos, score_size; //for scores other than myteam
if (spectatee_status == -1 || autocvar_hud_panel_score_rankings)
{
- for(tm = teams.sort_next; tm, tm.team != COLOR_SPECTATOR; tm = tm.sort_next)
+ for(tm = teams.sort_next; tm, tm.team != NUM_SPECTATOR; tm = tm.sort_next)
++scores_count;
if (autocvar_hud_panel_score_rankings)
{
draw_beginBoldFont();
row = column = 0;
for(tm = teams.sort_next; tm; tm = tm.sort_next) {
- if(tm.team == COLOR_SPECTATOR)
+ if(tm.team == NUM_SPECTATOR)
continue;
score = tm.(teamscores[ts_primary]);
if(autocvar__hud_configure)
score_pos = pos + eX * column * (score_size_x + offset_x) + eY * row * (score_size_y + offset_y);
if (max_fragcount == score)
HUD_Panel_DrawHighlight(score_pos, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(score_pos, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(score_pos, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
++row;
if(row >= rows)
{
else if(tm.team == myteam) {
if (max_fragcount == score)
HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
} else {
if (max_fragcount == score)
HUD_Panel_DrawHighlight(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
++rows;
}
}
float mod_active; // is there any active mod icon?
-// Clan Arena HUD modicons
-void HUD_Mod_CA(vector pos, vector mySize)
+void DrawCAItem(vector myPos, vector mySize, float aspect_ratio, float layout, float i)
{
- mod_active = 1; // CA should never hide the mod icons panel
- float redalive, bluealive;
- redalive = getstati(STAT_REDALIVE);
- bluealive = getstati(STAT_BLUEALIVE);
+ float stat;
+ string pic;
+ vector color;
+#ifdef GMQCC
+ stat = -1;
+ pic = "";
+ color = '0 0 0';
+#endif
+ switch(i)
+ {
+ case 0:
+ stat = getstati(STAT_REDALIVE);
+ pic = "player_red.tga";
+ color = '1 0 0';
+ break;
+ case 1:
+ stat = getstati(STAT_BLUEALIVE);
+ pic = "player_blue.tga";
+ color = '0 0 1';
+ break;
+ case 2:
+ stat = getstati(STAT_YELLOWALIVE);
+ pic = "player_yellow.tga";
+ color = '1 1 0';
+ break;
+ default:
+ case 3:
+ stat = getstati(STAT_PINKALIVE);
+ pic = "player_pink.tga";
+ color = '1 0 1';
+ break;
+ }
- vector redpos, bluepos;
- if(mySize_x > mySize_y)
+ if(mySize_x/mySize_y > aspect_ratio)
+ {
+ i = aspect_ratio * mySize_y;
+ myPos_x = myPos_x + (mySize_x - i) / 2;
+ mySize_x = i;
+ }
+ else
{
- redpos = pos;
- bluepos = pos + eY * 0.5 * mySize_y;
- drawpic_aspect_skin(redpos, "player_red.tga", 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(redpos + eX * 0.5 * mySize_x, ftos(redalive), 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawpic_aspect_skin(bluepos, "player_blue.tga", 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(bluepos + eX * 0.5 * mySize_x, ftos(bluealive), 0.5 * mySize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ i = 1/aspect_ratio * mySize_x;
+ myPos_y = myPos_y + (mySize_y - i) / 2;
+ mySize_y = i;
+ }
+
+ if(layout)
+ {
+ drawpic_aspect_skin(myPos, pic, eX * 0.7 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring_aspect(myPos + eX * 0.7 * mySize_x, ftos(stat), eX * 0.3 * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
}
else
+ drawstring_aspect(myPos, ftos(stat), mySize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
+}
+
+// Clan Arena and Freeze Tag HUD modicons
+void HUD_Mod_CA(vector myPos, vector mySize)
+{
+ mod_active = 1; // required in each mod function that always shows something
+ entity tm;
+ float teams_count = 0;
+ for(tm = teams.sort_next; tm; tm = tm.sort_next)
+ if(tm.team != COLOR_SPECTATOR)
+ ++teams_count;
+
+ float layout;
+ if(gametype == MAPINFO_TYPE_CA)
+ layout = autocvar_hud_panel_modicons_ca_layout;
+ else //if(gametype == MAPINFO_TYPE_FREEZETAG)
+ layout = autocvar_hud_panel_modicons_freezetag_layout;
+ float rows, columns, aspect_ratio;
+ rows = mySize_y/mySize_x;
+ aspect_ratio = (layout) ? 2 : 1;
+ rows = bound(1, floor((sqrt((4 * aspect_ratio * teams_count + rows) * rows) + rows + 0.5) / 2), teams_count);
+ columns = ceil(teams_count/rows);
+
+ int i;
+ float row = 0, column = 0;
+ vector pos, itemSize;
+ itemSize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
+ for(i=0; i<teams_count; ++i)
{
- redpos = pos;
- bluepos = pos + eY * 0.5 * mySize_y;
- drawpic_aspect_skin(redpos, "player_red.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(redpos + eY * 0.3 * mySize_y, ftos(redalive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawpic_aspect_skin(bluepos, "player_blue.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawstring_aspect(bluepos + eY * 0.3 * mySize_y, ftos(bluealive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ pos = myPos + eX * column * itemSize_x + eY * row * itemSize_y;
+
+ DrawCAItem(pos, itemSize, aspect_ratio, layout, i);
+
+ ++row;
+ if(row >= rows)
+ {
+ row = 0;
+ ++column;
+ }
}
}
case 2: red_icon = "flag_red_lost"; break;
case 3: red_icon = "flag_red_carrying"; red_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM2))
+ if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
red_icon = "flag_red_shielded";
else
red_icon = string_null;
default:
if(redflag == 3)
red_icon_prevstatus = "flag_red_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM2))
+ else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_2))
red_icon_prevstatus = "flag_red_shielded";
else
red_icon_prevstatus = string_null;
case 2: blue_icon = "flag_blue_lost"; break;
case 3: blue_icon = "flag_blue_carrying"; blue_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
default:
- if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM1))
+ if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
blue_icon = "flag_blue_shielded";
else
blue_icon = string_null;
default:
if(blueflag == 3)
blue_icon_prevstatus = "flag_blue_carrying"; // make it more visible
- else if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM1))
+ else if((stat_items & IT_CTF_SHIELDED) && (myteam == NUM_TEAM_1))
blue_icon_prevstatus = "flag_blue_shielded";
else
blue_icon_prevstatus = string_null;
}
if(mySize_x > mySize_y) {
- if (myteam == COLOR_TEAM1) { // always draw own flag on left
+ if (myteam == NUM_TEAM_1) { // always draw own flag on left
redflag_pos = pos;
blueflag_pos = pos + eX * 0.5 * mySize_x;
} else {
}
flag_size = eX * 0.5 * mySize_x + eY * mySize_y;
} else {
- if (myteam == COLOR_TEAM1) { // always draw own flag on left
+ if (myteam == NUM_TEAM_1) { // always draw own flag on left
redflag_pos = pos;
blueflag_pos = pos + eY * 0.5 * mySize_y;
} else {
{
switch(keyteam)
{
- case COLOR_TEAM1:
+ case NUM_TEAM_1:
drawpic_aspect_skin(pa, "kh_redarrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL); // show 30% theAlpha key
break;
- case COLOR_TEAM2:
+ case NUM_TEAM_2:
drawpic_aspect_skin(pa, "kh_bluearrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL); // show 30% theAlpha key
break;
- case COLOR_TEAM3:
+ case NUM_TEAM_3:
drawpic_aspect_skin(pa, "kh_yellowarrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL); // show 30% theAlpha key
break;
- case COLOR_TEAM4:
+ case NUM_TEAM_4:
drawpic_aspect_skin(pa, "kh_pinkarrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL); // show 30% theAlpha key
break;
default:
else
rank = 0;
string rankname;
- rankname = race_PlaceName(rank);
+ rankname = count_ordinal(rank);
vector namepos;
namepos = medalPos + '0 0.8 0' * squareSize;
entity tm;
float teams_count = 0;
for(tm = teams.sort_next; tm; tm = tm.sort_next)
- if(tm.team != COLOR_SPECTATOR)
+ if(tm.team != NUM_SPECTATOR)
++teams_count;
float layout = autocvar_hud_panel_modicons_dom_layout;
int i;
float row = 0, column = 0;
+ vector pos, itemSize;
+ itemSize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
for(i=0; i<teams_count; ++i)
{
- vector pos, itemSize;
- pos = myPos + eX * column * mySize_x*(1/columns) + eY * row * mySize_y*(1/rows);
- itemSize = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
+ pos = myPos + eX * column * itemSize_x + eY * row * itemSize_y;
DrawDomItem(pos, itemSize, aspect_ratio, layout, i);
{
for(; tm.sort_next; tm = tm.sort_next)
{
- if(!tm.team_size || tm.team == COLOR_SPECTATOR)
+ if(!tm.team_size || tm.team == NUM_SPECTATOR)
continue;
if(!ts_min) ts_min = tm.team_size;
else ts_min = min(ts_min, tm.team_size);
s = strcat(blinkcolor, _("Teamnumbers are unbalanced!"));
tm = GetTeam(myteam, false);
if (tm)
- if (tm.team != COLOR_SPECTATOR)
+ if (tm.team != NUM_SPECTATOR)
if (tm.team_size == ts_max)
s = strcat(s, sprintf(_(" Press ^3%s%s to adjust"), getcommandkey("team menu", "menu_showteamselect"), blinkcolor));
drawInfoMessage(s)
void centerprint_generic(float new_id, string strMessage, float duration, float countdown_num)
{
+ //print(sprintf("centerprint_generic(%d, '%s^7', %d, %d);\n", new_id, strMessage, duration, countdown_num));
float i, j;
if(strMessage == "" && new_id == 0)
centerprint_messages[j] = strzone(strMessage);
centerprint_msgID[j] = new_id;
if (duration < 0)
+ {
centerprint_time[j] = -1;
+ centerprint_expire_time[j] = time;
+ }
else
{
if(duration == 0)
fontsize = '1 1 0' * height;
entries = bound(1, floor(panel_size_y/height), CENTERPRINT_MAX_ENTRIES);
- float i, j, k, n;
+ float i, j, k, n, g;
float a, sz, align, current_msg_pos_y = 0, msg_size;
vector pos;
string ts;
if (autocvar_hud_panel_centerprint_flip)
pos_y += panel_size_y;
align = bound(0, autocvar_hud_panel_centerprint_align, 1);
- for (i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
+ for (g=0, i=0, j=cpm_index; i<CENTERPRINT_MAX_MSGS; ++i, ++j)
{
if (j == CENTERPRINT_MAX_MSGS)
j = 0;
continue;
centerprint_expire_time[j] = centerprint_expire_time[j] + centerprint_time[j];
}
- else
+ else if(centerprint_time[j] != -1)
continue;
}
-
+
+
// fade the centerprint_hud in/out
- if (centerprint_time[j] < 0 || centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time)
+ if(centerprint_time[j] < 0)
+ a = bound(0, (time - centerprint_expire_time[j]) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1);
+ else if(centerprint_expire_time[j] - autocvar_hud_panel_centerprint_fade_out > time)
a = bound(0, (time - (centerprint_expire_time[j] - centerprint_time[j])) / max(0.0001, autocvar_hud_panel_centerprint_fade_in), 1);
- else if (centerprint_expire_time[j] > time)
+ else if(centerprint_expire_time[j] > time)
a = (centerprint_expire_time[j] - time) / max(0.0001, autocvar_hud_panel_centerprint_fade_out);
else
a = 0;
// also fade it based on positioning
if(autocvar_hud_panel_centerprint_fade_subsequent)
{
- a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (i / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1); // pass one: all messages after the first have half theAlpha
- a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (i / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1); // pass two: after that, gradually lower theAlpha even more for each message
+ a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passone_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passone))), 1); // pass one: all messages after the first have half theAlpha
+ a = a * bound(autocvar_hud_panel_centerprint_fade_subsequent_passtwo_minalpha, (1 - (g / max(1, autocvar_hud_panel_centerprint_fade_subsequent_passtwo))), 1); // pass two: after that, gradually lower theAlpha even more for each message
}
// finally set the size based on the new theAlpha from subsequent fading
drawfontscale = sz * '1 1 0';
if (centerprint_countdown_num[j])
- n = tokenizebyseparator(sprintf(centerprint_messages[j], centerprint_countdown_num[j]), "\n");
+ n = tokenizebyseparator(strreplace("^COUNT", count_seconds(centerprint_countdown_num[j]), centerprint_messages[j]), "\n");
else
n = tokenizebyseparator(centerprint_messages[j], "\n");
pos_y += fontsize_y * CENTERPRINT_SPACING/2;
}
}
+
+ ++g; // move next position number up
+
msg_size = pos_y - msg_size;
if (autocvar_hud_panel_centerprint_flip)
{
case HUD_PANEL_NOTIFY:
HUD_Write_PanelCvar_q("_flip");
HUD_Write_PanelCvar_q("_fontsize");
- HUD_Write_PanelCvar_q("_print");
HUD_Write_PanelCvar_q("_time");
HUD_Write_PanelCvar_q("_fadetime");
break;
HUD_Write_PanelCvar_q("_scale");
HUD_Write_PanelCvar_q("_maximized_scale");
HUD_Write_PanelCvar_q("_maximized_size");
+ HUD_Write_PanelCvar_q("_maximized_rotation");
+ HUD_Write_PanelCvar_q("_maximized_zoommode");
break;
case HUD_PANEL_SCORE:
HUD_Write_PanelCvar_q("_rankings");
HUD_Write_PanelCvar_q("_alreadyvoted_alpha");
break;
case HUD_PANEL_MODICONS:
+ HUD_Write_PanelCvar_q("_ca_layout");
HUD_Write_PanelCvar_q("_dom_layout");
+ HUD_Write_PanelCvar_q("_freezetag_layout");
break;
case HUD_PANEL_PRESSEDKEYS:
HUD_Write_PanelCvar_q("_aspect");
const float TE_CSQC_LIGHTNINGARC = 105;
const float TE_CSQC_TEAMNAGGER = 106;
const float TE_CSQC_PINGPLREPORT = 107;
- const float TE_CSQC_ANNOUNCE = 110;
- const float TE_CSQC_TARGET_MUSIC = 111;
- const float TE_CSQC_KILLNOTIFY = 112;
- const float TE_CSQC_KILLCENTERPRINT = 113;
- const float TE_CSQC_CENTERPRINT_GENERIC = 114;
- const float TE_CSQC_WEAPONCOMPLAIN = 115;
- const float TE_CSQC_NEX_SCOPE = 116;
- const float TE_CSQC_MINELAYER_MAXMINES = 117;
- const float TE_CSQC_HAGAR_MAXROCKETS = 118;
- const float TE_CSQC_VEHICLESETUP = 119;
- const float TE_CSQC_SVNOTICE = 120;
+ const float TE_CSQC_ANNOUNCE = 108;
+ const float TE_CSQC_TARGET_MUSIC = 109;
+ const float TE_CSQC_WEAPONCOMPLAIN = 110;
+ const float TE_CSQC_NEX_SCOPE = 111;
+ const float TE_CSQC_MINELAYER_MAXMINES = 112;
+ const float TE_CSQC_HAGAR_MAXROCKETS = 113;
+ const float TE_CSQC_VEHICLESETUP = 114;
+ const float TE_CSQC_SVNOTICE = 115;
const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
const float RACE_NET_CHECKPOINT_CLEAR = 1;
const float ENT_CLIENT_MODEL = 33;
const float ENT_CLIENT_ITEM = 34;
const float ENT_CLIENT_BUMBLE_RAYGUN = 35;
+ const float ENT_CLIENT_NOTIFICATION = 36;
const float ENT_CLIENT_TURRET = 40;
const float ENT_CLIENT_AUXILIARYXHAIR = 50;
const float STAT_SECRETS_FOUND = 71;
const float STAT_RESPAWN_TIME = 72;
+const float STAT_ROUNDSTARTTIME = 73;
// mod stats (1xx)
const float STAT_REDALIVE = 100;
float SPECIES_ROBOT_SHINY = 5;
float SPECIES_RESERVED = 15;
- // Deathtypes (weapon deathtypes are the IT_* constants below)
- // NOTE: when adding death types, please add an explanation to Docs/spamlog.txt too.
- float DEATH_SPECIAL_START = 10000;
- float DEATH_FALL = 10000;
- float DEATH_TELEFRAG = 10001;
- float DEATH_DROWN = 10002;
- float DEATH_HURTTRIGGER = 10003;
- float DEATH_LAVA = 10004;
- float DEATH_SLIME = 10005;
- float DEATH_KILL = 10006;
- float DEATH_NOAMMO = 10007;
- float DEATH_SWAMP = 10008;
- float DEATH_TEAMCHANGE = 10009;
- float DEATH_AUTOTEAMCHANGE = 10010;
- float DEATH_CAMP = 10011;
- float DEATH_SHOOTING_STAR = 10012;
- float DEATH_ROT = 10013;
- float DEATH_MIRRORDAMAGE = 10014;
- float DEATH_TOUCHEXPLODE = 10015;
- float DEATH_CHEAT = 10016;
- float DEATH_FIRE = 10017;
- float DEATH_QUIET = 10021;
-
- float DEATH_VHFIRST = 10030;
- float DEATH_VHCRUSH = 10030;
- float DEATH_SBMINIGUN = 10031;
- float DEATH_SBROCKET = 10032;
- float DEATH_SBBLOWUP = 10033;
- float DEATH_WAKIGUN = 10034;
- float DEATH_WAKIROCKET = 10035;
- float DEATH_WAKIBLOWUP = 10036;
- float DEATH_RAPTOR_CANNON = 10037;
- float DEATH_RAPTOR_BOMB = 10038;
- float DEATH_RAPTOR_BOMB_SPLIT = 10039;
- float DEATH_RAPTOR_DEATH = 10040;
- float DEATH_BUMB_GUN = 10041;
- float DEATH_BUMB_RAY = 10042;
- float DEATH_BUMB_RAY_HEAL = 10043;
- float DEATH_BUMB_DEATH = 10044;
- float DEATH_VHLAST = 10044;
- #define DEATH_ISVEHICLE(t) ((t) >= DEATH_VHFIRST && (t) <= DEATH_VHLAST)
-
- float DEATH_GENERIC = 10050;
-
- float DEATH_WEAPON = 10100;
-
- float DEATH_CUSTOM = 10300;
-
- float DEATH_TURRET = 10500;
- float DEATH_TURRET_EWHEEL = 10501;
- float DEATH_TURRET_FLAC = 10502;
- float DEATH_TURRET_MACHINEGUN = 10503;
- float DEATH_TURRET_WALKER_GUN = 10504;
- float DEATH_TURRET_WALKER_MEELE = 10505;
- float DEATH_TURRET_WALKER_ROCKET = 10506;
- float DEATH_TURRET_HELLION = 10507;
- float DEATH_TURRET_HK = 10508;
- float DEATH_TURRET_MLRS = 10509;
- float DEATH_TURRET_PLASMA = 10510;
- float DEATH_TURRET_PHASER = 10511;
- float DEATH_TURRET_TESLA = 10512;
- float DEATH_TURRET_LAST = 10512;
-
- float DEATH_WEAPONMASK = 0xFF;
- float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
- float HITTYPE_SECONDARY = 0x100;
- float HITTYPE_SPLASH = 0x200; // automatically set by RadiusDamage
- float HITTYPE_BOUNCE = 0x400;
- float HITTYPE_RESERVED2 = 0x800;
- float HITTYPE_RESERVED = 0x1000; // unused yet
-
- // macros to access these
- #define DEATH_ISTURRET(t) ((t) >= DEATH_TURRET && (t) <= DEATH_TURRET_LAST)
- #define DEATH_ISSPECIAL(t) ((t) >= DEATH_SPECIAL_START)
- #define DEATH_WEAPONOFWEAPONDEATH(t) ((t) & DEATH_WEAPONMASK)
- #define DEATH_ISWEAPON(t,w) (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
- #define DEATH_WEAPONOF(t) (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
- #define WEP_VALID(w) ((w) >= WEP_FIRST && (w) <= WEP_LAST)
-
#define FRAGS_PLAYER 0
#define FRAGS_SPECTATOR -666
#define FRAGS_LMS_LOSER -616
float MAX_SHOT_DISTANCE = 32768;
- //centerprint ID list
- float CPID_TEAMCHANGE = 1;
- float CPID_CTF_CAPTURESHIELD = 2;
- float CPID_MINSTA_FINDAMMO = 3;
- float CPID_NIX_WPNCHANGE = 4;
- float CPID_DISCONNECT_IDLING = 5;
-
- float CPID_GAME_STARTING = 7;
- float CPID_TIMEOUT_COUNTDOWN = 8;
- float CPID_MOTD = 9;
- float CPID_KH_MSG = 10;
- float CPID_PREVENT_JOIN = 11;
- float CPID_WAITING_PLAYERS = 12;
-
- // CSQC centerprint/notify message types
- float MSG_SUICIDE = 0;
- float MSG_KILL = 1;
- float MSG_SPREE = 2;
- float MSG_KILL_ACTION = 3;
- float MSG_KILL_ACTION_SPREE = 4;
- float MSG_INFO = 5;
- float MSG_KA = 6;
- float MSG_RACE = 10;
-
- float KILL_TEAM_RED = 12001;
- float KILL_TEAM_BLUE = 12002;
- float KILL_TEAM_SPREE = 12003;
- float KILL_FIRST_BLOOD = 12004;
- float KILL_FIRST_VICTIM = 12005;
- float KILL_TYPEFRAG = 12006;
- float KILL_TYPEFRAGGED = 12007;
- float KILL_FRAG = 12008;
- float KILL_FRAGGED = 12009;
- float KILL_SPREE = 12010;
- float KILL_END_SPREE = 12011;
- float KILL_SPREE_3 = 12012;
- float KILL_SPREE_5 = 12013;
- float KILL_SPREE_10 = 12014;
- float KILL_SPREE_15 = 12015;
- float KILL_SPREE_20 = 12016;
- float KILL_SPREE_25 = 12017;
- float KILL_SPREE_30 = 12018;
-
- float INFO_GOTFLAG = 13001;
- float INFO_PICKUPFLAG = 13002;
- float INFO_LOSTFLAG = 13003;
- float INFO_RETURNFLAG = 13004;
- float INFO_CAPTUREFLAG = 13005;
-
- float KA_PICKUPBALL = 14001;
- float KA_DROPBALL = 14002;
-
- float RACE_SERVER_RECORD = 15001;
- float RACE_NEW_TIME = 15002;
- float RACE_NEW_RANK = 15003;
- float RACE_FAIL = 15004;
-
// weapon requests
float WR_SETUP = 1; // (SVQC) setup weapon data
float WR_THINK = 2; // (SVQC) logic to run every frame
float WR_CHECKAMMO2 = 4; // (SVQC) checks ammo for weapon
float WR_AIM = 5; // (SVQC) runs bot aiming code for this weapon
float WR_PRECACHE = 6; // (CSQC and SVQC) precaches models/sounds used by this weapon
- float WR_SUICIDEMESSAGE = 7; // (CSQC) sets w_deathtypestring or leaves it alone (and may inspect w_deathtype for details)
- float WR_KILLMESSAGE = 8; // (CSQC) sets w_deathtypestring or leaves it alone
+ float WR_SUICIDEMESSAGE = 7; // (SVQC) notification number for suicide message (may inspect w_deathtype for details)
+ float WR_KILLMESSAGE = 8; // (SVQC) notification number for kill message (may inspect w_deathtype for details)
float WR_RELOAD = 9; // (SVQC) does not need to do anything
float WR_RESETPLAYER = 10; // (SVQC) does not need to do anything
float WR_IMPACTEFFECT = 11; // (CSQC) impact effect
float autocvar_g_arena_point_leadlimit;
float autocvar_g_arena_point_limit;
float autocvar_g_arena_roundbased;
+float autocvar_g_arena_round_timelimit;
float autocvar_g_arena_warmup;
float autocvar_g_assault;
float autocvar_g_balance_armor_blockpercent;
float autocvar_g_ca_point_limit;
float autocvar_g_ca_round_timelimit;
float autocvar_g_ca_spectate_enemies;
+float autocvar_g_ca_teams;
+float autocvar_g_ca_teams_override;
float autocvar_g_ca_warmup;
float autocvar_g_campaign;
#define autocvar_g_campaign_forceteam cvar("g_campaign_forceteam")
float autocvar_g_chat_flood_spl_tell;
float autocvar_g_chat_nospectators;
float autocvar_g_chat_teamcolors;
+ float autocvar_g_chat_tellprivacy;
float autocvar_g_ctf_allow_vehicle_carry;
float autocvar_g_ctf_allow_vehicle_touch;
float autocvar_g_ctf_throw;
float autocvar_g_ctf_pass_turnrate;
float autocvar_g_ctf_pass_timelimit;
float autocvar_g_ctf_pass_velocity;
- float autocvar_g_ctf_captimerecord_always;
float autocvar_g_ctf_dynamiclights;
string autocvar_g_ctf_flag_blue_model;
float autocvar_g_ctf_flag_blue_skin;
float autocvar_g_ctf_flag_dropped_floatinwater;
float autocvar_g_ctf_flag_glowtrails;
float autocvar_g_ctf_flag_health;
- float autocvar_g_ctf_flag_pickup_verbosename;
string autocvar_g_ctf_flag_red_model;
float autocvar_g_ctf_flag_red_skin;
float autocvar_g_ctf_flag_return_time;
string autocvar_g_forced_team_red;
string autocvar_g_forced_team_yellow;
float autocvar_g_freezetag_frozen_force;
+float autocvar_g_freezetag_frozen_maxtime;
float autocvar_g_freezetag_point_leadlimit;
float autocvar_g_freezetag_point_limit;
float autocvar_g_freezetag_revive_extra_size;
float autocvar_g_freezetag_revive_speed;
float autocvar_g_freezetag_revive_clearspeed;
+float autocvar_g_freezetag_round_timelimit;
+float autocvar_g_freezetag_teams;
+float autocvar_g_freezetag_teams_override;
float autocvar_g_freezetag_warmup;
#define autocvar_g_friendlyfire cvar("g_friendlyfire")
#define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
float autocvar_g_lms_campcheck_damage;
float autocvar_g_lms_campcheck_distance;
float autocvar_g_lms_campcheck_interval;
- string autocvar_g_lms_campcheck_message;
float autocvar_g_lms_join_anytime;
float autocvar_g_lms_last_join;
#define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
float autocvar_g_spawnpoints_auto_move_out_of_solid;
#define autocvar_g_spawnshieldtime cvar("g_spawnshieldtime")
float autocvar_g_spawnsound;
-float autocvar_g_start_delay;
#define autocvar_g_start_weapon_laser cvar("g_start_weapon_laser")
float autocvar_g_tdm_team_spawns;
float autocvar_g_tdm_teams;
string autocvar_sv_eventlog_files_nameprefix;
string autocvar_sv_eventlog_files_namesuffix;
float autocvar_sv_eventlog_files_timestamps;
- float autocvar_sv_fraginfo;
- float autocvar_sv_fraginfo_handicap;
- float autocvar_sv_fraginfo_ping;
- float autocvar_sv_fraginfo_stats;
float autocvar_sv_friction;
float autocvar_sv_friction_on_land;
float autocvar_sv_gameplayfix_q2airaccelerate;
+ float autocvar_sv_gentle;
#define autocvar_sv_gravity cvar("sv_gravity")
string autocvar_sv_intermission_cdtrack;
string autocvar_sv_jumpspeedcap_max;
bot_setnameandstuff();
if(self.bot_forced_team==1)
- self.team = COLOR_TEAM1;
+ self.team = NUM_TEAM_1;
else if(self.bot_forced_team==2)
- self.team = COLOR_TEAM2;
+ self.team = NUM_TEAM_2;
else if(self.bot_forced_team==3)
- self.team = COLOR_TEAM3;
+ self.team = NUM_TEAM_3;
else if(self.bot_forced_team==4)
- self.team = COLOR_TEAM4;
+ self.team = NUM_TEAM_4;
else
JoinBestTeam(self, FALSE, TRUE);
bestcount = 0;
while (head)
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
thiscount = c1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
thiscount = c2;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
thiscount = c3;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
thiscount = c4;
else
thiscount = 0;
FOR_EACH_REALCLIENT(head)
{
- if(head.classname == "player" || g_lms || g_arena || g_ca)
+ if(head.classname == "player" || g_lms || g_arena || head.caplayer == 1)
++activerealplayers;
++realplayers;
}
else
{
float mindist;
- if (arena_roundbased && !g_ca)
+ if (g_arena && arena_roundbased)
mindist = 800;
else
mindist = 100;
WriteEntity(MSG_ONE, self);
}
+ if(g_lms)
+ {
+ // Only if the player cannot play at all
+ if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
+ self.frags = FRAGS_SPECTATOR;
+ else
+ self.frags = FRAGS_LMS_LOSER;
+ }
+ else if((g_race && g_race_qualifying) || g_cts)
+ {
+ if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+ self.frags = FRAGS_LMS_LOSER;
+ else
+ self.frags = FRAGS_SPECTATOR;
+ }
+ else
+ self.frags = FRAGS_SPECTATOR;
+
DropAllRunes(self);
MUTATOR_CALLHOOK(MakePlayerObserver);
if(self.killcount != -666) {
if(g_lms) {
- if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0)
- bprint ("^4", self.netname, "^4 has no more lives left\n");
+ if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2)
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname);
else
- bprint ("^4", self.netname, "^4 is spectating now\n"); // TODO turn this into a proper forfeit?
- } else
- bprint ("^4", self.netname, "^4 is spectating now\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname);
+ } else { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); }
if(self.just_joined == FALSE) {
LogTeamchange(self.playerid, -1, 4);
self.punchvector = '0 0 0';
self.oldvelocity = self.velocity;
self.fire_endtime = -1;
-
- if(g_arena)
- {
- if(self.version_mismatch)
- {
- self.frags = FRAGS_SPECTATOR;
- Spawnqueue_Unmark(self);
- Spawnqueue_Remove(self);
- }
- else
- {
- self.frags = FRAGS_LMS_LOSER;
- Spawnqueue_Insert(self);
- }
- }
- else if(g_lms)
- {
- // Only if the player cannot play at all
- if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666)
- self.frags = FRAGS_SPECTATOR;
- else
- self.frags = FRAGS_LMS_LOSER;
- }
- else if(g_ca)
- {
- if(self.caplayer)
- self.frags = FRAGS_LMS_LOSER;
- else
- self.frags = FRAGS_SPECTATOR;
- }
- else if((g_race && g_race_qualifying) || g_cts)
- {
- if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
- self.frags = FRAGS_LMS_LOSER;
- else
- self.frags = FRAGS_SPECTATOR;
- }
- else
- self.frags = FRAGS_SPECTATOR;
}
.float model_randomizer;
if(teamplay)
{
string s;
- s = Team_ColorNameLowerCase(self.team);
+ s = Team_ColorName_Lower(self.team);
if(s != "neutral")
{
defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
self.skin = stof(self.playerskin);
}
- if(chmdl || oldskin != self.skin)
- self.species = player_getspecies(); // model or skin has changed
+ if(chmdl || oldskin != self.skin) // model or skin has changed
+ {
+ self.species = player_getspecies(); // update species
+ UpdatePlayerSounds(); // update skin sounds
+ }
if(!teamplay)
if(strlen(autocvar_sv_defaultplayercolors))
void PutClientInServer (void)
{
if(clienttype(self) == CLIENTTYPE_BOT)
- {
self.classname = "player";
- if(g_ca)
- self.caplayer = 1;
- }
else if(clienttype(self) == CLIENTTYPE_REAL)
{
msg_entity = self;
self.classname = "observer";
}
- if((g_arena && !self.spawned) || (g_ca && !allowed_to_spawn))
- self.classname = "observer";
+ MUTATOR_CALLHOOK(PutClientInServer);
if(gameover)
self.classname = "observer";
- if(self.classname == "player" && (!g_ca || (g_ca && allowed_to_spawn))) {
+ if(self.classname == "player") {
entity spot, oldself;
float j;
spot = SelectSpawnPoint (FALSE);
if(!spot)
{
- centerprint(self, "Sorry, no spawnpoints available!\nHope your team can fix it...");
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_JOIN_NOSPAWNS);
return; // spawn failed
}
self.lastteleporttime = time; // prevent insane speeds due to changing origin
self.hud = HUD_NORMAL;
- if(g_arena)
- {
- Spawnqueue_Remove(self);
- Spawnqueue_Mark(self);
- }
- else if(g_ca)
- self.caplayer = 1;
-
self.event_damage = PlayerDamage;
self.bot_attack = TRUE;
if(g_assault) {
if(self.team == assault_attacker_team)
- centerprint(self, "You are attacking!");
+ Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING);
else
- centerprint(self, "You are defending!");
+ Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING);
}
target_voicescript_clear(self);
}
else if(self.killindicator_teamchange == -2)
{
- if(g_ca)
- self.caplayer = 0;
if(blockSpectators)
- sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
PutObserverInServer();
}
else
SV_ChangeTeam(self.killindicator_teamchange - 1);
+ self.killindicator_teamchange = 0;
}
void ClientKill_Now()
self.killindicator.colormod = '0 0 0';
if(clienttype(self) == CLIENTTYPE_REAL)
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "^1Suicide in %d seconds", 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SUICIDE, self.killindicator.cnt);
}
else if(targetteam == -1) // auto
{
self.killindicator.colormod = '0 1 0';
if(clienttype(self) == CLIENTTYPE_REAL)
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Changing team in %d seconds", 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_AUTO, self.killindicator.cnt);
}
else if(targetteam == -2) // spectate
{
self.killindicator.colormod = '0.5 0.5 0.5';
if(clienttype(self) == CLIENTTYPE_REAL)
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, "Spectating in %d seconds", 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SPECTATE, self.killindicator.cnt);
}
else
{
- self.killindicator.colormod = TeamColor(targetteam);
+ self.killindicator.colormod = Team_ColorRGB(targetteam);
if(clienttype(self) == CLIENTTYPE_REAL)
if(self.killindicator.cnt > 0)
- Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM_4(targetteam, CENTER_TEAMCHANGE_), self.killindicator.cnt);
}
}
void ClientKill (void)
{
- if (gameover)
- return;
+ if(gameover) return;
+ if(self.player_blocked) return;
+ if(self.freezetag_frozen) return;
- if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either
- {
- // do nothing
- }
- else if(self.freezetag_frozen)
- {
- // do nothing
- }
- else
- ClientKill_TeamChange(0);
+ ClientKill_TeamChange(0);
}
void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed
stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
if(autocvar_g_antilag == 3) // client side hitscan
stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
- if(sv_gentle)
+ if(autocvar_sv_gentle)
stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
/*
* we no longer need to stuff this. Remove this comment block if you feel
Called when a client connects to the server
=============
*/
- string ColoredTeamName(float t);
void DecodeLevelParms (void);
//void dom_player_join_team(entity pl);
void set_dom_state(entity e);
DecodeLevelParms();
#ifdef WATERMARK
- sprint(self, strcat("^4SVQC Build information: ^1", WATERMARK, "\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_WATERMARK, WATERMARK);
#endif
self.classname = "player_joining";
{
switch(autocvar_g_campaign_forceteam)
{
- case 1: self.team_forced = COLOR_TEAM1; break;
- case 2: self.team_forced = COLOR_TEAM2; break;
- case 3: self.team_forced = COLOR_TEAM3; break;
- case 4: self.team_forced = COLOR_TEAM4; break;
+ case 1: self.team_forced = NUM_TEAM_1; break;
+ case 2: self.team_forced = NUM_TEAM_2; break;
+ case 3: self.team_forced = NUM_TEAM_3; break;
+ case 4: self.team_forced = NUM_TEAM_4; break;
default: self.team_forced = 0;
}
}
}
else if(PlayerInIDList(self, autocvar_g_forced_team_red))
- self.team_forced = COLOR_TEAM1;
+ self.team_forced = NUM_TEAM_1;
else if(PlayerInIDList(self, autocvar_g_forced_team_blue))
- self.team_forced = COLOR_TEAM2;
+ self.team_forced = NUM_TEAM_2;
else if(PlayerInIDList(self, autocvar_g_forced_team_yellow))
- self.team_forced = COLOR_TEAM3;
+ self.team_forced = NUM_TEAM_3;
else if(PlayerInIDList(self, autocvar_g_forced_team_pink))
- self.team_forced = COLOR_TEAM4;
+ self.team_forced = NUM_TEAM_4;
else if(autocvar_g_forced_team_otherwise == "red")
- self.team_forced = COLOR_TEAM1;
+ self.team_forced = NUM_TEAM_1;
else if(autocvar_g_forced_team_otherwise == "blue")
- self.team_forced = COLOR_TEAM2;
+ self.team_forced = NUM_TEAM_2;
else if(autocvar_g_forced_team_otherwise == "yellow")
- self.team_forced = COLOR_TEAM3;
+ self.team_forced = NUM_TEAM_3;
else if(autocvar_g_forced_team_otherwise == "pink")
- self.team_forced = COLOR_TEAM4;
+ self.team_forced = NUM_TEAM_4;
else if(autocvar_g_forced_team_otherwise == "spectate")
self.team_forced = -1;
else if(autocvar_g_forced_team_otherwise == "spectator")
self.netname_previous = strzone(self.netname);
- bprint("^4", self.netname, "^4 connected");
-
- if(self.classname != "observer" && (g_domination || g_ctf))
- bprint(" and joined the ", ColoredTeamName(self.team));
-
- bprint("\n");
+ if((self.classname == STR_PLAYER && teamplay))
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(self, INFO_JOIN_CONNECT_TEAM_), self.netname);
+ else
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_CONNECT, self.netname);
stuffcmd(self, strcat(clientstuff, "\n"));
stuffcmd(self, "cl_particles_reloadeffects\n"); // TODO do we still need this?
else
stuffcmd(self, "set _teams_available 0\n");
- if(g_arena || g_ca)
- {
- self.classname = "observer";
- if(g_arena)
- Spawnqueue_Insert(self);
- }
-
attach_entcs();
bot_relinkplayerlist();
self.spectatortime = time;
if(blockSpectators)
{
- sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
}
self.jointime = time;
CheatInitClient();
if(!autocvar_g_campaign)
- Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
CSQCMODEL_AUTOINIT();
self.model_randomizer = random();
-
- if(clienttype(self) != CLIENTTYPE_REAL)
- return;
-
- sv_notice_join();
-
- MUTATOR_CALLHOOK(ClientConnect);
+
+ if(clienttype(self) == CLIENTTYPE_REAL)
+ sv_notice_join();
+
+ MUTATOR_CALLHOOK(ClientConnect);
}
/*
=============
if(autocvar_sv_eventlog)
GameLogEcho(strcat(":part:", ftos(self.playerid)));
- bprint ("^4",self.netname);
- bprint ("^4 disconnected\n");
+
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
DropAllRunes(self);
MUTATOR_CALLHOOK(ClientDisconnect);
bot_relinkplayerlist();
- if(g_arena)
- {
- Spawnqueue_Unmark(self);
- Spawnqueue_Remove(self);
- }
-
accuracy_free(self);
ClientData_Detach();
PlayerScore_Detach(self);
self.alpha = default_player_alpha;
self.exteriorweaponentity.alpha = default_weapon_alpha;
self.items &~= IT_STRENGTH;
- sprint(self, "^3Invisibility has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_INVISIBILITY, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
}
}
else
self.alpha = g_minstagib_invis_alpha;
self.exteriorweaponentity.alpha = g_minstagib_invis_alpha;
self.items |= IT_STRENGTH;
- sprint(self, "^3You are invisible\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
}
}
if (time > self.invincible_finished)
{
self.items = self.items - (self.items & IT_INVINCIBLE);
- sprint(self, "^3Speed has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SPEED, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
}
}
else
if (time < self.invincible_finished)
{
self.items = self.items | IT_INVINCIBLE;
- sprint(self, "^3You are on speed\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
}
}
}
if (time > self.strength_finished)
{
self.items = self.items - (self.items & IT_STRENGTH);
- sprint(self, "^3Strength has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_STRENGTH, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_STRENGTH);
}
}
else
if (time < self.strength_finished)
{
self.items = self.items | IT_STRENGTH;
- sprint(self, "^3Strength infuses your weapons with devastating power\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_STRENGTH, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_STRENGTH);
}
}
if (self.items & IT_INVINCIBLE)
if (time > self.invincible_finished)
{
self.items = self.items - (self.items & IT_INVINCIBLE);
- sprint(self, "^3Shield has worn off\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SHIELD, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SHIELD);
}
}
else
if (time < self.invincible_finished)
{
self.items = self.items | IT_INVINCIBLE;
- sprint(self, "^3Shield surrounds you\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SHIELD, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SHIELD);
}
}
if (self.items & IT_SUPERWEAPON)
{
self.superweapons_finished = 0;
self.items = self.items - (self.items & IT_SUPERWEAPON);
- sprint(self, "^3Superweapons have been lost\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_LOST, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
}
else if (self.items & IT_UNLIMITED_SUPERWEAPONS)
{
{
self.items = self.items - (self.items & IT_SUPERWEAPON);
WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS);
- sprint(self, "^3Superweapons have broken down\n");
+ //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_BROKEN, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_BROKEN);
}
}
}
if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS))
{
self.items = self.items | IT_SUPERWEAPON;
- sprint(self, "^3You now have a superweapon\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_PICKUP, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_PICKUP);
}
else
{
limita = limita * limit_mod;
//limitf = limitf * limit_mod;
- if(g_lms && g_ca)
+ if(g_ca)
rot_mod = 0;
if (!g_minstagib && !g_ca && (!g_lms || autocvar_g_lms_regenerate))
}
}
- .float prevent_join_msgtime;
void LeaveSpectatorMode()
{
- if(nJoinAllowed(self)) {
- if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) {
+ if(self.caplayer)
+ return;
+ if(nJoinAllowed(self))
+ {
+ if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
+ {
self.classname = "player";
if(autocvar_g_campaign || autocvar_g_balance_teams)
- JoinBestTeam(self, FALSE, TRUE);
+ { JoinBestTeam(self, FALSE, TRUE); }
if(autocvar_g_campaign)
- campaign_bots_may_start = 1;
+ { campaign_bots_may_start = 1; }
+ else
+ { Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); }
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
+
PutClientInServer();
- if(self.classname == "player")
- bprint ("^4", self.netname, "^4 is playing now\n");
-
- if(!autocvar_g_campaign)
- if (time < self.jointime + autocvar_welcome_message_time)
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD); // clear MOTD
-
- if (self.prevent_join_msgtime)
- {
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_PREVENT_JOIN);
- self.prevent_join_msgtime = 0;
- }
- } else {
- stuffcmd(self, "menu_showteamselect\n");
+ if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); }
}
- else if not(g_ca && self.caplayer) { stuffcmd(self, "menu_showteamselect\n"); }
++ else
++ stuffcmd(self, "menu_showteamselect\n");
}
- else {
- //player may not join because of g_maxplayers is set
- if (time - self.prevent_join_msgtime > 2)
- {
- Send_CSQC_Centerprint_Generic(self, CPID_PREVENT_JOIN, PREVENT_JOIN_TEXT, 0, 0);
- self.prevent_join_msgtime = time;
- }
+ else
+ {
+ // Player may not join because g_maxplayers is set
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
}
}
return maxclients - totalClients;
float currentlyPlaying = 0;
- FOR_EACH_REALPLAYER(e)
- currentlyPlaying += 1;
+ FOR_EACH_REALCLIENT(e)
+ if(e.classname == "player" || e.caplayer == 1)
+ currentlyPlaying += 1;
if(currentlyPlaying < autocvar_g_maxplayers)
return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying);
void checkSpectatorBlock() {
if(self.classname == "spectator" || self.classname == "observer") {
if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
- sprint(self, "^7You were kicked from the server because you are spectator and spectators aren't allowed at the moment.\n");
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
dropclient(self);
}
}
if (autocvar_g_campaign) {
if ((self.classname == "player" && self.BUTTON_INFO) || (self.classname != "player")) {
self.motd_actived_time = time;
- Send_CSQC_Centerprint_Generic(self, CPID_MOTD, campaign_message, -1, 0);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, campaign_message);
}
} else {
if ((time - self.jointime > autocvar_welcome_message_time) && self.BUTTON_INFO) {
self.motd_actived_time = time;
- Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), -1, 0);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
}
}
} else { // showing MOTD or campaign message
self.motd_actived_time = time;
else if ((time - self.motd_actived_time > 2) && self.classname == "player") { // hide it some seconds after BUTTON_INFO has been released
self.motd_actived_time = 0;
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
}
} else {
if ((time - self.jointime) > autocvar_welcome_message_time) {
self.motd_actived_time = time;
else if (time - self.motd_actived_time > 2) { // hide it some seconds after BUTTON_INFO has been released
self.motd_actived_time = 0;
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_MOTD);
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
}
}
}
WarpZone_PlayerPhysics_FixVAngle();
self.stat_game_starttime = game_starttime;
+ self.stat_round_starttime = round_starttime;
self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
self.stat_leadlimit = autocvar_leadlimit;
- if(g_arena || (g_ca && !allowed_to_spawn))
- self.stat_respawn_time = 0;
- else
- self.stat_respawn_time = self.respawn_time;
+ self.stat_respawn_time = self.respawn_time;
if(frametime)
{
{
// notify release users if connecting to git
dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
- sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
}
else
{
{
// give users new version
dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n");
- sprint(self, strcat("\{1}^1NOTE: ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
}
else if(r > 0)
{
// notify users about old server version
print("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n");
- sprint(self, strcat("\{1}^1NOTE: ^7the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, self.cvar_g_xonoticversion);
}
}
}
// GOD MODE info
if(!(self.flags & FL_GODMODE)) if(self.max_armorvalue)
{
- sprint(self, strcat("godmode saved you ", ftos(self.max_armorvalue), " units of damage, cheater!\n"));
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_GODMODE_OFF, self.max_armorvalue);
self.max_armorvalue = 0;
}
//sprint(self, "distance: ", ftos(self.lms_traveled_distance), "\n");
if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance)
{
- centerprint(self, autocvar_g_lms_campcheck_message);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_CAMPCHECK);
// FIXME KadaverJack: gibbing player here causes playermodel to bounce around, instead of eye.md3
// I wasn't able to find out WHY that happens, so I put a workaround in place that shall prevent players from being gibbed :(
Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0');
{
if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10
{
- if(self.idlekick_lasttimeleft)
- {
- Send_CSQC_Centerprint_Generic_Expire(self, CPID_DISCONNECT_IDLING);
- self.idlekick_lasttimeleft = 0;
- }
+ if(self.idlekick_lasttimeleft) { self.idlekick_lasttimeleft = 0; }
}
else
{
if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10
{
if(!self.idlekick_lasttimeleft)
- Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_DISCONNECT_IDLING, timeleft);
}
if(timeleft <= 0)
{
- bprint("^3", self.netname, "^3 was kicked for idling.\n");
- AnnounceTo(self, "terminated");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_KICK_IDLING, self.netname);
dropclient(self);
return;
}
}
void ClientKill_Now_TeamChange();
-void freezetag_CheckWinner();
void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
float valid_damage_for_weaponstats;
float excess;
- if((g_arena && numspawned < 2) || (g_ca && allowed_to_spawn) && !inWarmupStage)
- return;
-
dh = max(self.health, 0);
da = max(self.armorvalue, 0);
{
self.pain_finished = time + 0.5; //Supajoe
- if(sv_gentle < 1) {
+ if(autocvar_sv_gentle < 1) {
if(self.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
{
if (!self.animstate_override)
if(valid_damage_for_weaponstats)
WeaponStats_LogKill(awep, abot, self.weapon, vbot);
- if(sv_gentle < 1) // TODO make a "gentle" version?
+ if(autocvar_sv_gentle < 1) // TODO make a "gentle" version?
if(sound_allowed(MSG_BROADCAST, attacker))
{
if(deathtype == DEATH_DROWN)
}
}
- if(!g_freezetag)
- {
- // become fully visible
- self.alpha = default_player_alpha;
- // throw a weapon
- SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
- }
-
// print an obituary message
Obituary (attacker, inflictor, self, deathtype);
race_PreDie();
if(accuracy_isgooddamage(attacker, self))
attacker.accuracy.(accuracy_frags[w-1]) += 1;
- if(deathtype == DEATH_HURTTRIGGER && g_freezetag)
- {
- PutClientInServer();
- count_alive_players(); // re-count players
- freezetag_CheckWinner();
- return;
- }
-
frag_attacker = attacker;
frag_inflictor = inflictor;
frag_target = self;
+ frag_deathtype = deathtype;
MUTATOR_CALLHOOK(PlayerDies);
+
weapon_action(self.weapon, WR_PLAYERDEATH);
RemoveGrapplingHook(self);
//WriteAngle (MSG_ONE, 80);
}
- if(defer_ClientKill_Now_TeamChange) // TODO does this work with FreezeTag?
- ClientKill_Now_TeamChange();
-
- if(g_arena)
- Spawnqueue_Unmark(self);
+ if(defer_ClientKill_Now_TeamChange)
+ ClientKill_Now_TeamChange(); // can turn player into spectator
- if(g_freezetag)
+ // player could have been miraculously resuscitated ;)
+ // e.g. players in freezetag get frozen, they don't really die
+ if(self.health >= 1 || self.classname != "player")
return;
// when we get here, player actually dies
- // clear waypoints (do this AFTER FreezeTag)
+
+ // clear waypoints
WaypointSprite_PlayerDead();
+ // throw a weapon
+ SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
+ // become fully visible
+ self.alpha = default_player_alpha;
// make the corpse upright (not tilted)
self.angles_x = 0;
self.angles_z = 0;
// set up to fade out later
SUB_SetFade (self, time + 6 + random (), 1);
- if(sv_gentle > 0 || autocvar_ekg) {
+ if(autocvar_sv_gentle > 0 || autocvar_ekg) {
// remove corpse
PlayerCorpseDamage (inflictor, attacker, autocvar_sv_gibhealth+1.0, deathtype, hitloc, force);
}
if(sourcecmsgstr != "" && !privatesay)
centerprint(source, sourcecmsgstr);
}
- else if(privatesay) // private message, between 2 people only, not sent to server console
+ else if(privatesay) // private message, between 2 people only
{
sprint(source, sourcemsgstr);
sprint(privatesay, msgstr);
+ if not(autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
if(cmsgstr != "")
centerprint(privatesay, cmsgstr);
}
else if(teamsay > 0) // team message, only sent to team mates
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
if(sourcecmsgstr != "")
centerprint(source, sourcecmsgstr);
FOR_EACH_REALPLAYER(head) if(head.team == source.team)
else if(teamsay < 0) // spectator message, only sent to spectators
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
FOR_EACH_REALCLIENT(head) if(head.classname != "player")
if(head != source)
sprint(head, msgstr);
else if(sourcemsgstr != msgstr) // trimmed/server fixed message, sent to all players
{
sprint(source, sourcemsgstr);
- //print(msgstr); // send to server console too
+ dedicated_print(msgstr); // send to server console too
FOR_EACH_REALCLIENT(head)
if(head != source)
sprint(head, msgstr);
break;
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
tauntrand = random();
msg_entity = self;
animdecide_setaction(self, ANIMACTION_TAUNT, TRUE);
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
msg_entity = self;
if (msg_entity.cvar_cl_voice_directional >= 1)
break;
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
tauntrand = random();
FOR_EACH_REALCLIENT(msg_entity)
animdecide_setaction(self, ANIMACTION_TAUNT, TRUE);
if(!sv_taunt)
break;
- if(sv_gentle)
+ if(autocvar_sv_gentle)
break;
FOR_EACH_REALCLIENT(msg_entity)
{
FakeGlobalSound(self.sample, CH_VOICE, voicetype);
}
- void MoveToTeam(entity client, float team_colour, float type, float show_message)
+ void MoveToTeam(entity client, float team_colour, float type)
{
- // show_message
- // 0 (00) automove centerprint, admin message
- // 1 (01) automove centerprint, no admin message
- // 2 (10) no centerprint, admin message
- // 3 (11) no centerprint, no admin message
-
float lockteams_backup;
lockteams_backup = lockteams; // backup any team lock
TeamchangeFrags(client); // move the players frags
SetPlayerColors(client, team_colour - 1); // set the players colour
- Damage(client, client, client, 100000, ((show_message & 2) ? DEATH_QUIET : DEATH_AUTOTEAMCHANGE), client.origin, '0 0 0'); // kill the player
+ Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE, client.origin, '0 0 0'); // kill the player
lockteams = lockteams_backup; // restore the team lock
LogTeamchange(client.playerid, client.team, type);
-
- if not(show_message & 1) // admin message
- sprint(client, strcat("\{1}\{13}^3", admin_name(), "^7: You have been moved to the ", Team_ColorNameLowerCase(team_colour), " team\n")); // send a chat message
-
- bprint(strcat(client.netname, " joined the ", ColoredTeamName(client.team), "\n"));
}
return (get_weaponinfo(wpn)).weapon_func(wrequest);
}
- string W_Name(float weaponid)
- {
- return (get_weaponinfo(weaponid)).message;
- }
-
- float W_AmmoItemCode(float wpn)
- {
- return (get_weaponinfo(wpn)).items & IT_AMMO;
- }
-
.float savenextthink;
void thrown_wep_think()
{
return 0;
if (g_lms)
return 0;
- if (g_ca)
- return 0;
if (g_cts)
return 0;
if (g_nexball && w == WEP_GRENADE_LAUNCHER)
W_SwitchWeapon_Force(self, w_getbestweapon(self));
a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo);
- if not(a)
- return;
- if(a == "")
- sprint(self, strcat("You dropped the ^2", W_Name(w), "\n"));
- else
- sprint(self, strcat("You dropped the ^2", W_Name(w), " with ", a, "\n"));
+
+ if not(a) return;
+ Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_WEAPON_DROP, a, w);
}
-// Bringed back weapon frame
+float forbidWeaponUse()
+{
+ if(time < game_starttime && !autocvar_sv_ready_restart_after_countdown)
+ return 1;
+ if(round_handler_IsActive() && !round_handler_IsRoundStarted())
+ return 1;
+ if(self.player_blocked)
+ return 1;
+ if(self.freezetag_frozen)
+ return 1;
+ return 0;
+}
+
void W_WeaponFrame()
{
vector fo, ri, up;
if (frametime)
self.weapon_frametime = frametime;
- if(((arena_roundbased || g_ca || g_freezetag) && time < warmup) || ((time < game_starttime) && !autocvar_sv_ready_restart_after_countdown))
- return;
-
- if(self.freezetag_frozen == 1)
- return;
-
if (!self.weaponentity || self.health < 1)
return; // Dead player can't use weapons and injure impulse commands
+ if(forbidWeaponUse())
+ if(self.weaponentity.state != WS_CLEAR)
+ {
+ w_ready();
+ return;
+ }
+
if(!self.switchweapon)
{
self.weapon = 0;
{
if(nJoinAllowed(self))
{
- if(g_ca) { self.caplayer = 1; }
if(autocvar_g_campaign) { campaign_bots_may_start = 1; }
-
+
self.classname = "player";
PlayerScore_Clear(self);
- bprint ("^4", self.netname, "^4 is playing now\n");
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD);
+ Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname);
PutClientInServer();
}
else
{
//player may not join because of g_maxplayers is set
- centerprint(self, PREVENT_JOIN_TEXT);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_PREVENT_JOIN);
}
}
}
{
if(!readyrestart_happened || autocvar_sv_ready_restart_repeatable)
{
+ if(time < game_starttime + 1) // game is already restarting
+ return;
if (self.ready) // toggle
{
self.ready = FALSE;
switch(argv(1))
{
- case "red": selection = COLOR_TEAM1; break;
- case "blue": selection = COLOR_TEAM2; break;
- case "yellow": selection = COLOR_TEAM3; break;
- case "pink": selection = COLOR_TEAM4; break;
+ case "red": selection = NUM_TEAM_1; break;
+ case "blue": selection = NUM_TEAM_2; break;
+ case "yellow": selection = NUM_TEAM_3; break;
+ case "pink": selection = NUM_TEAM_4; break;
case "auto": selection = (-1); break;
default: selection = 0; break;
{
if(self.lms_spectate_warning)
{
+ // for the forfeit message...
+ self.lms_spectate_warning = 2;
// mark player as spectator
PlayerScore_Add(self, SP_LMS_RANK, 666 - PlayerScore_Add(self, SP_LMS_RANK, 0));
}
if(self.classname == "player" && autocvar_sv_spectate == 1)
ClientKill_TeamChange(-2); // observe
-
+
// in CA, allow a dead player to move to spectators (without that, caplayer!=0 will be moved back to the player list)
// note: if arena game mode is ever done properly, this needs to be removed.
- if(g_ca && self.caplayer && (self.classname == "spectator" || self.classname == "observer"))
+ if(self.caplayer && (self.classname == "spectator" || self.classname == "observer"))
{
sprint(self, "WARNING: you will spectate in the next round.\n");
self.caplayer = 0;
float g_jetpack;
float sv_clones;
- float sv_gentle;
float sv_foginterval;
entity activator;
float maxclients;
+ // flag set on worldspawn so that the code knows if it is dedicated or not
+ float server_is_dedicated;
+
// Fields
.void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) event_damage;
void weapon_defaultspawnfunc(float wpn);
- string w_deathtypestring;
-
.vector dest1, dest2;
float gameover;
.entity flagcarried;
- .entity lastrocket;
-
.float playerid;
float playerid_last;
.float noalign; // if set to 1, the item or spawnpoint won't be dropped to the floor
string cvar_purechanges;
float cvar_purechanges_count;
-float game_starttime; //point in time when the countdown is over
+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 stat_game_starttime;
+.float stat_round_starttime;
.float stat_sv_airaccel_qw;
.float stat_sv_airstrafeaccel_qw;
.float clip_load;
.float old_clip_load;
.float clip_size;
+
+ .entity lastrocket;
.float minelayer_mines;
+ .float nex_charge;
+ .float nex_charge_rottime;
+ .float nex_chargepool_ammo;
+ .float hagar_load;
.float grab; // 0 = can't grab, 1 = owner can grab, 2 = owner and team mates can grab, 3 = anyone can grab
.void (float act_state) setactive;
.entity realowner;
- .float nex_charge;
- .float nex_charge_rottime;
- .float nex_chargepool_ammo;
-
- .float hagar_load;
-float allowed_to_spawn; // boolean variable used by the clan arena code to determine if a player can spawn (after the round has ended)
--
float serverflags;
.float team_forced; // can be a team number to force a team, or 0 for default action, or -1 for forced spectator
.float player_blocked;
.float freezetag_frozen;
-.float freezetag_revive_progress;
.entity muzzle_flash;
.float misc_bulletcounter; // replaces uzi & hlac bullet counter.
PlayerScore_Add(targ, SP_DEATHS, 1);
- if(g_arena || g_ca)
- if(autocvar_g_arena_roundbased)
- return;
-
if(targ != attacker) // not for suicides
if(g_weaponarena_random)
{
UpdateFrags(attacker, f);
}
- string Obituary_ExtraFragInfo(entity player) // Extra fragmessage information
- {
- string health_output = string_null;
- string ping_output = string_null;
- string handicap_output = string_null;
- string output = string_null;
-
- if(autocvar_sv_fraginfo && ((autocvar_sv_fraginfo == 2) || inWarmupStage))
- {
- // health/armor of attacker (person who killed you)
- if(autocvar_sv_fraginfo_stats && (player.health >= 1))
- health_output = strcat("^7(Health ^1", ftos(rint(player.health)), "^7 / Armor ^2", ftos(rint(player.armorvalue)), "^7)");
-
- // ping display
- if(autocvar_sv_fraginfo_ping)
- ping_output = ((clienttype(player) == CLIENTTYPE_BOT) ? "^2Bot" : strcat("Ping ", ((player.ping >= 150) ? "^1" : "^2"), ftos(rint(player.ping)), "ms"));
-
- // handicap display
- if(autocvar_sv_fraginfo_handicap)
- {
- if(autocvar_sv_fraginfo_handicap == 2)
- handicap_output = strcat(output, strcat("Handicap ^2", ((player.cvar_cl_handicap <= 1) ? "Off" : ftos(rint(player.cvar_cl_handicap)))));
- else if(player.cvar_cl_handicap) // with _handicap 1, only show this if there actually is a handicap enabled.
- handicap_output = strcat("Handicap ^2", ftos(rint(player.cvar_cl_handicap)));
- }
-
- // format the string
- output = strcat(health_output, (health_output ? ((ping_output || handicap_output) ? " ^7(" : "") : ((ping_output || handicap_output) ? "^7(" : "")),
- ping_output, (handicap_output ? "^7 / " : ""),
- handicap_output, ((ping_output || handicap_output) ? "^7)" : ""));
-
- // add new line to the beginning if there is a message
- if(output) { output = strcat("\n", output); }
- }
-
- return output;
- }
-
string AppendItemcodes(string s, entity player)
{
float w;
s = strcat(":kill:", mode);
s = strcat(s, ":", ftos(killer.playerid));
s = strcat(s, ":", ftos(killed.playerid));
- s = strcat(s, ":type=", ftos(deathtype));
+ s = strcat(s, ":type=", Deathtype_Name(deathtype));
s = strcat(s, ":items=");
s = AppendItemcodes(s, killer);
if(killed != killer)
GameLogEcho(s);
}
- void Send_KillNotification (string s1, string s2, string s3, float msg, float type)
+ void Obituary_SpecialDeath(
+ entity notif_target,
+ float murder,
+ float deathtype,
+ string s1, string s2, string s3,
+ float f1, float f2, float f3)
{
- WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
- WriteByte(MSG_BROADCAST, TE_CSQC_KILLNOTIFY);
- WriteString(MSG_BROADCAST, s1);
- WriteString(MSG_BROADCAST, s2);
- WriteString(MSG_BROADCAST, s3);
- WriteShort(MSG_BROADCAST, msg);
- WriteByte(MSG_BROADCAST, type);
+ if(DEATH_ISSPECIAL(deathtype))
+ {
+ entity deathent = deathtypes[(deathtype - DT_FIRST) - 1];
+ if not(deathent) { backtrace("Obituary_SpecialDeath: Could not find deathtype entity!\n"); return; }
+
+ if(murder)
+ {
+ if(deathent.death_msgmurder)
+ {
+ Send_Notification_WOVA(
+ NOTIF_ONE,
+ notif_target,
+ MSG_MULTI,
+ deathent.death_msgmurder.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ Send_Notification_WOVA(
+ NOTIF_ALL_EXCEPT,
+ notif_target,
+ MSG_INFO,
+ deathent.death_msgmurder.nent_msginfo.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ }
+ }
+ else
+ {
+ if(deathent.death_msgself)
+ {
+ Send_Notification_WOVA(
+ NOTIF_ONE,
+ notif_target,
+ MSG_MULTI,
+ deathent.death_msgself.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ Send_Notification_WOVA(
+ NOTIF_ALL_EXCEPT,
+ notif_target,
+ MSG_INFO,
+ deathent.death_msgself.nent_msginfo.nent_id,
+ s1, s2, s3, "",
+ f1, f2, f3, 0
+ );
+ }
+ }
+ }
+ else { backtrace("Obituary_SpecialDeath called without a special deathtype?\n"); return; }
}
- // Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
- void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
+ float w_deathtype;
+ float Obituary_WeaponDeath(
+ entity notif_target,
+ float murder,
+ float deathtype,
+ string s1, string s2, string s3,
+ float f1, float f2)
{
- if (clienttype(e) == CLIENTTYPE_REAL)
+ float death_weapon = DEATH_WEAPONOF(deathtype);
+ if(death_weapon)
{
- msg_entity = e;
- WRITESPECTATABLE_MSG_ONE({
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
- WriteString(MSG_ONE, s1);
- WriteString(MSG_ONE, s2);
- WriteShort(MSG_ONE, msg);
- WriteByte(MSG_ONE, type);
- });
+ w_deathtype = deathtype;
+ float death_message = weapon_action(death_weapon, ((murder) ? WR_KILLMESSAGE : WR_SUICIDEMESSAGE));
+ w_deathtype = FALSE;
+
+ if(death_message)
+ {
+ Send_Notification_WOVA(
+ NOTIF_ONE,
+ notif_target,
+ MSG_MULTI,
+ death_message,
+ s1, s2, s3, "",
+ f1, f2, 0, 0
+ );
+ Send_Notification_WOVA(
+ NOTIF_ALL_EXCEPT,
+ notif_target,
+ MSG_INFO,
+ msg_multi_notifs[death_message - 1].nent_msginfo.nent_id,
+ s1, s2, s3, "",
+ f1, f2, 0, 0
+ );
+ }
+ else
+ {
+ dprint(sprintf(
+ "Obituary_WeaponDeath(): ^1Deathtype ^7(%d)^1 has no notification for weapon %d!\n",
+ deathtype,
+ death_weapon
+ ));
+ }
+
+ return TRUE;
}
+ return FALSE;
}
- void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
+ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
{
- string s, a, msg;
- float type;
-
- if (targ.classname == "player")
+ // Sanity check
+ if not(IS_PLAYER(targ)) { backtrace("Obituary called on non-player?!\n"); return; }
+
+ // Declarations
+ float notif_firstblood = FALSE;
+ float kill_count_to_attacker, kill_count_to_target;
+
+ // Set final information for the death
+ targ.death_origin = targ.origin;
+ if(targ != attacker) { targ.killer_origin = attacker.origin; }
+ string deathlocation = (autocvar_notification_server_allows_location ? NearestLocation(targ.death_origin) : "");
+
+ #ifdef NOTIFICATIONS_DEBUG
+ dprint(
+ sprintf(
+ "Obituary(%s, %s, %s, %s = %d);\n",
+ attacker.netname,
+ inflictor.netname,
+ targ.netname,
+ Deathtype_Name(deathtype),
+ deathtype
+ )
+ );
+ #endif
+
+ // =======
+ // SUICIDE
+ // =======
+ if(targ == attacker)
{
- s = targ.netname;
- a = attacker.netname;
-
- if (targ == attacker) // suicides
+ if(DEATH_ISSPECIAL(deathtype))
{
- if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
- msg = ColoredTeamName(targ.team); // TODO: check if needed?
- else
- msg = "";
- if(!g_cts) // no "killed your own dumb self" message in CTS
- Send_CSQC_KillCenterprint(targ, msg, "", deathtype, MSG_SUICIDE);
-
- if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET)
+ if(deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
{
- LogDeath("suicide", deathtype, targ, targ);
- GiveFrags(attacker, targ, -1, deathtype);
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.team, 0, 0);
}
-
- if (targ.killcount > 2)
- msg = ftos(targ.killcount);
else
- msg = "";
- if(teamplay && deathtype == DEATH_MIRRORDAMAGE)
{
- if(attacker.team == COLOR_TEAM1)
- deathtype = KILL_TEAM_RED;
- else
- deathtype = KILL_TEAM_BLUE;
+ switch(deathtype)
+ {
+ case DEATH_MIRRORDAMAGE:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ break;
+ }
+
+ default:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ break;
+ }
+ }
}
-
- Send_KillNotification(s, msg, "", deathtype, MSG_SUICIDE);
}
- else if (attacker.classname == "player")
+ else if not(Obituary_WeaponDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0))
{
- if(!IsDifferentTeam(attacker, targ))
- {
- if(attacker.team == COLOR_TEAM1)
- type = KILL_TEAM_RED;
- else
- type = KILL_TEAM_BLUE;
-
- GiveFrags(attacker, targ, -1, deathtype);
+ backtrace("SUICIDE: what the hell happened here?\n");
+ return;
+ }
+ LogDeath("suicide", deathtype, targ, targ);
+ GiveFrags(attacker, targ, -1, deathtype);
+ }
- Send_CSQC_KillCenterprint(attacker, s, "", type, MSG_KILL);
+ // ======
+ // MURDER
+ // ======
+ else if(IS_PLAYER(attacker))
+ {
+ if(!IsDifferentTeam(attacker, targ))
+ {
+ LogDeath("tk", deathtype, attacker, targ);
+ GiveFrags(attacker, targ, -1, deathtype);
- if (targ.killcount > 2)
- msg = ftos(targ.killcount);
- else
- msg = "";
+ attacker.killcount = 0;
+
+ 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.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, targ.killcount);
- if (attacker.killcount > 2) {
- msg = ftos(attacker.killcount);
- type = KILL_TEAM_SPREE;
+ // In this case, the death message will ALWAYS be "foo was betrayed by bar"
+ // No need for specific death/weapon messages...
+ }
+ else
+ {
+ LogDeath("frag", deathtype, attacker, targ);
+ GiveFrags(attacker, targ, 1, deathtype);
+
+ attacker.taunt_soundtime = time + 1;
+ attacker.killcount = attacker.killcount + 1;
+
+ #define SPREE_ITEM(counta,countb,center,normal,gentle) \
+ case counta: \
+ { \
+ AnnounceTo(attacker, strcat(#countb, "kills")); \
+ PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
+ break; \
}
- Send_KillNotification(a, s, msg, type, MSG_KILL);
-
- attacker.killcount = 0;
+ switch(attacker.killcount)
+ {
+ KILL_SPREE_LIST
+ default: break;
+ }
+ #undef SPREE_ITEM
- LogDeath("tk", deathtype, attacker, targ);
+ if(!checkrules_firstblood)
+ {
+ checkrules_firstblood = TRUE;
+ notif_firstblood = TRUE; // modify the current messages so that they too show firstblood information
+ PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
+ PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
+
+ // tell spree_inf and spree_cen that this is a first-blood and first-victim event
+ kill_count_to_attacker = -1;
+ kill_count_to_target = -2;
}
else
{
- if (!checkrules_firstblood)
- {
- checkrules_firstblood = TRUE;
- Send_KillNotification(a, "", "", KILL_FIRST_BLOOD, MSG_KILL);
- // TODO: make these print a newline if they dont
- Send_CSQC_KillCenterprint(attacker, "", "", KILL_FIRST_BLOOD, MSG_KILL);
- Send_CSQC_KillCenterprint(targ, "", "", KILL_FIRST_VICTIM, MSG_KILL);
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
- PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
- }
-
- if(targ.istypefrag) {
- Send_CSQC_KillCenterprint(attacker, s, Obituary_ExtraFragInfo(targ), KILL_TYPEFRAG, MSG_KILL);
- Send_CSQC_KillCenterprint(targ, a, Obituary_ExtraFragInfo(attacker), KILL_TYPEFRAGGED, MSG_KILL);
- } else {
- Send_CSQC_KillCenterprint(attacker, s, Obituary_ExtraFragInfo(targ), KILL_FRAG, MSG_KILL);
- Send_CSQC_KillCenterprint(targ, a, Obituary_ExtraFragInfo(attacker), KILL_FRAGGED, MSG_KILL);
- }
-
- attacker.taunt_soundtime = time + 1;
+ kill_count_to_attacker = attacker.killcount;
+ kill_count_to_target = 0;
+ }
- if (deathtype == DEATH_HURTTRIGGER && inflictor.message2 != "")
- msg = inflictor.message2;
- else if (deathtype == DEATH_CUSTOM)
- msg = deathmessage;
+ float verbose_allowed = (autocvar_notification_server_allows_frag_verbose && ((autocvar_notification_server_allows_frag_verbose == 2) || inWarmupStage));
+ if(targ.istypefrag)
+ {
+ if(attacker.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping));
else
- msg = "";
-
- if(strstrofs(msg, "%", 0) < 0)
- msg = strcat("%s ", msg, " by %s");
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAG, targ.netname, kill_count_to_attacker);
- Send_KillNotification(a, s, msg, deathtype, MSG_KILL);
+ if(targ.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping));
+ else
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_TYPEFRAGGED, attacker.netname, kill_count_to_target);
+ }
+ else
+ {
+ if(attacker.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_FRAG_VERBOSE, targ.netname, kill_count_to_attacker, (IS_BOT_CLIENT(targ) ? NO_MSG : targ.ping));
+ else
+ Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_MURDER_FRAG, targ.netname, kill_count_to_attacker);
- GiveFrags(attacker, targ, 1, deathtype);
+ if(targ.FRAG_VERBOSE && verbose_allowed)
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED_VERBOSE, attacker.netname, kill_count_to_target, attacker.health, attacker.armorvalue, (IS_BOT_CLIENT(attacker) ? NO_MSG : attacker.ping));
+ else
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_MURDER_FRAGGED, attacker.netname, kill_count_to_target);
+ }
- if (targ.killcount > 2) {
- Send_KillNotification(s, ftos(targ.killcount), a, KILL_END_SPREE, MSG_SPREE);
- }
+ if not(Obituary_WeaponDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker))
+ Obituary_SpecialDeath(targ, TRUE, deathtype, targ.netname, attacker.netname, deathlocation, targ.killcount, kill_count_to_attacker, 0);
+ }
+ }
- attacker.killcount = attacker.killcount + 1;
+ // =============
+ // ACCIDENT/TRAP
+ // =============
+ else
+ {
+ switch(deathtype)
+ {
+ // For now, we're just forcing HURTTRIGGER to behave as "DEATH_VOID" and giving it no special options...
+ // Later on you will only be able to make custom messages using DEATH_CUSTOM,
+ // and there will be a REAL DEATH_VOID implementation which mappers will use.
+ /*case DEATH_HURTTRIGGER:
+ {
+ s1 = targ.netname;
+ s2 = inflictor.message;
+ if(strstrofs(s2, "%", 0) < 0) { s2 = strcat("%s ", s2); }
+ break;
+ }*/
- if (attacker.killcount == 3)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_3, MSG_SPREE);
- AnnounceTo(attacker, "03kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3, 1);
- }
- else if (attacker.killcount == 5)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_5, MSG_SPREE);
- AnnounceTo(attacker, "05kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5, 1);
- }
- else if (attacker.killcount == 10)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_10, MSG_SPREE);
- AnnounceTo(attacker, "10kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10, 1);
- }
- else if (attacker.killcount == 15)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_15, MSG_SPREE);
- AnnounceTo(attacker, "15kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15, 1);
- }
- else if (attacker.killcount == 20)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_20, MSG_SPREE);
- AnnounceTo(attacker, "20kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20, 1);
- }
- else if (attacker.killcount == 25)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_25, MSG_SPREE);
- AnnounceTo(attacker, "25kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25, 1);
- }
- else if (attacker.killcount == 30)
- {
- Send_KillNotification(a, "", "", KILL_SPREE_30, MSG_SPREE);
- AnnounceTo(attacker, "30kills");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30, 1);
- }
- else if (attacker.killcount > 2) {
- Send_KillNotification(a, ftos(attacker.killcount), "", KILL_SPREE, MSG_SPREE);
- }
- LogDeath("frag", deathtype, attacker, targ);
+ case DEATH_CUSTOM:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype,
+ targ.netname,
+ ((strstrofs(deathmessage, "%", 0) < 0) ? strcat("%s ", deathmessage) : deathmessage),
+ deathlocation,
+ targ.killcount,
+ 0,
+ 0);
+ break;
}
- }
- else
- {
- Send_CSQC_KillCenterprint(targ, "", "", deathtype, MSG_KILL_ACTION);
- if (deathtype == DEATH_HURTTRIGGER && inflictor.message != "")
- msg = inflictor.message;
- else if (deathtype == DEATH_CUSTOM)
- msg = deathmessage;
- else
- msg = "";
- if(strstrofs(msg, "%", 0) < 0)
- msg = strcat("%s ", msg);
-
- GiveFrags(targ, targ, -1, deathtype);
- if(PlayerScore_Add(targ, SP_SCORE, 0) == -5) {
- AnnounceTo(targ, "botlike");
- PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+
+ default:
+ {
+ Obituary_SpecialDeath(targ, FALSE, deathtype, targ.netname, deathlocation, "", targ.killcount, 0, 0);
+ break;
}
- Send_KillNotification(s, msg, "", deathtype, MSG_KILL_ACTION);
-
- if (targ.killcount > 2)
- Send_KillNotification(s, ftos(targ.killcount), "", 0, MSG_KILL_ACTION_SPREE);
-
- LogDeath("accident", deathtype, targ, targ);
}
- targ.death_origin = targ.origin;
- if(targ != attacker)
- targ.killer_origin = attacker.origin;
+ LogDeath("accident", deathtype, targ, targ);
+ GiveFrags(targ, targ, -1, deathtype);
- // FIXME: this should go in PutClientInServer
- if (targ.killcount)
- targ.killcount = 0;
+ if(PlayerScore_Add(targ, SP_SCORE, 0) == -5)
+ {
+ AnnounceTo(targ, "botlike");
+ PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
+ }
}
+
+ // reset target kill count
+ if(targ.killcount) { targ.killcount = 0; }
}
// these are updated by each Damage call for use in button triggering and such
{
float mirrordamage;
float mirrorforce;
- float teamdamage0;
+ float complainteamdamage = 0;
entity attacker_save;
mirrordamage = 0;
mirrorforce = 0;
}
}
- if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE || deathtype == DEATH_QUIET)
+ if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
{
// These are ALWAYS lethal
// No damage modification here
{
if(targ.classname == "player" && targ.deadflag == DEAD_NO)
{
- teamdamage0 = max(attacker.dmg_team, autocvar_g_teamdamage_threshold);
attacker.dmg_team = attacker.dmg_team + damage;
- if(attacker.dmg_team > teamdamage0 && !g_ca)
- mirrordamage = autocvar_g_mirrordamage * (attacker.dmg_team - teamdamage0);
+ complainteamdamage = attacker.dmg_team - autocvar_g_teamdamage_threshold;
+ if(complainteamdamage > 0 && !g_ca) // FIXME why is g_ca ruled out here? Why not just g_mirrordamage 0 on CA servers?
+ mirrordamage = autocvar_g_mirrordamage * complainteamdamage;
mirrorforce = autocvar_g_mirrordamage * vlen(force);
if(g_minstagib)
{
{
damage = 0;
mirrordamage = 0;
+ complainteamdamage = 0;
if (targ != attacker)
{
if ((targ.health >= 1) && (targ.classname == "player"))
{
damage *= g_weapondamagefactor;
mirrordamage *= g_weapondamagefactor;
+ complainteamdamage *= g_weapondamagefactor;
force = force * g_weaponforcefactor;
mirrorforce *= g_weaponforcefactor;
}
{
attacker.typehitsound += 1;
}
- if(mirrordamage > 0)
+ if(complainteamdamage > 0)
if(time > attacker.teamkill_complain)
{
attacker.teamkill_complain = time + 5;
BADCVAR("g_arena");
BADCVAR("g_assault");
BADCVAR("g_ca");
+ BADCVAR("g_ca_teams");
BADCVAR("g_ctf");
BADCVAR("g_cts");
BADCVAR("g_dm");
BADCVAR("g_domination");
BADCVAR("g_domination_default_teams");
BADCVAR("g_freezetag");
+ BADCVAR("g_freezetag_teams");
BADCVAR("g_keepaway");
BADCVAR("g_keyhunt");
BADCVAR("g_keyhunt_teams");
- BADCVAR("g_keyhunt_teams");
BADCVAR("g_lms");
BADCVAR("g_nexball");
BADCVAR("g_onslaught");
BADCVAR("g_balance_teams_scorefactor");
BADCVAR("g_ban_sync_trusted_servers");
BADCVAR("g_ban_sync_uri");
+ BADCVAR("g_ca_teams_override");
BADCVAR("g_ctf_ignore_frags");
BADCVAR("g_domination_point_limit");
+ BADCVAR("g_freezetag_teams_override");
BADCVAR("g_friendlyfire");
BADCVAR("g_fullbrightitems");
BADCVAR("g_fullbrightplayers");
// needs to be done so early because of the constants they create
CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+ CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
compressShortVector_init();
- allowed_to_spawn = TRUE;
-
entity head;
head = nextent(world);
maxclients = 0;
head = nextent(head);
}
+ server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? TRUE : FALSE);
+
// needs to be done so early because of the constants they create
CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
+ CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
+ addstat(STAT_ROUNDSTARTTIME, AS_FLOAT, stat_round_starttime);
addstat(STAT_ALLOW_OLDNEXBEAM, AS_INT, stat_allow_oldnexbeam);
Nagger_Init();
addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
- if(g_ca || g_freezetag)
- {
- addstat(STAT_REDALIVE, AS_INT, redalive_stat);
- addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
- addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
- addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
- }
- if(g_freezetag)
- {
- addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
- addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
- }
-
// g_movementspeed hack
addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
for(i = 0, j = 0; i < MapInfo_count; ++i)
{
if(MapInfo_Get_ByID(i))
- if not(MapInfo_Map_flags & (MAPINFO_FLAG_HIDDEN | MAPINFO_FLAG_FORBIDDEN))
+ if not(MapInfo_Map_flags & MapInfo_ForbiddenFlags())
{
if(mod(i, 2))
col = "^2";
{
s = strcat(":player:see-labels:", GetPlayerScoreString(other, 0), ":");
s = strcat(s, ftos(rint(time - other.jointime)), ":");
- if(other.classname == "player" || g_arena || g_ca || g_lms)
+ if(other.classname == "player" || g_arena || other.caplayer == 1 || g_lms)
s = strcat(s, ftos(other.team), ":");
else
s = strcat(s, "spectator:");
PlayerStats_Shutdown();
WeaponStats_Shutdown();
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now
+
if(autocvar_sv_eventlog)
GameLogEcho(":gameover");
tl = autocvar_timelimit;
tl += autocvar_timelimit_overtime;
cvar_set("timelimit", ftos(tl));
- string minutesPlural;
- if (autocvar_timelimit_overtime == 1)
- minutesPlural = " ^3minute";
- else
- minutesPlural = " ^3minutes";
-
- bcenterprint(
- strcat(
- "^3Now playing ^1OVERTIME^3!\n\n^3Added ^1",
- ftos(autocvar_timelimit_overtime),
- minutesPlural,
- " to the game!"
- )
- );
+
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_TIME, autocvar_timelimit_overtime);
}
float GetWinningCode(float fraglimitreached, float equality)
{
if (head.health > 0)
{
- if (head.team == COLOR_TEAM1) t1 = 1;
- if (head.team == COLOR_TEAM2) t2 = 1;
- if (head.team == COLOR_TEAM3) t3 = 1;
- if (head.team == COLOR_TEAM4) t4 = 1;
+ if (head.team == NUM_TEAM_1) t1 = 1;
+ if (head.team == NUM_TEAM_2) t2 = 1;
+ if (head.team == NUM_TEAM_3) t3 = 1;
+ if (head.team == NUM_TEAM_4) t4 = 1;
}
head = find(head, classname, "onslaught_generator");
}
{
// game over, only one team remains (or none)
ClearWinners();
- if (t1) SetWinners(team, COLOR_TEAM1);
- if (t2) SetWinners(team, COLOR_TEAM2);
- if (t3) SetWinners(team, COLOR_TEAM3);
- if (t4) SetWinners(team, COLOR_TEAM4);
+ if (t1) SetWinners(team, NUM_TEAM_1);
+ if (t2) SetWinners(team, NUM_TEAM_2);
+ if (t3) SetWinners(team, NUM_TEAM_3);
+ if (t4) SetWinners(team, NUM_TEAM_4);
dprint("Have a winner, ending game.\n");
return WINNING_YES;
}
status = WINNING_NO;
// as the timelimit has not yet passed just assume the defending team will win
- if(assault_attacker_team == COLOR_TEAM1)
+ if(assault_attacker_team == NUM_TEAM_1)
{
- SetWinners(team, COLOR_TEAM2);
+ SetWinners(team, NUM_TEAM_2);
}
else
{
- SetWinners(team, COLOR_TEAM1);
+ SetWinners(team, NUM_TEAM_1);
}
entity ent;
if(teamplay)
{
- team1_score = TeamScore_GetCompareValue(COLOR_TEAM1);
- team2_score = TeamScore_GetCompareValue(COLOR_TEAM2);
- team3_score = TeamScore_GetCompareValue(COLOR_TEAM3);
- team4_score = TeamScore_GetCompareValue(COLOR_TEAM4);
+ team1_score = TeamScore_GetCompareValue(NUM_TEAM_1);
+ team2_score = TeamScore_GetCompareValue(NUM_TEAM_2);
+ team3_score = TeamScore_GetCompareValue(NUM_TEAM_3);
+ team4_score = TeamScore_GetCompareValue(NUM_TEAM_4);
}
ClearWinners();
FOR_EACH_PLAYER(head) if(head.deadflag == DEAD_NO)
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
team1_score = 1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
team2_score = 1;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
team3_score = 1;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
team4_score = 1;
}
for(head = world; (head = find(head, classname, "info_player_deathmatch")) != world; )
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
team1_score = 1;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
team2_score = 1;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
team3_score = 1;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
team4_score = 1;
}
{
float t, i;
if(team1_score)
- t = COLOR_TEAM1;
+ t = NUM_TEAM_1;
else if(team2_score)
- t = COLOR_TEAM2;
+ t = NUM_TEAM_2;
else if(team3_score)
- t = COLOR_TEAM3;
+ t = NUM_TEAM_3;
else // if(team4_score)
- t = COLOR_TEAM4;
+ t = NUM_TEAM_4;
CheckAllowedTeams(world);
for(i = 0; i < MAX_TEAMSCORE; ++i)
{
- if(t != COLOR_TEAM1) if(c1 >= 0) TeamScore_AddToTeam(COLOR_TEAM1, i, -1000);
- if(t != COLOR_TEAM2) if(c2 >= 0) TeamScore_AddToTeam(COLOR_TEAM2, i, -1000);
- if(t != COLOR_TEAM3) if(c3 >= 0) TeamScore_AddToTeam(COLOR_TEAM3, i, -1000);
- if(t != COLOR_TEAM4) if(c4 >= 0) TeamScore_AddToTeam(COLOR_TEAM4, i, -1000);
+ if(t != NUM_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(NUM_TEAM_1, i, -1000);
+ if(t != NUM_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(NUM_TEAM_2, i, -1000);
+ if(t != NUM_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(NUM_TEAM_3, i, -1000);
+ if(t != NUM_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(NUM_TEAM_4, i, -1000);
}
AddWinners(team, t);
{
checkrules_suddendeathwarning = TRUE;
if(g_race && !g_race_qualifying)
- bcenterprint("^3Everyone, finish your lap! The race is over!");
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_RACE_FINISHLAP);
else
- bcenterprint("^3Now playing ^1OVERTIME^3!\n\n^3Keep fragging until we have a ^1winner^3!");
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_FRAG);
}
}
else
void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
void() spawnpoint_use;
string GetMapname();
- string ColoredTeamName(float t);
string admin_name(void)
{
#define move_out_of_solid(e) WarpZoneLib_MoveOutOfSolid(e)
-
string STR_PLAYER = "player";
string STR_SPECTATOR = "spectator";
string STR_OBSERVER = "observer";
- #if 0
- #define FOR_EACH_CLIENT(v) for(v = world; (v = findflags(v, flags, FL_CLIENT)) != world; )
- #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(clienttype(v) == CLIENTTYPE_REAL)
- #define FOR_EACH_PLAYER(v) for(v = world; (v = find(v, classname, STR_PLAYER)) != world; )
- #define FOR_EACH_REALPLAYER(v) FOR_EACH_PLAYER(v) if(clienttype(v) == CLIENTTYPE_REAL)
- #else
+ #define IS_PLAYER(v) (v.classname == STR_PLAYER)
+ #define IS_SPEC(v) (v.classname == STR_SPECTATOR)
+ #define IS_OBSERVER(v) (v.classname == STR_OBSERVER)
+ #define IS_CLIENT(v) (v.flags & FL_CLIENT)
+ #define IS_BOT_CLIENT(v) (clienttype(v) == CLIENTTYPE_BOT)
+ #define IS_REAL_CLIENT(v) (clienttype(v) == CLIENTTYPE_REAL)
+ #define IS_NOT_A_CLIENT(v) (clienttype(v) == CLIENTTYPE_NOTACLIENT)
+
#define FOR_EACH_CLIENTSLOT(v) for(v = world; (v = nextent(v)) && (num_for_edict(v) <= maxclients); )
- #define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(v.flags & FL_CLIENT)
- #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(clienttype(v) == CLIENTTYPE_REAL)
- #define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(v.classname == STR_PLAYER)
- #define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if(v.classname != STR_PLAYER)
- #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(v.classname == STR_PLAYER)
- #endif
+ #define FOR_EACH_CLIENT(v) FOR_EACH_CLIENTSLOT(v) if(IS_CLIENT(v))
+ #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(IS_REAL_CLIENT(v))
+
+ #define FOR_EACH_PLAYER(v) FOR_EACH_CLIENT(v) if(IS_PLAYER(v))
+ #define FOR_EACH_SPEC(v) FOR_EACH_CLIENT(v) if not(IS_PLAYER(v)) // Samual: shouldn't this be IS_SPEC(v)? and rather create a separate macro to include observers too
+ #define FOR_EACH_REALPLAYER(v) FOR_EACH_REALCLIENT(v) if(IS_PLAYER(v))
- #define CENTER_OR_VIEWOFS(ent) (ent.origin + ((ent.classname == STR_PLAYER) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
+ #define CENTER_OR_VIEWOFS(ent) (ent.origin + (IS_PLAYER(ent) ? ent.view_ofs : ((ent.mins + ent.maxs) * 0.5)))
// copies a string to a tempstring (so one can strunzone it)
string strcat1(string s) = #115; // FRIK_FILE
float logfile_open;
float logfile;
- void bcenterprint(string s)
- {
- // TODO replace by MSG_ALL (would show it to spectators too, though)?
- entity head;
- FOR_EACH_PLAYER(head)
- if (clienttype(head) == CLIENTTYPE_REAL)
- centerprint(head, s);
- }
-
void GameLogEcho(string s)
{
string fn;
get_cvars_f = f;
get_cvars_s = s;
+
MUTATOR_CALLHOOK(GetCvars);
+
+ Notification_GetCvars();
+
GetCvars_handleFloat(s, f, autoswitch, "cl_autoswitch");
GetCvars_handleFloat(s, f, cvar_cl_autoscreenshot, "cl_autoscreenshot");
GetCvars_handleString(s, f, cvar_g_xonoticversion, "g_xonoticversion");
}
}
- void backtrace(string msg)
- {
- float dev, war;
- dev = autocvar_developer;
- war = autocvar_prvm_backtraceforwarnings;
- cvar_set("developer", "1");
- cvar_set("prvm_backtraceforwarnings", "1");
- print("\n");
- print("--- CUT HERE ---\nWARNING: ");
- print(msg);
- print("\n");
- remove(world); // isn't there any better way to cause a backtrace?
- print("\n--- CUT UNTIL HERE ---\n");
- cvar_set("developer", ftos(dev));
- cvar_set("prvm_backtraceforwarnings", ftos(war));
- }
-
- string Team_ColorCode(float teamid)
- {
- if (teamid == COLOR_TEAM1)
- return "^1";
- else if (teamid == COLOR_TEAM2)
- return "^4";
- else if (teamid == COLOR_TEAM3)
- return "^3";
- else if (teamid == COLOR_TEAM4)
- return "^6";
- else
- return "^7";
- }
-
- string Team_ColorName(float t)
- {
- // fixme: Search for team entities and get their .netname's!
- if (t == COLOR_TEAM1)
- return "Red";
- if (t == COLOR_TEAM2)
- return "Blue";
- if (t == COLOR_TEAM3)
- return "Yellow";
- if (t == COLOR_TEAM4)
- return "Pink";
- return "Neutral";
- }
-
- string Team_ColorNameLowerCase(float t)
- {
- // fixme: Search for team entities and get their .netname's!
- if (t == COLOR_TEAM1)
- return "red";
- if (t == COLOR_TEAM2)
- return "blue";
- if (t == COLOR_TEAM3)
- return "yellow";
- if (t == COLOR_TEAM4)
- return "pink";
- return "neutral";
- }
-
- float ColourToNumber(string team_colour)
- {
- if (team_colour == "red")
- return COLOR_TEAM1;
-
- if (team_colour == "blue")
- return COLOR_TEAM2;
-
- if (team_colour == "yellow")
- return COLOR_TEAM3;
-
- if (team_colour == "pink")
- return COLOR_TEAM4;
-
- if (team_colour == "auto")
- return 0;
-
- return -1;
- }
-
- float NumberToTeamNumber(float number)
- {
- if (number == 1)
- return COLOR_TEAM1;
-
- if (number == 2)
- return COLOR_TEAM2;
-
- if (number == 3)
- return COLOR_TEAM3;
-
- if (number == 4)
- return COLOR_TEAM4;
-
- return -1;
- }
-
// decolorizes and team colors the player name when needed
string playername(entity p)
{
g_touchexplode_force = cvar("g_touchexplode_force");
sv_clones = cvar("sv_clones");
- sv_gentle = cvar("sv_gentle");
sv_foginterval = cvar("sv_foginterval");
g_cloaked = cvar("g_cloaked");
if(g_cts)
if(!g_weapon_stay)
g_weapon_stay = cvar("g_weapon_stay");
- if not(inWarmupStage && !g_ca)
+ if not(inWarmupStage)
game_starttime = cvar("g_start_delay");
readplayerstartcvars();
#endif
}
- // sorry, but using \ in macros breaks line numbers
- #define WRITESPECTATABLE_MSG_ONE_VARNAME(varname,statement) entity varname; varname = msg_entity; FOR_EACH_REALCLIENT(msg_entity) if(msg_entity == varname || (msg_entity.classname == STR_SPECTATOR && msg_entity.enemy == varname)) statement msg_entity = varname
- #define WRITESPECTATABLE_MSG_ONE(statement) WRITESPECTATABLE_MSG_ONE_VARNAME(oldmsg_entity, statement)
- #define WRITESPECTATABLE(msg,statement) if(msg == MSG_ONE) { WRITESPECTATABLE_MSG_ONE(statement); } else statement float WRITESPECTATABLE_workaround = 0
-
-
- void Send_CSQC_Centerprint_Generic(entity e, float id, string s, float duration, float countdown_num)
- {
- if ((clienttype(e) == CLIENTTYPE_REAL) && (e.flags & FL_CLIENT))
- {
- msg_entity = e;
- WRITESPECTATABLE_MSG_ONE({
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_CENTERPRINT_GENERIC);
- WriteByte(MSG_ONE, id);
- WriteString(MSG_ONE, s);
- if (id != 0 && s != "")
- {
- WriteByte(MSG_ONE, duration);
- WriteByte(MSG_ONE, countdown_num);
- }
- });
- }
- }
- void Send_CSQC_Centerprint_Generic_Expire(entity e, float id)
- {
- Send_CSQC_Centerprint_Generic(e, id, "", 1, 0);
- }
// WARNING: this kills the trace globals
#define EXACTTRIGGER_TOUCH if(WarpZoneLib_ExactTrigger_Touch()) return
#define EXACTTRIGGER_INIT WarpZoneLib_ExactTrigger_Init()
return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
}
- string race_placeName(float pos) {
- if(floor((mod(pos, 100))/10) * 10 != 10) // examples: 12th, 111th, 213th will not execute this block
- {
- if(mod(pos, 10) == 1)
- return strcat(ftos(pos), "st");
- else if(mod(pos, 10) == 2)
- return strcat(ftos(pos), "nd");
- else if(mod(pos, 10) == 3)
- return strcat(ftos(pos), "rd");
- else
- return strcat(ftos(pos), "th");
- }
- else
- return strcat(ftos(pos), "th");
- }
-
float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
{
float m, i;
-void freezetag_Initialize()
+.float freezetag_frozen_time;
+.float freezetag_frozen_timeout;
+.float freezetag_revive_progress;
+.entity freezetag_ice;
+#define ICE_MAX_ALPHA 1
+#define ICE_MIN_ALPHA 0.1
+float freezetag_teams;
+
+void freezetag_count_alive_players()
{
- precache_model("models/ice/ice.md3");
- warmup = time + autocvar_g_start_delay + autocvar_g_freezetag_warmup;
- ScoreRules_freezetag();
+ entity e;
+ total_players = redalive = bluealive = yellowalive = pinkalive = 0;
+ FOR_EACH_PLAYER(e) {
+ if(e.team == COLOR_TEAM1 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++redalive;
+ }
+ else if(e.team == COLOR_TEAM2 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++bluealive;
+ }
+ else if(e.team == COLOR_TEAM3 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++yellowalive;
+ }
+ else if(e.team == COLOR_TEAM4 && e.health >= 1)
+ {
+ ++total_players;
+ if (!e.freezetag_frozen) ++pinkalive;
+ }
+ }
+ FOR_EACH_REALCLIENT(e) {
+ e.redalive_stat = redalive;
+ e.bluealive_stat = bluealive;
+ e.yellowalive_stat = yellowalive;
+ e.pinkalive_stat = pinkalive;
+ }
}
+#define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
+#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams)
-void freezetag_CheckWinner()
+float prev_total_players;
+float freezetag_CheckTeams()
{
- if(time <= game_starttime) // game didn't even start yet! nobody can win in that case.
- return;
-
- if(next_round || (time > warmup - autocvar_g_freezetag_warmup && time < warmup))
- return; // already waiting for next round to start
-
- if((redalive >= 1 && bluealive >= 1)
- || (redalive >= 1 && yellowalive >= 1)
- || (redalive >= 1 && pinkalive >= 1)
- || (bluealive >= 1 && yellowalive >= 1)
- || (bluealive >= 1 && pinkalive >= 1)
- || (yellowalive >= 1 && pinkalive >= 1))
- return; // we still have active players on two or more teams, nobody won yet
-
- entity e, winner;
- winner = world;
-
- FOR_EACH_PLAYER(e)
+ entity e;
+ if(FREEZETAG_ALIVE_TEAMS_OK())
{
- if(e.freezetag_frozen == 0 && e.health >= 1) // here's one player from the winning team... good
+ if(prev_total_players != -1)
{
- winner = e;
- break; // break, we found the winner
+ FOR_EACH_REALCLIENT(e)
+ Send_CSQC_Centerprint_Generic_Expire(e, CPID_WAITING_PLAYERS);
}
+ prev_total_players = -1;
+ return 1;
+ }
+ if(prev_total_players != total_players)
+ {
+ string teams_missing = "";
+ if(!redalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM1), ", ");
+ if(!bluealive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM2), ", ");
+ if(freezetag_teams >= 3)
+ if(!yellowalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM3), ", ");
+ if(freezetag_teams == 4)
+ if(!pinkalive) teams_missing = strcat(teams_missing, ColoredTeamName(COLOR_TEAM4), ", ");
+ teams_missing = substring(teams_missing, 0, strlen(teams_missing)-2);
+
+ FOR_EACH_REALCLIENT(e)
+ Send_CSQC_Centerprint_Generic(e, CPID_WAITING_PLAYERS, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), -1, 0);
+ prev_total_players = total_players;
+ }
+ return 0;
+}
+
+float freezetag_getWinnerTeam()
+{
+ float winner_team = 0;
+ if(redalive >= 1)
+ winner_team = COLOR_TEAM1;
+ if(bluealive >= 1)
+ {
+ if(winner_team) return 0;
+ winner_team = COLOR_TEAM2;
+ }
+ if(yellowalive >= 1)
+ {
+ if(winner_team) return 0;
+ winner_team = COLOR_TEAM3;
+ }
+ if(pinkalive >= 1)
+ {
+ if(winner_team) return 0;
+ winner_team = COLOR_TEAM4;
+ }
+ if(winner_team)
+ return winner_team;
+ return -1; // no player left
+}
+
+float freezetag_CheckWinner()
+{
+ entity e;
+ if(round_handler_GetTimeLeft() <= 0)
+ {
+ FOR_EACH_REALCLIENT(e)
+ centerprint(e, "Round over, there's no winner");
+ bprint("Round over, there's no winner.\n");
+ FOR_EACH_PLAYER(e)
+ e.freezetag_frozen_timeout = 0;
+ round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+ return 1;
}
- if(winner != world) // just in case a winner wasn't found
+ if(FREEZETAG_ALIVE_TEAMS() > 1)
+ return 0;
+
+ float winner_team;
+ string teamname;
+ winner_team = freezetag_getWinnerTeam();
+ if(winner_team > 0)
{
- teamname = ColoredTeamName(winner_team);
- FOR_EACH_REALCLIENT(e)
- centerprint(e, strcat(teamname, "^5 wins the round, all other teams were frozen."));
- bprint(teamname, "^5 wins the round since all the other teams were frozen.\n");
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner.team, CENTER_FREEZETAG_ROUND_WIN_));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner.team, INFO_FREEZETAG_ROUND_WIN_));
- TeamScore_AddToTeam(winner.team, ST_SCORE, +1);
+ TeamScore_AddToTeam(winner_team, ST_SCORE, +1);
+ }
+ else if(winner_team == -1)
+ {
+ FOR_EACH_REALCLIENT(e)
+ centerprint(e, "^5Round tied! All teams were frozen.");
+ bprint("^5Round tied! All teams were frozen.\n");
}
- next_round = time + 5;
+ FOR_EACH_PLAYER(e)
+ e.freezetag_frozen_timeout = 0;
+ round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+ return 1;
}
// this is needed to allow the player to turn his view around (fixangle can't
self.nextthink = time;
}
+void freezetag_Add_Score(entity attacker)
+{
+ if(attacker == self)
+ {
+ // you froze your own dumb self
+ // counted as "suicide" already
+ PlayerScore_Add(self, SP_SCORE, -1);
+ }
+ else if(attacker.classname == "player")
+ {
+ // got frozen by an enemy
+ // counted as "kill" and "death" already
+ PlayerScore_Add(self, SP_SCORE, -1);
+ PlayerScore_Add(attacker, SP_SCORE, +1);
+ }
+ // else nothing - got frozen by the game type rules themselves
+}
+
void freezetag_Freeze(entity attacker)
{
if(self.freezetag_frozen)
return;
self.freezetag_frozen = 1;
+ self.freezetag_frozen_time = time;
self.freezetag_revive_progress = 0;
self.health = 1;
+ if(autocvar_g_freezetag_frozen_maxtime > 0)
+ self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
+
+ freezetag_count_alive_players();
entity ice;
ice = spawn();
ice.think = freezetag_Ice_Think;
ice.nextthink = time;
ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+ ice.alpha = ICE_MAX_ALPHA;
+ ice.colormod = TeamColor(self.team);
+ ice.glowmod = ice.colormod;
setmodel(ice, "models/ice/ice.md3");
- entity oldself;
- oldself = self;
- self = ice;
- freezetag_Ice_Think();
- self = oldself;
+ self.freezetag_ice = ice;
RemoveGrapplingHook(self);
// add waypoint
WaypointSprite_Spawn("freezetag_frozen", 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
- if(attacker == self)
- {
- // you froze your own dumb self
- // counted as "suicide" already
- PlayerScore_Add(self, SP_SCORE, -1);
- }
- else if(attacker.classname == "player")
- {
- // got frozen by an enemy
- // counted as "kill" and "death" already
- PlayerScore_Add(self, SP_SCORE, -1);
- PlayerScore_Add(attacker, SP_SCORE, +1);
- }
- else
- {
- // nothing - got frozen by the game type rules themselves
- }
+ freezetag_Add_Score(attacker);
}
void freezetag_Unfreeze(entity attacker)
{
self.freezetag_frozen = 0;
+ self.freezetag_frozen_time = 0;
+ self.freezetag_frozen_timeout = 0;
self.freezetag_revive_progress = 0;
- self.health = autocvar_g_balance_health_start;
- // remove the ice block
- entity ice;
- for(ice = world; (ice = find(ice, classname, "freezetag_ice")); ) if(ice.owner == self)
- {
- remove(ice);
- break;
- }
+ remove(self.freezetag_ice);
+ self.freezetag_ice = world;
- // remove waypoint
if(self.waypointsprite_attached)
WaypointSprite_Kill(self.waypointsprite_attached);
}
MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
{
- if(self.freezetag_frozen == 0 && self.health >= 1)
- {
- if(self.team == NUM_TEAM_1)
- --redalive;
- else if(self.team == NUM_TEAM_2)
- --bluealive;
- else if(self.team == NUM_TEAM_3)
- --yellowalive;
- else if(self.team == NUM_TEAM_4)
- --pinkalive;
- --totalalive;
- }
-
- if(total_players > 2) // only check for winners if we had more than two players (one of them left, don't let the other player win just because of that)
- freezetag_CheckWinner();
-
+ self.health = 0; // neccessary to update correctly alive stats
freezetag_Unfreeze(world);
-
+ freezetag_count_alive_players();
return 1;
}
MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
{
- if(self.freezetag_frozen == 0)
+ if(round_handler_IsActive())
+ if(round_handler_CountdownRunning())
{
- if(self.team == NUM_TEAM_1)
- --redalive;
- else if(self.team == NUM_TEAM_2)
- --bluealive;
- else if(self.team == NUM_TEAM_3)
- --yellowalive;
- else if(self.team == NUM_TEAM_4)
- --pinkalive;
- --totalalive;
+ if(self.freezetag_frozen)
+ freezetag_Unfreeze(world);
+ freezetag_count_alive_players();
+ return 1; // let the player die so that he can respawn whenever he wants
+ }
- freezetag_Freeze(frag_attacker);
+ // Cases DEATH_TEAMCHANGE and DEATH_AUTOTEAMCHANGE are needed to fix a bug whe
+ // you succeed changing team through the menu: you both really die (gibbing) and get frozen
+ if(ITEM_DAMAGE_NEEDKILL(frag_deathtype)
+ || frag_deathtype == DEATH_TEAMCHANGE || frag_deathtype == DEATH_AUTOTEAMCHANGE)
+ {
+ // let the player die, he will be automatically frozen when he respawns
+ if(!self.freezetag_frozen)
+ {
+ freezetag_Add_Score(frag_attacker);
+ freezetag_count_alive_players();
+ }
+ else
+ freezetag_Unfreeze(world); // remove ice
+ self.freezetag_frozen_timeout = -2; // freeze on respawn
+ return 1;
}
+ if(self.freezetag_frozen)
+ return 1;
+
+ freezetag_Freeze(frag_attacker);
+
if(frag_attacker == frag_target || frag_attacker == world)
{
if(frag_target.classname == STR_PLAYER)
- centerprint(frag_target, "^1You froze yourself.\n");
- bprint("^7", frag_target.netname, "^1 froze himself.\n");
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_SELF);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_SELF, frag_target.netname);
}
else
{
if(frag_target.classname == STR_PLAYER)
- centerprint(frag_target, strcat("^1You were frozen by ^7", frag_attacker.netname, ".\n"));
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_FROZEN, frag_attacker.netname);
if(frag_attacker.classname == STR_PLAYER)
- centerprint(frag_attacker, strcat("^2You froze ^7", frag_target.netname, ".\n"));
- bprint("^7", frag_target.netname, "^1 was frozen by ^7", frag_attacker.netname, ".\n");
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_FREEZETAG_FREEZE, frag_target.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
}
frag_target.health = 1; // "respawn" the player :P
- freezetag_CheckWinner();
-
return 1;
}
MUTATOR_HOOKFUNCTION(freezetag_PlayerSpawn)
{
- freezetag_Unfreeze(world); // start by making sure that all ice blocks are removed
+ if(self.freezetag_frozen_timeout == -1) // if PlayerSpawn is called by reset_map_players
+ return 1; // do nothing, round is starting right now
- if(total_players == 1 && time > game_starttime) // only one player active on server, start a new match immediately
- if(!next_round && warmup && (time < warmup - autocvar_g_freezetag_warmup || time > warmup)) // not awaiting next round
+ if(self.freezetag_frozen_timeout == -2) // player was dead
{
- next_round = time;
+ freezetag_Freeze(world);
return 1;
}
- if(warmup && time > warmup) // spawn too late, freeze player
+
+ freezetag_count_alive_players();
+
+ if(round_handler_IsActive())
+ if(round_handler_IsRoundStarted())
{
- centerprint(self, "^1Round already started, you spawn as frozen.");
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_SPAWN_LATE);
freezetag_Freeze(world);
}
return 1;
}
+MUTATOR_HOOKFUNCTION(freezetag_reset_map_players)
+{
+ FOR_EACH_PLAYER(self)
+ {
+ if (self.freezetag_frozen)
+ freezetag_Unfreeze(world);
+ self.freezetag_frozen_timeout = -1;
+ PutClientInServer();
+ self.freezetag_frozen_timeout = 0;
+ }
+ freezetag_count_alive_players();
+ return 1;
+}
+
MUTATOR_HOOKFUNCTION(freezetag_GiveFragsForKill)
{
frag_score = 0; // no frags counted in Freeze Tag
return 1;
}
+.float reviving; // temp var
MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
{
float n;
- vector revive_extra_size;
- revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+ if(gameover)
+ return 1;
+
+ if(self.freezetag_frozen)
+ {
+ // keep health = 1
+ self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
+ }
+
+ if(round_handler_IsActive())
+ if(!round_handler_IsRoundStarted())
+ return 1;
entity o;
o = world;
- n = 0;
- FOR_EACH_PLAYER(other) if(self != other)
+ if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
+ self.freezetag_ice.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
+
+ if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
+ n = -1;
+ else
{
- if(other.freezetag_frozen == 0)
+ vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+ n = 0;
+ FOR_EACH_PLAYER(other) if(self != other)
{
- if(other.team == self.team)
+ if(other.freezetag_frozen == 0)
{
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
+ if(other.team == self.team)
{
- if(!o)
- o = other;
- ++n;
+ if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
+ {
+ if(!o)
+ o = other;
+ if(self.freezetag_frozen)
+ other.reviving = TRUE;
+ ++n;
+ }
}
}
}
if(self.freezetag_revive_progress >= 1)
{
freezetag_Unfreeze(self);
+ freezetag_count_alive_players();
+
+ if(n == -1)
+ {
+ string s = ftos(autocvar_g_freezetag_frozen_maxtime);
+ centerprint(self, strcat("^5You were automatically revived after ", s, " seconds^5.\n"));
+ bprint("^7", self.netname, "^5 were automatically revived after ", s, " seconds^5.\n");
+ return 1;
+ }
// EVERY team mate nearby gets a point (even if multiple!)
- FOR_EACH_PLAYER(other) if(self != other)
+ FOR_EACH_PLAYER(other)
{
- if(other.freezetag_frozen == 0)
+ if(other.reviving)
{
- if(other.team == self.team)
- {
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
- {
- PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
- PlayerScore_Add(other, SP_SCORE, +1);
- }
- }
+ PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
+ PlayerScore_Add(other, SP_SCORE, +1);
}
}
- if(n > 1)
- centerprint(self, strcat("^5You were revived by ^7", o.netname, "^5 et al.\n"));
- else
- centerprint(self, strcat("^5You were revived by ^7", o.netname, "^5.\n"));
- centerprint(o, strcat("^5You revived ^7", self.netname, "^5.\n"));
- if(n > 1)
- bprint("^7", o.netname, "^5 et al revived ^7", self.netname, "^5.\n");
- else
- bprint("^7", o.netname, "^5 revived ^7", self.netname, "^5.\n");
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname);
+ Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVE, self.netname, o.netname);
}
- // now find EVERY teammate within reviving radius, set their revive_progress values correct
- FOR_EACH_PLAYER(other) if(self != other)
+ FOR_EACH_PLAYER(other)
{
- if(other.freezetag_frozen == 0)
+ if(other.reviving)
{
- if(other.team == self.team)
- {
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
- other.freezetag_revive_progress = self.freezetag_revive_progress;
- }
+ other.freezetag_revive_progress = self.freezetag_revive_progress;
+ other.reviving = FALSE;
}
}
}
MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate)
{
- if(g_freezetag)
- {
- if(frag_target.freezetag_frozen == 1 && frag_deathtype != DEATH_HURTTRIGGER)
- {
- frag_damage = 0;
- frag_force = frag_force * autocvar_g_freezetag_frozen_force;
- }
- }
- return 1;
+ if(frag_target.freezetag_frozen && frag_deathtype != DEATH_HURTTRIGGER)
+ {
+ frag_damage = 0;
+ frag_force = frag_force * autocvar_g_freezetag_frozen_force;
+ }
+ return 1;
}
MUTATOR_HOOKFUNCTION(freezetag_ForbidThrowCurrentWeapon)
else
self.havocbot_role = havocbot_role_ft_offense;
}
-
+
return TRUE;
}
+MUTATOR_HOOKFUNCTION(freezetag_SpectateCopy)
+{
+ self.freezetag_frozen = other.freezetag_frozen;
+ self.freezetag_revive_progress = other.freezetag_revive_progress;
+ return 0;
+}
+
+MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
+{
+ freezetag_teams = autocvar_g_freezetag_teams_override;
+ if(freezetag_teams < 2)
+ freezetag_teams = autocvar_g_freezetag_teams;
+ freezetag_teams = bound(2, freezetag_teams, 4);
+ ret_float = freezetag_teams;
+ return 0;
+}
+
+void freezetag_Initialize()
+{
+ precache_model("models/ice/ice.md3");
+ ScoreRules_freezetag();
+
+ round_handler_Spawn(freezetag_CheckTeams, freezetag_CheckWinner, func_null);
+ round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
+
+ addstat(STAT_REDALIVE, AS_INT, redalive_stat);
+ addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
+ addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
+ addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
+
+ addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
+ addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
+}
+
MUTATOR_DEFINITION(gamemode_freezetag)
{
MUTATOR_HOOK(MakePlayerObserver, freezetag_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientDisconnect, freezetag_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerDies, freezetag_PlayerDies, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, freezetag_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY);
MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerPhysics, freezetag_PlayerPhysics, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerDamage_Calculate, freezetag_PlayerDamage_Calculate, CBC_ORDER_ANY);
- MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_FIRST); //first, last or any? dunno.
+ MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
MUTATOR_HOOK(HavocBot_ChooseRule, freezetag_BotRoles, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
MUTATOR_ONADD
{
.entity kh_next;
float kh_Key_AllOwnedByWhichTeam();
-// used by arena.qc ready-restart:
typedef void(void) kh_Think_t;
void kh_StartRound();
- void kh_Controller_SetThink_NoMsg(float t, kh_Think_t func);
+ void kh_Controller_SetThink(float t, kh_Think_t func);
if(cmd_argc == 2)
{
if(argv(1) == "red")
- _team = COLOR_TEAM1;
+ _team = NUM_TEAM_1;
else
- _team = COLOR_TEAM2;
+ _team = NUM_TEAM_2;
}
FOR_EACH_PLAYER(_player)
MUTATOR_HOOKFUNCTION(superspec_ClientConnect)
{
+ if(clienttype(self) != CLIENTTYPE_REAL)
+ return FALSE;
+
string fn = "superspec-local.options";
float fh;
../warpzonelib/server.qh
../common/constants.qh
+ ../common/teams.qh
../common/util.qh
+ ../common/counting.qh
../common/items.qh
../common/explosion_equation.qh
../common/urllib.qh
constants.qh
defs.qh // Should rename this, it has fields and globals
+ ../common/notifications.qh // must be after autocvars
+ ../common/deathtypes.qh // must be after notifications
+
mutators/base.qh
mutators/mutators.qh
+mutators/gamemode_arena.qh
+mutators/gamemode_ca.qh
mutators/gamemode_ctf.qh
mutators/gamemode_domination.qh
mutators/gamemode_keyhunt.qh // TODO fix this
playerdemo.qh
+round_handler.qh
+
// singleplayer stuff
item_key.qh
secret.qh
g_tetris.qc
runematch.qc
-arena.qc
g_violence.qc
g_damage.qc
cheats.qc
playerstats.qc
+round_handler.qc
+
../common/explosion_equation.qc
mutators/base.qc
+mutators/gamemode_arena.qc
+mutators/gamemode_ca.qc
mutators/gamemode_ctf.qc
mutators/gamemode_domination.qc
mutators/gamemode_freezetag.qc
../common/animdecide.qc
../common/util.qc
+ ../common/notifications.qc
../common/if-this-file-errors-scroll-up-and-fix-the-warnings.fteqccfail
Net_LinkEntity(scores_initialized, FALSE, 0, ScoreInfo_SendEntity);
}
if(teams >= 1)
- TeamScore_Spawn(COLOR_TEAM1, "Red");
+ TeamScore_Spawn(NUM_TEAM_1, "Red");
if(teams >= 2)
- TeamScore_Spawn(COLOR_TEAM2, "Blue");
+ TeamScore_Spawn(NUM_TEAM_2, "Blue");
if(teams >= 3)
- TeamScore_Spawn(COLOR_TEAM3, "Yellow");
+ TeamScore_Spawn(NUM_TEAM_3, "Yellow");
if(teams >= 4)
- TeamScore_Spawn(COLOR_TEAM4, "Pink");
+ TeamScore_Spawn(NUM_TEAM_4, "Pink");
}
/*
if(teamscores_entities_count)
return 0;
+ if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
if(g_lms) return 0;
- if(g_arena || g_ca) return 0;
if(g_cts) return 0; // in CTS, you don't lose score by observing
if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing
s = strcat(s, ":human");
else
s = strcat(s, ":bot");
- if(p.classname != "player" && !g_arena && !g_ca && !g_lms)
+ if(p.classname != "player" && !g_arena && p.caplayer != 1 && !g_lms)
s = strcat(s, ":spectator");
}
else
{
- if(p.classname == "player" || g_arena || g_ca || g_lms)
+ if(p.classname == "player" || g_arena || p.caplayer == 1 || g_lms)
s = GetPlayerScoreString(p, 2);
else
s = "-666";
sk = teamscorekeepers[t - 1];
if(sk)
{
- s = strcat(s, ColoredTeamName(t));
+ s = strcat(s, Team_ColoredFullName(t));
for(i = 0; i < MAX_TEAMSCORE; ++i)
if(teamscores_label[i] != "")
{
PlayerScore_Clear(e);
}
- vector TeamColor(float teem)
- {
- switch(teem)
- {
- case COLOR_TEAM1:
- return '1 0.0625 0.0625';
- case COLOR_TEAM2:
- return '0.0625 0.0625 1';
- case COLOR_TEAM3:
- return '1 1 0.0625';
- case COLOR_TEAM4:
- return '1 0.0625 1';
- default:
- return '1 1 1';
- }
- }
-
- string TeamName(float t)
- {
- return strcat(Team_ColorName(t), " Team");
- }
- string ColoredTeamName(float t)
- {
- return strcat(Team_ColorCode(t), Team_ColorName(t), " Team^7");
- }
- string TeamNoName(float t)
- {
- // fixme: Search for team entities and get their .netname's!
- if(t == 1)
- return "Red Team";
- if(t == 2)
- return "Blue Team";
- if(t == 3)
- return "Yellow Team";
- if(t == 4)
- return "Pink Team";
- return "Neutral Team";
- }
-
void runematch_init();
void tdm_init();
void entcs_init();
{
fraglimit_override = autocvar_g_arena_point_limit;
leadlimit_override = autocvar_g_arena_point_leadlimit;
- maxspawned = autocvar_g_arena_maxspawned;
- if(maxspawned < 2)
- maxspawned = 2;
- arena_roundbased = autocvar_g_arena_roundbased;
+ MUTATOR_ADD(gamemode_arena);
}
if(g_ca)
ActivateTeamplay();
fraglimit_override = autocvar_g_ca_point_limit;
leadlimit_override = autocvar_g_ca_point_leadlimit;
- precache_sound("ctf/red_capture.wav");
- precache_sound("ctf/blue_capture.wav");
+ MUTATOR_ADD(gamemode_ca);
}
+
if(g_keyhunt)
{
ActivateTeamplay();
float _color;
if(t == 4)
- _color = COLOR_TEAM4 - 1;
+ _color = NUM_TEAM_4 - 1;
else if(t == 3)
- _color = COLOR_TEAM3 - 1;
+ _color = NUM_TEAM_3 - 1;
else if(t == 2)
- _color = COLOR_TEAM2 - 1;
+ _color = NUM_TEAM_2 - 1;
else
- _color = COLOR_TEAM1 - 1;
+ _color = NUM_TEAM_1 - 1;
SetPlayerColors(pl,_color);
LogTeamchange(pl.playerid, pl.team, 3); // log manual team join
if(!noprint)
- bprint(pl.netname, "^7 has changed from ", TeamNoName(s), " to ", TeamNoName(t), "\n");
+ bprint(pl.netname, "^7 has changed from ", Team_NumberToColoredFullName(s), "^7 to ", Team_NumberToColoredFullName(t), "\n");
}
}
head = findchain(classname, "onslaught_generator");
while (head)
{
- if (head.team == COLOR_TEAM1) c1 = 0;
- if (head.team == COLOR_TEAM2) c2 = 0;
- if (head.team == COLOR_TEAM3) c3 = 0;
- if (head.team == COLOR_TEAM4) c4 = 0;
+ if (head.team == NUM_TEAM_1) c1 = 0;
+ if (head.team == NUM_TEAM_2) c2 = 0;
+ if (head.team == NUM_TEAM_3) c3 = 0;
+ if (head.team == NUM_TEAM_4) c4 = 0;
head = head.chain;
}
}
{
if(!(g_domination && head.netname == ""))
{
- if(head.team == COLOR_TEAM1)
+ if(head.team == NUM_TEAM_1)
c1 = 0;
- else if(head.team == COLOR_TEAM2)
+ else if(head.team == NUM_TEAM_2)
c2 = 0;
- else if(head.team == COLOR_TEAM3)
+ else if(head.team == NUM_TEAM_3)
c3 = 0;
- else if(head.team == COLOR_TEAM4)
+ else if(head.team == NUM_TEAM_4)
c4 = 0;
}
head = find(head, classname, teament_name);
}
// if player has a forced team, ONLY allow that one
- if(self.team_forced == COLOR_TEAM1 && c1 >= 0)
+ if(self.team_forced == NUM_TEAM_1 && c1 >= 0)
c2 = c3 = c4 = -1;
- else if(self.team_forced == COLOR_TEAM2 && c2 >= 0)
+ else if(self.team_forced == NUM_TEAM_2 && c2 >= 0)
c1 = c3 = c4 = -1;
- else if(self.team_forced == COLOR_TEAM3 && c3 >= 0)
+ else if(self.team_forced == NUM_TEAM_3 && c3 >= 0)
c1 = c2 = c4 = -1;
- else if(self.team_forced == COLOR_TEAM4 && c4 >= 0)
+ else if(self.team_forced == NUM_TEAM_4 && c4 >= 0)
c1 = c2 = c3 = -1;
}
bvalue = value;
else
bvalue = 0;
- if(t == COLOR_TEAM1)
+ if(t == NUM_TEAM_1)
{
if(c1 >= 0)
{
cb1 = cb1 + bvalue;
}
}
- if(t == COLOR_TEAM2)
+ if(t == NUM_TEAM_2)
{
if(c2 >= 0)
{
cb2 = cb2 + bvalue;
}
}
- if(t == COLOR_TEAM3)
+ if(t == NUM_TEAM_3)
{
if(c3 >= 0)
{
cb3 = cb3 + bvalue;
}
}
- if(t == COLOR_TEAM4)
+ if(t == NUM_TEAM_4)
{
if(c4 >= 0)
{
// if he's not on a valid team, then let other code put him on the smallest team
if(!forcebestteam)
{
- if( c1 >= 0 && pl.team == COLOR_TEAM1)
+ if( c1 >= 0 && pl.team == NUM_TEAM_1)
selectedteam = pl.team;
- else if(c2 >= 0 && pl.team == COLOR_TEAM2)
+ else if(c2 >= 0 && pl.team == NUM_TEAM_2)
selectedteam = pl.team;
- else if(c3 >= 0 && pl.team == COLOR_TEAM3)
+ else if(c3 >= 0 && pl.team == NUM_TEAM_3)
selectedteam = pl.team;
- else if(c4 >= 0 && pl.team == COLOR_TEAM4)
+ else if(c4 >= 0 && pl.team == NUM_TEAM_4)
selectedteam = pl.team;
else
selectedteam = -1;
TeamchangeFrags(self);
if(smallest == 1)
{
- SetPlayerColors(pl, COLOR_TEAM1 - 1);
+ SetPlayerColors(pl, NUM_TEAM_1 - 1);
}
else if(smallest == 2)
{
- SetPlayerColors(pl, COLOR_TEAM2 - 1);
+ SetPlayerColors(pl, NUM_TEAM_2 - 1);
}
else if(smallest == 3)
{
- SetPlayerColors(pl, COLOR_TEAM3 - 1);
+ SetPlayerColors(pl, NUM_TEAM_3 - 1);
}
else if(smallest == 4)
{
- SetPlayerColors(pl, COLOR_TEAM4 - 1);
+ SetPlayerColors(pl, NUM_TEAM_4 - 1);
}
else
{
scolor = self.clientcolors & 0x0F;
dcolor = _color & 0x0F;
- if(scolor == COLOR_TEAM1 - 1)
+ if(scolor == NUM_TEAM_1 - 1)
steam = 1;
- else if(scolor == COLOR_TEAM2 - 1)
+ else if(scolor == NUM_TEAM_2 - 1)
steam = 2;
- else if(scolor == COLOR_TEAM3 - 1)
+ else if(scolor == NUM_TEAM_3 - 1)
steam = 3;
- else // if(scolor == COLOR_TEAM4 - 1)
+ else // if(scolor == NUM_TEAM_4 - 1)
steam = 4;
- if(dcolor == COLOR_TEAM1 - 1)
+ if(dcolor == NUM_TEAM_1 - 1)
dteam = 1;
- else if(dcolor == COLOR_TEAM2 - 1)
+ else if(dcolor == NUM_TEAM_2 - 1)
dteam = 2;
- else if(dcolor == COLOR_TEAM3 - 1)
+ else if(dcolor == NUM_TEAM_3 - 1)
dteam = 3;
- else // if(dcolor == COLOR_TEAM4 - 1)
+ else // if(dcolor == NUM_TEAM_4 - 1)
dteam = 4;
CheckAllowedTeams(self);
}
if(source_team == 1)
- steam = COLOR_TEAM1;
+ steam = NUM_TEAM_1;
else if(source_team == 2)
- steam = COLOR_TEAM2;
+ steam = NUM_TEAM_2;
else if(source_team == 3)
- steam = COLOR_TEAM3;
+ steam = NUM_TEAM_3;
else // if(source_team == 4)
- steam = COLOR_TEAM4;
+ steam = NUM_TEAM_4;
lowest_bot = world;
lowest_bot_score = 999999999;
if(selected.deadflag == DEAD_NO)
Damage(selected, selected, selected, 100000, DEATH_AUTOTEAMCHANGE, selected.origin, '0 0 0');
- centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", ColoredTeamName(selected.team)));
+ centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", Team_ColoredFullName(selected.team)));
}
// code from here on is just to support maps that don't have team entities
numteams = autocvar_g_tdm_teams;
numteams = bound(2, numteams, 4);
- tdm_spawnteam("Red", COLOR_TEAM1-1);
- tdm_spawnteam("Blue", COLOR_TEAM2-1);
+ tdm_spawnteam("Red", NUM_TEAM_1-1);
+ tdm_spawnteam("Blue", NUM_TEAM_2-1);
if(numteams >= 3)
- tdm_spawnteam("Yellow", COLOR_TEAM3-1);
+ tdm_spawnteam("Yellow", NUM_TEAM_3-1);
if(numteams >= 4)
- tdm_spawnteam("Pink", COLOR_TEAM4-1);
+ tdm_spawnteam("Pink", NUM_TEAM_4-1);
}
void tdm_delayedinit()
{
switch(self.team)
{
- case COLOR_TEAM1: // Red
+ case NUM_TEAM_1: // Red
if(damage_goodhits)
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED_HIT"), w_shotorg, v);
else
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED"), w_shotorg, v);
break;
- case COLOR_TEAM2: // Blue
+ case NUM_TEAM_2: // Blue
if(damage_goodhits)
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE_HIT"), w_shotorg, v);
else
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE"), w_shotorg, v);
break;
- case COLOR_TEAM3: // Yellow
+ case NUM_TEAM_3: // Yellow
if(damage_goodhits)
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW_HIT"), w_shotorg, v);
else
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW"), w_shotorg, v);
break;
- case COLOR_TEAM4: // Pink
+ case NUM_TEAM_4: // Pink
if(damage_goodhits)
WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK_HIT"), w_shotorg, v);
else
{
if (!e.minstagib_needammo)
return;
- Send_CSQC_Centerprint_Generic_Expire(e, CPID_MINSTA_FINDAMMO);
+ Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_MINSTA_FINDAMMO);
e.minstagib_needammo = FALSE;
}
void minstagib_ammocheck(void)
minstagib_stop_countdown(self);
else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
{
+ if (self.minstagib_needammo)
+ self.health = 100;
minstagib_stop_countdown(self);
- self.health = 100;
}
else
{
}
else if (self.health == 90)
{
- Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "^1%d^7 seconds left to find some ammo", 1, 9);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO);
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
AnnounceTo(self, "9");
}
else if (self.health == 100)
{
- Send_CSQC_Centerprint_Generic(self, CPID_MINSTA_FINDAMMO, "get some ammo or\nyou'll be dead in ^3%d^7 seconds...", 1, 10);
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO_FIRST);
Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
if not(self.flags & FL_GODMODE)
AnnounceTo(self, "10");
W_Reload(used_ammo, autocvar_g_balance_minstanex_reload_ammo, autocvar_g_balance_minstanex_reload_time, "weapons/reload.wav");
}
+ else if (req == WR_SUICIDEMESSAGE)
+ {
+ return WEAPON_THINKING_WITH_PORTALS;
+ }
+ else if (req == WR_KILLMESSAGE)
+ {
+ return WEAPON_MINSTANEX_MURDER;
+ }
return TRUE;
}
#endif
{
precache_sound("weapons/neximpact.wav");
}
- else if (req == WR_SUICIDEMESSAGE)
- w_deathtypestring = _("%s is now thinking with portals");
- else if (req == WR_KILLMESSAGE)
- w_deathtypestring = _("%s has been vaporized by %s's minstanex");
return TRUE;
}
#endif