]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Item Pickup panel
authorz411 <z411@omaera.org>
Wed, 4 Jan 2023 20:40:42 +0000 (20:40 +0000)
committerterencehill <piuntn@gmail.com>
Wed, 4 Jan 2023 20:40:42 +0000 (20:40 +0000)
* This panel shows the weapon or item that has been just picked up, with its icon, item name, and time of pickup.
* The time of pickup can be hidden by the client or the server (default in XPM ruleset).
* If you pick up the same item several times in a row it will show (x2, x3...) in parentheses.
* Display time, fade out time and icon size can all be configured. The size of its contents automatically change size to fit the panel size.

30 files changed:
_hud_common.cfg
_hud_descriptions.cfg
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
qcsrc/client/hud/hud.qh
qcsrc/client/hud/panel/_mod.inc
qcsrc/client/hud/panel/_mod.qh
qcsrc/client/hud/panel/pickup.qc [new file with mode: 0644]
qcsrc/client/hud/panel/pickup.qh [new file with mode: 0644]
qcsrc/client/hud/panel/timer.qc
qcsrc/common/constants.qh
qcsrc/common/items/inventory.qh
qcsrc/common/items/item/ammo.qh
qcsrc/common/items/item/jetpack.qh
qcsrc/common/net_linked.qh
qcsrc/common/notifications/all.qh
qcsrc/menu/xonotic/_mod.inc
qcsrc/menu/xonotic/_mod.qh
qcsrc/menu/xonotic/dialog_hudpanel_pickup.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_hudpanel_pickup.qh [new file with mode: 0644]
qcsrc/menu/xonotic/mainwindow.qc
qcsrc/server/items/items.qc
qcsrc/server/weapons/common.qc
qcsrc/server/world.qc
ruleset-XPM.cfg
xonotic-server.cfg

index 74f48a6aa5b408a337eccc5cf9cf1390bab969bc..0c808dd3784f54e960cbfe4897606f9dea07c000 100644 (file)
@@ -49,6 +49,7 @@ seta hud_panel_scoreboard_accuracy 1 "show weapon accuracy stats panel in the sc
 seta hud_panel_scoreboard_ctf_leaderboard 1 "show a capture time rankings leaderboard in the scoreboard if allowed by the server"
 seta hud_panel_scoreboard_itemstats 1 "show item stats panel in the scoreboard"
 seta hud_panel_strafehud        3 "enable this panel, 1 = show if not observing, 2 = show always, 3 = show only in race/cts if not observing"
+seta hud_panel_pickup           1 "enable this panel"
 
 seta hud_panel_weapons_dynamichud          1 "apply the dynamic hud effects to this panel"
 seta hud_panel_ammo_dynamichud             1 "apply the dynamic hud effects to this panel"
@@ -69,6 +70,7 @@ seta hud_panel_centerprint_dynamichud      1 "apply the dynamic hud effects to t
 seta hud_panel_itemstime_dynamichud        1 "apply the dynamic hud effects to this panel"
 seta hud_panel_scoreboard_dynamichud       0 "apply the dynamic hud effects to this panel"
 seta hud_panel_strafehud_dynamichud        1 "apply the dynamic hud effects to this panel"
+seta hud_panel_pickup_dynamichud           1 "apply the dynamic hud effects to this panel"
 
 seta hud_panel_weapons_ammo_full_shells 60 "show 100% of the status bar at this ammo count"
 seta hud_panel_weapons_ammo_full_nails 320 "show 100% of the status bar at this ammo count"
@@ -275,3 +277,8 @@ seta hud_shownames_maxdistance 5000 "alpha/size is 0 at this distance"
 seta hud_shownames_antioverlap 1 "if two tags overlap, fade out the one further away from you"
 seta hud_shownames_antioverlap_minalpha 0.4 "fade out overlapping tags to this alpha value"
 seta hud_shownames_offset 52 "offset (along z-axis) tag from player origin by this many units"
+
+seta hud_panel_pickup_showtimer 1 "0 = hide timer, 1 = show timer, 2 = only when spectating"
+seta hud_panel_pickup_iconsize 1.5 "icon size scale"
+seta hud_panel_pickup_time 3 "pickup message duration (can't be higher than 5)"
+seta hud_panel_pickup_fade_out 0.15 "how long a pickup message takes to fade out (this time is included in the message duration)"
index 545e0b92b51209e986926dcec132e4fdfe345f6d..b1831264694caaaa858c95e834366e48bfcc8ed3 100644 (file)
@@ -380,3 +380,12 @@ seta hud_panel_strafehud_bg_color_team "" "override panel color with team color
 seta hud_panel_strafehud_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
 seta hud_panel_strafehud_bg_border "" "if set to something else than \"\" = override default size of border around the background"
 seta hud_panel_strafehud_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
+
+seta hud_panel_pickup_pos "" "position of this base of the panel"
+seta hud_panel_pickup_size "" "size of this panel"
+seta hud_panel_pickup_bg "" "if set to something else than \"\" = override default background"
+seta hud_panel_pickup_bg_color "" "if set to something else than \"\" = override default panel background color"
+seta hud_panel_pickup_bg_color_team "" "override panel color with team color in team based games"
+seta hud_panel_pickup_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
+seta hud_panel_pickup_bg_border "" "if set to something else than \"\" = override default size of border around the background"
+seta hud_panel_pickup_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
index 384024e34536a8f91e2cd0941f5f20d32d4c3ef3..9aaaac6f7c5db29a2ad9902ec8394451d129d26a 100644 (file)
@@ -30,7 +30,7 @@ seta hud_progressbar_acceleration_neg_color "0.86 0.35 0"
 seta hud_progressbar_vehicles_ammo1_color "0.77 0.67 0"
 seta hud_progressbar_vehicles_ammo2_color "0.86 0.35 0"
 
