- wget -nv -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints\r
- wget -nv -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache\r
\r
- - EXPECT=4c834aa9b5950ffe25deec1880f21641\r
+ - EXPECT=8fb740a3cb3754ca7b9295ddc5c911b5\r
- HASH=$(${ENGINE} +timestamps 1 +exec serverbench.cfg\r
| tee /dev/stderr\r
| sed -e 's,^\[[^]]*\] ,,'\r
-Thu Dec 22 07:23:37 CET 2022
+Tue Dec 27 07:23:39 CET 2022
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"
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"
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)"
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"
#: qcsrc/common/notifications/all.inc:446
#, c-format
msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Accordeon%s%s"
-msgstr "^BG%s^K1 suis auribus M@!%% Harmonica nocuit%s%s"
+msgstr "^BG%s^K1 suis auribus M@!#%% Harmonica nocuit%s%s"
#: qcsrc/common/notifications/all.inc:447
#, c-format
#: qcsrc/common/notifications/all.inc:471
#, c-format
msgid "^BG%s%s^K1 was caught in ^BG%s^K1's Hook gravity bomb%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1, gravitatis bombo ^BG%s^K1 Unci, offensus est%s%s"
#: qcsrc/common/notifications/all.inc:472
#, c-format
msgid ""
"^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Klein Bottle%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1, magno canto ^BG%s^K1 M@!#%% Klein Lagenae, occisus est%s%s"
#: qcsrc/common/notifications/all.inc:473
#, c-format
msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Klein Bottle%s%s"
-msgstr ""
+msgstr "^BG%s^K1 suis auribus M@!#%% Klein Lagena nocuit%s%s"
#: qcsrc/common/notifications/all.inc:474
#, c-format
#: qcsrc/common/notifications/all.inc:475
#, c-format
msgid "^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1, Polybolo ^BG%s^K1, perforatus est%s%s"
#: qcsrc/common/notifications/all.inc:476
#: qcsrc/common/notifications/all.inc:783
#, c-format
msgid "^BGYou cannot place more than ^F2%s^BG mines at a time"
-msgstr ""
+msgstr "^F2%s^BG tribuli simul ponere non potes"
#: qcsrc/common/notifications/all.inc:477
#, c-format
msgid "^BG%s%s^K1 got too close to ^BG%s^K1's mine%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ad ^BG%s^K1 tribulum proxime fuit%s%s"
#: qcsrc/common/notifications/all.inc:478
#, c-format
msgid "^BG%s^K1 forgot about their mine%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sui tribuli oblitus est%s%s"
#: qcsrc/common/notifications/all.inc:479
#, c-format
msgid "^BG%s%s^K1 got too close to ^BG%s^K1's Mortar grenade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1 ad ^BG%s^K1 Mortarii granatam proxime fuit%s%s"
#: qcsrc/common/notifications/all.inc:480
#, c-format
msgid "^BG%s%s^K1 ate ^BG%s^K1's Mortar grenade%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1, granatam ^BG%s^K1 Mortarii, edit%s%s"
#: qcsrc/common/notifications/all.inc:481
#, c-format
msgid "^BG%s^K1 didn't see their own Mortar grenade%s%s"
-msgstr ""
+msgstr "^BG%s^K1 sui ipsius Mortarii granatam non vidit%s%s"
#: qcsrc/common/notifications/all.inc:482
#, c-format
msgid "^BG%s^K1 blew themself up with their own Mortar%s%s"
-msgstr ""
+msgstr "^BG%s^K1 suo Mortario se rupit%s%s"
#: qcsrc/common/notifications/all.inc:483
#, c-format
#: qcsrc/common/notifications/all.inc:505
#, c-format
msgid "^BG%s%s^K1 died of ^BG%s^K1's great playing on the @!#%%'n Tuba%s%s"
-msgstr ""
+msgstr "^BG%s%s^K1, magno cantu ^BG%s^K1 M@!#%% Tubae, occisus est%s%s"
#: qcsrc/common/notifications/all.inc:506
#, c-format
msgid "^BG%s^K1 hurt their own ears with the @!#%%'n Tuba%s%s"
-msgstr ""
+msgstr "^BG%s^K1 suis auribus M@!#%% Tuba nocuit%s%s"
#: qcsrc/common/notifications/all.inc:507
#, c-format
#: qcsrc/common/notifications/all.inc:527
msgid "^F4You are now alone!"
-msgstr ""
+msgstr "^F4Iam solus es!"
#: qcsrc/common/notifications/all.inc:529
msgid "^BGYou are attacking!"
-msgstr ""
+msgstr "^BGImpetis!"
#: qcsrc/common/notifications/all.inc:530
msgid "^BGYou are defending!"
-msgstr ""
+msgstr "^BGDefendis!"
#: qcsrc/common/notifications/all.inc:531
#, c-format
msgid "^BGObjective destroyed in ^F4%s^BG!"
-msgstr ""
+msgstr "^BGMeta ^F4%s^BG deleta est!"
#: qcsrc/common/notifications/all.inc:533
#, c-format
#: qcsrc/common/notifications/all.inc:534
msgid "^BGBegin!"
-msgstr ""
+msgstr "^BGIncipe!"
#: qcsrc/common/notifications/all.inc:535
msgid "^BGGame starts in"
-msgstr ""
+msgstr "^BGLudus incipietur post"
#: qcsrc/common/notifications/all.inc:536
#, c-format
msgid "^BGRound %s starts in"
-msgstr ""
+msgstr "^BGTempus %sum incipietur post"
#: qcsrc/common/notifications/all.inc:537
msgid "^F4Round cannot start"
-msgstr ""
+msgstr "^F4Tempus incipi non potest"
#: qcsrc/common/notifications/all.inc:542
msgid "^F2Don't camp!"
#: qcsrc/common/notifications/all.inc:549
msgid "^BGYou captured the ^TC^TT^BG flag!"
-msgstr ""
+msgstr "^BGVexillum ^TC^TT^BG cepisti!"
#: qcsrc/common/notifications/all.inc:550
msgid "^BGYou captured the flag!"
-msgstr ""
+msgstr "^BGVexillum cepisti!"
#: qcsrc/common/notifications/all.inc:551
#, c-format
#: qcsrc/common/notifications/all.inc:552
#, c-format
msgid "^BG%s^BG passed the ^TC^TT^BG flag to %s"
-msgstr ""
+msgstr "^BG%s^BG vexillum ^TC^TT^BG %s^BG dedit"
#: qcsrc/common/notifications/all.inc:553
#, c-format
msgid "^BG%s^BG passed the flag to %s"
-msgstr ""
+msgstr "^BG%s^BG vexillum %s^BG dedit"
#: qcsrc/common/notifications/all.inc:554
#, c-format
msgid "^BGYou received the ^TC^TT^BG flag from %s"
-msgstr ""
+msgstr "^BGVexillum ^TC^TT^BG a %s^BG accepisti"
#: qcsrc/common/notifications/all.inc:555
#, c-format
msgid "^BGYou received the flag from %s"
-msgstr ""
+msgstr "^BGVexillum a %s^BG accepisti"
#: qcsrc/common/notifications/all.inc:556
#, c-format
msgid "^BGPress ^F2%s^BG to receive the flag from %s^BG"
-msgstr ""
+msgstr "^F2%s^BG preme ut vexillum a %s^BG accipias"
#: qcsrc/common/notifications/all.inc:557
#, c-format
msgid "^BGRequesting %s^BG to pass you the flag"
-msgstr ""
+msgstr "^BGRogatur ut ^BG%s^BG vexillum tibi det"
#: qcsrc/common/notifications/all.inc:558
#, c-format
msgid "^BGYou passed the ^TC^TT^BG flag to %s"
-msgstr ""
+msgstr "^BGVexillum ^TC^TT^BG %s^BG dedisti"
#: qcsrc/common/notifications/all.inc:559
#, c-format
msgid "^BGYou passed the flag to %s"
-msgstr ""
+msgstr "^BGVexillum %s^BG dedisti"
#: qcsrc/common/notifications/all.inc:560
msgid "^BGYou got the ^TC^TT^BG flag!"
-msgstr ""
+msgstr "^BGVexillum ^TC^TT^BG tenes!"
#: qcsrc/common/notifications/all.inc:561
msgid "^BGYou got the flag!"
-msgstr ""
+msgstr "^BGVexillum tenes!"
#: qcsrc/common/notifications/all.inc:562
#, c-format
msgid "^BGYou got your %steam^BG's flag, return it!"
-msgstr ""
+msgstr "^BGTuae %smanus^BG vexillum tenes, id refer!"
#: qcsrc/common/notifications/all.inc:563
#, c-format
msgid "^BGYou got the %senemy^BG's flag, return it!"
-msgstr ""
+msgstr "%sHostium^BG vexillum tenes, id refer!"
#: qcsrc/common/notifications/all.inc:564
#, c-format
msgid "^BGThe %senemy^BG got your flag! Retrieve it!"
-msgstr ""
+msgstr "%sHostes^BG tuum vexillum tenent! Id recipe!"
#: qcsrc/common/notifications/all.inc:565
#, c-format
msgid "^BGThe %senemy (^BG%s%s)^BG got your flag! Retrieve it!"
-msgstr ""
+msgstr "%sHostes (^BG%s%s)^BG tuum vexillum tenent! Id recipe!"
#: qcsrc/common/notifications/all.inc:566
#, c-format
msgid "^BGThe %senemy^BG got the flag! Retrieve it!"
-msgstr ""
+msgstr "%sHostes^BG vexillum tenent! Id recipe!"
#: qcsrc/common/notifications/all.inc:567
#, c-format
msgid "^BGThe %senemy (^BG%s%s)^BG got the flag! Retrieve it!"
-msgstr ""
+msgstr "%sHostes (^BG%s%s)^BG vexillum tenent! Id recipe!"
#: qcsrc/common/notifications/all.inc:568
#, c-format
msgid "^BGThe %senemy^BG got their flag! Retrieve it!"
-msgstr ""
+msgstr "%sHostes^BG suum vexillum tenent! Id recipe!"
#: qcsrc/common/notifications/all.inc:569
#, c-format
msgid "^BGThe %senemy (^BG%s%s)^BG got their flag! Retrieve it!"
-msgstr ""
+msgstr "%sHostes (^BG%s%s)^BG suum vexillum tenent! Id recipe!"
#: qcsrc/common/notifications/all.inc:570
#, c-format
msgid "^BGYour %steam mate^BG got the ^TC^TT^BG flag! Protect them!"
-msgstr ""
+msgstr "^BGTuus %scollega^BG vexillum ^TC^TT^BG tenet! Eum serva!"
#: qcsrc/common/notifications/all.inc:571
#, c-format
msgid "^BGYour %steam mate (^BG%s%s)^BG got the ^TC^TT^BG flag! Protect them!"
-msgstr ""
+msgstr "^BGTuus %scollega (^BG%s%s)^BG vexillum ^TC^TT^BG tenet! Eum serva!"
#: qcsrc/common/notifications/all.inc:572
#, c-format
msgid "^BGYour %steam mate^BG got the flag! Protect them!"
-msgstr ""
+msgstr "^BGTuus %scollega^BG vexillum tenet! Eum serva!"
#: qcsrc/common/notifications/all.inc:573
#, c-format
msgid "^BGYour %steam mate (^BG%s%s)^BG got the flag! Protect them!"
-msgstr ""
+msgstr "^BGTuus %scollega (^BG%s%s)^BG vexillum tenet! Eum serva!"
#: qcsrc/common/notifications/all.inc:574
#: qcsrc/common/notifications/all.inc:712
msgid "^BGEnemies can now see you on radar!"
-msgstr ""
+msgstr "^BGInimici detectro te videre possunt!"
#: qcsrc/common/notifications/all.inc:575
msgid "^BGYou returned the ^TC^TT^BG flag!"
-msgstr ""
+msgstr "^BGVexillum ^TC^TT^BG rettulisti!"
#: qcsrc/common/notifications/all.inc:576
msgid "^BGStalemate! Enemies can now see you on radar!"
#: qcsrc/common/notifications/all.inc:581
#, c-format
msgid "^K3%sYou fragged ^BG%s"
-msgstr ""
+msgstr "^K3%s^BG%s^K3 occidisti"
#: qcsrc/common/notifications/all.inc:582
#: qcsrc/common/notifications/all.inc:591
#: qcsrc/common/notifications/all.inc:583
#, c-format
msgid "^K1%sYou were fragged by ^BG%s"
-msgstr ""
+msgstr "^K1%sA ^BG%s^K1 occisus es"
#: qcsrc/common/notifications/all.inc:584
#: qcsrc/common/notifications/all.inc:593
#: qcsrc/common/notifications/all.inc:590
#, c-format
msgid "^K3%sYou burned ^BG%s"
-msgstr ""
+msgstr "^K3%s^BG%s^K3 cremavisti"
#: qcsrc/common/notifications/all.inc:592
#, c-format
msgid "^K1%sYou were burned by ^BG%s"
-msgstr ""
+msgstr "^K1%sA ^BG%s^K1 crematus es"
#: qcsrc/common/notifications/all.inc:599
#, c-format
msgid "^K3%sYou froze ^BG%s"
-msgstr ""
+msgstr "^K3%s^BG%s^K3 gelavisti"
#: qcsrc/common/notifications/all.inc:601
#, c-format
msgid "^K1%sYou were frozen by ^BG%s"
-msgstr ""
+msgstr "^K1%sA ^BG%s^K1 gelatus es"
#: qcsrc/common/notifications/all.inc:608
#, c-format
msgid "^K1%sYou typefragged ^BG%s"
-msgstr ""
+msgstr "^K1%s^BG%s^K1 scribentem occidisti"
#: qcsrc/common/notifications/all.inc:609
#, c-format
#: qcsrc/common/notifications/all.inc:610
#, c-format
msgid "^K1%sYou were typefragged by ^BG%s"
-msgstr ""
+msgstr "^K1%sTu scribens a ^BG%s^K1 occisus es"
#: qcsrc/common/notifications/all.inc:611
#, c-format
#: qcsrc/common/notifications/all.inc:617
#, c-format
msgid "^BGPress ^F2%s^BG again to toss the nade!"
-msgstr ""
+msgstr "^F2%s^BG iterum preme ut granatam iacias!"
#: qcsrc/common/notifications/all.inc:618
msgid "^F2You got a ^K1BONUS GRENADE^F2!"
-msgstr ""
+msgstr "^F2Tibi ^K1GRANATA DONATA^F2 est!"
#: qcsrc/common/notifications/all.inc:620
#, c-format
#: qcsrc/client/hud/panel/scoreboard.qc:126
msgid "SCO^destroyed"
-msgstr "销毁"
+msgstr "摧毁"
#: qcsrc/client/hud/panel/scoreboard.qc:127
msgid "SCO^damage"
#: qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc:18
msgid "^1You have no more lives left"
-msgstr "^1你已经用尽你的生命"
+msgstr "^1你已耗尽生命"
#: qcsrc/common/gamemodes/gamemode/lms/lms.qh:11
msgid "Last Man Standing"
#: qcsrc/common/notifications/all.inc:646
msgid "^K1You got caught in the blast of a Bumblebee explosion!"
-msgstr "^K1你被笼罩在野蜂的爆炸中!"
+msgstr "^K1你被野蜂的爆炸吞噬!"
#: qcsrc/common/notifications/all.inc:647
msgid "^K1You were crushed by a vehicle!"
#: qcsrc/common/notifications/all.inc:648
msgid "^K1You were caught in a Raptor cluster bomb!"
-msgstr "^K1ä½ è¢«ç¬¼ç½©å\9c¨ç\8c\9bæ\9eç\9a\84é\9b\86æ\9d\9fç\88\86ç ´ä¸!"
+msgstr "^K1ä½ è¢«ç\8c\9bæ\9eç\9a\84é\9b\86æ\9d\9fç\88\86ç ´å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:649
msgid "^K1You got caught in the blast of a Raptor explosion!"
-msgstr "^K1ä½ è¢«ç¬¼ç½©å\9c¨ç\8c\9bæ\9eç\9a\84ç\88\86ç\82¸ä¸!"
+msgstr "^K1ä½ è¢«ç\8c\9bæ\9eç\9a\84ç\88\86ç\82¸å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:650
msgid "^K1You got caught in the blast of a Spiderbot explosion!"
-msgstr "^K1你被笼罩在蜘蛛机器人的爆炸中!"
+msgstr "^K1你被蜘蛛机器人的爆炸吞噬!"
#: qcsrc/common/notifications/all.inc:651
msgid "^K1You were blasted to bits by a Spiderbot rocket!"
-msgstr "^K1你被蜘蛛机器人炸成了碎片!"
+msgstr "^K1ä½ è¢«è\9c\98è\9b\9bæ\9cºå\99¨äººç\81«ç®å¼¹ç\82¸æ\88\90äº\86ç¢\8eç\89\87ï¼\81"
#: qcsrc/common/notifications/all.inc:652
msgid "^K1You got caught in the blast of a Racer explosion!"
-msgstr "^K1ä½ è¢«ç¬¼ç½©å\9c¨ç«\9eé\80\9fè\80\85ç\9a\84ç\88\86ç\82¸ä¸!"
+msgstr "^K1ä½ è¢«ç«\9eé\80\9fè\80\85ç\9a\84ç\88\86ç\82¸å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:653
msgid "^K1You couldn't find shelter from a Racer rocket!"
#: qcsrc/common/notifications/all.inc:710
msgid "^BGYou have no lives left, you must wait until the next match"
-msgstr "^BG你已耗尽生命,你必须等待至下一轮竞赛"
+msgstr "^BG你已耗尽生命,请静候下一轮竞赛"
#: qcsrc/common/notifications/all.inc:711
msgid ""
"^F4WARNING:^BG you can't rejoin this match after spectating.\n"
"Use the same command again to spectate anyway."
msgstr ""
-"^F4警告:^BG在进入旁观模式后,不能重新加入此局竞赛。\n"
+"^F4警告:^BG进入旁观模式后,将不能重新加入这一局竞赛。\n"
"再次运行此指令以旁观。"
#: qcsrc/common/notifications/all.inc:713
#: qcsrc/common/notifications/all.inc:718
msgid "^BGYour weapon has been downgraded until you find some ammo!"
-msgstr "^BG你的武器被降级,找到一些弹药来恢复!"
+msgstr "^BG你的武器被降级,去找些弹药来恢复!"
#: qcsrc/common/notifications/all.inc:719
msgid "^F4^COUNT^BG left to find some ammo!"
"^F2Now playing ^F4OVERTIME^F2!\n"
"Keep fragging until we have a winner!"
msgstr ""
-"^F2现在是^F4超时阶段^F2!\n"
-"继ç»æ\9d\80æ\95\8cã\80\81ç\9b´å\88°å\86³è\83\9c!"
+"^F2现在是^F4决胜时刻^F2!\n"
+"继ç»æ\9d\80æ\95\8cã\80\81ç\9c\8bè\8a±è\90½è°\81家!"
#: qcsrc/common/notifications/all.inc:737
msgid ""
"^F2Now playing ^F4OVERTIME^F2!\n"
"Keep scoring until we have a winner!"
msgstr ""
-"^F2现在是^F4超时阶段^F2!\n"
-"尽全力进球、直到决胜!"
+"^F2现在是^F4决胜时刻^F2!\n"
+"尽全力进球、力拔头筹!"
#: qcsrc/common/notifications/all.inc:738
msgid ""
"The more control points your team holds,\n"
"the faster the enemy generator decays"
msgstr ""
-"^F2现在是^F4超时阶段^F2!\n"
+"^F2现在是^F4决胜时刻^F2!\n"
"\n"
"发电机开始衰减。\n"
"团队占领的控制点越多,\n"
-"敌方的发电机衰减越快"
+"敌方发电机衰减越快"
#: qcsrc/common/notifications/all.inc:739
#, c-format
"^F2Now playing ^F4OVERTIME^F2!\n"
"^BGAdded ^F4%s^BG to the game!"
msgstr ""
-"^F2现在是^F4超时阶段^F2!\n"
+"^F2现在是^F4决胜时刻^F2!\n"
"^BG为游戏添加了 ^F4%s^BG!"
#: qcsrc/common/notifications/all.inc:741
#: qcsrc/common/turrets/turret/phaser_weapon.qh:7
msgid "Phaser"
-msgstr "相位炮"
+msgstr "相位仪"
#: qcsrc/common/turrets/turret/plasma.qh:13
msgid "Plasma Cannon"
#: qcsrc/common/vehicles/vehicle/bumblebee.qc:956
msgid "No right gunner!"
-msgstr "没有右舷炮架!"
+msgstr "右舷炮架没有炮手!"
#: qcsrc/common/vehicles/vehicle/bumblebee.qc:962
msgid "No left gunner!"
-msgstr "没有左舷炮架!"
+msgstr "左舷炮架没有炮手!"
#: qcsrc/common/vehicles/vehicle/bumblebee.qh:21
msgid "Bumblebee"
#: qcsrc/menu/xonotic/statslist.qc:46
#, no-c-format
msgid "DATE^%m %d, %Y"
-msgstr "%Y 年 %m %d日"
+msgstr "%Y 年 %m %d 日"
#: qcsrc/menu/xonotic/statslist.qc:97
msgid "Joined:"
#: qcsrc/menu/xonotic/util.qc:419
msgid "Update can be downloaded at:"
-msgstr "可从这里下载更新:"
+msgstr "可在这里下载更新:"
#: qcsrc/menu/xonotic/util.qc:509
msgid "Autogenerating mapinfo for newly added maps..."
-msgstr "正在自动生成新增地图的地图信息..."
+msgstr "正在自动生成新增地图的地图信息 (mapinfo)..."
#: qcsrc/menu/xonotic/util.qc:544
#, c-format
#: qcsrc/client/hud/panel/scoreboard.qc:126
msgid "SCO^destroyed"
-msgstr "銷燬"
+msgstr "摧毀"
#: qcsrc/client/hud/panel/scoreboard.qc:127
msgid "SCO^damage"
#: qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc:18
msgid "^1You have no more lives left"
-msgstr "^1你已經用盡你的生命"
+msgstr "^1你已耗盡生命"
#: qcsrc/common/gamemodes/gamemode/lms/lms.qh:11
msgid "Last Man Standing"
#: qcsrc/common/notifications/all.inc:646
msgid "^K1You got caught in the blast of a Bumblebee explosion!"
-msgstr "^K1你被籠罩在野蜂的爆炸中!"
+msgstr "^K1你被野蜂的爆炸吞噬!"
#: qcsrc/common/notifications/all.inc:647
msgid "^K1You were crushed by a vehicle!"
#: qcsrc/common/notifications/all.inc:648
msgid "^K1You were caught in a Raptor cluster bomb!"
-msgstr "^K1ä½ è¢«ç± ç½©å\9c¨ç\8c\9bæ¢\9fç\9a\84é\9b\86æ\9d\9fç\88\86ç ´ä¸!"
+msgstr "^K1ä½ è¢«ç\8c\9bæ¢\9fç\9a\84é\9b\86æ\9d\9fç\88\86ç ´å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:649
msgid "^K1You got caught in the blast of a Raptor explosion!"
-msgstr "^K1ä½ è¢«ç± ç½©å\9c¨ç\8c\9bæ¢\9fç\9a\84ç\88\86ç\82¸ä¸!"
+msgstr "^K1ä½ è¢«ç\8c\9bæ¢\9fç\9a\84ç\88\86ç\82¸å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:650
msgid "^K1You got caught in the blast of a Spiderbot explosion!"
-msgstr "^K1你被籠罩在蜘蛛機器人的爆炸中!"
+msgstr "^K1你被蜘蛛機器人的爆炸吞噬!"
#: qcsrc/common/notifications/all.inc:651
msgid "^K1You were blasted to bits by a Spiderbot rocket!"
-msgstr "^K1你被蜘蛛機器人炸成了碎片!"
+msgstr "^K1ä½ è¢«è\9c\98è\9b\9bæ©\9få\99¨äººç\81«ç®å½\88ç\82¸æ\88\90äº\86ç¢\8eç\89\87ï¼\81"
#: qcsrc/common/notifications/all.inc:652
msgid "^K1You got caught in the blast of a Racer explosion!"
-msgstr "^K1ä½ è¢«ç± ç½©å\9c¨ç«¶é\80\9fè\80\85ç\9a\84ç\88\86ç\82¸ä¸!"
+msgstr "^K1ä½ è¢«ç«¶é\80\9fè\80\85ç\9a\84ç\88\86ç\82¸å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:653
msgid "^K1You couldn't find shelter from a Racer rocket!"
#: qcsrc/common/notifications/all.inc:710
msgid "^BGYou have no lives left, you must wait until the next match"
-msgstr "^BG你已耗盡生命,你必須等待至下一輪競賽"
+msgstr "^BG你已耗盡生命,請靜候下一輪競賽"
#: qcsrc/common/notifications/all.inc:711
msgid ""
"^F4WARNING:^BG you can't rejoin this match after spectating.\n"
"Use the same command again to spectate anyway."
msgstr ""
-"^F4警告:^BG在進入旁觀模式後,不能重新加入此局競賽。\n"
+"^F4警告:^BG進入旁觀模式後,將不能重新加入這一局競賽。\n"
"再次運行此指令以旁觀。"
#: qcsrc/common/notifications/all.inc:713
#: qcsrc/common/notifications/all.inc:718
msgid "^BGYour weapon has been downgraded until you find some ammo!"
-msgstr "^BG你的武器被降級,找到一些彈藥來恢復!"
+msgstr "^BG你的武器被降級,去找些彈藥來恢復!"
#: qcsrc/common/notifications/all.inc:719
msgid "^F4^COUNT^BG left to find some ammo!"
"^F2Now playing ^F4OVERTIME^F2!\n"
"Keep fragging until we have a winner!"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
-"ç¹¼çº\8c殺æ\95µã\80\81ç\9b´å\88°æ±ºå\8b\9d!"
+"^F2現在是^F4決勝時刻^F2!\n"
+"ç¹¼çº\8c殺æ\95µã\80\81ç\9c\8bè\8a±è\90½èª°å®¶!"
#: qcsrc/common/notifications/all.inc:737
msgid ""
"^F2Now playing ^F4OVERTIME^F2!\n"
"Keep scoring until we have a winner!"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
-"盡全力進球、直到決勝!"
+"^F2現在是^F4決勝時刻^F2!\n"
+"盡全力進球、力拔頭籌!"
#: qcsrc/common/notifications/all.inc:738
msgid ""
"The more control points your team holds,\n"
"the faster the enemy generator decays"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
+"^F2現在是^F4決勝時刻^F2!\n"
"\n"
"發電機開始衰減。\n"
"團隊佔領的控制點越多,\n"
-"æ\95µæ\96¹ç\9a\84ç\99¼é\9b»æ©\9fè¡°æ¸\9bè¶\8aå¿«"
+"敵方發電機衰減越快"
#: qcsrc/common/notifications/all.inc:739
#, c-format
"^F2Now playing ^F4OVERTIME^F2!\n"
"^BGAdded ^F4%s^BG to the game!"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
+"^F2現在是^F4決勝時刻^F2!\n"
"^BG為遊戲添加了 ^F4%s^BG!"
#: qcsrc/common/notifications/all.inc:741
#: qcsrc/common/turrets/turret/phaser_weapon.qh:7
msgid "Phaser"
-msgstr "相位炮"
+msgstr "相位儀"
#: qcsrc/common/turrets/turret/plasma.qh:13
msgid "Plasma Cannon"
#: qcsrc/common/vehicles/vehicle/bumblebee.qc:956
msgid "No right gunner!"
-msgstr "沒有右舷炮架!"
+msgstr "右舷炮架沒有炮手!"
#: qcsrc/common/vehicles/vehicle/bumblebee.qc:962
msgid "No left gunner!"
-msgstr "沒有左舷炮架!"
+msgstr "左舷炮架沒有炮手!"
#: qcsrc/common/vehicles/vehicle/bumblebee.qh:21
msgid "Bumblebee"
#: qcsrc/menu/xonotic/statslist.qc:46
#, no-c-format
msgid "DATE^%m %d, %Y"
-msgstr "%Y 年 %m %d日"
+msgstr "%Y 年 %m %d 日"
#: qcsrc/menu/xonotic/statslist.qc:97
msgid "Joined:"
#: qcsrc/menu/xonotic/util.qc:419
msgid "Update can be downloaded at:"
-msgstr "å\8f¯å¾\9e這裏下載更新:"
+msgstr "å\8f¯å\9c¨這裏下載更新:"
#: qcsrc/menu/xonotic/util.qc:509
msgid "Autogenerating mapinfo for newly added maps..."
-msgstr "正在自動生成新增地圖的地圖信息..."
+msgstr "正在自動生成新增地圖的地圖信息 (mapinfo)..."
#: qcsrc/menu/xonotic/util.qc:544
#, c-format
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-12-04 07:22+0100\n"
"PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: é»\83æ\9f\8f諺 <s8321414@gmail.com>, 2015\n"
+"Last-Translator: é\9f¬ å\88\98 <jiegushijia@gmail.com>, 2019\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/team-xonotic/"
"xonotic/language/zh_TW/)\n"
"Language: zh_TW\n"
#: qcsrc/client/hud/panel/scoreboard.qc:126
msgid "SCO^destroyed"
-msgstr "銷燬"
+msgstr "摧毀"
#: qcsrc/client/hud/panel/scoreboard.qc:127
msgid "SCO^damage"
#: qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc:18
msgid "^1You have no more lives left"
-msgstr "^1你已經用盡你的生命"
+msgstr "^1你已耗盡生命"
#: qcsrc/common/gamemodes/gamemode/lms/lms.qh:11
msgid "Last Man Standing"
#: qcsrc/common/notifications/all.inc:646
msgid "^K1You got caught in the blast of a Bumblebee explosion!"
-msgstr "^K1你被籠罩在野蜂的爆炸中!"
+msgstr "^K1你被野蜂的爆炸吞噬!"
#: qcsrc/common/notifications/all.inc:647
msgid "^K1You were crushed by a vehicle!"
#: qcsrc/common/notifications/all.inc:648
msgid "^K1You were caught in a Raptor cluster bomb!"
-msgstr "^K1ä½ è¢«ç± ç½©å\9c¨ç\8c\9b禽ç\9a\84é\9b\86æ\9d\9fç\88\86ç ´ä¸!"
+msgstr "^K1ä½ è¢«ç\8c\9b禽ç\9a\84é\9b\86æ\9d\9fç\88\86ç ´å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:649
msgid "^K1You got caught in the blast of a Raptor explosion!"
-msgstr "^K1ä½ è¢«ç± ç½©å\9c¨ç\8c\9b禽ç\9a\84ç\88\86ç\82¸ä¸!"
+msgstr "^K1ä½ è¢«ç\8c\9b禽ç\9a\84ç\88\86ç\82¸å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:650
msgid "^K1You got caught in the blast of a Spiderbot explosion!"
-msgstr "^K1你被籠罩在蜘蛛機器人的爆炸中!"
+msgstr "^K1你被蜘蛛機器人的爆炸吞噬!"
#: qcsrc/common/notifications/all.inc:651
msgid "^K1You were blasted to bits by a Spiderbot rocket!"
-msgstr "^K1你被蜘蛛機器人炸成了碎片!"
+msgstr "^K1ä½ è¢«è\9c\98è\9b\9bæ©\9få\99¨äººç\81«ç®å½\88ç\82¸æ\88\90äº\86ç¢\8eç\89\87ï¼\81"
#: qcsrc/common/notifications/all.inc:652
msgid "^K1You got caught in the blast of a Racer explosion!"
-msgstr "^K1ä½ è¢«ç± ç½©å\9c¨ç«¶é\80\9fè\80\85ç\9a\84ç\88\86ç\82¸ä¸!"
+msgstr "^K1ä½ è¢«ç«¶é\80\9fè\80\85ç\9a\84ç\88\86ç\82¸å\90\9eå\99¬!"
#: qcsrc/common/notifications/all.inc:653
msgid "^K1You couldn't find shelter from a Racer rocket!"
#: qcsrc/common/notifications/all.inc:710
msgid "^BGYou have no lives left, you must wait until the next match"
-msgstr "^BG你已耗盡生命,你必須等待至下一輪競賽"
+msgstr "^BG你已耗盡生命,請靜候下一輪競賽"
#: qcsrc/common/notifications/all.inc:711
msgid ""
"^F4WARNING:^BG you can't rejoin this match after spectating.\n"
"Use the same command again to spectate anyway."
msgstr ""
-"^F4警告:^BG在進入旁觀模式後,不能重新加入此局競賽。\n"
+"^F4警告:^BG進入旁觀模式後,將不能重新加入這一局競賽。\n"
"再次執行此指令以旁觀。"
#: qcsrc/common/notifications/all.inc:713
#: qcsrc/common/notifications/all.inc:718
msgid "^BGYour weapon has been downgraded until you find some ammo!"
-msgstr "^BG你的武器被降級,找到一些彈藥來恢復!"
+msgstr "^BG你的武器被降級,去找些彈藥來恢復!"
#: qcsrc/common/notifications/all.inc:719
msgid "^F4^COUNT^BG left to find some ammo!"
"^F2Now playing ^F4OVERTIME^F2!\n"
"Keep fragging until we have a winner!"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
-"ç¹¼çº\8c殺æ\95µã\80\81ç\9b´å\88°æ±ºå\8b\9d!"
+"^F2現在是^F4決勝時刻^F2!\n"
+"ç¹¼çº\8c殺æ\95µã\80\81ç\9c\8bè\8a±è\90½èª°å®¶!"
#: qcsrc/common/notifications/all.inc:737
msgid ""
"^F2Now playing ^F4OVERTIME^F2!\n"
"Keep scoring until we have a winner!"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
-"盡全力進球、直到決勝!"
+"^F2現在是^F4決勝時刻^F2!\n"
+"盡全力進球、力拔頭籌!"
#: qcsrc/common/notifications/all.inc:738
msgid ""
"The more control points your team holds,\n"
"the faster the enemy generator decays"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
+"^F2現在是^F4決勝時刻^F2!\n"
"\n"
"發電機開始衰減。\n"
"團隊佔領的控制點越多,\n"
-"æ\95µæ\96¹ç\9a\84ç\99¼é\9b»æ©\9fè¡°æ¸\9bè¶\8aå¿«"
+"敵方發電機衰減越快"
#: qcsrc/common/notifications/all.inc:739
#, c-format
"^F2Now playing ^F4OVERTIME^F2!\n"
"^BGAdded ^F4%s^BG to the game!"
msgstr ""
-"^F2現在是^F4超時階段^F2!\n"
+"^F2現在是^F4決勝時刻^F2!\n"
"^BG為遊戲添加了 ^F4%s^BG!"
#: qcsrc/common/notifications/all.inc:741
#: qcsrc/common/turrets/turret/phaser_weapon.qh:7
msgid "Phaser"
-msgstr "相位炮"
+msgstr "相位儀"
#: qcsrc/common/turrets/turret/plasma.qh:13
msgid "Plasma Cannon"
#: qcsrc/common/vehicles/vehicle/bumblebee.qc:956
msgid "No right gunner!"
-msgstr "沒有右舷炮架!"
+msgstr "右舷炮架沒有炮手!"
#: qcsrc/common/vehicles/vehicle/bumblebee.qc:962
msgid "No left gunner!"
-msgstr "沒有左舷炮架!"
+msgstr "左舷炮架沒有炮手!"
#: qcsrc/common/vehicles/vehicle/bumblebee.qh:21
msgid "Bumblebee"
#: qcsrc/menu/xonotic/statslist.qc:46
#, no-c-format
msgid "DATE^%m %d, %Y"
-msgstr "%Y 年 %m %d日"
+msgstr "%Y 年 %m %d 日"
#: qcsrc/menu/xonotic/statslist.qc:97
msgid "Joined:"
#: qcsrc/menu/xonotic/util.qc:419
msgid "Update can be downloaded at:"
-msgstr "å\8f¯å¾\9e這裡下載更新:"
+msgstr "å\8f¯å\9c¨這裡下載更新:"
#: qcsrc/menu/xonotic/util.qc:509
msgid "Autogenerating mapinfo for newly added maps..."
-msgstr "正在自動生成新增地圖的地圖資訊..."
+msgstr "正在自動生成新增地圖的地圖資訊 (mapinfo)..."
#: qcsrc/menu/xonotic/util.qc:544
#, c-format
set g_ctf_stalemate_endcondition 1 "condition for stalemate mode to be finished: 1 = If ONE flag is no longer stale, 2 = If BOTH flags are no longer stale"
set g_ctf_stalemate_time 60 "time for each flag until stalemate mode is activated"
set g_ctf_flagcarrier_waypointforenemy_spotting 1 "show the enemy flagcarrier location if a team mate presses +use to spot them"
-set g_ctf_dropped_capture_delay 1.5 "autocapture delay when flag is thrown onto the base - counted from throw, not landing"
+set g_ctf_dropped_capture_delay 1 "autocapture delay when flag is thrown onto the base - counted from when the flag lands on the ground"
set g_ctf_dropped_capture_radius 100 "allow dropped flags to be automatically captured by base flags if the dropped flag is within this radius of it"
set g_ctf_flag_damageforcescale 2
set g_ctf_portalteleport 0 "allow flag carriers to go through portals made in portal gun without dropping the flag"
set g_cts_finish_kill_delay 2 "kill player this many seconds after stage completion to prevent cheating by starting out with more speed than otherwise possible; set it to 0 to not kill or to -1 to kill instantly"
set g_cts_send_rankings_cnt 15 "send this number of map records to clients"
set g_cts_removeprojectiles 0 "remove projectiles when the player dies, to prevent using weapons earlier in the stage than intended"
+set g_cts_drop_monster_items 0 "allow killed monsters to drop their items"
// ==========================
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"
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
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"
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
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"
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 ""
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
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"
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 ""
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
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"
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
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"
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 ""
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
fi "Finnish" "Suomi" 99%
sv "Swedish" "Svenska" 99%
tr "Turkish" "Türkçe" 51%
-zh_HK "zh_HK" "zh_HK" 100%
cs "Czech" "Čeština" 31%
el "Greek" "Ελληνική" 44%
be "Belarusian" "Беларуская" 50%
ru "Russian" "Русский" 100%
sr "Serbian" "Српски" 59%
uk "Ukrainian" "Українська" 50%
-zh_CN "Chinese (China)" "中文" 100%
-zh_TW "Chinese (Taiwan)" "國語" 100%
+zh_TW "Chinese (Taiwan)" "中文(正體字)" 100%
+zh_CN "Chinese (China)" "中文(简体字)" 100%
+zh_HK "Chinese (Hong Kong)" "中文(香港字)" 100%
ja_JP "Japanese" "日本語" 99%
ko "Korean" "한국의" 35%
set g_monster_mage_heal_delay 1.5
set g_monster_mage_heal_minhealth 250
set g_monster_mage_heal_range 250
-set g_monster_mage_heal_self 40
set g_monster_mage_health 400
set g_monster_mage_shield_blockpercent 0.8
set g_monster_mage_shield_delay 7
float weapontime;
float weaponprevtime;
+float timer;
float teamnagger;
int hudShiftState;
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:
#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>
#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>
else
{
row = column = 0;
- // disabling new-style loop for now to restore original order of ammo types
- //FOREACH(Resources, it.instanceOfAmmoResource && !it.m_hidden,
- for(int j = 0; j < AMMO_COUNT; ++j)
+ IL_EACH(default_order_resources, it.instanceOfAmmoResource && !it.m_hidden,
{
- Resource ammotype = GetAmmoTypeFromNum(j);
DrawAmmoItem(
pos + vec2(column * (ammo_size.x + offset.x), row * (ammo_size.y + offset.y)),
ammo_size,
- ammotype,
- (wep.ammo_type == ammotype),
+ it,
+ (wep.ammo_type == it),
infinite_ammo
);
row = 0;
column = column + 1;
}
- }
+ });
}
if (draw_nades)
--- /dev/null
+#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);
+ }
+}
--- /dev/null
+#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);
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;
// 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);
// 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;
// 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);
}
}
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);
Scoreboard_UI_Enable(0);
return true;
}
- if (!isdemo() && cvar("_menu_gamemenu_dialog_available"))
+ if (autocvar_menu_gamemenu && !isdemo() && cvar("_menu_gamemenu_dialog_available"))
{
localcmd("\nmenu_showgamemenudialog\n");
return true;
bool autocvar_cl_race_cptimes_onlyself; // TODO: move to race gamemode
bool autocvar_cl_race_cptimes_showself = false;
bool autocvar_cl_welcome = true;
+bool autocvar_menu_gamemenu = true;
// Map coordinate base calculations need these
vector mi_center;
this.origin += bobmodel_ofs(view);
}
-.vector viewmodel_origin, viewmodel_angles;
.float weapon_nextthink;
.float weapon_eta_last;
.float weapon_switchdelay;
void viewmodel_draw(entity this)
{
- if(!this.activeweapon || !autocvar_r_drawviewmodel)
- return;
int mask = (intermission || (STAT(HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL;
float a = ((autocvar_cl_viewmodel_alpha) ? bound(-1, autocvar_cl_viewmodel_alpha, this.m_alpha) : this.m_alpha);
int wepskin = this.m_skin;
{
this.name_last = name;
CL_WeaponEntity_SetModel(this, name, swap);
- this.viewmodel_origin = this.origin;
- this.viewmodel_angles = this.angles;
+ this.origin += autocvar_cl_gunoffset;
}
anim_update(this);
if ((!this.animstate_override && !this.animstate_looping) || time > this.animstate_endtime)
}
}
this.weapon_eta_last = f;
- this.origin = this.viewmodel_origin;
- this.angles = this.viewmodel_angles;
this.angles_x = (-90 * f * f);
viewmodel_animate(this);
MUTATOR_CALLHOOK(DrawViewModel, this);
UpdateDamage();
HUD_Crosshair(this);
HitSound();
+ Local_Notification_Queue_Process();
}
void ViewLocation_Mouse()
// run viewmodel_draw before updating view_angles to the angles calculated by WarpZone_FixView
// viewmodel_draw needs to use the view_angles set by the engine on every CSQC_UpdateView call
- for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- viewmodel_draw(viewmodels[slot]);
+ if(autocvar_r_drawviewmodel)
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ if(viewmodels[slot].activeweapon)
+ viewmodel_draw(viewmodels[slot]);
// Render the Scene
view_origin = getpropertyvec(VF_ORIGIN);
string autocvar__togglezoom;
int autocvar_cl_nade_timer;
bool autocvar_r_drawviewmodel;
+vector autocvar_cl_gunoffset;
void calc_followmodel_ofs(entity view);
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;
REPLICATE(cvar_r_drawviewmodel, int, "r_drawviewmodel");
#ifdef SVQC
-void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity)
+void SpawnCasing(vector vel, vector ang, int casingtype, entity casingowner, .entity weaponentity)
{
vector org = casingowner.(weaponentity).spawnorigin;
org = casingowner.origin + casingowner.view_ofs + org.x * v_forward - org.y * v_right + org.z * v_up;
FOREACH_CLIENT(true, {
if (!(CS_CVAR(it).cvar_cl_casings))
continue;
- if (it == casingowner && !(CS_CVAR(it).cvar_r_drawviewmodel))
+
+ casingtype &= 0x3F; // reset any bitflags that were set for the previous client
+
+ if (it == casingowner || (IS_SPEC(it) && it.enemy == casingowner))
+ {
+ if (!(CS_CVAR(it).cvar_r_drawviewmodel))
+ continue;
+
+ casingtype |= 0x40; // client will apply autocvar_cl_gunoffset in first person
+ }
+ else if (1 & ~checkpvs(it.origin + it.view_ofs, casingowner)) // 1 or 3 means visible
continue;
- msg_entity = it;
+ msg_entity = it; // sound_allowed checks this
if (!sound_allowed(MSG_ONE, it))
casingtype |= 0x80; // silent
WriteShort(MSG_ONE, compressShortVector(vel)); // actually compressed velocity
WriteByte(MSG_ONE, ang.x * 256 / 360);
WriteByte(MSG_ONE, ang.y * 256 / 360);
- WriteByte(MSG_ONE, ang.z * 256 / 360);
+ // weapons only have pitch and yaw, so no need to send ang.z
});
}
#endif
classfield(Casing) .int state;
classfield(Casing) .float cnt;
+// this is only needed because LimitedChildrenRubble() takes a func pointer
void Casing_Delete(entity this)
{
delete(this);
if (this.alpha < ALPHA_MIN_VISIBLE)
{
- Casing_Delete(this);
+ delete(this);
this.drawmask = 0;
return;
}
+ trace_startsolid = 0; // due to cl_casings_ticrate, traces are not always performed
Movetype_Physics_MatchTicrate(this, autocvar_cl_casings_ticrate, autocvar_cl_casings_sloppy);
//if (wasfreed(this))
// return; // deleted by touch function
+
+ // prevent glitchy casings when the gun model is poking into a wall
+ // doing this here is cheaper than doing it on the server as the client performs the trace anyway
+ if (trace_startsolid)
+ {
+ delete(this);
+ this.drawmask = 0;
+ return;
+ }
}
SOUND(BRASS1, W_Sound("brass1"));
{
if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
{
- Casing_Delete(this);
+ delete(this);
return;
}
NET_HANDLE(casings, bool isNew)
{
- int _state = ReadByte();
- vector org = ReadVector();
- vector vel = decompressShortVector(ReadShort());
- vector ang;
- ang_x = ReadByte() * 360 / 256;
- ang_y = ReadByte() * 360 / 256;
- ang_z = ReadByte() * 360 / 256;
+ Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
+
+ casing.state = ReadByte();
+ casing.origin = ReadVector();
+ casing.velocity = decompressShortVector(ReadShort());
+ casing.angles_x = ReadByte() * 360 / 256;
+ casing.angles_y = ReadByte() * 360 / 256;
+
return = true;
- Casing casing = ListNewChildRubble(CasingsNGibs, new(casing));
- casing.silent = (_state & 0x80);
- casing.state = (_state & 0x7F);
- casing.origin = org;
+ casing.silent = casing.state & 0x80;
+ if (casing.state & 0x40 && !autocvar_chase_active)
+ casing.origin += autocvar_cl_gunoffset.x * v_forward
+ - autocvar_cl_gunoffset.y * v_right
+ + autocvar_cl_gunoffset.z * v_up;
+ casing.state &= 0x3F; // the 2 most significant bits are reserved for the silent and casingowner bitflags
+
setorigin(casing, casing.origin);
- casing.velocity = vel;
- casing.angles = ang;
casing.drawmask = MASK_NORMAL;
-
casing.draw = Casing_Draw;
if (isNew) IL_PUSH(g_drawables, casing);
- casing.velocity = casing.velocity + 2 * prandomvec();
- casing.avelocity = '0 250 0' + 100 * prandomvec();
+ casing.velocity += 2 * prandomvec();
+ casing.avelocity = '0 10 0' + 100 * prandomvec();
set_movetype(casing, MOVETYPE_BOUNCE);
- casing.bouncefactor = 0.25;
settouch(casing, Casing_Touch);
casing.move_time = time;
casing.event_damage = Casing_Damage;
{
case 1:
setmodel(casing, MDL_CASING_SHELL);
+ casing.bouncefactor = 0.25;
casing.cnt = time + autocvar_cl_casings_shell_time;
break;
default:
setmodel(casing, MDL_CASING_BULLET);
+ casing.bouncefactor = 0.5;
casing.cnt = time + autocvar_cl_casings_bronze_time;
break;
}
- setsize(casing, '0 0 -1', '0 0 -1');
-
LimitedChildrenRubble(CasingsNGibs, "casing", autocvar_cl_casings_maxcount, Casing_Delete, NULL);
}
int autocvar_cl_casings_maxcount = 100;
float autocvar_cl_casings_shell_time;
bool autocvar_cl_casings_sloppy = 1;
-float autocvar_cl_casings_ticrate = 0.1;
+float autocvar_cl_casings_ticrate;
#endif
#ifdef GAMEQC
#ifdef SVQC
int autocvar_g_casings;
-void SpawnCasing(vector vel, float randomvel, vector ang, vector avel, float randomavel, int casingtype, entity casingowner, .entity weaponentity);
+void SpawnCasing(vector vel, vector ang, int casingtype, entity casingowner, .entity weaponentity);
#endif
WriteByte(MSG_ENTITY, bound(1, this.dmg, 255));
WriteByte(MSG_ENTITY, bound(0, this.dmg_radius, 255));
WriteByte(MSG_ENTITY, bound(1, this.dmg_edge, 255));
- WriteShort(MSG_ENTITY, this.oldorigin.x);
+ WriteVector(MSG_ENTITY, this.velocity);
WriteByte(MSG_ENTITY, this.species);
return true;
}
-void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner)
+void Damage_DamageInfo(vector org, bool is_solid_hit, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner)
{
// TODO maybe call this from non-edgedamage too?
// TODO maybe make the client do the particle effects for the weapons and the impact sounds using this info?
e.dmg_radius = rad;
e.dmg_force = vlen(force);
e.velocity = force;
- e.oldorigin_x = compressShortVector(e.velocity);
e.species = bloodtype;
+ if(is_solid_hit)
+ e.species |= 0x80;
Net_LinkEntity(e, false, 0.2, Damage_DamageInfo_SendEntity);
}
thedamage = ReadByte();
rad = ReadByte();
edge = ReadByte();
- force = decompressShortVector(ReadShort());
+ force = ReadVector();
species = ReadByte();
+ bool is_solid_hit = (species & 0x80);
+ species = (species & 0x7F);
return = true;
w_random = prandom();
vector force_dir = normalize(force);
- traceline(w_org - force_dir * 16, w_org + force_dir * 16, MOVE_NOMONSTERS, NULL);
- if(trace_fraction < 1 && !(hitwep.spawnflags & WEP_TYPE_HITSCAN))
- w_backoff = trace_plane_normal;
- else
+ if (is_solid_hit) // traceline not needed
w_backoff = -force_dir;
+ else
+ {
+ traceline(w_org - force_dir * 16, w_org + force_dir * 16, MOVE_NOMONSTERS, NULL);
+ if(trace_fraction < 1 && !(hitwep.spawnflags & WEP_TYPE_HITSCAN))
+ w_backoff = trace_plane_normal;
+ else
+ w_backoff = -force_dir;
+ }
setorigin(this, w_org + w_backoff * 2); // for sound() calls
if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY))
flag.angles = '0 0 0';
SetResourceExplicit(flag, RES_HEALTH, flag.max_health);
flag.ctf_droptime = time;
+ flag.ctf_landtime = 0;
flag.ctf_dropper = player;
flag.ctf_status = FLAG_DROPPED;
flag.solid = SOLID_TRIGGER;
flag.ctf_dropper = player;
flag.ctf_droptime = time;
+ flag.ctf_landtime = 0;
flag.flags = FL_ITEM | FL_NOTARGET; // clear FL_ONGROUND for MOVETYPE_TOSS
for(tmp_entity = ctf_worldflaglist; tmp_entity; tmp_entity = tmp_entity.ctf_worldflagnext)
if(tmp_entity.ctf_status == FLAG_DROPPED)
if(vdist(this.origin - tmp_entity.origin, <, autocvar_g_ctf_dropped_capture_radius))
- if(time > tmp_entity.ctf_droptime + autocvar_g_ctf_dropped_capture_delay)
+ if((this.noalign || tmp_entity.ctf_landtime) && time > ((this.noalign) ? tmp_entity.ctf_droptime : tmp_entity.ctf_landtime) + autocvar_g_ctf_dropped_capture_delay)
ctf_Handle_Capture(this, tmp_entity, CAPTURE_DROPPED);
}
return;
case FLAG_DROPPED:
{
this.angles = '0 0 0'; // reset flag angles in case warpzones adjust it
+ if(IS_ONGROUND(this) && !this.ctf_landtime)
+ this.ctf_landtime = time; // landtime is reset when thrown, and we don't want to restart the timer if the flag is pushed
if(autocvar_g_ctf_flag_dropped_floatinwater)
{
flag.ctf_dropper = NULL;
flag.ctf_pickuptime = 0;
flag.ctf_droptime = 0;
+ flag.ctf_landtime = 0;
flag.ctf_flagdamaged_byworld = false;
navigation_dynamicgoal_unset(flag);
float ctf_captimerecord; // record time for capturing the flag
.float ctf_pickuptime;
.float ctf_droptime;
+.float ctf_landtime;
.int ctf_status; // status of the flag (FLAG_BASE, FLAG_DROPPED, FLAG_CARRY declared globally)
.entity ctf_dropper; // don't allow spam of dropping the flag
.float next_take_time;
float autocvar_g_cts_finish_kill_delay;
bool autocvar_g_cts_selfdamage;
bool autocvar_g_cts_removeprojectiles;
+bool autocvar_g_cts_drop_monster_items;
// legacy bot roles
.float race_checkpoint;
if (Item_IsLoot(item))
{
+ if(item.monster_loot && autocvar_g_cts_drop_monster_items)
+ return false;
return true;
}
}
#endif
#ifdef CSQC
+#include <client/hud/panel/pickup.qh>
+
Inventory g_inventory;
+
void Inventory_remove(entity this)
{
if(g_inventory == this)
.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
ENDCLASS(Ammo)
+// NOTE: ammo resource registration order should match ammo (as item) registration order
+// see REGISTER_RESOURCE calls order
+
+// ammo type #1: shells
#ifdef GAMEQC
-MODEL(Bullets_ITEM, Item_Model("a_bullets.mdl"));
+MODEL(Shells_ITEM, Item_Model("a_shells.md3"));
#endif
#ifdef SVQC
-PROPERTY(int, g_pickup_nails);
-void ammo_bullets_init(Pickup this, entity item)
+PROPERTY(int, g_pickup_shells);
+void ammo_shells_init(Pickup this, entity item)
{
- if(!GetResource(item, RES_BULLETS))
- SetResourceExplicit(item, RES_BULLETS, g_pickup_nails);
+ if(!GetResource(item, RES_SHELLS))
+ SetResourceExplicit(item, RES_SHELLS, g_pickup_shells);
}
#endif
-CLASS(Bullets, Ammo)
-ENDCLASS(Bullets)
+CLASS(Shells, Ammo)
+ENDCLASS(Shells)
-REGISTER_ITEM(Bullets, Bullets) {
- this.m_canonical_spawnfunc = "item_bullets";
+REGISTER_ITEM(Shells, Shells) {
+ this.m_canonical_spawnfunc = "item_shells";
#ifdef GAMEQC
- this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
- this.m_model = MDL_Bullets_ITEM;
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
+ this.m_model = MDL_Shells_ITEM;
#endif
- this.netname = "bullets";
- this.m_name = _("bullets");
- this.m_icon = "ammo_bullets";
+ this.netname = "shells";
+ this.m_name = _("Shells");
+ this.m_icon = "ammo_shells";
#ifdef SVQC
- this.m_botvalue = 1500;
- this.m_itemid = IT_RESOURCE;
- this.m_iteminit = ammo_bullets_init;
+ this.m_botvalue = 1000;
+ this.m_itemid = IT_RESOURCE;
+ this.m_iteminit = ammo_shells_init;
#endif
}
-SPAWNFUNC_ITEM(item_bullets, ITEM_Bullets)
+SPAWNFUNC_ITEM(item_shells, ITEM_Shells)
+
+// ammo type #2: bullets
#ifdef GAMEQC
-MODEL(Cells_ITEM, Item_Model("a_cells.md3"));
+MODEL(Bullets_ITEM, Item_Model("a_bullets.mdl"));
#endif
#ifdef SVQC
-PROPERTY(int, g_pickup_cells);
-void ammo_cells_init(Pickup this, entity item)
+PROPERTY(int, g_pickup_nails);
+void ammo_bullets_init(Pickup this, entity item)
{
- if(!GetResource(item, RES_CELLS))
- SetResourceExplicit(item, RES_CELLS, g_pickup_cells);
+ if(!GetResource(item, RES_BULLETS))
+ SetResourceExplicit(item, RES_BULLETS, g_pickup_nails);
}
#endif
-REGISTER_ITEM(Cells, Ammo) {
- this.m_canonical_spawnfunc = "item_cells";
+
+CLASS(Bullets, Ammo)
+ENDCLASS(Bullets)
+
+REGISTER_ITEM(Bullets, Bullets) {
+ this.m_canonical_spawnfunc = "item_bullets";
#ifdef GAMEQC
- this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
- this.m_model = MDL_Cells_ITEM;
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
+ this.m_model = MDL_Bullets_ITEM;
#endif
- this.netname = "cells";
- this.m_name = _("cells");
- this.m_icon = "ammo_cells";
+ this.netname = "bullets";
+ this.m_name = _("Bullets");
+ this.m_icon = "ammo_bullets";
#ifdef SVQC
- this.m_botvalue = 1500;
- this.m_itemid = IT_RESOURCE;
- this.m_iteminit = ammo_cells_init;
+ this.m_botvalue = 1500;
+ this.m_itemid = IT_RESOURCE;
+ this.m_iteminit = ammo_bullets_init;
#endif
}
-SPAWNFUNC_ITEM(item_cells, ITEM_Cells)
+SPAWNFUNC_ITEM(item_bullets, ITEM_Bullets)
+
+// ammo type #3: rockets
#ifdef GAMEQC
-MODEL(Plasma_ITEM, Item_Model("a_cells.md3"));
+MODEL(Rockets_ITEM, Item_Model("a_rockets.md3"));
#endif
#ifdef SVQC
-PROPERTY(int, g_pickup_plasma);
-void ammo_plasma_init(Pickup this, entity item)
+PROPERTY(int, g_pickup_rockets);
+void ammo_rockets_init(Pickup this, entity item)
{
- if(!GetResource(item, RES_PLASMA))
- SetResourceExplicit(item, RES_PLASMA, g_pickup_plasma);
+ if(!GetResource(item, RES_ROCKETS))
+ SetResourceExplicit(item, RES_ROCKETS, g_pickup_rockets);
}
#endif
-REGISTER_ITEM(Plasma, Ammo) {
- this.m_canonical_spawnfunc = "item_plasma";
+REGISTER_ITEM(Rockets, Ammo) {
+ this.m_canonical_spawnfunc = "item_rockets";
#ifdef GAMEQC
- this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
- this.m_model = MDL_Plasma_ITEM;
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
+ this.m_model = MDL_Rockets_ITEM;
#endif
- this.netname = "plasma";
- this.m_name = _("plasma");
- this.m_icon = "ammo_plasma";
+ this.netname = "rockets";
+ this.m_name = _("Rockets");
+ this.m_icon = "ammo_rockets";
#ifdef SVQC
- this.m_botvalue = 1500;
- this.m_itemid = IT_RESOURCE;
- this.m_iteminit = ammo_plasma_init;
+ this.m_botvalue = 1500;
+ this.m_itemid = IT_RESOURCE;
+ this.m_iteminit = ammo_rockets_init;
#endif
}
-SPAWNFUNC_ITEM(item_plasma, ITEM_Plasma)
+SPAWNFUNC_ITEM(item_rockets, ITEM_Rockets)
+
+// ammo type #4: cells
#ifdef GAMEQC
-MODEL(Rockets_ITEM, Item_Model("a_rockets.md3"));
+MODEL(Cells_ITEM, Item_Model("a_cells.md3"));
#endif
#ifdef SVQC
-PROPERTY(int, g_pickup_rockets);
-void ammo_rockets_init(Pickup this, entity item)
+PROPERTY(int, g_pickup_cells);
+void ammo_cells_init(Pickup this, entity item)
{
- if(!GetResource(item, RES_ROCKETS))
- SetResourceExplicit(item, RES_ROCKETS, g_pickup_rockets);
+ if(!GetResource(item, RES_CELLS))
+ SetResourceExplicit(item, RES_CELLS, g_pickup_cells);
}
#endif
-REGISTER_ITEM(Rockets, Ammo) {
- this.m_canonical_spawnfunc = "item_rockets";
+REGISTER_ITEM(Cells, Ammo) {
+ this.m_canonical_spawnfunc = "item_cells";
#ifdef GAMEQC
- this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
- this.m_model = MDL_Rockets_ITEM;
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
+ this.m_model = MDL_Cells_ITEM;
#endif
- this.netname = "rockets";
- this.m_name = _("rockets");
- this.m_icon = "ammo_rockets";
+ this.netname = "cells";
+ this.m_name = _("Cells");
+ this.m_icon = "ammo_cells";
#ifdef SVQC
- this.m_botvalue = 1500;
- this.m_itemid = IT_RESOURCE;
- this.m_iteminit = ammo_rockets_init;
+ this.m_botvalue = 1500;
+ this.m_itemid = IT_RESOURCE;
+ this.m_iteminit = ammo_cells_init;
#endif
}
-SPAWNFUNC_ITEM(item_rockets, ITEM_Rockets)
+SPAWNFUNC_ITEM(item_cells, ITEM_Cells)
+
+// ammo type #5: plasma
#ifdef GAMEQC
-MODEL(Shells_ITEM, Item_Model("a_shells.md3"));
+MODEL(Plasma_ITEM, Item_Model("a_cells.md3"));
#endif
#ifdef SVQC
-PROPERTY(int, g_pickup_shells);
-void ammo_shells_init(Pickup this, entity item)
+PROPERTY(int, g_pickup_plasma);
+void ammo_plasma_init(Pickup this, entity item)
{
- if(!GetResource(item, RES_SHELLS))
- SetResourceExplicit(item, RES_SHELLS, g_pickup_shells);
+ if(!GetResource(item, RES_PLASMA))
+ SetResourceExplicit(item, RES_PLASMA, g_pickup_plasma);
}
#endif
-
-CLASS(Shells, Ammo)
-ENDCLASS(Shells)
-
-REGISTER_ITEM(Shells, Shells) {
- this.m_canonical_spawnfunc = "item_shells";
+REGISTER_ITEM(Plasma, Ammo) {
+ this.m_canonical_spawnfunc = "item_plasma";
#ifdef GAMEQC
- this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
- this.m_model = MDL_Shells_ITEM;
+ this.spawnflags = ITEM_FLAG_NORMAL | ITEM_FLAG_RESOURCE;
+ this.m_model = MDL_Plasma_ITEM;
#endif
- this.netname = "shells";
- this.m_name = _("shells");
- this.m_icon = "ammo_shells";
+ this.netname = "plasma";
+ this.m_name = _("Plasma");
+ this.m_icon = "ammo_plasma";
#ifdef SVQC
- this.m_botvalue = 1000;
- this.m_itemid = IT_RESOURCE;
- this.m_iteminit = ammo_shells_init;
+ this.m_botvalue = 1500;
+ this.m_itemid = IT_RESOURCE;
+ this.m_iteminit = ammo_plasma_init;
#endif
}
-SPAWNFUNC_ITEM(item_shells, ITEM_Shells)
+SPAWNFUNC_ITEM(item_plasma, ITEM_Plasma)
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;
delete(this.move_controller);
}
controller = new_pure(SUB_CalcMove_controller);
+ set_movetype(controller, MOVETYPE_NONE); // mark the entity as physics driven so that thinking is handled by QC
controller.owner = this;
this.move_controller = controller;
controller.platmovetype = this.platmovetype;
// only do the EXACTTRIGGER_TOUCH checks when really needed (saves some cpu)
if (toucher.iscreature)
{
- if (time >= toucher.triggerhurttime + ((q3compat && !(this.spawnflags & HURT_SLOW)) ? autocvar_sys_ticrate : 1))
+ if (time >= toucher.triggerhurttime + (q3compat && !(this.spawnflags & HURT_SLOW) ? 0.05 : 1))
{
EXACTTRIGGER_TOUCH(this, toucher);
toucher.triggerhurttime = time;
float autocvar_g_monster_mage_attack_teleport_delay = 2;
float autocvar_g_monster_mage_attack_teleport_random = 0.4;
float autocvar_g_monster_mage_attack_teleport_random_range = 1200;
-float autocvar_g_monster_mage_heal_self;
float autocvar_g_monster_mage_heal_allies;
float autocvar_g_monster_mage_heal_minhealth;
float autocvar_g_monster_mage_heal_range;
);
}
case 2: return (GetResource(targ, RES_ARMOR) < autocvar_g_balance_armor_regenstable);
- case 3: return (GetResource(targ, RES_HEALTH) > 0);
}
return false;
fx = EFFECT_ARMOR_REPAIR;
}
break;
- case 3:
- float hp = ((it == this) ? autocvar_g_monster_mage_heal_self : autocvar_g_monster_mage_heal_allies);
- TakeResource(it, RES_HEALTH, hp); // TODO: use regular damage functions? needs a way to bypass friendly fire checks
- fx = EFFECT_RAGE;
- break;
}
Send_Effect(fx, it.origin, '0 0 0', 1);
{
e.noalign = true;
StartItem(e, e.monster_loot);
+ if(startitem_failed || wasfreed(e))
+ return;
e.gravity = 1;
setorigin(e, org);
e.velocity = randomvec() * 175 + '0 0 325';
void Monster_Reset(entity this)
{
+ if(this.spawnflags & MONSTERFLAG_SPAWNED)
+ {
+ Monster_Remove(this);
+ return;
+ }
+
setorigin(this, this.pos1);
this.angles = this.pos2;
-string Buff_UndeprecateName(string buffname)
+string Buff_CompatName(string buffname)
{
switch(buffname)
{
#define BUFF_SPAWNFUNC_Q3COMPAT(o, r)
#endif
-string Buff_UndeprecateName(string buffname);
+string Buff_CompatName(string buffname);
BUFF_SPAWNFUNCS(random, NULL)
RadiusDamage(this, this.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
autocvar_g_nades_nade_radius, this, NULL, autocvar_g_nades_nade_force, this.projectiledeathtype, DMG_NOWEP, this.enemy);
- Damage_DamageInfo(this.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+ Damage_DamageInfo(this.origin, false, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this);
}
delete(this);
{
RadiusDamage(this, this.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
autocvar_g_nades_nade_radius, this, NULL, autocvar_g_nades_nade_force, this.projectiledeathtype, DMG_NOWEP, this.enemy);
- Damage_DamageInfo(this.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this);
+ Damage_DamageInfo(this.origin, false, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, this.projectiledeathtype, 0, this);
}
if(this.takedamage)
if (autocvar_g_casings >= 2) // casing code
{
makevectors(actor.v_angle); // for some reason, this is lost
- SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
+ SpawnCasing(((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
}
ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(okhmg, refire) * W_WeaponRateFactor(actor);
/* wepimg */ ATTRIB(OverkillHeavyMachineGun, model2, string, "weaponhmg");
/* refname */ ATTRIB(OverkillHeavyMachineGun, netname, string, "okhmg");
/* wepname */ ATTRIB(OverkillHeavyMachineGun, m_name, string, _("Overkill Heavy Machine Gun"));
+/* legacy */ ATTRIB(OverkillHeavyMachineGun, m_deprecated_netname, string, "hmg");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
if(autocvar_g_casings >= 2) // casing code
{
makevectors(actor.v_angle); // for some reason, this is lost
- SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
+ SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
}
ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(okmachinegun, refire) * W_WeaponRateFactor(actor);
/* wepimg */ ATTRIB(OverkillRocketPropelledChainsaw, model2, string, "weaponrpc");
/* refname */ ATTRIB(OverkillRocketPropelledChainsaw, netname, string, "okrpc");
/* wepname */ ATTRIB(OverkillRocketPropelledChainsaw, m_name, string, _("Overkill Rocket Propelled Chainsaw"));
+/* legacy */ ATTRIB(OverkillRocketPropelledChainsaw, m_deprecated_netname, string, "rpc");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
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;
#define N_GNTLOFF 1
#define N__ALWAYS 2
+// default time for announcer queue (time to wait before the next announcer is played)
+// -1 = bypass queue and play the announcer immediately
+// 0 = use the announcer sound length
+// >0 = use the specified time in seconds
+#define ANNCE_INSTANT -1
+#define ANNCE_LENGTH 0
+#define ANNCE_DEFTIME 2
+
#define MULTITEAM_ANNCE(prefix, defaultvalue, sound, channel, volume, position) \
NOTIF_ADD_AUTOCVAR(ANNCE_##prefix, defaultvalue) \
MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_1, prefix##_RED, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_1)), channel, volume, position) \
MSG_ANNCE_NOTIF_TEAM(NUM_TEAM_4, prefix##_PINK, prefix, defaultvalue, sprintf(sound, strtolower(STATIC_NAME_TEAM_4)), channel, volume, position)
// MSG_ANNCE_NOTIFICATIONS
- MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_20, N_GNTLOFF, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_25, N_GNTLOFF, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(KILLSTREAK_30, N_GNTLOFF, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(MULTIFRAG, N___NEVER, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
-
- MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
- MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AIRSHOT, N_GNTLOFF, "airshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AMAZING, N_GNTLOFF, "amazing", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_AWESOME, N_GNTLOFF, "awesome", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_BOTLIKE, N_GNTLOFF, "botlike", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_ELECTROBITCH, N__ALWAYS, "electrobitch", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_IMPRESSIVE, N_GNTLOFF, "impressive", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(ACHIEVEMENT_YODA, N_GNTLOFF, "yoda", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(BEGIN, N__ALWAYS, "begin", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(HEADSHOT, N__ALWAYS, "headshot", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(KILLSTREAK_03, N_GNTLOFF, "03kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_05, N_GNTLOFF, "05kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_10, N_GNTLOFF, "10kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_15, N_GNTLOFF, "15kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_20, N_GNTLOFF, "20kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_25, N_GNTLOFF, "25kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(KILLSTREAK_30, N_GNTLOFF, "30kills", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(INSTAGIB_LASTSECOND, N_GNTLOFF, "lastsecond", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(INSTAGIB_NARROWLY, N_GNTLOFF, "narrowly", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(INSTAGIB_TERMINATED, N_GNTLOFF, "terminated", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(MULTIFRAG, N___NEVER, "multifrag", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(NUM_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_6, N__ALWAYS, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_7, N__ALWAYS, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_8, N__ALWAYS, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_9, N__ALWAYS, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_10, N__ALWAYS, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_4, N__ALWAYS, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_5, N__ALWAYS, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_GAMESTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(NUM_KILL_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_KILL_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_1, N___NEVER, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_2, N___NEVER, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_3, N___NEVER, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_RESPAWN_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_1, N__ALWAYS, "1", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_2, N__ALWAYS, "2", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_3, N__ALWAYS, "3", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_4, N___NEVER, "4", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_5, N___NEVER, "5", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_6, N___NEVER, "6", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_7, N___NEVER, "7", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_8, N___NEVER, "8", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_9, N___NEVER, "9", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+ MSG_ANNCE_NOTIF(NUM_ROUNDSTART_10, N___NEVER, "10", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(PREPARE, N__ALWAYS, "prepareforbattle", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_1, N_GNTLOFF, "1fragleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_2, N_GNTLOFF, "2fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_FRAG_3, N_GNTLOFF, "3fragsleft", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(REMAINING_MIN_1, N__ALWAYS, "1minuteremains", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(REMAINING_MIN_5, N__ALWAYS, "5minutesremain", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+
+ MSG_ANNCE_NOTIF(TIMEOUT, N__ALWAYS, "timeoutcalled", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_INSTANT)
+
+ MSG_ANNCE_NOTIF(VOTE_ACCEPT, N__ALWAYS, "voteaccept", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(VOTE_CALL, N__ALWAYS, "votecall", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
+ MSG_ANNCE_NOTIF(VOTE_FAIL, N__ALWAYS, "votefail", CH_INFO, VOL_BASEVOICE, ATTEN_NONE, ANNCE_DEFTIME)
#undef N___NEVER
#undef N_GNTLOFF
float channel,
string snd,
float vol,
- float position)
+ float position,
+ float queuetime)
{
// Set MSG_ANNCE information and handle precaching
#ifdef CSQC
notif.nent_snd = strzone(snd);
notif.nent_vol = vol;
notif.nent_position = position;
+ notif.nent_queuetime = queuetime;
}
}
else
#endif
centerprint_Add(ORDINAL(cpid), input, stof(arg_slot[0]), stof(arg_slot[1]));
}
+
+void Local_Notification_Queue_Run(MSG net_type, entity notif)
+{
+ switch (net_type)
+ {
+ case MSG_ANNCE:
+ {
+ Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position);
+ break;
+ }
+ }
+}
+
+void Local_Notification_Queue_Add(MSG net_type, entity notif, float queue_time)
+{
+ // Guess length if required
+ if(queue_time == 0)
+ queue_time = soundlength(AnnouncerFilename(notif.nent_snd));
+
+ if(queue_time == -1 || time > notif_queue_next_time) {
+ // Run immediately
+ Local_Notification_Queue_Run(net_type, notif);
+ notif_queue_next_time = time + queue_time;
+ } else {
+ // Put in queue
+ if(notif_queue_length >= NOTIF_QUEUE_MAX) return;
+
+ notif_queue_type[notif_queue_length] = net_type;
+ notif_queue_entity[notif_queue_length] = notif;
+ notif_queue_time[notif_queue_length] = notif_queue_next_time;
+
+ notif_queue_next_time += queue_time;
+ ++notif_queue_length;
+ }
+}
+
+void Local_Notification_Queue_Process()
+{
+ if(!notif_queue_length || notif_queue_time[0] > time)
+ return;
+
+ Local_Notification_Queue_Run(notif_queue_type[0], notif_queue_entity[0]);
+
+ // Shift queue to the left
+ --notif_queue_length;
+ for (int j = 0; j < notif_queue_length; j++) {
+ notif_queue_type[j] = notif_queue_type[j+1];
+ notif_queue_entity[j] = notif_queue_entity[j+1];
+ notif_queue_time[j] = notif_queue_time[j+1];
+ }
+}
+
#endif
void Local_Notification(MSG net_type, Notification net_name, ...count)
case MSG_ANNCE:
{
#ifdef CSQC
- Local_Notification_sound(notif.nent_channel, notif.nent_snd, notif.nent_vol, notif.nent_position);
+ Local_Notification_Queue_Add(net_type, notif, notif.nent_queuetime);
#else
backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n");
#endif
found_choice.nent_floatcount,
s1, s2, s3, s4,
f1, f2, f3, f4);
+ break;
}
}
}
float channel,
string snd,
float vol,
- float position);
+ float position,
+ float queuetime);
void Create_Notification_Entity_InfoCenter(entity notif,
float var_cvar,
const float NOTIF_MAX_HUDARGS = 2;
const float NOTIF_MAX_DURCNT = 2;
+#ifdef CSQC
+const int NOTIF_QUEUE_MAX = 10;
+entity notif_queue_entity[NOTIF_QUEUE_MAX];
+MSG notif_queue_type[NOTIF_QUEUE_MAX];
+float notif_queue_time[NOTIF_QUEUE_MAX];
+
+float notif_queue_next_time;
+int notif_queue_length;
+
+void Local_Notification_Queue_Process();
+#endif
+
string arg_slot[NOTIF_MAX_ARGS];
const float ARG_CS_SV_HA = 1; // enabled on CSQC, SVQC, and Hudargs
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));
}
.string nent_snd;
.float nent_vol;
.float nent_position;
+.float nent_queuetime;
// MSG_INFO and MSG_CENTER entity values
.string nent_args; // used by both
return it;
}
-#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \
- MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position)
+#define MSG_ANNCE_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
+ MSG_ANNCE_NOTIF_(teamnum, ANNCE_##name, ANNCE_##cvarname, defaultvalue, sound, channel, volume, position, queuetime)
-#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position) \
+#define MSG_ANNCE_NOTIF(name, defaultvalue, sound, channel, volume, position, queuetime) \
NOTIF_ADD_AUTOCVAR(ANNCE_##name, defaultvalue) \
- MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position)
+ MSG_ANNCE_NOTIF_(0, ANNCE_##name, ANNCE_##name, defaultvalue, sound, channel, volume, position, queuetime)
-#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position) \
+#define MSG_ANNCE_NOTIF_(teamnum, name, cvarname, defaultvalue, sound, channel, volume, position, queuetime) \
REGISTER(Notifications, name, m_id, new_pure(msg_annce_notification)) { \
Create_Notification_Entity (this, defaultvalue, ACVNN(cvarname), MSG_ANNCE, strtoupper(#name), teamnum); \
Create_Notification_Entity_Annce(this, ACVNN(cvarname), strtoupper(#name), \
- channel, /* channel */ \
- sound, /* snd */ \
- volume, /* vol */ \
- position); /* position */ \
+ channel, /* channel */ \
+ sound, /* snd */ \
+ volume, /* vol */ \
+ position, /* position */ \
+ queuetime); /* queuetime */ \
}
#define MSG_INFO_NOTIF_TEAM(teamnum, name, cvarname, defaultvalue, strnum, flnum, args, hudargs, icon, normal, gentle) \
void set_movetype(entity this, int mt)
{
this.move_movetype = mt;
- if (mt == MOVETYPE_PHYSICS) {
- this.move_qcphysics = false;
- } else if (autocvar_sv_qcphysics == 2) {
- this.move_qcphysics = true;
- }
+ this.move_qcphysics = (mt != MOVETYPE_PHYSICS);
if(!IL_CONTAINS(g_moveables, this))
IL_PUSH(g_moveables, this); // add it to the moveable entities list (even if it doesn't move!) logic: if an object never sets its movetype, we assume it never does anything notable
this.movetype = (this.move_qcphysics) ? MOVETYPE_QCENTITY : mt;
#ifdef SVQC
// undefined on client, engine cvar
bool autocvar_physics_ode;
-
-int autocvar_sv_qcphysics = 1; // TODO this is for testing - remove when qcphysics work
#endif
// water levels
#endif
ENDCLASS(AmmoResource)
+// NOTE: ammo resource registration order should match ammo (item) registration order
+// see REGISTER_ITEM calls order
+
REGISTER_RESOURCE(SHELLS, NEW(AmmoResource)) {
this.netname = "shells";
#ifdef GAMEQC
#define REGISTER_RESOURCE(id, inst) REGISTER(Resources, RES, id, m_id, inst)
REGISTRY(Resources, BITS(4));
REGISTER_REGISTRY(Resources)
+
+#ifdef CSQC
+// Copy Resources registry here before it gets sorted alphabetically by REGISTRY_SORT
+// so we can keep resources sorted by categories (as they appear in the code)
+IntrusiveList default_order_resources;
+STATIC_INIT(default_order_resources)
+{
+ default_order_resources = IL_NEW();
+ FOREACH(Resources, true, {
+ IL_PUSH(default_order_resources, it);
+ });
+}
+#endif
+
REGISTRY_SORT(Resources);
REGISTRY_CHECK(Resources);
entity bomblet;
float i;
- Damage_DamageInfo(this.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT.m_id, 0, this);
+ Damage_DamageInfo(this.origin, false, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT.m_id, 0, this);
for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i)
{
return s;
}
-string W_UndeprecateName(string s)
-{
- switch (s)
- {
- case "nex": return "vortex";
- case "rocketlauncher": return "devastator";
- case "laser": return "blaster";
- case "minstanex": return "vaporizer";
- case "grenadelauncher": return "mortar";
- case "uzi": return "machinegun";
- case "hmg": return "okhmg";
- case "rpc": return "okrpc";
- default: return s;
- }
-}
string W_NameWeaponOrder(string order)
{
return mapPriorityList(order, W_NameWeaponOrder_MapFunc);
string W_NumberWeaponOrder_MapFunc(string s)
{
if (s == "0" || stof(s)) return s;
- s = W_UndeprecateName(s);
- FOREACH(Weapons, it != WEP_Null && it.netname == s, return ftos(i));
+ FOREACH(Weapons, it != WEP_Null && (it.netname == s || it.m_deprecated_netname == s), return ftos(i));
return s;
}
string W_NumberWeaponOrder(string order)
}
#ifdef CSQC
-Resource GetAmmoTypeFromNum(int i)
-{
- switch (i)
- {
- case 0: return RES_SHELLS;
- case 1: return RES_BULLETS;
- case 2: return RES_ROCKETS;
- case 3: return RES_CELLS;
- case 4: return RES_PLASMA;
- case 5: return RES_FUEL;
- default: return RES_NONE;
- }
-}
-
int GetAmmoStat(Resource ammotype)
{
switch (ammotype)
* this.origin, this.angles
* this.weaponchild
* this.movedir, this.view_ofs, this.movedir_aligned
+ * this.spawnorigin (SVQC only)
* attachment stuff
* anim stuff
* to free:
if (this.weaponchild) delete(this.weaponchild);
this.weaponchild = NULL;
this.movedir = '0 0 0';
+#ifdef SVQC
this.spawnorigin = '0 0 0';
+#endif
this.oldorigin = '0 0 0';
this.anim_fire1 = '0 1 0.01';
this.anim_fire2 = '0 1 0.01';
this.movedir = '0 0 0';
}
}
+#ifdef SVQC
{
int idx = 0;
// v_ model attached to invisible h_ model
this.spawnorigin = this.movedir;
}
}
+#endif
if (v_shot_idx)
{
this.oldorigin = '0 0 0'; // use regular attachment
vector v = this.movedir;
this.movedir = shotorg_adjust(v, false, false, algn);
this.movedir_aligned = shotorg_adjust(v, false, true, algn);
- this.view_ofs = shotorg_adjust(v, false, true, algn) - v;
+ this.view_ofs = this.movedir_aligned - v;
}
int compressed_shotorg = compressShotOrigin(this.movedir);
// make them match perfectly
#endif
this.movedir = decompressShotOrigin(compressed_shotorg);
+#ifdef SVQC
this.spawnorigin += this.view_ofs; // offset the casings origin by the same amount
+#endif
// check if an instant weapon switch occurred
setorigin(this, this.view_ofs);
//.int weapon; // current weapon
.string weaponname; // name of .weapon
+#ifdef SVQC
.vector spawnorigin; // for casings
+#endif
.vector movedir_aligned; // shot origin based on weapon alignment (unaffected by shootfromeye)
ATTRIB(Weapon, netname, string, "");
/** M: wepname : human readable name */
ATTRIB(Weapon, m_name, string, "AOL CD Thrower");
+ /** M: deprecated refname : old reference name for compatibility with weapons that were renamed */
+ ATTRIB(Weapon, m_deprecated_netname, string, "");
ATTRIB(Weapon, m_pickup, entity);
// functions:
string W_FixWeaponOrder(string order, float complete);
-string W_UndeprecateName(string s);
string W_NameWeaponOrder(string order);
string W_NumberWeaponOrder(string order);
string W_FixWeaponOrder_BuildImpulseList(string o);
entity GetAmmoItem(Resource ammotype);
#ifdef CSQC
-Resource GetAmmoTypeFromNum(int i);
-
int GetAmmoStat(Resource ammotype);
#endif
/* wepimg */ ATTRIB(Blaster, model2, string, "weaponlaser");
/* refname */ ATTRIB(Blaster, netname, string, "blaster");
/* wepname */ ATTRIB(Blaster, m_name, string, _("Blaster"));
+/* legacy */ ATTRIB(Blaster, m_deprecated_netname, string, "laser");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
/* wepimg */ ATTRIB(Devastator, model2, string, "weaponrocketlauncher");
/* refname */ ATTRIB(Devastator, netname, string, "devastator");
/* wepname */ ATTRIB(Devastator, m_name, string, _("Devastator"));
+/* legacy */ ATTRIB(Devastator, m_deprecated_netname, string, "rocketlauncher");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
if(bot_aim(actor, weaponentity, WEP_CVAR_PRI(fireball, speed), 0, WEP_CVAR_PRI(fireball, lifetime), false, false))
{
PHYS_INPUT_BUTTON_ATCK(actor) = true;
- if(random() < 0.02) actor.bot_primary_fireballmooth = 0;
+ if(random() < 0.02) actor.bot_primary_fireballmooth = 1;
}
}
else
if(bot_aim(actor, weaponentity, WEP_CVAR_SEC(fireball, speed), WEP_CVAR_SEC(fireball, speed_up), WEP_CVAR_SEC(fireball, lifetime), true, false))
{
PHYS_INPUT_BUTTON_ATCK2(actor) = true;
- if(random() < 0.01) actor.bot_primary_fireballmooth = 1;
+ if(random() < 0.01) actor.bot_primary_fireballmooth = 0;
}
}
}
if(autocvar_g_casings >= 2)
{
makevectors(actor.v_angle); // for some reason, this is lost
- SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
+ SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
}
if(actor.(weaponentity).misc_bulletcounter == 1)
if(autocvar_g_casings >= 2) // casing code
{
makevectors(actor.v_angle); // for some reason, this is lost
- SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
+ SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
}
ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(machinegun, first_refire) * W_WeaponRateFactor(actor);
if(autocvar_g_casings >= 2) // casing code
{
makevectors(actor.v_angle); // for some reason, this is lost
- SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
+ SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
}
actor.(weaponentity).misc_bulletcounter = actor.(weaponentity).misc_bulletcounter + 1;
/* wepimg */ ATTRIB(MachineGun, model2, string, "weaponuzi");
/* refname */ ATTRIB(MachineGun, netname, string, "machinegun");
/* wepname */ ATTRIB(MachineGun, m_name, string, _("MachineGun"));
+/* legacy */ ATTRIB(MachineGun, m_deprecated_netname, string, "uzi");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
METHOD(Mortar, wr_impacteffect, void(entity thiswep, entity actor))
{
- vector org2;
- org2 = w_org + w_backoff * 12;
- pointparticles(EFFECT_GRENADE_EXPLODE, org2, '0 0 0', 1);
+ pointparticles(EFFECT_GRENADE_EXPLODE, w_org + w_backoff, '0 0 0', 1);
if(!w_issilent)
sound(actor, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTN_NORM);
}
/* wepimg */ ATTRIB(Mortar, model2, string, "weapongrenadelauncher");
/* refname */ ATTRIB(Mortar, netname, string, "mortar");
/* wepname */ ATTRIB(Mortar, m_name, string, _("Mortar"));
+/* legacy */ ATTRIB(Mortar, m_deprecated_netname, string, "grenadelauncher");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
if(autocvar_g_casings >= 2)
{
makevectors(actor.v_angle); // for some reason, this is lost
- SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
+ SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), vectoangles(v_forward), 3, actor, weaponentity);
}
}
{
//if(other==this.realowner)
// return;
- Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, 0, this);
+ Damage_DamageInfo(this.origin, false, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE, 0, this);
delete(this);
}
te_knightspike(org2);
this.event_damage = func_null;
- Damage_DamageInfo(this.origin, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY, toucher.species, this);
+ Damage_DamageInfo(this.origin, false, 0, 0, 0, this.velocity, WEP_SEEKER.m_id | HITTYPE_BOUNCE | HITTYPE_SECONDARY, toucher.species, this);
if(toucher.takedamage == DAMAGE_AIM && !IS_DEAD(toucher))
{
W_Shockwave_Send(actor);
Damage_DamageInfo(
attack_hitpos,
+ trace_ent && trace_ent.solid == SOLID_BSP,
WEP_CVAR(shockwave, blast_splash_damage),
WEP_CVAR(shockwave, blast_splash_edgedamage),
WEP_CVAR(shockwave, blast_splash_radius),
{
makevectors(actor.v_angle); // for some reason, this is lost
//for(int sc = 0;sc < WEP_CVAR_PRI(shotgun, ammo);sc = sc + 1)
- SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 1, actor, weaponentity);
+ SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 30) * v_up), vectoangles(v_forward), 1, actor, weaponentity);
}
}
/* wepimg */ ATTRIB(Vaporizer, model2, string, "weaponminstanex");
/* refname */ ATTRIB(Vaporizer, netname, string, "vaporizer");
/* wepname */ ATTRIB(Vaporizer, m_name, string, _("Vaporizer"));
+/* legacy */ ATTRIB(Vaporizer, m_deprecated_netname, string, "minstanex");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
/* wepimg */ ATTRIB(Vortex, model2, string, "weaponnex");
/* refname */ ATTRIB(Vortex, netname, string, "vortex");
/* wepname */ ATTRIB(Vortex, m_name, string, _("Vortex"));
+/* legacy */ ATTRIB(Vortex, m_deprecated_netname, string, "nex");
#define X(BEGIN, P, END, class, prefix) \
BEGIN(class) \
void CSQCPlayer_CalcRefdef(entity this)
{
+ if(use_engine_refdef)
+ {
+ int refdefflags = 0;
+ if (this.csqcmodel_teleported) refdefflags |= REFDEFFLAG_TELEPORTED;
+ if (input_buttons & BIT(1)) refdefflags |= REFDEFFLAG_JUMPING;
+ // note: these two only work in WIP2, but are harmless in WIP1
+ if (PHYS_HEALTH(NULL) <= 0 && PHYS_HEALTH(NULL) != -666 && PHYS_HEALTH(NULL) != -2342) refdefflags |= REFDEFFLAG_DEAD;
+ if (intermission) refdefflags |= REFDEFFLAG_INTERMISSION;
+ V_CalcRefdef(this, refdefflags); // TODO? uses .health stat in the engine when this isn't called here, may be broken!
+ return;
+ }
+
vector vieworg = this.origin;
if(intermission)
{
setproperty(VF_ANGLES, view_angles);
}
-bool autocvar_cl_useenginerefdef = false;
-
/** Called once per CSQC_UpdateView() */
void CSQCPlayer_SetCamera()
{
InterpolateOrigin_Do(view);
view.view_ofs = '0 0 1' * vh;
}
- if(autocvar_cl_useenginerefdef)
- {
- int refdefflags = 0;
- if (view.csqcmodel_teleported) refdefflags |= REFDEFFLAG_TELEPORTED;
- if (input_buttons & BIT(1)) refdefflags |= REFDEFFLAG_JUMPING;
- // note: these two only work in WIP2, but are harmless in WIP1
- if (PHYS_HEALTH(NULL) <= 0 && PHYS_HEALTH(NULL) != -666 && PHYS_HEALTH(NULL) != -2342) refdefflags |= REFDEFFLAG_DEAD;
- if (intermission) refdefflags |= REFDEFFLAG_INTERMISSION;
- V_CalcRefdef(view, refdefflags); // TODO? uses .health stat in the engine when this isn't called here, may be broken!
- }
- else
- {
- CSQCPlayer_CalcRefdef(view);
- }
+ CSQCPlayer_CalcRefdef(view);
}
else
{
const int CSQCPLAYERSTATUS_FROMSERVER = 1;
const int CSQCPLAYERSTATUS_PREDICTED = 2;
+bool use_engine_refdef; // debug option for testing legacy engine code
+
// only ever READ these!
.int pmove_flags;
const int PMF_JUMP_HELD = 1;
#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>
#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>
--- /dev/null
+#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"));
+}
--- /dev/null
+#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)
#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"
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);
if (IS_REAL_CLIENT(this))
sv_notice_join(this);
- this.move_qcphysics = autocvar_sv_qcphysics;
+ this.move_qcphysics = true;
// update physics stats (players can spawn before physics runs)
Physics_UpdateStats(this);
// Supporting functions for VoteCommand
// ======================================
-float Votecommand_check_assignment(entity caller, float assignment)
+bool Votecommand_check_assignment(entity caller, float assignment)
{
- float from_server = (!caller);
+ bool from_server = (!caller);
if ((assignment == VC_ASGNMNT_BOTH)
|| ((!from_server && assignment == VC_ASGNMNT_CLIENTONLY)
return output;
}
-float VoteCommand_checknasty(string vote_command)
+bool VoteCommand_checknasty(string vote_command)
{
- if ((strstrofs(vote_command, ";", 0) >= 0)
+ return !((strstrofs(vote_command, ";", 0) >= 0)
|| (strstrofs(vote_command, "\n", 0) >= 0)
|| (strstrofs(vote_command, "\r", 0) >= 0)
- || (strstrofs(vote_command, "$", 0) >= 0)) return false;
-
- return true;
+ || (strstrofs(vote_command, "$", 0) >= 0));
}
// NOTE: requires input to be surrounded by spaces
string VoteCommand_checkreplacements(string input)
{
- string output = input;
+ // add a space around the input so the start and end of the list is captured
+ string output = strcat(" ", input, " ");
// allow gotomap replacements
output = strreplace(" map ", " gotomap ", output);
output = strreplace(" chmap ", " gotomap ", output);
return output;
}
-float VoteCommand_checkinlist(string vote_command, string list)
+bool VoteCommand_checkinlist(string vote_command, string list)
{
- string l = VoteCommand_checkreplacements(strcat(" ", list, " "));
+ if (vote_command == "" || list == "")
+ return false;
- if (strstrofs(l, VoteCommand_checkreplacements(strcat(" ", vote_command, " ")), 0) >= 0) return true;
-
- return false;
+ string l = VoteCommand_checkreplacements(list);
+ return (strstrofs(l, VoteCommand_checkreplacements(vote_command), 0) >= 0);
}
string ValidateMap(string validated_map, entity caller)
else
force = normalize(force);
if(forceintensity >= 0)
- Damage_DamageInfo(inflictororigin, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
+ Damage_DamageInfo(inflictororigin, false, coredamage, edgedamage, rad, forceintensity * force, deathtype, 0, attacker);
else
- Damage_DamageInfo(inflictororigin, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
+ Damage_DamageInfo(inflictororigin, false, coredamage, edgedamage, -rad, (-forceintensity) * force, deathtype, 0, attacker);
}
stat_damagedone = 0;
bool Damage_DamageInfo_SendEntity(entity this, entity to, int sf);
-void Damage_DamageInfo(vector org, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner);
+void Damage_DamageInfo(vector org, bool is_solid_hit, float coredamage, float edgedamage, float rad, vector force, int deathtype, float bloodtype, entity dmgowner);
float checkrules_firstblood;
#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>
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
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)
{
float ammo_pickupevalfunc(entity player, entity item)
{
- bool need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false;
+ entity item_resource = NULL; // pointer to the resource that may be associated with the given item
entity wpn = NULL;
float c = 0;
float rating = 0;
- // Detect needed ammo
+ // detect needed ammo
if(item.itemdef.instanceOfWeaponPickup)
{
- entity ammo = NULL;
- if(GetResource(item, RES_SHELLS)) { need_shells = true; ammo = ITEM_Shells; }
- else if(GetResource(item, RES_BULLETS)) { need_nails = true; ammo = ITEM_Bullets; }
- else if(GetResource(item, RES_ROCKETS)) { need_rockets = true; ammo = ITEM_Rockets; }
- else if(GetResource(item, RES_CELLS)) { need_cells = true; ammo = ITEM_Cells; }
- else if(GetResource(item, RES_PLASMA)) { need_plasma = true; ammo = ITEM_Plasma; }
- else if(GetResource(item, RES_FUEL)) { need_fuel = true; ammo = ITEM_JetpackFuel; }
-
+ entity res = item.itemdef.m_weapon.ammo_type;
+ entity ammo = (res != RES_NONE) ? GetAmmoItem(res) : NULL;
if(!ammo)
return 0;
+ if(res != RES_NONE && GetResource(item, res))
+ item_resource = res;
+
wpn = item;
rating = ammo.m_botvalue;
}
FOREACH(Weapons, it != WEP_Null, {
if(!(STAT(WEAPONS, player) & (it.m_wepset)))
continue;
+ if(it.ammo_type == RES_NONE)
+ continue;
- switch(it.ammo_type)
+ if(GetResource(item, it.ammo_type))
{
- case RES_SHELLS: need_shells = true; break;
- case RES_BULLETS: need_nails = true; break;
- case RES_ROCKETS: need_rockets = true; break;
- case RES_CELLS: need_cells = true; break;
- case RES_PLASMA: need_plasma = true; break;
- case RES_FUEL: need_fuel = true; break;
+ item_resource = it.ammo_type;
+ break;
}
});
rating = item.bot_pickupbasevalue;
float noammorating = 0.5;
- if ((need_shells) && GetResource(item, RES_SHELLS) && (GetResource(player, RES_SHELLS) < g_pickup_shells_max))
- c = GetResource(item, RES_SHELLS) / max(noammorating, GetResource(player, RES_SHELLS));
-
- if ((need_nails) && GetResource(item, RES_BULLETS) && (GetResource(player, RES_BULLETS) < g_pickup_nails_max))
- c = GetResource(item, RES_BULLETS) / max(noammorating, GetResource(player, RES_BULLETS));
-
- if ((need_rockets) && GetResource(item, RES_ROCKETS) && (GetResource(player, RES_ROCKETS) < g_pickup_rockets_max))
- c = GetResource(item, RES_ROCKETS) / max(noammorating, GetResource(player, RES_ROCKETS));
-
- if ((need_cells) && GetResource(item, RES_CELLS) && (GetResource(player, RES_CELLS) < g_pickup_cells_max))
- c = GetResource(item, RES_CELLS) / max(noammorating, GetResource(player, RES_CELLS));
-
- if ((need_plasma) && GetResource(item, RES_PLASMA) && (GetResource(player, RES_PLASMA) < g_pickup_plasma_max))
- c = GetResource(item, RES_PLASMA) / max(noammorating, GetResource(player, RES_PLASMA));
-
- if ((need_fuel) && GetResource(item, RES_FUEL) && (GetResource(player, RES_FUEL) < g_pickup_fuel_max))
- c = GetResource(item, RES_FUEL) / max(noammorating, GetResource(player, RES_FUEL));
+ if(item_resource && (GetResource(player, item_resource) < GetResourceLimit(player, item_resource)))
+ c = GetResource(item, item_resource) / max(noammorating, GetResource(player, item_resource));
rating *= min(c, 2);
if(wpn)
if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED)
{
delete(this);
- return;
+ return; // TODO does not set startitem_failed
}
this.classname = def.m_canonical_spawnfunc;
{
FOREACH(StatusEffect, it.instanceOfBuff,
{
- string s = Buff_UndeprecateName(argv(j));
+ string s = Buff_CompatName(argv(j));
if(s == it.netname)
{
this.buffdef = it;
}
});
FOREACH(Weapons, it != WEP_Null, {
- string s = W_UndeprecateName(argv(j));
- if(s == it.netname)
+ string s = argv(j);
+ if(s == it.netname || s == it.m_deprecated_netname)
{
STAT(WEAPONS, this) |= (it.m_wepset);
if(this.spawnflags == 0 || this.spawnflags == 2)
n = tokenize_console(this.netname);
for(int j = 0; j < n; ++j)
{
- FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, {
+ string cmd = argv(j);
+ FOREACH(Weapons, it != WEP_Null && (cmd == it.netname || cmd == it.m_deprecated_netname), {
it.wr_init(it);
break;
});
got += GiveResourceValue(e, RES_FUEL, op, val);
break;
default:
- FOREACH(StatusEffect, it.instanceOfBuff && buff_Available(it) && Buff_UndeprecateName(cmd) == it.netname,
+ FOREACH(StatusEffect, it.instanceOfBuff && buff_Available(it) && Buff_CompatName(cmd) == it.netname,
{
got += GiveBuff(e, it, op, val);
break;
});
- FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(cmd) == it.netname, {
+ FOREACH(Weapons, it != WEP_Null && (cmd == it.netname || cmd == it.m_deprecated_netname), {
got += GiveWeapon(e, it.m_id, op, val);
break;
});
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)
// mirror-impact of something hitting the projectile instead of the
// projectile hitting the something, or a touchareagrid one. Neither of
// these stop the projectile from moving, so...
+ // NOTE: this notice is disabled to prevent spam as projectiles can hit content-less objects (other projectiles!)
+#if 0
if(trace_dphitcontents == 0)
{
LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %i, classname: %s, origin: %v)", this, this.classname, this.origin);
checkclient(this); // TODO: .health is checked in the engine with this, possibly replace with a QC function?
}
+#endif
if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
return true;
if (toucher == NULL && this.size != '0 0 0')
traceline(this.origin - tic, this.origin + tic, MOVE_NORMAL, this);
if (trace_fraction >= 1)
{
- LOG_TRACE("Odd... did not hit...?");
+ // NOTE: this notice can occur when projectiles hit non-world objects, better to not spam the console!
+ //LOG_TRACE("Odd... did not hit...?");
}
else if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
{
}
if(trace_ent.solid == SOLID_BSP || trace_ent.solid == SOLID_SLIDEBOX)
- Damage_DamageInfo(trace_endpos, bdamage, 0, 0, force, deathtype, trace_ent.species, this);
+ Damage_DamageInfo(trace_endpos, (trace_ent.solid == SOLID_BSP), bdamage, 0, 0, force, deathtype, trace_ent.species, this);
// if it is NULL we can't hurt it so stop now
if (trace_ent == NULL || trace_fraction == 1)
is_weapclip = true;
if(!hit || hit.solid == SOLID_BSP || hit.solid == SOLID_SLIDEBOX)
- Damage_DamageInfo(start, damage * damage_fraction, 0, 0, max(1, force) * dir * damage_fraction, dtype, hit.species, this);
+ Damage_DamageInfo(start, (hit && hit.solid == SOLID_BSP), damage * damage_fraction, 0, 0, max(1, force) * dir * damage_fraction, dtype, hit.species, this);
if (hit && hit != WarpZone_trace_forent && hit != fireBullet_last_hit) // Avoid self-damage (except after going through a warp); avoid hitting the same entity twice (engine bug).
{
start = trace_endpos;
if(hit.solid == SOLID_BSP)
- Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
+ Damage_DamageInfo(start, true, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this);
}
if(headshot)
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");
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
cl_decals_fadetime 5
cl_decals_time 1
seta cl_gunalign 3 "Gun alignment; 1 = center, 3 = right, 4 = left; requires reconnect"
+seta cl_gunoffset "0 0 0" "Adjust the weapon viewmodel position, applies only to your own first person view and is relative to cl_gunalign"
seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
seta cl_particlegibs 0 "simpler gibs"
seta cl_gibs_damageforcescale 1.5 "force to push around gibs"
seta cl_casings 1 "enable or disable bullet casings"
seta cl_casings_shell_time 30 "shell casing lifetime"
seta cl_casings_bronze_time 10 "bullet casings lifetime"
-seta cl_casings_ticrate 0.1 "ticrate for casings"
+seta cl_casings_ticrate 0.03125 "ticrate for casings"
seta cl_casings_sloppy 1 "sloppy casings, may temporarily penetrate walls"
seta cl_projectiles_sloppy 1 "sloppy projectiles, may temporarily penetrate walls"
cl_stainmaps 0
scr_loadingscreen_scale_base 1
scr_loadingscreen_scale_limit 2
+// in-game menu
+seta menu_gamemenu 1 "1: show in-game menu when esc is pressed; 0: show main menu when esc is pressed"
+
// other config files
exec effects-normal.cfg
exec crosshairs.cfg
seta cl_showspectators 0 "Show who's spectating you if server has sv_showspectators enabled"
-set cl_useenginerefdef 0
-
set cl_rollkillspeed 10
// Facility for config.cfg use ONLY.
sv_gameplayfix_stepmultipletimes 1
sv_gameplayfix_stepdown 2
// only available in qc physics
-set sv_gameplayfix_stepdown_maxspeed 0 "maximum speed walking entities can be moving for stepping down to apply - requires sv_qcphysics 1"
+set sv_gameplayfix_stepdown_maxspeed 0 "maximum speed walking entities can be moving for stepping down to apply"
// delay for "kill" to prevent abuse
set g_balance_kill_delay 2 "timer before death when using the kill command"
// 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"