From: z411 Date: Fri, 1 Nov 2024 23:24:21 +0000 (-0300) Subject: Merge branch 'master' into z411/bai-server X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=2edcfece2fb573e620ab5bec394c85b66d3ce057;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into z411/bai-server --- 2edcfece2fb573e620ab5bec394c85b66d3ce057 diff --cc gamemodes-server.cfg index 8863cc496,a98bab43e..acbe800f3 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@@ -262,9 -263,9 +263,10 @@@ set g_ca_spectate_enemies 0 "allow elim set g_ca_warmup 10 "time players get to run around before the round starts" set g_ca_damage2score 100 "every this amount of damage done give players 1 point" set g_ca_round_timelimit 180 "round time limit in seconds" +set g_ca_round_stop 0 "freeze the game after round stops" // BaI mod + set g_ca_round_enddelay 1 "seconds of delay for score evaluation after round could end" set g_ca_teams_override 0 - set g_ca_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any" + set g_ca_team_spawns 1 "when 1, players spawn from the team spawnpoints of the map, if any" set g_ca_teams 0 set g_ca_prevent_stalemate 0 "When round time ends instead of instant stalemate give round win to the team with 1: most survivors. 2: most total health. 3: most survivors or if equal then most total health" set g_ca_weaponarena "most" "starting weapons - takes the same options as g_weaponarena" @@@ -414,8 -414,7 +416,9 @@@ set g_freezetag_revive_nade 1 "Enable r set g_freezetag_revive_nade_health 40 "Amount of health player has if they revived from their own nade explosion" set g_freezetag_revive_time_to_score 1.5 "every this amount of seconds give players reviving a frozen teammate 1 point" set g_freezetag_round_timelimit 360 "round time limit in seconds" +set g_freezetag_round_stop 0 "freeze game when round ends" // BaI mod +set g_freezetag_round_respawn 0 // BaI mod + set g_freezetag_round_enddelay 1 "seconds of delay for score evaluation after round could end" set g_freezetag_revive_auto 1 "automatically revive frozen players after some time (g_freezetag_frozen_maxtime)" set g_freezetag_revive_auto_progress 1 "start the automatic reviving progress as soon as the player gets frozen" set g_freezetag_revive_auto_reducible 1 "reduce auto-revival time when frozen players are hit by enemies; set to -1 to reduce it even when they are hit by teammates" @@@ -425,10 -423,9 +428,10 @@@ set g_freezetag_revive_respawn 1 "respa set g_freezetag_revive_spawnshield 1 "apply spawnshield for this time in seconds after the player has been revived" set g_freezetag_frozen_maxtime 60 "frozen players will be automatically unfrozen after this time in seconds" set g_freezetag_teams_override 0 - set g_freezetag_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any" + set g_freezetag_team_spawns 1 "when 1, players spawn from the team spawnpoints of the map, if any" set g_freezetag_teams 0 -set g_freezetag_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena" +// BaI mod changes this +set g_freezetag_weaponarena "0" "starting weapons - takes the same options as g_weaponarena" // ========== diff --cc qcsrc/client/hud/panel/chat.qc index d344b33ab,a4e1b64d7..fc34d1b84 --- a/qcsrc/client/hud/panel/chat.qc +++ b/qcsrc/client/hud/panel/chat.qc @@@ -159,9 -157,11 +159,12 @@@ void HUD_Chat( if (autocvar_con_chat != floor(mySize.y / autocvar_con_chatsize - 0.5)) cvar_set("con_chat", ftos(floor(mySize.y / autocvar_con_chatsize - 0.5))); + //vector chatsize = '1 1 0' * autocvar_con_chatsize; if(autocvar__hud_configure) { + float alpha = 1; // engine can display chat only at full alpha + if (hud_configure_menu_open == 2 && highlightedPanel != panel) + alpha = hud_fade_alpha; // fade only when the settings menu of another panel is open vector chatsize = '1 1 0' * autocvar_con_chatsize; if (cvar_string("con_chatrect_x") != "9001") cvar_set("con_chatrect_x", "9001"); // over 9000, we'll fake it instead for more control over alpha and such diff --cc qcsrc/client/hud/panel/infomessages.qc index 5342c77c1,5866271ef..898b000b5 --- a/qcsrc/client/hud/panel/infomessages.qc +++ b/qcsrc/client/hud/panel/infomessages.qc @@@ -122,20 -121,26 +124,29 @@@ void HUD_InfoMessages( break; } InfoMessage(s); - } + }*/ - bool mutator_returnvalue = MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group); - pos = M_ARGV(0, vector); - img_curr_group = M_ARGV(2, int); + //bool mutator_returnvalue = MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group); + //pos = M_ARGV(0, vector); + //img_curr_group = M_ARGV(2, int); - if(!mutator_returnvalue) + if(entcs_GetWantsJoin(current_player)) { - int tm = Team_IndexToTeam(entcs_GetWantsJoin(current_player)); - s = sprintf(_("^2You're queued to join the %s%s^2 team"), Team_ColorCode(tm), Team_ColorName(tm)); + int tm = entcs_GetWantsJoin(current_player); + if(tm > 0) + { + tm = Team_IndexToTeam(tm); + s = sprintf(_("^2You're queued to join the %s%s^2 team"), Team_ColorCode(tm), Team_ColorName(tm)); + } + else if (tm < 0) + s = sprintf(_("^2You're queued to join any available team")); + else + s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump")); + InfoMessage(s); } + else + s = sprintf(_("^1Press ^3%s^1 to join"), getcommandkey(_("jump"), "+jump")); + InfoMessage(s); } if (time < STAT(GAMESTARTTIME)) @@@ -229,12 -230,37 +236,44 @@@ InfoMessage(s); } } + + // z411 + if (motd_permanent != "") + InfoMessage(motd_permanent); + + MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize, img_curr_group); ++ + if(autocvar_cl_race_checkpoint_splits_hud && !spectatee_status) { + int lines[6]; + int ln = 5; + // show up to race_nextcheckpoint (not including) or everything + // if you are before start (0 or 254) + // (except race_laptime != 0 for race, means next is + // start+finish so don't show previous lap finish) + int i; + if (race_checkpoint != 0 && race_checkpoint != 254) + { // middle of run/race + i = race_checkpoint; + } + else if (ISGAMETYPE(RACE) && race_nextcheckpoint == 0) + { // before start, but on race, so don't keep old finish visible + i = 253; + } + else + { // before start, not on race (cts), keep old run cps visible + i = 255; + } + for (; ln >= 0 && i >= 0; --i) + { + if (race_checkpoint_splits[i]) + { + lines[ln] = i; + --ln; + } + } + for (int j = 0; j < 6; ++j) + InfoMessage(race_checkpoint_splits[lines[j]]); + } } else { diff --cc qcsrc/client/hud/panel/scoreboard.qc index 92e0f4ed0,af56134c2..c0f6ff5ff --- a/qcsrc/client/hud/panel/scoreboard.qc +++ b/qcsrc/client/hud/panel/scoreboard.qc @@@ -44,22 -43,17 +44,27 @@@ const int MAX_SBT_FIELDS = MAX_SCORE PlayerScoreField sbt_field[MAX_SBT_FIELDS + 1]; float sbt_field_size[MAX_SBT_FIELDS + 1]; string sbt_field_title[MAX_SBT_FIELDS + 1]; + float sbt_field_title_condense_factor[MAX_SBT_FIELDS + 1]; + float sbt_field_title_width[MAX_SBT_FIELDS + 1]; int sbt_num_fields; + float sbt_field_title_maxwidth; + float sbt_field_title_maxwidth_factor; string autocvar_hud_fontsize; - string hud_fontsize_str; float max_namesize; + float name_field_index; + int sb_field_sizes_init; +vector duel_score_fontsize; +vector duel_name_fontsize; +vector duel_score_size; +vector team_score_fontsize; +vector team_name_fontsize; +vector team_score_size; +int total_medals; + +float autocvar_hud_panel_scoreboard_duel_weapon_scale = 1.25; // z411 + float sbt_bg_alpha; float sbt_fg_alpha; float sbt_fg_alpha_self; @@@ -149,11 -130,10 +144,11 @@@ string Label_getInfo(string label, int SCO_LABEL(_("SCO^bctime"), "bctime", " ", _("Total amount of time holding the ball in Keepaway")); SCO_LABEL(_("SCO^caps"), "caps", " ", _("How often a flag (CTF) or a key (KeyHunt) was captured")); SCO_LABEL(_("SCO^captime"), "captime", " ", _("Time of fastest capture (CTF)")); + SCO_LABEL(_("SCO^cn"), "cn", " ", _("Country of player")); SCO_LABEL(_("SCO^deaths"), "deaths", " ", _("Number of deaths")); - SCO_LABEL(_("SCO^destroyed"), "destroyed", " ", _("Number of keys destroyed by pushing them into void")); - SCO_LABEL(_("SCO^damage"), "dmg", " ", _("The total damage done")); - SCO_LABEL(_("SCO^dmgtaken"), "dmgtaken", " ", _("The total damage taken")); + SCO_LABEL(_("SCO^destructions"), "destructions", " ", _("Number of keys destroyed by pushing them into void")); + SCO_LABEL(_("SCO^damage dealt"), "dmg", " ", _("The total damage dealt")); + SCO_LABEL(_("SCO^damage taken"), "dmgtaken", " ", _("The total damage taken")); SCO_LABEL(_("SCO^drops"), "drops", " ", _("Number of flag drops")); SCO_LABEL(_("SCO^elo"), "elo", " ", _("Player ELO")); SCO_LABEL(_("SCO^fastest"), "fastest", " ", _("Time of fastest lap (Race/CTS)")); @@@ -1301,22 -1263,41 +1331,44 @@@ string Scoreboard_FixColumnWidth(int i return str; } - void Scoreboard_initFieldSizes() + void Scoreboard_initFieldSizes(bool compress_more) { + if (compress_more) + { + float sbt_field_title_maxwidth_factor_prev = sbt_field_title_maxwidth_factor; + sbt_field_title_maxwidth_factor -= 0.05; + if (sbt_field_title_maxwidth * sbt_field_title_maxwidth_factor < 0.01 * vid_conwidth) + { + sbt_field_title_maxwidth_factor = (0.01 * vid_conwidth) / sbt_field_title_maxwidth; + if (sbt_field_title_maxwidth_factor_prev == sbt_field_title_maxwidth_factor) + return; + } + } + else + sbt_field_title_maxwidth_factor = 1; + for(int i = 0; i < sbt_num_fields; ++i) { - sbt_field_size[i] = stringwidth(sbt_field_title[i], false, hud_fontsize); - Scoreboard_FixColumnWidth(i, ""); + if (sbt_field[i] == SP_NAME) + { + name_field_index = i; + continue; + } + + Scoreboard_FixColumnWidth(i, "", true); } + + // update name field size in the end as it takes remaining space + Scoreboard_FixColumnWidth(name_field_index, "", true); } -vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players) +vector Scoreboard_DrawHeader(vector pos, vector rgb, bool other_players, int team) { int i; + string title_str; + vector title_rgb; vector column_dim = eY * panel_size.y; + if(other_players) column_dim.y -= 1.25 * hud_fontsize.y; vector text_offset = eY * (1.25 - 1) / 2 * hud_fontsize.y; @@@ -1341,9 -1310,18 +1393,22 @@@ if (sbt_highlight) if (i % 2) drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL); ++ + drawstring(pos + text_offset + text_offset_center, title_str, hud_fontsize, title_rgb, sbt_fg_alpha, DRAWFLAG_NORMAL); ++ + vector prev_drawfontscale = drawfontscale; + if (sbt_field_title_condense_factor[i]) + drawfontscale.x *= sbt_field_title_condense_factor[i]; + drawstring(pos + text_offset, sbt_field_title[i], hud_fontsize, rgb * 1.5, sbt_fg_alpha, DRAWFLAG_NORMAL); + if (sbt_field_title_condense_factor[i]) + { + drawfontscale.x *= sbt_field_title_condense_factor[i]; + drawfontscale = prev_drawfontscale; + } ++ pos.x += column_dim.x; } + if(sbt_field[i] == SP_SEPARATOR) { pos.x = panel_pos.x + panel_size.x - hud_fontsize.x * 0.5; @@@ -1518,26 -1504,16 +1596,35 @@@ vector Scoreboard_DrawOthers(vector ite continue; if(pl == ignored_pl) continue; + + string flag_name = ""; + vector flag_size = '0 0 0'; + Scoreboard_GetField(pl, SP_COUNTRY, autocvar_hud_panel_scoreboard_scores_per_round); + + if(sbt_field_icon3 != "") { + sz = draw_getimagesize(sbt_field_icon3); + flag_name = sbt_field_icon3; + flag_size = vec2(hud_fontsize.x * (sz.x / sz.y), hud_fontsize.y); + } + + if(entcs_GetWantsJoin(pl.sv_entnum)) + { + vector tmcolor = Team_ColorRGB(Team_IndexToTeam(entcs_GetWantsJoin(pl.sv_entnum))); + tmcolor -= tmcolor * sin(2*M_PI*time); + + drawstring(pos, "(Q)", hud_fontsize, tmcolor, sbt_fg_alpha, DRAWFLAG_NORMAL); + pos.x += stringwidth("(Q) ", true, hud_fontsize); + } + if(entcs_GetWantsJoin(pl.sv_entnum)) + { + vector tmcolor = Team_ColorRGB(Team_IndexToTeam(entcs_GetWantsJoin(pl.sv_entnum))); + tmcolor -= tmcolor * sin(2*M_PI*time); + + drawstring(pos, "(Q)", hud_fontsize, tmcolor, sbt_fg_alpha, DRAWFLAG_NORMAL); + pos.x += stringwidth("(Q) ", true, hud_fontsize); + } + field = ""; if(this_team == NUM_SPECTATOR) { @@@ -3083,8 -2632,10 +3197,12 @@@ void Scoreboard_Draw( pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size); } + pos = Scoreboard_MedalStats_Draw(pos); + + // if the name column is too small, try to compress all other field titles + if (sbt_field_size[name_field_index] < sbt_field_title_width[name_field_index] + hud_fontsize.x) + sb_field_sizes_init = 2; + // draw scoreboard spectators before accuracy and item stats if (autocvar_hud_panel_scoreboard_spectators_position == 0) { pos = Scoreboard_Spectators_Draw(pos); diff --cc qcsrc/client/hud/panel/timer.qc index 003f1c4b7,ae796fbdd..b1206791c --- a/qcsrc/client/hud/panel/timer.qc +++ b/qcsrc/client/hud/panel/timer.qc @@@ -149,13 -121,28 +149,26 @@@ void HUD_Timer( int overtimes = STAT(OVERTIMES); if(warmup_stage || autocvar__hud_configure) - subtext = _("Warmup"); + { + if (STAT(WARMUP_TIMELIMIT) > 0) + subtext = _("Warmup"); + else + { + Scoreboard_UpdatePlayerTeams(); // ensure numplayers is current + if (srv_minplayers - numplayers > 0) + subtext = _("Warmup: too few players!"); + else if (teamnagger && (ts_max - ts_min) >= teamnagger) + subtext = _("Warmup: teams unbalanced!"); + else + subtext = _("Warmup: no time limit"); + } + } else if(STAT(TIMEOUT_STATUS) == 2) subtext = _("Timeout"); - else if (overtimes == -1) - subtext = _("Sudden Death"); - else if(overtimes == 1) - subtext = _("Overtime"); - else if (overtimes >= 2) + else if(overtimes >= 2) subtext = sprintf(_("Overtime #%d"), overtimes); + else if(overtimes != 0) + subtext = _("Overtime"); subtext_size = vec2(mySize.x, mySize.y / 3); timer_size = vec2(mySize.x, mySize.y - subtext_size.y); diff --cc qcsrc/common/ent_cs.qc index 3dfea8f98,cca9b7015..7666710d7 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@@ -151,18 -151,11 +151,19 @@@ ENTCS_PROP(CLIENTCOLORS, true, clientco ENTCS_PROP(FRAGS, true, frags, frags, ENTCS_SET_NORMAL, { WriteShort(chan, ent.frags); }, { ent.frags = ReadShort(); }) + +ENTCS_PROP(COUNTRYCODE, true, countrycode, countrycode, ENTCS_SET_NORMAL, + { WriteByte(chan, ent.countrycode); }, + { ent.countrycode = ReadByte(); }) + +ENTCS_PROP(RANK, true, rank, rank, ENTCS_SET_NORMAL, + { WriteString(chan, ent.rank); }, + { strcpy(ent.rank, ReadString()); }) + // index of join queue team selection, max 127 because -1 means any available team ENTCS_PROP(WANTSJOIN, true, wants_join, wants_join, ENTCS_SET_NORMAL, - { WriteByte(chan, ent.wants_join); }, - { ent.wants_join = ReadByte(); }) + { WriteChar(chan, ent.wants_join); }, + { ent.wants_join = ReadChar(); }) // use sv_solid to avoid changing solidity state of entcs entities ENTCS_PROP(SOLID, true, sv_solid, solid, ENTCS_SET_NORMAL, diff --cc qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index 2c4a097d6,dcdc11414..bc9cdd304 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@@ -180,26 -158,35 +181,48 @@@ float CA_CheckWinner( if (!winner_team) winner_team = Team_GetWinnerAliveTeam(); if (!winner_team) + { + // Dr. Jaska: + // reset delay time here only for consistency + // CA players currently have no known ways to resurrect + round_handler_ResetEndDelayTime(); return 0; + } + + // delay round ending a bit + if (autocvar_g_ca_round_enddelay + && round_handler_GetEndTime() > 0 + && round_handler_GetEndTime() - time > 0) // don't delay past timelimit + { + if (round_handler_GetEndDelayTime() == -1) + { + round_handler_SetEndDelayTime(min(time + autocvar_g_ca_round_enddelay, round_handler_GetEndTime())); + return 0; + } + else if (round_handler_GetEndDelayTime() >= time) + { + return 0; + } + } + bool perfect = false; if(winner_team > 0) { + entity tm = Team_GetTeam(winner_team); + entity last_pl = ca_LastPlayer(winner_team); + + if(last_pl && Team_GetNumberOfPlayers(tm) >= 3) { + Give_Medal(last_pl, DEFENSE); + } + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); + if(fragsleft > 1) Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, APP_TEAM_NUM(winner_team, ANNCE_ROUND_TEAM_WIN)); TeamScore_AddToTeam(winner_team, ST_CA_ROUNDS, +1); + + if (Team_GetNumberOfPlayers(tm) >= 3 && + Team_GetNumberOfAlivePlayers(tm) == Team_GetNumberOfPlayers(tm)) + perfect = true; } else if(winner_team == -1) { diff --cc qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc index 32bd7acb2,a9f0143a8..4aba3f82d --- a/qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc +++ b/qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc @@@ -86,24 -85,11 +85,27 @@@ bool freezetag_CheckTeams( void nades_Clear(entity); void nades_GiveBonus(entity player, float score); +entity freezetag_LastPlayer(float tm) +{ + entity last_pl = NULL; + FOREACH_CLIENT(IS_PLAYER(it) && it.team == tm, { + if (STAT(FROZEN, it) != FROZEN_NORMAL && GetResource(it, RES_HEALTH) >= 1) + { + if (!last_pl) + last_pl = it; + else + return NULL; + } + }); + return last_pl; +} + + float autocvar_g_freezetag_round_enddelay = 1; ++ bool freezetag_CheckWinner() { - if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0) + if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0 + && round_handler_GetEndDelayTime() == -1) { Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_OVER); Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_OVER); diff --cc qcsrc/common/mutators/mutator/_mod.inc index 57e591d48,d07e3eae5..961927003 --- a/qcsrc/common/mutators/mutator/_mod.inc +++ b/qcsrc/common/mutators/mutator/_mod.inc @@@ -1,6 -1,5 +1,6 @@@ - // generated file; do not modify + // genmod.sh autogenerated file; do not modify +#include #include #include #include diff --cc qcsrc/common/notifications/all.inc index 2adf9371e,8527bdf29..8f6418a23 --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@@ -505,9 -425,9 +507,10 @@@ string multiteam_info_sprintf(string in MSG_INFO_NOTIF(POWERUP_STRENGTH, N_CONSOLE, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up Strength"), "") MSG_INFO_NOTIF(QUIT_DISCONNECT, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 disconnected"), "") + MSG_INFO_NOTIF(QUIT_KICK, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked"), "") MSG_INFO_NOTIF(QUIT_KICK_IDLING, N_CHATCON, 1, 1, "s1 f1", "", "", _("^BG%s^F3 was kicked after idling for %s seconds"), "") MSG_INFO_NOTIF(MOVETOSPEC_IDLING, N_CHATCON, 1, 1, "s1 f1", "", "", _("^BG%s^F3 was moved to^BG spectators^F3 after idling for %s seconds"), "") + MSG_INFO_NOTIF(MOVETOSPEC_IDLING_QUEUE, N_CHATCON, 1, 1, "s1 f1", "", "", _("^BG%s^F3 has left the join queue after idling for %s seconds"), "") MSG_INFO_NOTIF(MOVETOSPEC_REMOVE, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was moved to^BG spectators^F3 for balance reasons"), "") MSG_INFO_NOTIF(QUIT_KICK_SPECTATING, N_CONSOLE, 0, 0, "", "", "", _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") MSG_INFO_NOTIF(QUIT_KICK_TEAMKILL, N_CHATCON, 1, 0, "s1", "", "", _("^BG%s^F3 was kicked for excessive teamkilling"), "") diff --cc qcsrc/common/replicate.qh index 868b0b3b3,6c66771f8..0b3e78fea --- a/qcsrc/common/replicate.qh +++ b/qcsrc/common/replicate.qh @@@ -5,16 -7,18 +7,20 @@@ REPLICATE_INIT(bool, cvar_cl_autoswitch REPLICATE_INIT(int, cvar_cl_autoscreenshot); REPLICATE_INIT(bool, cvar_cl_clippedspectating); REPLICATE_INIT(bool, cvar_cl_cts_noautoswitch); - REPLICATE_INIT(float, cvar_cl_handicap); + REPLICATE_INIT(vector, cvar_cl_handicap); + REPLICATE_INIT(float, cvar_cl_handicap_damage_given); + REPLICATE_INIT(float, cvar_cl_handicap_damage_taken); REPLICATE_INIT(bool, cvar_cl_noantilag); +REPLICATE_INIT(bool, cvar_cl_chat_sounds); REPLICATE_INIT(string, cvar_g_xonoticversion); REPLICATE(cvar_cl_autoswitch, bool, "cl_autoswitch"); REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot"); REPLICATE(cvar_cl_clippedspectating, bool, "cl_clippedspectating"); REPLICATE(cvar_cl_cts_noautoswitch, bool, "cl_cts_noautoswitch"); - REPLICATE(cvar_cl_handicap, float, "cl_handicap"); + REPLICATE(cvar_cl_handicap, vector, "cl_handicap"); + REPLICATE(cvar_cl_handicap_damage_given, float, "cl_handicap_damage_given"); + REPLICATE(cvar_cl_handicap_damage_taken, float, "cl_handicap_damage_taken"); REPLICATE(cvar_cl_noantilag, bool, "cl_noantilag"); +REPLICATE(cvar_cl_chat_sounds, bool, "cl_chat_sounds"); REPLICATE(cvar_g_xonoticversion, string, "g_xonoticversion"); #endif diff --cc qcsrc/common/teams.qh index e99b001b2,dfedb2a27..cb53919f2 --- a/qcsrc/common/teams.qh +++ b/qcsrc/common/teams.qh @@@ -89,24 -83,9 +89,24 @@@ vector Team_ColorRGB(int teamid case NUM_TEAM_4: return '1 0.0625 1'; // 0xFF0FFF } - return '0 0 0'; + return '1 1 1'; } +#ifdef CSQC +string Team_CustomName(int teamid) +{ + switch(teamid) + { + case NUM_TEAM_1: return ((teamname_red != "") ? teamname_red : "^1RED^7 team"); + case NUM_TEAM_2: return ((teamname_blue != "")? teamname_blue : "^4BLUE^7 team"); + case NUM_TEAM_3: return ((teamname_yellow != "") ? teamname_yellow : "^3YELLOW^7 team"); + case NUM_TEAM_4: return ((teamname_pink != "") ? teamname_pink : "^6PINK^7 team"); + } + + return NAME_NEUTRAL; +} +#endif + string Team_ColorName(int teamid) { switch(teamid) diff --cc qcsrc/common/weapons/weapon/electro.qc index a5c2b86e8,8d4b85628..f041b6afb --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@@ -81,14 -82,13 +82,15 @@@ void W_Electro_Explode(entity this, ent if(IS_PLAYER(directhitentity)) if(DIFF_TEAM(this.realowner, directhitentity)) if(!IS_DEAD(directhitentity)) - if(IsFlying(directhitentity)) - Send_Notification(NOTIF_ONE, this.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH); - + if(IsFlying(directhitentity)) { + Give_Medal(this.realowner, ELECTROBITCH); + } + */ + this.event_damage = func_null; this.takedamage = DAMAGE_NO; - this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work + if (!this.velocity) + this.velocity = this.movedir; // .velocity must be != '0 0 0' for particle fx and decal to work if(this.move_movetype == MOVETYPE_BOUNCE || this.classname == "electro_orb") // TODO: classname is more reliable anyway? { diff --cc qcsrc/server/chat.qc index 62307cc15,2e7faa7b1..c9a7a28ec --- a/qcsrc/server/chat.qc +++ b/qcsrc/server/chat.qc @@@ -88,15 -87,12 +88,18 @@@ int Say(entity source, int teamsay, ent */ string namestr = ""; - if (source) - namestr = playername(source.netname, source.team, (autocvar_g_chat_teamcolors && IS_PLAYER(source))); + if (source) { + namestr = playername(source.netname, source.team, (autocvar_g_chat_teamcolors)); + + if (IS_DEAD(source) || source.frags == FRAGS_PLAYER_OUT_OF_GAME) + namestr = strcat("(DEAD) ", namestr); + else if (IS_OBSERVER(source) || IS_SPEC(source)) + namestr = strcat("(s) ", namestr); + } + if (autocvar_g_chat_show_playerid) + namestr = strcat(namestr, " ^9#", itos(etof(source)), "^7"); + string colorprefix = (strdecolorize(namestr) == namestr) ? "^3" : "^7"; string msgstr = "", cmsgstr = ""; @@@ -394,98 -382,76 +393,102 @@@ return ret; } +bool play_chatsound(entity source, string msgin) +{ + if(autocvar_sv_chat_sounds && CS_CVAR(source).cvar_cl_chat_sounds) { + var .float flood_sound = floodcontrol_chatsound; + + if (source.(flood_sound) < time - autocvar_sv_chat_sounds_flood) { + string rawmsg; + bool found = false; + rawmsg = strreplace("\n", " ", msgin); + + FOREACH_WORD(autocvar_sv_chat_sounds_list, it == rawmsg, { found = true; }); + if (found) { + FOREACH_CLIENT(IS_REAL_CLIENT(it) && CS_CVAR(it).cvar_cl_chat_sounds, { + msg_entity = it; + WriteHeader(MSG_ONE, TE_CSQC_CHATSOUND); + WriteString(MSG_ONE, rawmsg); + }); + source.(flood_sound) = time; + return true; + } + } + } + + return false; +} + entity findnearest(vector point, bool checkitems, vector axismod) { - vector dist; - int num_nearest = 0; - - IL_EACH(((checkitems) ? g_items : g_locations), ((checkitems) ? (it.target == "###item###") : (it.classname == "target_location")), - { - if ((it.items == IT_KEY1 || it.items == IT_KEY2) && it.target == "###item###") - dist = it.oldorigin; - else - dist = it.origin; - dist = dist - point; - dist = dist.x * axismod.x * '1 0 0' + dist.y * axismod.y * '0 1 0' + dist.z * axismod.z * '0 0 1'; - float len = vlen2(dist); - - int l; - for (l = 0; l < num_nearest; ++l) - { - if (len < nearest_length[l]) - break; - } - - // now i tells us where to insert at - // INSERTION SORT! YOU'VE SEEN IT! RUN! - if (l < NUM_NEAREST_ENTITIES) - { - for (int j = NUM_NEAREST_ENTITIES - 1; j >= l; --j) - { - nearest_length[j + 1] = nearest_length[j]; - nearest_entity[j + 1] = nearest_entity[j]; - } - nearest_length[l] = len; - nearest_entity[l] = it; - if (num_nearest < NUM_NEAREST_ENTITIES) - num_nearest = num_nearest + 1; - } - }); - - // now use the first one from our list that we can see - for (int j = 0; j < num_nearest; ++j) - { - traceline(point, nearest_entity[j].origin, true, NULL); - if (trace_fraction == 1) - { - if (j != 0) - LOG_TRACEF("Nearest point (%s) is not visible, using a visible one.", nearest_entity[0].netname); - return nearest_entity[j]; - } - } - - if (num_nearest == 0) - return NULL; - - LOG_TRACE("Not seeing any location point, using nearest as fallback."); - /* DEBUGGING CODE: - dprint("Candidates were: "); - for(j = 0; j < num_nearest; ++j) - { - if(j != 0) - dprint(", "); - dprint(nearest_entity[j].netname); - } - dprint("\n"); - */ - - return nearest_entity[0]; + vector dist; + int num_nearest = 0; + + IntrusiveList list = ((checkitems) ? g_items : g_locations); + IL_EACH(list, (checkitems ? (it.target == "###item###") : (it.classname == "target_location")), + { + if ((it.items == IT_KEY1 || it.items == IT_KEY2) && it.target == "###item###") + dist = it.oldorigin; + else + dist = it.origin; + dist = dist - point; + dist = vec3(dist.x * axismod.x, dist.y * axismod.y, dist.z * axismod.z); + float len = vlen2(dist); + + int l; + for (l = 0; l < num_nearest; ++l) + { + if (len < nearest_length[l]) + break; + } + + // now i tells us where to insert at + // INSERTION SORT! YOU'VE SEEN IT! RUN! + if (l < NUM_NEAREST_ENTITIES) + { + for (int j = NUM_NEAREST_ENTITIES - 2; j >= l; --j) + { + nearest_length[j + 1] = nearest_length[j]; + nearest_entity[j + 1] = nearest_entity[j]; + } + nearest_length[l] = len; + nearest_entity[l] = it; + if (num_nearest < NUM_NEAREST_ENTITIES) + num_nearest = num_nearest + 1; + } + }); + + // now use the first one from our list that we can see + for (int j = 0; j < num_nearest; ++j) + { + traceline(point, nearest_entity[j].origin, true, NULL); + if (trace_fraction == 1) + { + if (j != 0) + { + LOG_TRACEF("Nearest point (%s) is not visible, using a visible one.", + nearest_entity[0].netname); + } + return nearest_entity[j]; + } + } + + if (num_nearest == 0) + return NULL; + + LOG_TRACE("Not seeing any location point, using nearest as fallback."); + /* DEBUGGING CODE: + dprint("Candidates were: "); + for(j = 0; j < num_nearest; ++j) + { + if(j != 0) + dprint(", "); + dprint(nearest_entity[j].netname); + } + dprint("\n"); + */ + + return nearest_entity[0]; } string NearestLocation(vector p) diff --cc qcsrc/server/chat.qh index c07a23124,1b2f970b4..62bd8d05c --- a/qcsrc/server/chat.qh +++ b/qcsrc/server/chat.qh @@@ -17,11 -17,8 +17,12 @@@ bool autocvar_g_chat_team_allowed int autocvar_g_chat_nospectators; bool autocvar_g_chat_teamcolors; bool autocvar_g_chat_tellprivacy; + bool autocvar_g_chat_show_playerid; +bool autocvar_sv_chat_sounds; +float autocvar_sv_chat_sounds_flood; +string autocvar_sv_chat_sounds_list; + const float NUM_NEAREST_ENTITIES = 4; entity nearest_entity[NUM_NEAREST_ENTITIES]; float nearest_length[NUM_NEAREST_ENTITIES]; diff --cc qcsrc/server/client.qc index 18051aa08,8d0db75da..17dd51186 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@@ -97,20 -97,6 +97,20 @@@ STATIC_METHOD(Client, Remove, void(Clie ClientDisconnect(this); } - void send_CSQC_teamnagger() { - WriteHeader(MSG_BROADCAST, TE_CSQC_TEAMNAGGER); - } ++/* TODO void send_CSQC_teamnagger() { ++ WriteHeader(MSG_BROADCAST, TE_CSQC_TEAMNAGGER); ++}*/ + +void send_TeamNames(int channel, entity to) { - msg_entity = to; - - WriteHeader(channel, TE_CSQC_TEAMNAMES); - WriteString(channel, autocvar_g_teamnames_red); - WriteString(channel, autocvar_g_teamnames_blue); - WriteString(channel, autocvar_g_teamnames_yellow); - WriteString(channel, autocvar_g_teamnames_pink); ++ msg_entity = to; ++ ++ WriteHeader(channel, TE_CSQC_TEAMNAMES); ++ WriteString(channel, autocvar_g_teamnames_red); ++ WriteString(channel, autocvar_g_teamnames_blue); ++ WriteString(channel, autocvar_g_teamnames_yellow); ++ WriteString(channel, autocvar_g_teamnames_pink); +} + int CountSpectators(entity player, entity to) { if(!player) { return 0; } // not sure how, but best to be safe @@@ -424,12 -427,9 +441,13 @@@ void PutObserverInServer(entity this, b if (CS(this).just_joined) CS(this).just_joined = false; - if (this.wants_join) - this.wants_join = 0; + // for RJZ + if (autocvar_rjz_count_shards) + send_TotalShards(this); ++ + if (recount_ready) + ReadyCount(); // must be called after SetPlayerTeam() and TRANSMUTE(Observer } int player_getspecies(entity this) @@@ -554,34 -554,16 +572,32 @@@ void FixPlayermodel(entity player setcolor(player, stof(autocvar_sv_defaultplayercolors)); } -void GiveWarmupResources(entity this) +void ResetPlayerResources(entity this) { - SetResource(this, RES_SHELLS, warmup_start_ammo_shells); - SetResource(this, RES_BULLETS, warmup_start_ammo_nails); - SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets); - SetResource(this, RES_CELLS, warmup_start_ammo_cells); - SetResource(this, RES_FUEL, warmup_start_ammo_fuel); - SetResource(this, RES_HEALTH, warmup_start_health); - SetResource(this, RES_ARMOR, warmup_start_armorvalue); - STAT(WEAPONS, this) = WARMUP_START_WEAPONS; + if (warmup_stage) { - SetResource(this, RES_SHELLS, warmup_start_ammo_shells); - SetResource(this, RES_BULLETS, warmup_start_ammo_nails); - SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets); - SetResource(this, RES_CELLS, warmup_start_ammo_cells); - SetResource(this, RES_PLASMA, warmup_start_ammo_plasma); - SetResource(this, RES_FUEL, warmup_start_ammo_fuel); - SetResource(this, RES_HEALTH, warmup_start_health); - SetResource(this, RES_ARMOR, warmup_start_armorvalue); - STAT(WEAPONS, this) = WARMUP_START_WEAPONS; ++ SetResource(this, RES_SHELLS, warmup_start_ammo_shells); ++ SetResource(this, RES_BULLETS, warmup_start_ammo_nails); ++ SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets); ++ SetResource(this, RES_CELLS, warmup_start_ammo_cells); ++ SetResource(this, RES_FUEL, warmup_start_ammo_fuel); ++ SetResource(this, RES_HEALTH, warmup_start_health); ++ SetResource(this, RES_ARMOR, warmup_start_armorvalue); ++ STAT(WEAPONS, this) = WARMUP_START_WEAPONS; + } else { - SetResource(this, RES_SHELLS, start_ammo_shells); - SetResource(this, RES_BULLETS, start_ammo_nails); - SetResource(this, RES_ROCKETS, start_ammo_rockets); - SetResource(this, RES_CELLS, start_ammo_cells); - SetResource(this, RES_PLASMA, start_ammo_plasma); - SetResource(this, RES_FUEL, start_ammo_fuel); - SetResource(this, RES_HEALTH, start_health); - SetResource(this, RES_ARMOR, start_armorvalue); - STAT(WEAPONS, this) = start_weapons; - if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false) - { - GiveRandomWeapons(this, random_start_weapons_count, - autocvar_g_random_start_weapons, random_start_ammo); - } ++ SetResource(this, RES_SHELLS, start_ammo_shells); ++ SetResource(this, RES_BULLETS, start_ammo_nails); ++ SetResource(this, RES_ROCKETS, start_ammo_rockets); ++ SetResource(this, RES_CELLS, start_ammo_cells); ++ SetResource(this, RES_FUEL, start_ammo_fuel); ++ SetResource(this, RES_HEALTH, start_health); ++ SetResource(this, RES_ARMOR, start_armorvalue); ++ STAT(WEAPONS, this) = start_weapons; ++ if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false) ++ { ++ GiveRandomWeapons(this, random_start_weapons_count, ++ autocvar_g_random_start_weapons, random_start_ammo); ++ } + } } void PutPlayerInServer(entity this) @@@ -626,8 -615,24 +649,7 @@@ this.takedamage = DAMAGE_AIM; this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT; - if (warmup_stage) - GiveWarmupResources(this); - else - { - SetResource(this, RES_SHELLS, start_ammo_shells); - SetResource(this, RES_BULLETS, start_ammo_nails); - SetResource(this, RES_ROCKETS, start_ammo_rockets); - SetResource(this, RES_CELLS, start_ammo_cells); - SetResource(this, RES_FUEL, start_ammo_fuel); - SetResource(this, RES_HEALTH, start_health); - SetResource(this, RES_ARMOR, start_armorvalue); - STAT(WEAPONS, this) = start_weapons; - if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false) - { - GiveRandomWeapons(this, random_start_weapons_count, - autocvar_g_random_start_weapons, random_start_ammo); - } - } + ResetPlayerResources(this); - SetSpectatee_status(this, 0); PS(this).dual_weapons = '0 0 0'; @@@ -866,9 -872,7 +889,11 @@@ void PutClientInServer(entity this } else if (IS_PLAYER(this)) { PutPlayerInServer(this); } + + // send team names + if(teamplay && IS_REAL_CLIENT(this)) + send_TeamNames(MSG_ONE, this); ++ bot_relinkplayerlist(); } @@@ -908,13 -912,6 +933,13 @@@ void ClientInit_misc(entity this WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor WriteByte(channel, serverflags); WriteCoord(channel, autocvar_g_trueaim_minrange); - ++ + // z411 send full hostname + WriteString(channel, (autocvar_hostname_full != "" ? autocvar_hostname_full : autocvar_hostname)); + WriteString(channel, autocvar_sv_motd_permanent); - ++ + // z411 send client countdown type + WriteByte(channel, autocvar_sv_timer_countdown); } void ClientInit_CheckUpdate(entity this) @@@ -1140,13 -1153,9 +1181,13 @@@ void ClientConnect(entity this else CS(this).allowed_timeouts = autocvar_sv_timeout_number; - if (autocvar_sv_eventlog) + if (autocvar_sv_eventlog) { GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? GameLog_ProcessIP(this.netaddress) : "bot"), ":", playername(this.netname, this.team, false))); - + + /* z411 for RJZ */ + if(autocvar_rjz_ranks) GameLogEcho(strcat(":idfp:", ftos(etof(this)), ":", this.crypto_idfp)); + } + CS(this).just_joined = true; // stop spamming the eventlog with additional lines when the client connects this.wants_join = 0; @@@ -2202,8 -2306,8 +2338,9 @@@ bool PlayerThink(entity this return false; } - if (timeout_status == TIMEOUT_ACTIVE) { ++ //if (timeout_status == TIMEOUT_ACTIVE) { + if (game_timeout) { - // don't allow the player to turn around while game is paused + // don't allow the player to turn around while game is paused // FIXME turn this into CSQC stuff this.v_angle = this.lastV_angle; this.angles = this.lastV_angle; diff --cc qcsrc/server/client.qh index cb71a3eaa,cd3c162ba..65fadd997 --- a/qcsrc/server/client.qh +++ b/qcsrc/server/client.qh @@@ -225,8 -209,8 +227,9 @@@ CLASS(Client, Object ATTRIB(Client, cvar_cl_pokenade_type, string, this.cvar_cl_pokenade_type); ATTRIB(Client, cvar_cl_spawn_near_teammate, bool, this.cvar_cl_spawn_near_teammate); ATTRIB(Client, cvar_cl_gunalign, int, this.cvar_cl_gunalign); + ATTRIB(Client, cvar_cl_chat_sounds, bool, this.cvar_cl_chat_sounds); - ATTRIB(Client, cvar_cl_handicap, float, this.cvar_cl_handicap); + ATTRIB(Client, cvar_cl_handicap_damage_given, float, this.cvar_cl_handicap_damage_given); + ATTRIB(Client, cvar_cl_handicap_damage_taken, float, this.cvar_cl_handicap_damage_taken); ATTRIB(Client, cvar_cl_clippedspectating, bool, this.cvar_cl_clippedspectating); ATTRIB(Client, cvar_cl_autoscreenshot, int, this.cvar_cl_autoscreenshot); ATTRIB(Client, cvar_cl_jetpack_jump, bool, this.cvar_cl_jetpack_jump); @@@ -330,15 -314,8 +333,11 @@@ bool independent_players #define IS_INDEPENDENT_PLAYER(e) ((e).solid == SOLID_TRIGGER) #define MAKE_INDEPENDENT_PLAYER(e) (((e).solid = SOLID_TRIGGER), ((e).frags = FRAGS_PLAYER_OUT_OF_GAME)) +.float lastkill; +.int countrycode; .int killcount; +.string rank; // RJZ - //flood fields - .float nickspamtime; // time of last nick change - .float nickspamcount; - void SendWelcomeMessage(entity this, int msg_type); // respawning diff --cc qcsrc/server/command/cmd.qc index 52ff6a644,5bae26bbd..3f4f1de83 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@@ -356,10 -439,10 +439,10 @@@ void ClientCommand_join(entity caller, { case CMD_REQUEST_COMMAND: { - if (!game_stopped && IS_CLIENT(caller) && !IS_PLAYER(caller)) + if (!game_stopped && !game_timeout && IS_CLIENT(caller) && !IS_PLAYER(caller)) { - if (joinAllowed(caller)) - Join(caller); + if (joinAllowed(caller, caller.wants_join)) + Join(caller, teamplay); else if(time < CS(caller).jointime + MIN_SPEC_TIME) CS(caller).autojoin_checked = -1; } diff --cc qcsrc/server/command/common.qc index 33fc4a3ab,71da040ed..7dae83ce7 --- a/qcsrc/server/command/common.qc +++ b/qcsrc/server/command/common.qc @@@ -263,20 -242,8 +263,13 @@@ void timeout_handler_think(entity this timeout_status = TIMEOUT_ACTIVE; // set the slowmo value to the timeout default slowmo value - cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE)); + //cvar_set("slowmo", ftos(TIMEOUT_SLOWMO_VALUE)); + game_timeout = true; + timeout_last = time; + + // play timeout sound + sound(NULL, CH_INFO, SND_TIMEOUT, VOL_BASE, ATTN_NONE); - // reset all the flood variables - FOREACH_CLIENT(true, { - it.nickspamcount = it.nickspamtime = it.floodcontrol_chat = - it.floodcontrol_chatteam = it.floodcontrol_chattell = - it.floodcontrol_voice = it.floodcontrol_voiceteam = 0; - }); - // copy .v_angle to .lastV_angle for every player in order to fix their view during pause (see PlayerPreThink) FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it), { it.lastV_angle = it.v_angle; diff --cc qcsrc/server/command/vote.qc index e27c5fe8a,7c008c10e..970d913ae --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@@ -569,17 -561,21 +575,21 @@@ void ReadyCount( { warmup_stage = autocvar_g_warmup; // CAN change it AFTER calling Nagger_ReadyCounted() this frame game_starttime = time; - Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP, minplayers); + if (total_players < minplayers) + Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP_MINPLAYERS, minplayers); + else + Send_Notification(NOTIF_ALL, NULL, MSG_MULTI, COUNTDOWN_STOP_BADTEAMS); if (!sv_ready_restart_after_countdown) // if we ran reset_map() at start of countdown - FOREACH_CLIENT(IS_PLAYER(it), { GiveWarmupResources(it); }); + FOREACH_CLIENT(IS_PLAYER(it), { ResetPlayerResources(it); }); } - if (warmup_limit > 0) - warmup_limit = -1; - return; // don't ReadyRestart if players are ready but too few + warmup_limit = -1; + return; // don't ReadyRestart if players are ready but too few or teams are bad } - else if (minplayers && warmup_limit <= 0) + else if (warmup_limit <= 0 + && game_starttime <= time) // No countdown in progress, check prevents early countdown end if only player leaves { - // there's enough players now but we're still in infinite warmup + // there's enough players now and teams are ok + // but we're still in infinite warmup and may need to switch to timed warmup warmup_limit = cvar("g_warmup_limit"); if (warmup_limit == 0) warmup_limit = autocvar_timelimit * 60; diff --cc qcsrc/server/items/items.qc index 86ede0b7b,6adc4f9b4..ad83450d1 --- a/qcsrc/server/items/items.qc +++ b/qcsrc/server/items/items.qc @@@ -566,15 -555,7 +566,14 @@@ bool Item_GiveTo(entity item, entity pl pickedup |= Item_GiveAmmoTo(item, player, RES_BULLETS, g_pickup_nails_max); pickedup |= Item_GiveAmmoTo(item, player, RES_ROCKETS, g_pickup_rockets_max); pickedup |= Item_GiveAmmoTo(item, player, RES_CELLS, g_pickup_cells_max); - pickedup |= Item_GiveAmmoTo(item, player, RES_PLASMA, g_pickup_plasma_max); pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max); + + // for RJZ + if (autocvar_rjz_count_shards && !warmup_stage && item.itemdef == ITEM_ArmorSmall) { + total_shards++; + send_TotalShardsAll(); + } + if (item.itemdef.instanceOfWeaponPickup) { WepSet w, wp; diff --cc qcsrc/server/round_handler.qc index 12da5149f,191051e4d..c4c96025f --- a/qcsrc/server/round_handler.qc +++ b/qcsrc/server/round_handler.qc @@@ -71,9 -65,9 +71,10 @@@ void round_handler_Think(entity this if (this.canRoundEnd()) { // schedule a new round + round_delaytime = time; this.wait = true; this.nextthink = time + this.delay; + round_handler_ResetEndDelayTime(); } else { @@@ -114,7 -109,9 +115,8 @@@ void round_handler_Spawn(bool() canRoun this.canRoundEnd = canRoundEnd_func; this.roundStart = roundStart_func; this.wait = false; + round_handler_ResetEndDelayTime(); round_handler_Init(5, 5, 180); - this.nextthink = time; ScoreInfo_SetLabel_PlayerScore(SP_ROUNDS_PL, "rounds_pl", 0); } diff --cc qcsrc/server/world.qc index 3848659d1,cf0448b27..caf7a176b --- a/qcsrc/server/world.qc +++ b/qcsrc/server/world.qc @@@ -464,9 -430,8 +463,10 @@@ void cvar_changes_init( BADPREFIX("sv_timeout_"); BADPREFIX("sv_vote_"); BADPREFIX("timelimit_"); + BADPREFIX("sv_chat_"); + BADPREFIX("sv_jingle_"); BADPRESUFFIX("g_", "_round_timelimit"); + BADPRESUFFIX("g_", "_round_enddelay"); // allowed changes to server admins (please sync this to server.cfg) // vi commands: diff --cc qcsrc/server/world.qh index dd0b18134,9a07bb60d..03959c99b --- a/qcsrc/server/world.qh +++ b/qcsrc/server/world.qh @@@ -171,15 -158,8 +165,15 @@@ void readplayerstartcvars() void readlevelcvars(); .vector dropped_origin; - void droptofloor(entity this); + void DropToFloor_QC_DelayedInit(entity this); +/* z411 for RJZ */ +bool autocvar_rjz_count_shards = false; +bool autocvar_rjz_ranks = false; +int total_shards = 0; +void send_TotalShards(entity to); +void send_TotalShardsAll(); + IntrusiveList g_moveables; STATIC_INIT(g_moveables) { g_moveables = IL_NEW(); }