-seta _hud_panelorder "17 25 15 12 9 5 10 6 14 0 7 4 11 2 1 3 8 13 16 18 23 19 20 21 22 24 "
+seta _hud_panelorder "17 25 15 12 9 5 10 6 14 0 7 4 11 2 1 3 8 13 16 18 23 19 20 21 22 24 25 26 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.005000"
@@ -382,4 +382,13 @@ seta hud_panel_strafehud_bg_alpha "0.7"
 seta hud_panel_strafehud_bg_border ""
 seta hud_panel_strafehud_bg_padding ""
 
+seta hud_panel_pickup_pos "0.010000 0.945000"
+seta hud_panel_pickup_size "0.260000 0.035000"
+seta hud_panel_pickup_bg "0"
+seta hud_panel_pickup_bg_color ""
+seta hud_panel_pickup_bg_color_team ""
+seta hud_panel_pickup_bg_alpha "1"
+seta hud_panel_pickup_bg_border ""
+seta hud_panel_pickup_bg_padding ""
+
 menu_sync
index 82b07077fecd7da6dda4d5cc8bcd50176be1aee0..6bc988364184b9a5707e4c3a7a99f4cdb87f470f 100644 (file)
@@ -30,7 +30,7 @@ seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 seta hud_progressbar_vehicles_ammo1_color "0.8 0.7 0"
 seta hud_progressbar_vehicles_ammo2_color "0.7 0.4 0"
 
-seta _hud_panelorder "17 25 15 12 9 10 5 6 14 0 7 4 11 2 1 3 8 13 16 18 23 19 20 21 22 24 "
+seta _hud_panelorder "17 25 15 12 9 10 5 6 14 0 7 4 11 2 1 3 8 13 16 18 23 19 20 21 22 24 25 26 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
@@ -382,4 +382,13 @@ seta hud_panel_strafehud_bg_alpha ""
 seta hud_panel_strafehud_bg_border ""
 seta hud_panel_strafehud_bg_padding ""
 
+seta hud_panel_pickup_pos "0.010000 0.950000"
+seta hud_panel_pickup_size "0.260000 0.030000"
+seta hud_panel_pickup_bg "0"
+seta hud_panel_pickup_bg_color ""
+seta hud_panel_pickup_bg_color_team ""
+seta hud_panel_pickup_bg_alpha "1"
+seta hud_panel_pickup_bg_border ""
+seta hud_panel_pickup_bg_padding ""
+
 menu_sync
index 3d93b90b38e538724a51ee64d391acb66d3517d8..c798b7564c527d35f4fb29c65cf6174ee703f0b2 100644 (file)
@@ -30,7 +30,7 @@ seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 seta hud_progressbar_vehicles_ammo1_color "0.8 0.7 0"
 seta hud_progressbar_vehicles_ammo2_color "0.7 0.4 0"
 
-seta _hud_panelorder "17 10 3 0 14 6 9 13 4 1 2 11 12 7 5 8 25 15 16 18 23 19 20 21 22 24 "
+seta _hud_panelorder "17 10 3 0 14 6 9 13 4 1 2 11 12 7 5 8 25 15 16 18 23 19 20 21 22 24 25 26 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
@@ -178,7 +178,7 @@ seta hud_panel_racetimer_bg_alpha ""
 seta hud_panel_racetimer_bg_border ""
 seta hud_panel_racetimer_bg_padding ""
 
-seta hud_panel_vote_pos "0 0.890000"
+seta hud_panel_vote_pos "0.720000 0.890000"
 seta hud_panel_vote_size "0.170000 0.110000"
 seta hud_panel_vote_bg ""
 seta hud_panel_vote_bg_color ""
@@ -382,4 +382,13 @@ seta hud_panel_strafehud_bg_alpha ""
 seta hud_panel_strafehud_bg_border ""
 seta hud_panel_strafehud_bg_padding ""
 
+seta hud_panel_pickup_pos "0 0.960000"
+seta hud_panel_pickup_size "0.270000 0.030000"
+seta hud_panel_pickup_bg "0"
+seta hud_panel_pickup_bg_color ""
+seta hud_panel_pickup_bg_color_team ""
+seta hud_panel_pickup_bg_alpha "1"
+seta hud_panel_pickup_bg_border ""
+seta hud_panel_pickup_bg_padding ""
+
 menu_sync
index c1a69a88ca192f5affc15999e4cbdc6b3ee39114..7532b807f3081a9f3c7794a9e909365b0742c8fc 100644 (file)
@@ -30,7 +30,7 @@ seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 seta hud_progressbar_vehicles_ammo1_color "0.8 0.7 0"
 seta hud_progressbar_vehicles_ammo2_color "0.7 0.4 0"
 
-seta _hud_panelorder "17 25 15 3 1 2 11 10 0 14 6 9 13 4 12 7 5 8 16 18 23 19 20 21 22 24 "
+seta _hud_panelorder "17 25 15 3 1 2 11 10 0 14 6 9 13 4 12 7 5 8 16 18 23 19 20 21 22 24 25 26 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
@@ -178,7 +178,7 @@ seta hud_panel_racetimer_bg_alpha ""
 seta hud_panel_racetimer_bg_border ""
 seta hud_panel_racetimer_bg_padding ""
 
-seta hud_panel_vote_pos "0 0.890000"
+seta hud_panel_vote_pos "0.720000 0.890000"
 seta hud_panel_vote_size "0.170000 0.110000"
 seta hud_panel_vote_bg ""
 seta hud_panel_vote_bg_color ""
@@ -382,4 +382,13 @@ seta hud_panel_strafehud_bg_alpha ""
 seta hud_panel_strafehud_bg_border ""
 seta hud_panel_strafehud_bg_padding ""
 
+seta hud_panel_pickup_pos "0 0.960000"
+seta hud_panel_pickup_size "0.270000 0.030000"
+seta hud_panel_pickup_bg "0"
+seta hud_panel_pickup_bg_color ""
+seta hud_panel_pickup_bg_color_team ""
+seta hud_panel_pickup_bg_alpha "1"
+seta hud_panel_pickup_bg_border ""
+seta hud_panel_pickup_bg_padding ""
+
 menu_sync
index f0842bc640a3e4d97913886c3031f9cb51dc9607..80ab470df64411161bb78761cbc08ff6785da37d 100644 (file)
@@ -30,7 +30,7 @@ seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 seta hud_progressbar_vehicles_ammo1_color "0.8 0.7 0"
 seta hud_progressbar_vehicles_ammo2_color "0.7 0.4 0"
 
-seta _hud_panelorder "17 25 15 10 9 6 8 14 5 0 4 13 2 7 1 3 11 12 16 18 23 19 20 21 22 24 "
+seta _hud_panelorder "17 25 15 10 9 6 8 14 5 0 4 13 2 7 1 3 11 12 16 18 23 19 20 21 22 24 25 26 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
@@ -382,4 +382,13 @@ seta hud_panel_strafehud_bg_alpha ""
 seta hud_panel_strafehud_bg_border ""
 seta hud_panel_strafehud_bg_padding ""
 
+seta hud_panel_pickup_pos "0.700000 0.940000"
+seta hud_panel_pickup_size "0.260000 0.040000"
+seta hud_panel_pickup_bg "0"
+seta hud_panel_pickup_bg_color ""
+seta hud_panel_pickup_bg_color_team ""
+seta hud_panel_pickup_bg_alpha "1"
+seta hud_panel_pickup_bg_border ""
+seta hud_panel_pickup_bg_padding ""
+
 menu_sync
index 2b035c8a4eccc1b9b25ab3441b4d1c2a151c0844..2b8fe146577715ec77f3286ef4bf3bb9ca37b268 100644 (file)
@@ -30,7 +30,7 @@ seta hud_progressbar_acceleration_neg_color "0.125 0.25 0.5"
 seta hud_progressbar_vehicles_ammo1_color "0.8 0.7 0"
 seta hud_progressbar_vehicles_ammo2_color "0.7 0.4 0"
 
-seta _hud_panelorder "17 25 15 0 11 8 5 6 14 9 13 7 2 3 1 10 12 4 16 18 23 19 20 21 22 24 "
+seta _hud_panelorder "17 25 15 0 11 8 5 6 14 9 13 7 2 3 1 10 12 4 16 18 23 19 20 21 22 24 25 26 "
 
 seta hud_configure_grid "1"
 seta hud_configure_grid_xsize "0.010000"
@@ -211,7 +211,7 @@ seta hud_panel_pressedkeys_bg_padding ""
 seta hud_panel_pressedkeys_aspect "1.8"
 seta hud_panel_pressedkeys_attack "0"
 
-seta hud_panel_chat_pos "0 0.760000"
+seta hud_panel_chat_pos "0 0.730000"
 seta hud_panel_chat_size "0.420000 0.130000"
 seta hud_panel_chat_bg "0"
 seta hud_panel_chat_bg_color ""
@@ -382,4 +382,13 @@ seta hud_panel_strafehud_bg_alpha ""
 seta hud_panel_strafehud_bg_border ""
 seta hud_panel_strafehud_bg_padding ""
 
+seta hud_panel_pickup_pos "0.010000 0.860000"
+seta hud_panel_pickup_size "0.330000 0.030000"
+seta hud_panel_pickup_bg "0"
+seta hud_panel_pickup_bg_color ""
+seta hud_panel_pickup_bg_color_team ""
+seta hud_panel_pickup_bg_alpha "1"
+seta hud_panel_pickup_bg_border ""
+seta hud_panel_pickup_bg_padding ""
+
 menu_sync
index 463dcd402da61fdc8317108e327f8f1b30f51d71..0eb81916cec1562540c718b4589fb0a2c7dd640d 100644 (file)
@@ -121,6 +121,7 @@ int ts_primary, ts_secondary;
 float weapontime;
 float weaponprevtime;
 
+float timer;
 float teamnagger;
 
 int hudShiftState;
@@ -274,6 +275,7 @@ REGISTER_HUD_PANEL(ITEMSTIME,       HUD_ItemsTime,      PANEL_CONFIG_MAIN | PANE
 REGISTER_HUD_PANEL(QUICKMENU,       HUD_QuickMenu,      PANEL_CONFIG_MAIN                        , PANEL_SHOW_MAINGAME | PANEL_SHOW_MINIGAME                                          ) // QUICKMENU
 REGISTER_HUD_PANEL(SCOREBOARD,      Scoreboard_Draw,    PANEL_CONFIG_NO                          , PANEL_SHOW_MAINGAME | PANEL_SHOW_MINIGAME | PANEL_SHOW_MAPVOTE | PANEL_SHOW_WITH_SB) // SCOREBOARD
 REGISTER_HUD_PANEL(STRAFEHUD,       HUD_StrafeHUD,      PANEL_CONFIG_MAIN | PANEL_CONFIG_CANBEOFF, PANEL_SHOW_MAINGAME                                                                ) // STRAFEHUD
+REGISTER_HUD_PANEL(PICKUP,          HUD_Pickup,         PANEL_CONFIG_MAIN | PANEL_CONFIG_CANBEOFF, PANEL_SHOW_MAINGAME                                                                ) // PICKUP
 // always add new panels to the end of list
 
 // Because calling lots of functions in QC apparently cuts fps in half on many machines:
index 68e368ed13cb0c9dad0227073710fe0f885c7c57..9f6c7fb5c4e9dd63322a07ee3be2cc5b73c6df88 100644 (file)
@@ -9,6 +9,7 @@
 #include <client/hud/panel/modicons.qc>
 #include <client/hud/panel/notify.qc>
 #include <client/hud/panel/physics.qc>
+#include <client/hud/panel/pickup.qc>
 #include <client/hud/panel/powerups.qc>
 #include <client/hud/panel/pressedkeys.qc>
 #include <client/hud/panel/quickmenu.qc>
index 1b45f0cd042a5be7fa4b42483c1e08039c04f636..4f901379e8e46618242acd1aba3a6a614002a24e 100644 (file)
@@ -9,6 +9,7 @@
 #include <client/hud/panel/modicons.qh>
 #include <client/hud/panel/notify.qh>
 #include <client/hud/panel/physics.qh>
+#include <client/hud/panel/pickup.qh>
 #include <client/hud/panel/powerups.qh>
 #include <client/hud/panel/pressedkeys.qh>
 #include <client/hud/panel/quickmenu.qh>
diff --git a/qcsrc/client/hud/panel/pickup.qc b/qcsrc/client/hud/panel/pickup.qc
new file mode 100644 (file)
index 0000000..1858931
--- /dev/null
@@ -0,0 +1,105 @@
+#include "pickup.qh"
+
+#include <client/draw.qh>
+#include <client/hud/hud.qh>
+#include <client/hud/panel/timer.qh>
+#include <common/items/inventory.qh>
+
+// Pickup (#26)
+
+void HUD_Pickup_Export(int fh)
+{
+       // allow saving cvars that aesthetically change the panel into hud skin files
+}
+
+void Pickup_Update(entity it, int count)
+{
+       if(last_pickup_item != it || time - STAT(LAST_PICKUP) > autocvar_hud_panel_pickup_time)
+               last_pickup_count = 0;
+       last_pickup_item = it;
+       last_pickup_count += count;
+}
+
+float HUD_Pickup_Time(float t)
+{
+       float timelimit = (warmup_stage ? STAT(WARMUP_TIMELIMIT) : STAT(TIMELIMIT) * 60);
+
+       if(autocvar_hud_panel_timer_increment || timelimit <= 0)
+               return floor(t - STAT(GAMESTARTTIME));
+       else
+               return ceil(timelimit + STAT(GAMESTARTTIME) - t);
+}
+
+void HUD_Pickup()
+{
+       if(!autocvar_hud_panel_pickup) return;
+
+       HUD_Panel_LoadCvars();
+       vector pos, mySize;
+       pos = panel_pos;
+       mySize = panel_size;
+
+       if (autocvar_hud_panel_pickup_dynamichud)
+               HUD_Scale_Enable();
+       else
+               HUD_Scale_Disable();
+       HUD_Panel_DrawBg();
+       if(panel_bg_padding)
+       {
+               pos += '1 1 0' * panel_bg_padding;
+               mySize -= '2 2 0' * panel_bg_padding;
+       }
+
+       float last_pickup_time = STAT(LAST_PICKUP);
+       float display_time = min(5, autocvar_hud_panel_pickup_time);
+       entity it = last_pickup_item;
+
+       if((last_pickup_time && last_pickup_time > time - display_time && it) || autocvar__hud_configure) {
+               string str_timer, str_name, icon;
+               vector sz, sz2;
+               vector fontsize = '1 1 0' * mySize.y;
+               vector iconsize = fontsize * autocvar_hud_panel_pickup_iconsize;
+
+               if(autocvar__hud_configure)
+                       icon = strcat(hud_skin_path, "/armor_mega");
+               else
+                       icon = strcat(hud_skin_path, "/", ((it.model2) ? it.model2 : it.m_icon));
+
+               sz = draw_getimagesize(icon);
+               sz2 = vec2(iconsize.y*(sz.x/sz.y), iconsize.y);
+               if(autocvar__hud_configure)
+                       str_name = "Mega armor";
+               else
+                       str_name = ((last_pickup_count > 1) ? sprintf("%s (x%d)", it.m_name, last_pickup_count) : it.m_name);
+
+               float a;
+               float fade_out_time = min(display_time, autocvar_hud_panel_pickup_fade_out);
+
+               if(autocvar__hud_configure)
+                       a = 1;
+               else if(time < last_pickup_time + display_time - fade_out_time)
+                       a = 1;
+               else
+                       a = (last_pickup_time + display_time - time) / fade_out_time;
+
+               if(autocvar_hud_panel_pickup_showtimer) {
+                       // 1 will show the timer always
+                       // 2 will show the timer only if spectating
+                       // forbid serverflag will force the 2nd behavior
+                       if((autocvar_hud_panel_pickup_showtimer == 1 && !(serverflags & SERVERFLAG_FORBID_PICKUPTIMER)) || spectatee_status)
+                       {
+                               if(autocvar__hud_configure)
+                                       str_timer = "13:02";
+                               else
+                                       str_timer = seconds_tostring(HUD_Pickup_Time(last_pickup_time));
+                               drawstring(pos, str_timer, fontsize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+                               pos.x += stringwidth(str_timer, false, fontsize) + fontsize.x * 0.25;
+                       }
+               }
+
+               drawpic(pos - eY * ((iconsize.y - fontsize.y) / 2), icon, sz2, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+               pos.x += sz2.x + fontsize.x * 0.25;
+               str_name = textShortenToWidth(str_name, mySize.x - (pos.x - panel_pos.x), fontsize, stringwidth_nocolors);
+               drawstring(pos, str_name, fontsize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
+       }
+}
diff --git a/qcsrc/client/hud/panel/pickup.qh b/qcsrc/client/hud/panel/pickup.qh
new file mode 100644 (file)
index 0000000..503308d
--- /dev/null
@@ -0,0 +1,14 @@
+#pragma once
+#include "../panel.qh"
+
+bool autocvar_hud_panel_pickup;
+bool autocvar_hud_panel_pickup_dynamichud = true;
+int autocvar_hud_panel_pickup_showtimer = 1;
+float autocvar_hud_panel_pickup_iconsize = 1.5;
+float autocvar_hud_panel_pickup_time = 3;
+float autocvar_hud_panel_pickup_fade_out = 0.15;
+
+entity last_pickup_item;
+int last_pickup_count;
+
+void Pickup_Update(entity it, int count);
index 00a231b7cf44607d70fd56e338784f2fe3fdbdb5..aa0c73b5bf90c4d08ea4e37d0d49cdb7f1ab460e 100644 (file)
@@ -62,8 +62,8 @@ void HUD_Timer()
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
-       string timer;
-       string subtimer = string_null;
+       string timer_str = string_null;
+       string subtimer_str = string_null;
        string subtext = string_null;
        float curtime, timelimit, timeleft;
        vector timer_size, subtext_size, subtimer_size;
@@ -73,10 +73,7 @@ void HUD_Timer()
 
        // Use real or frozen time and get the time limit
        curtime = (intermission_time ? intermission_time : time);
-       if(warmup_stage)
-               timelimit = STAT(WARMUP_TIMELIMIT);
-       else
-               timelimit = STAT(TIMELIMIT) * 60;
+       timelimit = (warmup_stage ? STAT(WARMUP_TIMELIMIT) : STAT(TIMELIMIT) * 60);
 
        // Calculate time left
        timeleft = HUD_Timer_TimeLeft(curtime, STAT(GAMESTARTTIME), timelimit);
@@ -87,16 +84,16 @@ void HUD_Timer()
 
        // Timer text
        if (autocvar_hud_panel_timer_increment || timelimit <= 0)
-               timer = seconds_tostring(HUD_Timer_TimeElapsed(curtime, STAT(GAMESTARTTIME)));
+               timer = HUD_Timer_TimeElapsed(curtime, STAT(GAMESTARTTIME));
        else
-               timer = seconds_tostring(timeleft);
+               timer = timeleft;
 
        // Secondary timer for round-based game modes
        if(STAT(ROUNDSTARTTIME) && autocvar_hud_panel_timer_secondary)
        {
                if(STAT(ROUNDSTARTTIME) == -1) {
                        // Round can't start
-                       subtimer = "--:--";
+                       subtimer_str = "--:--";
                        subtimer_color = '1 0 0';
                } else {
                        float round_curtime, round_timelimit, round_timeleft;
@@ -114,9 +111,9 @@ void HUD_Timer()
 
                        // Subtimer text
                        if (autocvar_hud_panel_timer_increment || round_timelimit <= 0)
-                               subtimer = seconds_tostring(HUD_Timer_TimeElapsed(round_curtime, STAT(ROUNDSTARTTIME)));
+                               subtimer_str = seconds_tostring(HUD_Timer_TimeElapsed(round_curtime, STAT(ROUNDSTARTTIME)));
                        else
-                               subtimer = seconds_tostring(round_timeleft);
+                               subtimer_str = seconds_tostring(round_timeleft);
                }
        }
 
@@ -142,17 +139,18 @@ void HUD_Timer()
        subtext_size  = vec2(mySize.x, mySize.y / 3);
        timer_size    = vec2(mySize.x, mySize.y - subtext_size.y);
        subtimer_size = vec2(mySize.x / 3, mySize.y - subtext_size.y);
+       timer_str     = seconds_tostring(timer);
 
        panel_size.y -= subtext_size.y;
        HUD_Panel_DrawBg();
 
-       if(subtimer) {
+       if(subtimer_str) {
                float subtimer_padding = subtimer_size.y / 5;
                timer_size.x -= subtimer_size.x;
-               drawstring_aspect(pos + eX * timer_size.x + eY * subtimer_padding, (swap ? timer : subtimer), subtimer_size - eY * subtimer_padding * 2, (swap ? timer_color : subtimer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawstring_aspect(pos + eX * timer_size.x + eY * subtimer_padding, (swap ? timer_str : subtimer_str), subtimer_size - eY * subtimer_padding * 2, (swap ? timer_color : subtimer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
        }
 
-       drawstring_aspect(pos, (swap ? subtimer : timer), timer_size, (swap ? subtimer_color : timer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring_aspect(pos, (swap ? subtimer_str : timer_str), timer_size, (swap ? subtimer_color : timer_color), panel_fg_alpha, DRAWFLAG_NORMAL);
 
        if(subtext)
                drawstring_aspect(pos + eY * timer_size.y, subtext, subtext_size, '0 1 0', panel_fg_alpha, DRAWFLAG_NORMAL);
index a60a9de13ff0a6275a2b548aafcf785b052e2dcd..e0c17a7a128a0e623be23e7048a6afd4bec0e108 100644 (file)
@@ -17,6 +17,7 @@ const int SERVERFLAG_ALLOW_FULLBRIGHT = BIT(0);
 const int SERVERFLAG_TEAMPLAY = BIT(1);
 const int SERVERFLAG_PLAYERSTATS = BIT(2);
 const int SERVERFLAG_PLAYERSTATS_CUSTOM = BIT(3);
+const int SERVERFLAG_FORBID_PICKUPTIMER = BIT(4);
 
 const int SPECIES_HUMAN = 0;
 const int SPECIES_ROBOT_SOLID = 1;
index 22a4d94c387335f833d0867f2acb1df01e776663..6f6ebdc452a9f768b2626fc5aecf00e9f054876c 100644 (file)
@@ -37,7 +37,10 @@ STATIC_INIT(Inventory)
 #endif
 
 #ifdef CSQC
+#include <client/hud/panel/pickup.qh>
+
 Inventory g_inventory;
+
 void Inventory_remove(entity this)
 {
     if(g_inventory == this)
@@ -63,11 +66,20 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
             .int fld = inv_items[it.m_id];
             int prev = this.(fld);
             int next = this.(fld) = ReadByte();
+
+            Pickup_Update(it, next - prev);
             LOG_DEBUGF("%s: %.0f -> %.0f", it.m_name, prev, next);
         }
     }
     return true;
 }
+
+NET_HANDLE(TE_CSQC_WEAPONPICKUP, bool isnew)
+{
+       const Weapon it = REGISTRY_GET(Weapons, ReadByte());
+       Pickup_Update(it, 1);
+       return true;
+}
 #endif
 
 #ifdef SVQC
index 802922cc49584854e53fc7d42866f73f597a878f..179cc9a1d76df4878d167b3ad00a33ed48cbfb3f 100644 (file)
@@ -53,7 +53,7 @@ REGISTER_ITEM(Shells, Shells) {
     this.m_model    = MDL_Shells_ITEM;
 #endif
     this.netname    = "shells";
-    this.m_name     = _("shells");
+    this.m_name     = _("Shells");
     this.m_icon     = "ammo_shells";
 #ifdef SVQC
     this.m_botvalue = 1000;
@@ -89,7 +89,7 @@ REGISTER_ITEM(Bullets, Bullets) {
     this.m_model    = MDL_Bullets_ITEM;
 #endif
     this.netname    = "bullets";
-    this.m_name     = _("bullets");
+    this.m_name     = _("Bullets");
     this.m_icon     = "ammo_bullets";
 #ifdef SVQC
     this.m_botvalue = 1500;
@@ -121,7 +121,7 @@ REGISTER_ITEM(Rockets, Ammo) {
     this.m_model    = MDL_Rockets_ITEM;
 #endif
     this.netname    = "rockets";
-    this.m_name     = _("rockets");
+    this.m_name     = _("Rockets");
     this.m_icon     = "ammo_rockets";
 #ifdef SVQC
     this.m_botvalue = 1500;
@@ -153,7 +153,7 @@ REGISTER_ITEM(Cells, Ammo) {
     this.m_model    = MDL_Cells_ITEM;
 #endif
     this.netname    = "cells";
-    this.m_name     = _("cells");
+    this.m_name     = _("Cells");
     this.m_icon     = "ammo_cells";
 #ifdef SVQC
     this.m_botvalue = 1500;
@@ -185,7 +185,7 @@ REGISTER_ITEM(Plasma, Ammo) {
     this.m_model    = MDL_Plasma_ITEM;
 #endif
     this.netname    = "plasma";
-    this.m_name     = _("plasma");
+    this.m_name     = _("Plasma");
     this.m_icon     = "ammo_plasma";
 #ifdef SVQC
     this.m_botvalue = 1500;
index e9c5627c84dda6cb0799a42836ff9f5bcb79b682..0ece1bf32c93a81d1c012b771c5fa9af3cce0d17 100644 (file)
@@ -68,7 +68,7 @@ REGISTER_ITEM(JetpackFuel, Ammo) {
     this.m_model    =   MDL_JetpackFuel_ITEM;
 #endif
     this.netname    =   "fuel";
-    this.m_name     =   _("fuel");
+    this.m_name     =   _("Fuel");
     this.m_icon     =   "ammo_fuel";
 #ifdef SVQC
     this.m_botvalue =   2000;
index e1586c2034cd867b4a02d3e4fe995d8b3786d15a..f9e40965b8473282a398fdcedd9dd29c462b8532 100644 (file)
@@ -7,6 +7,7 @@ REGISTER_NET_TEMP(TE_CSQC_PINGPLREPORT)
 REGISTER_NET_TEMP(TE_CSQC_WEAPONCOMPLAIN)
 REGISTER_NET_TEMP(TE_CSQC_SERVERWELCOME)
 REGISTER_NET_TEMP(TE_CSQC_VEHICLESETUP)
+REGISTER_NET_TEMP(TE_CSQC_WEAPONPICKUP)
 
 const int RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
 const int RACE_NET_CHECKPOINT_CLEAR = 1;
index 2a7e68ad8241d4a3761c44e2d48eb8feac2789bf..9d39c219910f9d6c4fda29544169a7848b7feaa4 100644 (file)
@@ -656,7 +656,7 @@ string notif_arg_item_wepammo(float f1, float f2)
                case RES_FUEL:    ammoitems = ITEM_JetpackFuel.m_name; break;
                default: return ""; // doesn't use ammo
        }
-       return sprintf(_(" with %d %s"), f2, ammoitems);
+       return sprintf(_(" with %d %s"), f2, strtolower(ammoitems));
 }
 
 
index 2ee34aef81108f0da2e01c8bc1adc13150a9efb5..524c65915340a8999a5c52007efa49414f5dbbed 100644 (file)
@@ -31,6 +31,7 @@
 #include <menu/xonotic/dialog_hudpanel_modicons.qc>
 #include <menu/xonotic/dialog_hudpanel_notification.qc>
 #include <menu/xonotic/dialog_hudpanel_physics.qc>
+#include <menu/xonotic/dialog_hudpanel_pickup.qc>
 #include <menu/xonotic/dialog_hudpanel_powerups.qc>
 #include <menu/xonotic/dialog_hudpanel_pressedkeys.qc>
 #include <menu/xonotic/dialog_hudpanel_quickmenu.qc>
index 64475f6a18c4be17eb30c6c5cb563254a4a3c2ef..b4fe3d836cbd8cd598cd4256661754772ee41f5d 100644 (file)
@@ -31,6 +31,7 @@
 #include <menu/xonotic/dialog_hudpanel_modicons.qh>
 #include <menu/xonotic/dialog_hudpanel_notification.qh>
 #include <menu/xonotic/dialog_hudpanel_physics.qh>
+#include <menu/xonotic/dialog_hudpanel_pickup.qh>
 #include <menu/xonotic/dialog_hudpanel_powerups.qh>
 #include <menu/xonotic/dialog_hudpanel_pressedkeys.qh>
 #include <menu/xonotic/dialog_hudpanel_quickmenu.qh>
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pickup.qc b/qcsrc/menu/xonotic/dialog_hudpanel_pickup.qc
new file mode 100644 (file)
index 0000000..95cb5fe
--- /dev/null
@@ -0,0 +1,39 @@
+#include "dialog_hudpanel_pickup.qh"
+
+#include "checkbox.qh"
+#include "textlabel.qh"
+#include "slider.qh"
+#include "textslider.qh"
+
+void XonoticHUDPickupDialog_fill(entity me)
+{
+       entity e;
+       string panelname = "pickup";
+
+       dialog_hudpanel_main_checkbox(me, panelname);
+
+       dialog_hudpanel_main_settings(me, panelname);
+
+       me.TR(me);
+               me.TD(me, 1, 4, e = makeXonoticTextLabel(0, _("Pickup messages:")));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Message duration:")));
+               me.TD(me, 1, 2.6, e = makeXonoticSlider(1, 5, 1, "hud_panel_pickup_time"));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Fade time:")));
+               me.TD(me, 1, 2.6, e = makeXonoticSlider(0, 1, 0.05, "hud_panel_pickup_fade_out"));
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Show timer:")));
+               me.TD(me, 1, 2, e = makeXonoticTextSlider("hud_panel_pickup_showtimer"));
+                       e.addValue(e, _("Never"), "0");
+                       e.addValue(e, _("Always"), "1");
+                       e.addValue(e, _("Spectating"), "2");
+                       e.configureXonoticTextSliderValues(e);
+       me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Icon size scale:")));
+               me.TD(me, 1, 2.6, e = makeXonoticSlider(1, 3, 0.1, "hud_panel_pickup_iconsize"));
+}
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_pickup.qh b/qcsrc/menu/xonotic/dialog_hudpanel_pickup.qh
new file mode 100644 (file)
index 0000000..2ceb89d
--- /dev/null
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "rootdialog.qh"
+CLASS(XonoticHUDPickupDialog, XonoticRootDialog)
+       METHOD(XonoticHUDPickupDialog, fill, void(entity));
+       ATTRIB(XonoticHUDPickupDialog, title, string, _("Pickup Panel"));
+       ATTRIB(XonoticHUDPickupDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT);
+       ATTRIB(XonoticHUDPickupDialog, intendedWidth, float, 0.4);
+       ATTRIB(XonoticHUDPickupDialog, rows, float, 15.5);
+       ATTRIB(XonoticHUDPickupDialog, columns, float, 4);
+       ATTRIB(XonoticHUDPickupDialog, name, string, "HUDpickup");
+       ATTRIB(XonoticHUDPickupDialog, requiresConnection, float, true);
+ENDCLASS(XonoticHUDPickupDialog)
index e215e5080bd883bd26086268cf32aa9473b97a19..039d3452fd0038762f728159950f26807c1ee9ae 100644 (file)
@@ -20,6 +20,7 @@
 #include "dialog_hudpanel_timer.qh"
 #include "dialog_hudpanel_vote.qh"
 #include "dialog_hudpanel_weapons.qh"
+#include "dialog_hudpanel_pickup.qh"
 #include "dialog_hudpanel_engineinfo.qh"
 #include "dialog_hudpanel_infomessages.qh"
 #include "dialog_hudpanel_physics.qh"
@@ -158,6 +159,10 @@ void MainWindow_configureMainWindow(entity me)
        i.configureDialog(i);
        me.addItemRightCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
 
+       i = NEW(XonoticHUDPickupDialog);
+       i.configureDialog(i);
+       me.addItemRightCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
        i = NEW(XonoticHUDInfoMessagesDialog);
        i.configureDialog(i);
        me.addItemRightCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
index 347e956a3ec531a65cc3476bdb3e14dc5d434971..e68d858a8e72e55d9ad4a156cd0b81400cafbd8e 100644 (file)
@@ -11,6 +11,7 @@
 #include <common/mutators/mutator/buffs/sv_buffs.qh>
 #include <common/mutators/mutator/powerups/_mod.qh>
 #include <common/mutators/mutator/status_effects/_mod.qh>
+#include <common/net_linked.qh>
 #include <common/notifications/all.qh>
 #include <common/resources/resources.qh>
 #include <common/util.qh>
@@ -475,6 +476,15 @@ bool Item_GiveAmmoTo(entity item, entity player, Resource res_type, float ammoma
        return true;
 }
 
+void Item_NotifyWeapon(entity player, int wep)
+{
+       FOREACH_CLIENT(IS_REAL_CLIENT(it) && (it == player || (IS_SPEC(it) && it.enemy == player)), {
+               msg_entity = it;
+               WriteHeader(MSG_ONE, TE_CSQC_WEAPONPICKUP);
+               WriteByte(MSG_ONE, wep);
+       });
+}
+
 bool Item_GiveTo(entity item, entity player)
 {
        // if nothing happens to player, just return without taking the item
@@ -509,15 +519,18 @@ bool Item_GiveTo(entity item, entity player)
        pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max);
        if (item.itemdef.instanceOfWeaponPickup)
        {
-               WepSet w;
+               WepSet w, wp;
                w = STAT(WEAPONS, item);
-               w &= ~STAT(WEAPONS, player);
+               wp = w & ~STAT(WEAPONS, player);
 
-               if (w || (item.spawnshieldtime && item.pickup_anyway > 0))
+               if (wp || (item.spawnshieldtime && item.pickup_anyway > 0))
                {
                        pickedup = true;
                        FOREACH(Weapons, it != WEP_Null, {
                                if(w & (it.m_wepset))
+                                       Item_NotifyWeapon(player, it.m_id);
+
+                               if(wp & (it.m_wepset))
                                {
                                        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                                        {
index ff6f8ea4cb18659650fb36e751c76fef2d7909cd..a0dd86f5199e3afde64ff2cf7782ee167c28dd39 100644 (file)
@@ -35,10 +35,6 @@ void W_GiveWeapon(entity e, int wep)
        if (!wep) return;
 
        STAT(WEAPONS, e) |= WepSet_FromWeapon(REGISTRY_GET(Weapons, wep));
-
-       if (IS_PLAYER(e)) {
-           Send_Notification(NOTIF_ONE, e, MSG_MULTI, ITEM_WEAPON_GOT, wep);
-    }
 }
 
 void W_PlayStrengthSound(entity player)
index cdc7d3169816a6548b37d4b4b02112ef18fa7e9d..47198b7d98fd8c790ff81084038625bb4f0a8fea 100644 (file)
@@ -2100,6 +2100,10 @@ void readlevelcvars()
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
 
+       serverflags &= ~SERVERFLAG_FORBID_PICKUPTIMER;
+       if(cvar("sv_forbid_pickuptimer"))
+               serverflags |= SERVERFLAG_FORBID_PICKUPTIMER;
+
        sv_ready_restart_after_countdown = cvar("sv_ready_restart_after_countdown");
 
        warmup_stage = cvar("g_warmup");
index 2629ceb7ade8fd12679934964a5a36b681852035..10bad91b2eb5adb5d9ca4e6b071b2a27bb770975 100644 (file)
@@ -27,4 +27,5 @@ g_vehicles 0
 sv_showspectators 0
 sv_taunt 0
 sv_maxidle_playertospectator 0
+sv_forbid_pickuptimer 1 // we don't want people seeing their pickup times in competitive matches
 g_ca_spectate_enemies -1 // block freeroam camera in CA matches
index 76fca626990b1aea468f6b3d9e17198871d2f868..cf7544a08194a07f7965bebe78ce5adaaebe42e6 100644 (file)
@@ -529,6 +529,9 @@ set sv_db_saveasdump 0 "write server.db in dump format (loads slower, easier to
 // allow fullbright
 set sv_allow_fullbright 1 "when set, clients may use r_fullbright on this server without getting a night vision effect overlay"
 
+// forbid pickup timer
+set sv_forbid_pickuptimer 0 "when set, clients won't be able to see the time they picked up an item"
+
 // auto-teams (team selection by player ID)
 // any player not listed is forced to spectate
 set g_forced_team_red "" "list of player IDs for red team"