qcsrc/server/fteqcc.log
weapons.qc.tmp
*.lno
-qcsrc/qccversion.*
+qcsrc/qccversion*
+qcsrc/server/precache-for-csqc.inc
+.DS_Store
seta hud_panel_notify_fontsize "" "multiplier for the font size used for player names in the panel"
seta hud_panel_notify_fadetime "" "fade out time"
seta hud_panel_notify_time "" "time that a new entry stays until it fades out"
+seta hud_panel_notify_icon_aspect "" "aspect ratio of total drawing area per icon"
seta hud_panel_timer "" "enable/disable this panel"
seta hud_panel_timer_pos "" "position of this base of the panel"
seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "" "minimum factor that the second pass can fade to"
seta hud_panel_centerprint_fade_subsequent_minfontsize "" "minimum factor for the font size from the subsequent fading effects"
seta hud_panel_centerprint_fade_minfontsize "" "minimum factor for the font size from the fading in/out effects"
+
+seta hud_panel_buffs "" "enable/disable this panel"
+seta hud_panel_buffs_pos "" "position of this panel"
+seta hud_panel_buffs_size "" "size of this panel"
+seta hud_panel_buffs_bg "" "if set to something else than \"\" = override default background"
+seta hud_panel_buffs_bg_color "" "if set to something else than \"\" = override default panel background color"
+seta hud_panel_buffs_bg_color_team "" "override panel color with team color in team based games"
+seta hud_panel_buffs_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
+seta hud_panel_buffs_bg_border "" "if set to something else than \"\" = override default size of border around the background"
+seta hud_panel_buffs_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Са зброяй"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Толькі MinstaGib"
+msgid "InstaGib only"
+msgstr "Толькі InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Mit allen Items"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Nur MinstaGib"
+msgid "InstaGib only"
+msgstr "Nur InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr "SLCAT^Overkill Modus"
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "SLCAT^MinstaGib Modus"
+msgid "SLCAT^InstaGib Mode"
+msgstr "SLCAT^InstaGib Modus"
#: qcsrc/menu/xonotic/serverlist.c:156
msgid "SLCAT^Defrag Mode"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Con objetos"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Sólo MinstaGib"
+msgid "InstaGib only"
+msgstr "Sólo InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Esineiden täysi sijoittaminen"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Vain MinstaGib"
+msgid "InstaGib only"
+msgstr "Vain InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Placement complet des objets"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "MinstaGib uniquement"
+msgid "InstaGib only"
+msgstr "InstaGib uniquement"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr "Mode Overkill"
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "Mode MinstaGib"
+msgid "SLCAT^InstaGib Mode"
+msgstr "Mode InstaGib"
#: qcsrc/menu/xonotic/serverlist.c:156
msgid "SLCAT^Defrag Mode"
msgstr "Minden tárgy elhelyezése"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Csak MinstaGib"
+msgid "InstaGib only"
+msgstr "Csak InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Posizionamento oggetti completo"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Solo MinstaGib"
+msgid "InstaGib only"
+msgstr "Solo InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr "Modo Overkill"
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "Modo Minstagib"
+msgid "SLCAT^InstaGib Mode"
+msgstr "Modo InstaGib"
#: qcsrc/menu/xonotic/serverlist.c:156
msgid "SLCAT^Defrag Mode"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Volledige item distributie"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Alleen MinstaGib"
+msgid "InstaGib only"
+msgstr "Alleen InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Colocação total dos items"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Apenas MinstaGib"
+msgid "InstaGib only"
+msgstr "Apenas InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Plasare obiecte"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Numai MinstaGib"
+msgid "InstaGib only"
+msgstr "Numai InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "С оружием"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Только MinstaGib"
+msgid "InstaGib only"
+msgstr "Только InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr "Режим Overkill"
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "Режим MinstaGib"
+msgid "SLCAT^InstaGib Mode"
+msgstr "Режим InstaGib"
#: qcsrc/menu/xonotic/serverlist.c:156
msgid "SLCAT^Defrag Mode"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Fullständing sakplacering"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Endast MinstaGib"
+msgid "InstaGib only"
+msgstr "Endast InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr "Вся зброя"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Тільки MinstaGib"
+msgid "InstaGib only"
+msgstr "Тільки InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
msgid "Title:"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
msgstr ""
#: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
msgstr ""
#: qcsrc/menu/xonotic/serverlist.c:156
set sv_ready_restart_after_countdown 0 "if set to 1 the players and map items are reset after the countdown ended, otherwise they're reset already at the beginning of the countdown"
set sv_ready_restart_repeatable 0 "allows the players to restart the game as often as needed"
-seta cl_hitsound 1 "play a hit notifier sound when you have hit an enemy"
+seta cl_hitsound 1 "play a hit notifier sound when you have hit an enemy, 1: same pitch 2: increase pitch with more damage 3: decrease pitch with more damage"
set cl_hitsound_antispam_time 0.05 "don't play the hitsound more often than this"
+seta cl_hitsound_min_pitch 0.75 "minimum pitch of hit sound"
+seta cl_hitsound_max_pitch 1.5 "maximum pitch of hit sound"
+seta cl_hitsound_nom_damage 25 "damage amount at which hitsound bases pitch off"
seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead"
seta cl_eventchase_nexball 1 "camera goes into 3rd person mode when in nexball game-mode"
set g_grappling_hook 0 "let players spawn with the grappling hook which allows them to pull themselves up"
set g_spawn_alloweffects 1 "allow clients to enable spawn point and event effects such as particles and sounds, see cl_spawn_ cvars for more info"
-set g_spawn_furthest 1 "this amount of the spawns shall be far away from any players"
+set g_spawn_furthest 0.5 "this amount of the spawns shall be far away from any players"
set g_spawn_useallspawns 0 "use all spawns, e.g. also team spawns in non-teamplay, and all spawns, even enemy spawns, in teamplay"
// respawn delay
set g_respawn_delay_small 2 "small game number of seconds you have to wait before you can respawn again"
r_mipskins 1
r_shadow_realtime_world_lightmaps 1
cl_decals_fadetime 5
-cl_decals_time 2
+cl_decals_time 1
seta cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
seta cl_particlegibs 0 "simpler gibs"
seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
-seta cl_gibs_lifetime 5 "average lifetime of gibs"
+seta cl_gibs_lifetime 2.5 "average lifetime of gibs"
seta cl_gibs_velocity_scale 1 "gib throw velocity force scale"
seta cl_gibs_velocity_random 1 "gib throw velocity randomness scale"
seta cl_gibs_velocity_up 1 "extra z velocity for gibs"
seta cl_casings_bronze_time 10 "bullet casings lifetime"
seta cl_casings_ticrate 0.1 "ticrate for casings"
seta cl_casings_sloppy 1 "sloppy casings, may temporarily penetrate walls"
-seta cl_projectiles_sloppy 0 "sloppy projectiles, may temporarily penetrate walls"
+seta cl_projectiles_sloppy 1 "sloppy projectiles, may temporarily penetrate walls"
cl_stainmaps 0
cl_particles_smoke 1
vid_gl20 1
seta g_maplist_votable_abstain 0 "when 1, you can abstain from your vote"
seta g_maplist_votable_screenshot_dir "maps levelshots" "where to look for map screenshots"
+set sv_vote_gametype 0 "show a vote screen for gametypes before map vote screen"
+set sv_vote_gametype_keeptwotime 10 "show only 2 options for this amount of time during gametype vote screen"
+set sv_vote_gametype_options "dm ctf ca lms tdm ft"
+set sv_vote_gametype_timeout 20
+set sv_vote_gametype_default_current 1 "Keep the current gametype if no one votes"
+
set g_chat_flood_spl 3 "normal chat: seconds between lines to not count as flooding"
set g_chat_flood_lmax 2 "normal chat: maximum number of lines per chat message at once"
set g_chat_flood_burst 2 "normal chat: allow bursts of so many chat lines"
seta menu_slist_categories_CAT_XPM_override "CAT_NORMAL"
seta menu_slist_categories_CAT_MODIFIED_override ""
seta menu_slist_categories_CAT_OVERKILL_override ""
-seta menu_slist_categories_CAT_MINSTAGIB_override ""
+seta menu_slist_categories_CAT_INSTAGIB_override ""
seta menu_slist_categories_CAT_DEFRAG_override ""
seta menu_weaponarena ""
set con_completion_vmap map
set con_completion_vnextmap map
set con_completion_vdomap map
-set con_completion_playermodel models/player/*.iqm
+set con_completion_playermodel "models/player/*.iqm"
// helper
// these non-saved engine cvars shall be saved
set cl_loddistance1 1024
set cl_loddistance2 3072
-seta cl_playerdetailreduction 1 "the higher, the less detailed player models are displayed (LOD)"
+seta cl_playerdetailreduction 4 "the higher, the less detailed player models are displayed (LOD)"
seta cl_modeldetailreduction 1 "the higher, the less detailed certain map models are displayed (LOD)"
set g_mapinfo_settemp_acl "+*" "ACL for mapinfo setting cvars"
r_fakelight 1
r_water_hideplayer 1 // hide your own feet/player model in refraction views, this way you don't see half of your body under water
+r_water_refractdistort 0.019
// strength sound settings
set sv_strengthsound_antispam_time 0.1 "minimum distance of strength sounds"
cl_decals 1
cl_decals_models 0
-cl_decals_time 4
-cl_particles_quality 1
+cl_decals_fadetime 4
+cl_particles 1
+cl_particles_quality 1.0
cl_damageeffect 1
cl_spawn_point_particles 1
-cl_playerdetailreduction 0.5
+cl_playerdetailreduction 4.0
gl_flashblend 0
gl_picmip -1
mod_q3bsp_nolightmaps 0
hud_powerup 0
r_depthfirst 2
r_drawdecals_drawdistance 500
-r_drawparticles_drawdistance 2000
+r_drawparticles_drawdistance 1500
r_glsl_deluxemapping 1
r_glsl_offsetmapping 0
r_glsl_offsetmapping_reliefmapping 0
cl_decals 1
cl_decals_models 0
-cl_decals_time 2
+cl_decals_fadetime 2
+cl_particles 1
cl_particles_quality 0.4
cl_damageeffect 0
cl_spawn_point_particles 0
-cl_playerdetailreduction 2
+cl_playerdetailreduction 4
gl_flashblend 1
gl_picmip 1
mod_q3bsp_nolightmaps 1
cl_decals 1
cl_decals_models 0
-cl_decals_time 2
-cl_particles_quality 1
+cl_decals_fadetime 2
+cl_particles 1
+cl_particles_quality 0.8
cl_damageeffect 0
cl_spawn_point_particles 0
-cl_playerdetailreduction 1
+cl_playerdetailreduction 4
gl_flashblend 0
gl_picmip 0
mod_q3bsp_nolightmaps 0
hud_powerup 0
r_depthfirst 0
r_drawdecals_drawdistance 300
-r_drawparticles_drawdistance 1000
+r_drawparticles_drawdistance 750
r_glsl_deluxemapping 0
r_glsl_offsetmapping 0
r_glsl_offsetmapping_reliefmapping 0
cl_decals 1
cl_decals_models 0
-cl_decals_time 2
-cl_particles_quality 1
+cl_decals_fadetime 2
+cl_particles 1
+cl_particles_quality 1.0
cl_damageeffect 1
cl_spawn_point_particles 1
-cl_playerdetailreduction 1
+cl_playerdetailreduction 4
gl_flashblend 0
gl_picmip 0
mod_q3bsp_nolightmaps 0
cl_decals 0
cl_decals_models 0
-cl_decals_time 2
+cl_decals_fadetime 2
+cl_particles 1
cl_particles_quality 0.4
cl_damageeffect 0
cl_spawn_point_particles 0
cl_decals 1
cl_decals_models 1
-cl_decals_time 10
-cl_particles_quality 1
+cl_decals_fadetime 10
+cl_particles 1
+cl_particles_quality 1.0
cl_damageeffect 2
cl_spawn_point_particles 1
cl_playerdetailreduction 0
hud_powerup 0.5
r_depthfirst 2
r_drawdecals_drawdistance 500
-r_drawparticles_drawdistance 2000
+r_drawparticles_drawdistance 3000
r_glsl_deluxemapping 1
r_glsl_offsetmapping 1
r_glsl_offsetmapping_reliefmapping 1
cl_decals 1
cl_decals_models 0
-cl_decals_time 10
-cl_particles_quality 1
-cl_damageeffect 1
+cl_decals_fadetime 10
+cl_particles 1
+cl_particles_quality 1.0
+cl_damageeffect 2
cl_spawn_point_particles 1
cl_playerdetailreduction 0
gl_flashblend 0
alias sv_hook_gameend
+// =====================
+// gametype vote hooks
+// =====================
+// these are called when the mode is switched via gametype vote screen, earlier than gamestart hooks (useful for enabling per-gamemode mutators)
+alias sv_vote_gametype_hook_all
+alias sv_vote_gametype_hook_as
+alias sv_vote_gametype_hook_ca
+alias sv_vote_gametype_hook_ctf
+alias sv_vote_gametype_hook_cts
+alias sv_vote_gametype_hook_dm
+alias sv_vote_gametype_hook_dom
+alias sv_vote_gametype_hook_ft
+alias sv_vote_gametype_hook_inv
+alias sv_vote_gametype_hook_ka
+alias sv_vote_gametype_hook_kh
+alias sv_vote_gametype_hook_lms
+alias sv_vote_gametype_hook_nb
+alias sv_vote_gametype_hook_ons
+alias sv_vote_gametype_hook_rc
+alias sv_vote_gametype_hook_tdm
+
+
// ===========
// leadlimit
// ===========
// ============
// clan arena
// ============
-set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round."
-set g_ca_point_limit 10 "point limit 10 is standard for clan arena"
-set g_ca_point_leadlimit 0
-set g_ca_spectate_enemies 0 "Allow spectating enemy player by dead player during clan arena games."
+set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round"
+seta g_ca_point_limit -1 "Clan Arena point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+seta g_ca_point_leadlimit -1 "Clan Arena point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+set g_ca_spectate_enemies 0 "Allow spectating enemy player by dead player during clan arena games"
set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
set g_ca_damage2score_multiplier 0.01
set g_ca_round_timelimit 180 "round time limit in seconds"
set g_tdm_teams 2 "how many teams are in team deathmatch (set by mapinfo)"
set g_tdm_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
seta g_tdm_teams_override 0 "how many teams are in team deathmatch"
+set g_tdm_point_limit -1 "TDM point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+set g_tdm_point_leadlimit -1 "TDM point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
// ============
set g_domination_point_rate 0 "override: how often to give those points"
set g_domination_point_capturetime 0.1 "how long it takes to capture a point (given no interference)"
set g_domination_point_glow 0 "domination point glow (warning, slow)"
+set g_domination_roundbased 0 "enable round-based domination (capture all control points to win the round)"
+set g_domination_roundbased_point_limit 5 "capture limit in round-based domination mode"
+set g_domination_round_timelimit 120
+set g_domination_warmup 5
//set g_domination_balance_team_points 1 "# of points received is based on team sizes"
set g_freezetag_revive_speed 0.4 "Speed for reviving a frozen teammate"
set g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets lost when out of range"
set g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
+set g_freezetag_revive_nade 1 "Enable reviving from own nade explosion"
+set g_freezetag_revive_nade_health 40 "Amount of health player has if they revived from their own nade explosion"
set g_freezetag_revive_falldamage 0 "Enable reviving from this amount of fall damage"
set g_freezetag_revive_falldamage_health 40 "Amount of health player has if they revived from falling"
set g_freezetag_round_timelimit 180 "round time limit in seconds"
+set g_freezetag_frozen_damage_trigger 1 "if 1, frozen players falling into the void will die instead of teleporting to spawn"
set g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen player with"
set g_freezetag_frozen_maxtime 60 "frozen players will be automatically unfrozen after this time in seconds"
seta g_freezetag_teams_override 0
ALPHA_DISABLED 0.2
ALPHA_BEHIND 0.5
ALPHA_TEXT 0.7
+COLOR_TEXT '1 1 1'
// mouse
// uses "cursor" images
BORDER_TOOLTIP '16 16 0'
FONTSIZE_TOOLTIP 12
ALPHA_TOOLTIP 0.7
+COLOR_TOOLTIP '1 1 1'
WIDTH_TOOLTIP 0.3
AVOID_TOOLTIP '8 8 0'
ALPHA_SERVERLIST_HIGHPING 0.4
ALPHA_SERVERLIST_FAVORITE 0.8
COLOR_SERVERLIST_FAVORITE '1 1 1'
+ALPHA_SERVERLIST_CATEGORY 0.7
+COLOR_SERVERLIST_CATEGORY '1 1 1'
// item: skin list
COLOR_SKINLIST_TITLE '1 1 1'
// item: player color button
// uses "colorbutton" images
-// uses "color" images
// item: player name editor
// uses "charmap" images
ALPHA_DISABLED 0.2
ALPHA_BEHIND 0.5
ALPHA_TEXT 0.7
+COLOR_TEXT '1 1 1'
// mouse
// uses "cursor" images
BORDER_TOOLTIP '16 16 0'
FONTSIZE_TOOLTIP 12
ALPHA_TOOLTIP 0.7
+COLOR_TOOLTIP '1 1 1'
WIDTH_TOOLTIP 0.3
AVOID_TOOLTIP '8 8 0'
ALPHA_SERVERLIST_HIGHPING 0.4
ALPHA_SERVERLIST_FAVORITE 0.8
COLOR_SERVERLIST_FAVORITE '1 1 1'
+ALPHA_SERVERLIST_CATEGORY 0.7
+COLOR_SERVERLIST_CATEGORY '1 1 1'
// item: skin list
COLOR_SKINLIST_TITLE '1 1 1'
// item: player color button
// uses "colorbutton" images
-// uses "color" images
// item: player name editor
// uses "charmap" images
BORDER_TOOLTIP '1 1 0'
FONTSIZE_TOOLTIP 12
ALPHA_TOOLTIP 0.7
+COLOR_TOOLTIP '1 1 1'
WIDTH_TOOLTIP 0.3
AVOID_TOOLTIP '8 8 0'
ALPHA_DISABLED 0.2
ALPHA_BEHIND 1
ALPHA_TEXT 0.7
+COLOR_TEXT '1 1 1'
// item: button
// uses "button" images
// item: player color button
// uses "colorbutton" images
-// uses "color" images
// item: player model
COLOR_MODELTITLE '1 1 1'
ALPHA_SERVERLIST_HIGHPING 0.2
ALPHA_SERVERLIST_FAVORITE 0.8
COLOR_SERVERLIST_FAVORITE '1 1 1'
+ALPHA_SERVERLIST_CATEGORY 0.7
+COLOR_SERVERLIST_CATEGORY '1 1 1'
// item: server info
COLOR_SERVERINFO_NAME '1 1 1'
// after exec'ing them all from your autoexec.cfg
// Set the cvars for each gun
-seta cl_swapattacks_laser 0
+seta cl_swapattacks_blaster 0
seta cl_swapattacks_shotgun 0
-seta cl_swapattacks_uzi 0
-seta cl_swapattacks_grenadelauncher 0
+seta cl_swapattacks_machinegun 0
+seta cl_swapattacks_mortar 0
seta cl_swapattacks_minelayer 0
seta cl_swapattacks_electro 0
seta cl_swapattacks_crylink 0
-seta cl_swapattacks_nex 0
+seta cl_swapattacks_vortex 0
seta cl_swapattacks_hagar 0
-seta cl_swapattacks_rocketlauncher 0
+seta cl_swapattacks_devastator 0
seta cl_swapattacks_porto 0
-seta cl_swapattacks_minstanex 0
+seta cl_swapattacks_vaporizer 0
seta cl_swapattacks_hook 0
seta cl_swapattacks_hlac 0
seta cl_swapattacks_tuba 0
seta cl_swapattacks_fireball 0
seta cl_swapattacks_seeker 0
+// Backwards compatibility with 0.7.0
+alias cl_swapattacks_laser $cl_swapattacks_blaster
+alias cl_swapattacks_rocketlauncher $cl_swapattacks_devastator
+alias cl_swapattacks_uzi $cl_swapattacks_machinegun
+alias cl_swapattacks_grenadelauncher $cl_swapattacks_mortar
+alias cl_swapattacks_minstanex $cl_swapattacks_vaporizer
+alias cl_swapattacks_nex $cl_swapattacks_vortex
+
// This part of the code is necessary to keep us firing when we switch weapons while holding a fire button pressed
// Also updates the keys before firing, so we don't have to switch to another weapon and back to apply the changes
set fire_last 0
alias firing_swap_apply "firing_decision_${$1}"
alias firing_swap "firing_swap_apply cl_swapattacks_$1; set firing_lastweapon cl_swapattacks_$1; firing_switch"
-// Not correct, but prevents firing from braking after executing the script until switching weapons
+// Not correct, but prevents firing from breaking after executing the script until switching weapons
alias +fire +attack
alias -fire -attack
alias +fire2 +attack2
seta hud_panel_notify_fontsize "0.8"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
seta hud_panel_timer 1
seta hud_panel_timer_pos "0.800000 0.040000"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
menu_sync
seta hud_panel_notify_fontsize "0.8"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
seta hud_panel_timer 1
seta hud_panel_timer_pos "0.435000 0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
menu_sync
seta hud_panel_notify_fontsize "0.8"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
seta hud_panel_timer 1
seta hud_panel_timer_pos "0.435000 0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
menu_sync
seta hud_panel_notify_fontsize "0.8"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
seta hud_panel_timer 1
seta hud_panel_timer_pos "0.870000 0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
menu_sync
seta hud_panel_notify_fontsize "1"
seta hud_panel_notify_time "10"
seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
seta hud_panel_timer 1
seta hud_panel_timer_pos "0.850000 0"
seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
seta hud_panel_centerprint_fade_minfontsize "0"
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
menu_sync
"dropweapon" "drop weapon"
"+use" "drop key / drop flag"
"+button8" "drag object"
+"toggle chase_active" "3rd person view"
"" ""
"" "User defined"
"+userbind 1" "$userbind1"
"messagemode2" "Nachricht ans Team"
"team_auto" "Team automatisch wählen"
"menu_showteamselect" "Team auswählen"
-"menu_showsandboxtools" "Sandbox-Menu"
+"menu_showsandboxtools" "Sandkasten menu"
"spec" "Zuschauen"
"dropweapon" "Waffe wegwerfen"
"+use" "Schlüssel oder Flagge wegwerfen"
"+button8" "Objekt ziehen"
+"toggle chase_active" "Schultercamera"
"" ""
"" "Benutzerdefiniert"
"+userbind 1" "$userbind1"
"dropweapon" "soltar arma"
"+use" "soltar llave / soltar bandera"
"+button8" "drag object (FIXME)"
+"toggle chase_active" "3rd person view (FIXME)"
"" ""
"" "Definido por el usuario"
"+userbind 1" "$userbind1"
"weaplast" "dernière utilisée"
"weapbest" "meilleure arme"
"reload" "recharger"
-"weapon_group_1" "laser"
-"weapon_group_2" "shotgun"
-"weapon_group_3" "machine gun / rifle"
-"weapon_group_4" "mortar"
-"weapon_group_5" "electro"
-"weapon_group_6" "crylink / hlac"
-"weapon_group_7" "nex / minstanex"
-"weapon_group_8" "hagar"
-"weapon_group_9" "rocket launcher / fireball"
-"weapon_group_0" "porto / hook"
+"weapon_group_1" "Laser"
+"weapon_group_2" "Fusil"
+"weapon_group_3" "Mitrailleuse"
+"weapon_group_4" "Mortier / Poseur de Mines"
+"weapon_group_5" "Electro"
+"weapon_group_6" "Crylink / HLAC"
+"weapon_group_7" "Nex / Fusil de précision"
+"weapon_group_8" "Hagar / Seeker"
+"weapon_group_9" "Lance-roquettes / Fireball"
+"weapon_group_0" "Port-O-Launch / Grappin"
"" ""
"" "Vue"
-"+zoom" "zoom clic enfoncé"
+"+zoom" "zoom"
"togglezoom" "zoom 2 clics"
-"+showscores" "montrer les scores (enfoncé)"
+"+showscores" "afficher les scores"
"screenshot" "capture d'écran"
-"+hud_panel_radar_maximized" "maximize radar (FIXME)"
+"+hud_panel_radar_maximized" "agrandir le radar"
"" ""
-"" "Communiquer"
-"messagemode" "chat public"
-"messagemode2" "chat d'équipe"
-"+con_chat_maximize" "historique du chat (enfoncé)"
+"" "Communication"
+"messagemode" "tchat public"
+"messagemode2" "tchat d'équipe"
+"+con_chat_maximize" "historique du tchat"
"vyes" "voter OUI"
"vno" "voter NON"
-"ready" "prêt (en mode échauffement)"
+"ready" "prêt"
"" ""
-"" "Joueur"
+"" "Client"
"+show_info" "information serveur"
"toggleconsole" "ouvrir la console"
"disconnect" "se déconnecter"
"menu_showquitdialog" "quitter"
"" ""
"" "Équipe"
-"messagemode2" "chat d'équipe"
+"messagemode2" "tchat d'équipe"
"team_auto" "auto-joindre une équipe"
-"menu_showteamselect" "séléction d'équipe"
-"menu_showsandboxtools" "sandbox menu (FIXME)"
+"menu_showteamselect" "sélection d'équipe"
+"menu_showsandboxtools" "menu bac à sable"
"spec" "mode spectateur"
"dropweapon" "lâcher l'arme"
-"+use" "lâcher la clé / lâcher le drapeau"
-"+button8" "drag object (FIXME)"
+"+use" "lâcher la clef / drapeau"
+"+button8" "traîner l'objet"
+"toggle chase_active" "vue à la 3ème personne"
"" ""
-"" "Utilisateur"
+"" "Raccourcis personnalisés"
"+userbind 1" "$userbind1"
"+userbind 2" "$userbind2"
"+userbind 3" "$userbind3"
"dropweapon" "fegyver eldobás"
"+use" "zászló eldobás, kiszállás"
"+button8" "drag object"
+"toggle chase_active" "3rd person view (FIXME)"
"" ""
"" "Felhasználói hozzárendelések"
"+userbind 1" "$userbind1"
"dropweapon" "abbandona arma"
"+use" "abbandona chiave / bandiera"
"+button8" "trascina oggetto"
+"toggle chase_active" "3rd person view (FIXME)"
"" ""
"" "Definiti dall'utente"
"+userbind 1" "$userbind1"
"dropweapon" "бросить оружие"
"+use" "бросить ключ или флаг"
"+button8" "drag object"
+"toggle chase_active" "3rd person view (FIXME)"
"" ""
"" "Определенно пользователем"
"+userbind 1" "$userbind1"
"dropweapon" "викинути зброю"
"+use" "викинути ключ / прапор"
"+button8" "drag object"
+"toggle chase_active" "3rd person view (FIXME)"
"" ""
"" "Визначені користувачем"
"+userbind 1" "$userbind1"
sex Male
weight 105
age 26
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim3 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Male
weight 85
age 16
+description Lightweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Lightweight Xonotic Solider
sex Male
weight 90
age 20
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Male
weight 87
age 18
+description Mediumweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Mediumweight Xonotic Solider
sex Male
weight 88
age 31
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim3 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Male
weight 90
age 31
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim3 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Male
weight 92
age 31
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim3 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Male
weight 210
age 26
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim3 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Female
weight 100
age 24
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Soldier
sex Female
weight 57
age 53
+description Necro Warrior
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Necro Warrior
sex Female
weight 89
age 31
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Female
weight 90
age 31
+description Heavyweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Heavyweight Xonotic Solider
sex Female
weight 61
age 25
+description Lightweight Xonotic Soldier
bone_upperbody spine2
bone_aim0 0.25 spine2
bone_aim1 0.4 spine4
bone_aim2 0.35 bip01 r hand
bone_weapon bip01 r hand
fixbone 1
-
-Lightweight Xonotic Solider
--- /dev/null
+Plane,g_arc_simple
\ No newline at end of file
--- /dev/null
+Plane,g_campingrifle_simple
\ No newline at end of file
--- /dev/null
+Plane,g_fireball_simple
\ No newline at end of file
--- /dev/null
+Plane,g_hlac_simple
\ No newline at end of file
--- /dev/null
+Plane,g_hookgun_simple
\ No newline at end of file
--- /dev/null
+Plane,g_laser_simple
\ No newline at end of file
--- /dev/null
+Plane,g_minelayer_simple
\ No newline at end of file
--- /dev/null
+Plane,g_minstanex_simple
\ No newline at end of file
--- /dev/null
+Plane,g_porto_simple
\ No newline at end of file
--- /dev/null
+Plane,g_seeker_simple
\ No newline at end of file
--- /dev/null
+Plane,g_tuba_simple
\ No newline at end of file
--- /dev/null
+#!/bin/bash
+
+baseline=20
+
+sprite()
+{
+ name=$1
+ text=$(echo $2) # Handle newlines
+ color=$3
+
+ echo $name
+
+ # Text
+ exec {FD}< <(convert \
+ -size 185x120 \
+ -background transparent \
+ -fill "#$color" \
+ -font BigNoodleTitling \
+ -interline-spacing -15 \
+ -gravity south \
+ label:"$text" \
+ -trim \
+ png:-)
+ itext=$FD
+
+ # Rectangles
+
+ # Thick
+ xa1=34
+ xa2=$((xa1+185-1))
+ ya1=174
+ ya2=$((ya1+37-1))
+
+ # Thin
+ xb1=34
+ xb2=$((xb1+185-1))
+ yb1=224
+ yb2=$((yb1+15-1))
+
+ exec {FD}< <(convert \
+ -size 256x256 \
+ -background transparent \
+ -fill "#$color" \
+ xc:none \
+ -draw "rectangle $xa1,$ya1 $xa2,$ya2" \
+ -draw "rectangle $xb1,$yb1 $xb2,$yb2" \
+ png:-)
+ irects=$FD
+
+ # Join
+
+ composite \
+ -gravity south \
+ -geometry -2+$((82+$baseline)) \
+ -compress RLE \
+ png:fd:$itext png:fd:$irects g_${name}_simple.tga
+}
+
+# grep '* color' ../../qcsrc/common/weapons/w_*.qc | awk '{ print $1 " \t" $4 " " $5 " " $6 }'
+# def h(r,g,b): return '#{:02x}{:02x}{:02x}'.format(int(round(r*255)),int(round(g*255)),int(round(b*255)))
+sprite arc "Arc" ffffff # White
+sprite laser "Blaster" ff8080 # Vivid Tangerine
+sprite crylink "Crylink" ff80ff # Blush Pink
+sprite rl "Devastator" ffff00 # Yellow
+sprite electro "Electro" 0080ff # Azure Radiance
+sprite fireball "Fireball" ff8000 # Flush Orange
+sprite hagar "Hagar" ffff80 # Dolly
+sprite hlac "HLAC" 00ff00 # Green
+sprite hookgun "Grappling\nHook" 008000 # Japanese Laurel
+sprite uzi "Machine\nGun" ffff00 # Yellow
+sprite minelayer "Mine\nLayer" bfff00 # Lime
+sprite gl "Mortar" ff0000 # Red
+sprite porto "Port-O-Launch" 808080 # Gray
+sprite campingrifle "Rifle" 80ff00 # Chartreuse
+sprite seeker "T.A.G.\nSeeker" 80ff00 # Chartreuse
+#sprite shockwave "Shockwave" 804000 # Cinnamon
+sprite shotgun "Shotgun" 804000 # Cinnamon
+sprite tuba "Tuba" 00ff00 # Green
+sprite minstanex "Vaporizer" 80ffff # Anakiwa
+sprite nex "Vortex" 80ffff # Anakiwa
// ===========
-// minstagib
+// instagib
// ===========
-set g_minstagib 0 "enable minstagib"
-set g_minstagib_extralives 1 "how many extra lives you will get per powerup"
-set g_minstagib_ammo_start 10 "starting ammo"
-set g_minstagib_ammo_drop 5 "how much ammo you'll get for weapons or cells"
-set g_minstagib_invis_alpha 0.15
-set g_minstagib_speed_highspeed 1.5 "speed-multiplier that applies while you carry the invincibility powerup"
+set g_instagib 0 "enable instagib"
+set g_instagib_extralives 1 "how many extra lives you will get per powerup"
+set g_instagib_ammo_start 10 "starting ammo"
+set g_instagib_ammo_drop 5 "how much ammo you'll get for weapons or cells"
+set g_instagib_invis_alpha 0.15
+set g_instagib_speed_highspeed 1.5 "speed-multiplier that applies while you carry the invincibility powerup"
// =========
// =======
-// nades
+// Nades
// =======
set g_nades 0 "enable off-hand grenades"
set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire"
+set g_nades_client_select 0 "allow client side selection of nade type"
set g_nades_nade_lifetime 3.5
set g_nades_nade_minforce 400
set g_nades_nade_maxforce 2000
set g_nades_nade_radius 300
set g_nades_nade_force 650
set g_nades_nade_newton_style 0
+set g_nades_nade_type 1 "Type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade"
+
+seta cl_nade_timer 1 "show a visual timer for nades, 1 = only circle, 2 = circle with text"
+seta cl_nade_type 3
+seta cl_pokenade_type "zombie"
+
+// ------------
+// Nade bonus
+// ------------
+//
+// How the nade bonus system works:
+// Each player has a score counter that is increased by some actions (eg: capping, fragging...)
+// Once this counter reaches its maximum, the player will receive a bonus grenade and the score counter resets
+// If the player dies all the bonus nades will be lost and the score counter resets
+// If g_nades_bonus_score_time is not zero, this score will increase or decrease over time
+//
+set g_nades_bonus 0 "Enable bonus grenades"
+set g_nades_bonus_client_select 0 "Allow client side selection of bonus nade type"
+set g_nades_bonus_type 2 "Type of the bonus grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade"
+set g_nades_bonus_onstrength 1 "Always give bonus grenades to players that have the strength powerup"
+set g_nades_bonus_max 3 "Maximum number of bonus grenades"
+// Bonus score
+set g_nades_bonus_score_max 120 "Score value that will give a bonus nade"
+set g_nades_bonus_score_minor 5 "Score given for minor actions (pickups, regular frags etc.)"
+set g_nades_bonus_score_low 20 "Score given for frags and unfreezes"
+set g_nades_bonus_score_medium 30 "Score given for flag returns and flag carrier kills"
+set g_nades_bonus_score_high 60 "Score given for flag captures"
+set g_nades_bonus_score_spree 40 "Score given every spree of this many frags"
+set g_nades_bonus_score_time -1 "Bonus nade score given per second (negative to have the score decay)"
+set g_nades_bonus_score_time_flagcarrier 2 "Bonus nade score given per second as flag carrier (negative to have the score decay)"
+
+// Napalm (2)
+set g_nades_napalm_blast 1 "Whether the napalm grenades also give damage with the usual grenade explosion"
+set g_nades_napalm_burntime 0.5 "Time that the fire from napalm will stick to the player"
+set g_nades_napalm_selfdamage 1 "Whether the player that tossed the nade can be harmed by its fire"
+// Napalm fireballs
+set g_nades_napalm_ball_count 6 "Number of fireballs emitted during the explosion"
+set g_nades_napalm_ball_spread 500 "Maximum force which the fireballs will have on explosion"
+set g_nades_napalm_ball_damageforcescale 4
+set g_nades_napalm_ball_damage 40
+set g_nades_napalm_ball_lifetime 7
+set g_nades_napalm_ball_radius 100 "Distance from the fireball within which you may get burned"
+// Napalm Fire fountain
+set g_nades_napalm_fountain_lifetime 3 "Time period during which extra fire mines are ejected"
+set g_nades_napalm_fountain_delay 0.5 "Delay between emissions by the fountain"
+set g_nades_napalm_fountain_damage 50 "Damage caused by the center of the fountain"
+set g_nades_napalm_fountain_edgedamage 20 "Damage caused by the edge of the fountain"
+set g_nades_napalm_fountain_radius 130
+
+// Ice (3)
+set g_nades_ice_freeze_time 3 "How long the ice field will last"
+set g_nades_ice_health 0 "How much health the player will have after being unfrozen"
+set g_nades_ice_explode 0 "Whether the ice nade should explode again once the ice field dissipated"
+set g_nades_ice_teamcheck 0 "Don't freeze teammates"
+
+// Spawn (5)
+set g_nades_spawn_count 3 "Number of times player will spawn at their spawn nade explosion location"
+
+// Heal (6)
+set g_nades_heal_time 5 "How long the heling field will last"
+set g_nades_heal_rate 30 "Health given per second"
+set g_nades_heal_friend 1 "Multiplier of health given to team mates"
+set g_nades_heal_foe -2 "Multiplier of health given to enemies"
+
+// Pokenade (7)
+set g_nades_pokenade_monster_lifetime 150 "How long pokenade monster will survive"
+set g_nades_pokenade_monster_type "zombie" "Monster to spawn"
// ============
set g_campcheck_damage 100
set g_campcheck_distance 1800
+
+// =======
+// buffs
+// =======
+set cl_buffs_autoreplace 1 "automatically drop current buff when picking up another"
+set g_buffs 0 "enable buffs (requires buff items or powerups)"
+set g_buffs_waypoint_distance 1024 "maximum distance at which buff waypoint can be seen from item"
+set g_buffs_randomize 1 "randomize buff type when player drops buff"
+set g_buffs_random_lifetime 30 "re-spawn the buff again if it hasn't been touched after this time in seconds"
+set g_buffs_random_location 0 "randomize buff location on start and when reset"
+set g_buffs_random_location_attempts 10 "number of random locations a single buff will attempt to respawn at before giving up"
+set g_buffs_spawn_count 5 "how many buffs to spawn on the map if none exist already"
+set g_buffs_replace_powerups 1 "replace powerups on the map with random buffs"
+set g_buffs_cooldown_activate 5 "cooldown period when buff is first activated"
+set g_buffs_cooldown_respawn 3 "cooldown period when buff is reloading"
+set g_buffs_ammo 1 "ammo buff: infinite ammunition"
+set g_buffs_resistance 1 "resistance buff: greatly reduces damage taken"
+set g_buffs_resistance_blockpercent 0.7 "damage reduction multiplier, higher values mean less damage"
+set g_buffs_medic 1 "medic buff: increased regeneration speed, extra health, chance to survive a fatal attack"
+set g_buffs_medic_survive_chance 0.6 "multiplier chance of player surviving a fatal hit"
+set g_buffs_medic_survive_health 5 "amount of health player survives with after taking a fatal hit"
+set g_buffs_medic_rot 0.7 "health rot rate multiplier"
+set g_buffs_medic_max 1.5 "stable health medic limit multiplier"
+set g_buffs_medic_regen 1.7 "health medic rate multiplier"
+set g_buffs_vengeance 1 "vengeance buff: attackers also take damage"
+set g_buffs_vengeance_damage_multiplier 0.6 "amount of damage dealt the attacker takes when hitting a target with vengeance"
+set g_buffs_bash 1 "bash buff: increased knockback force and immunity to knockback"
+set g_buffs_bash_force 2 "bash force multiplier"
+set g_buffs_bash_force_self 1.2 "bash self force multiplier"
+set g_buffs_disability 1 "disability buff: attacks to players and monsters deal slowness (decreased movement/attack speed) for a few seconds"
+set g_buffs_disability_time 3 "time in seconds for target disability"
+set g_buffs_disability_speed 0.5 "player speed multiplier while disabled"
+set g_buffs_disability_rate 1.7 "player weapon rate multiplier while disabled"
+set g_buffs_speed 1 "speed buff: increased movement/attack/health regeneration speed, carrier takes slightly more damage"
+set g_buffs_speed_speed 1.7 "player speed multiplier while holding speed buff"
+set g_buffs_speed_rate 0.8 "player weapon rate multiplier while holding speed buff"
+set g_buffs_speed_damage_take 1.2 "damage taken multiplier while holding speed buff"
+set g_buffs_speed_regen 1.2 "regeneration speed multiplier while holding speed buff"
+set g_buffs_vampire 1 "vampire buff: attacks to players and monsters heal the carrier"
+set g_buffs_vampire_damage_steal 0.6 "damage stolen multiplier while holding vampire buff"
+set g_buffs_jump 1 "jump buff: greatly increased jump height"
+set g_buffs_jump_height 600 "jump height while holding jump buff"
+set g_buffs_flight 1 "flight buff: greatly decreased gravity"
+set g_buffs_flight_gravity 0.3 "player gravity multiplier while holding flight buff"
+set g_buffs_invisible 1 "invisible buff: carrier becomes invisible"
+set g_buffs_invisible_alpha 0.4 "player invisibility multiplier while holding invisible buff"
+
// ********************************************** //
// MSG_ANNCE notifications (count = 89):
-seta notification_ANNCE_ACHIEVEMENT_AIRSHOT "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_AMAZING "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_AWESOME "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_BOTLIKE "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_ELECTROBITCH "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_IMPRESSIVE "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_YODA "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_BEGIN "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_03 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_05 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_10 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_15 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_20 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_25 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_30 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MINSTAGIB_LASTSECOND "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MINSTAGIB_NARROWLY "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MINSTAGIB_TERMINATED "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MULTIFRAG "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_2 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_3 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_4 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_5 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_6 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_7 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_8 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_9 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_10 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_2 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_3 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_4 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_5 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_1 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_2 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_3 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_1 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_2 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_3 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_1 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_2 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_3 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_2 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_3 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_PREPARE "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_FRAG_1 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_FRAG_2 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_FRAG_3 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_MIN_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_MIN_5 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_TIMEOUT "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_VOTE_ACCEPT "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_VOTE_CALL "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_VOTE_FAIL "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
+seta notification_ANNCE_ACHIEVEMENT_AIRSHOT "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_AMAZING "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_AWESOME "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_BOTLIKE "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_ELECTROBITCH "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_IMPRESSIVE "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_YODA "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_BEGIN "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_03 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_05 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_10 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_15 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_20 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_25 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_30 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MINSTAGIB_LASTSECOND "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MINSTAGIB_NARROWLY "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MINSTAGIB_TERMINATED "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MULTIFRAG "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_4 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_5 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_6 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_7 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_8 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_9 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_10 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_4 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_5 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_PREPARE "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_FRAG_1 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_FRAG_2 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_FRAG_3 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_MIN_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_MIN_5 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_TIMEOUT "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_VOTE_ACCEPT "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_VOTE_CALL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_VOTE_FAIL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
-// MSG_INFO notifications (count = 214):
-seta notification_INFO_CTF_CAPTURE_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_BROKEN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_BROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_TIME_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_TIME_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_UNBROKEN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_UNBROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DAMAGED_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DAMAGED_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DROPPED_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DROPPED_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_LOST_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_LOST_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_PICKUP_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_PICKUP_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_RETURN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_RETURN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_CHEAT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_DROWN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_FALL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_FIRE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_LAVA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_NADE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_SLIME "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_SWAMP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_TELEFRAG "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_BUMB_GUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_RAPT_CANNON "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_SPID_MINIGUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_WAKI_GUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VOID "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_AUTOTEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_BETRAYAL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_CAMP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_CHEAT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_CUSTOM "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_DROWN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_FALL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_FIRE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_GENERIC "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_LAVA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_NADE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_NOAMMO "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_ROT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SLIME "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SWAMP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_EWHEEL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_FLAC "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_HELLION "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_HK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_MACHINEGUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_MLRS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_PHASER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_PLASMA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_TESLA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_WALK_GUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_WALK_MEELE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_WALK_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VOID "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_FREEZE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_REVIVED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_REVIVED_FALL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_AUTO_REVIVED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_PLAYER_WIN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TIED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_OVER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_SELF "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_GODMODE_OFF "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_DONTHAVE "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_DROP "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_GOT "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_NOAMMO "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_PRIMORSEC "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_UNAVAILABLE "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_BLUE "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_YELLOW "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_PINK "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_PLAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEEPAWAY_DROPPED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEEPAWAY_PICKUP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_LMS_FORFEIT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_LMS_NOLIVES "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_INVISIBILITY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_SHIELD "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_SPEED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_STRENGTH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_DISCONNECT "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_KICK_IDLING "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_KICK_SPECTATING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_SPECTATE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_ABANDONED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_FAIL_RANKED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_FAIL_UNRANKED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_FINISHED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_BROKEN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_IMPROVED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_MISSING_UID "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_SET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SPECTATE_WARNING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SUPERWEAPON_PICKUP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_VERSION_BETA "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_VERSION_OLD "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_VERSION_OUTDATED "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WATERMARK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ACCORDEON_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ACCORDEON_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_CRYLINK_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_CRYLINK_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_MURDER_BOLT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_MURDER_COMBO "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_MURDER_ORBS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_SUICIDE_BOLT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_SUICIDE_ORBS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_MURDER_BLAST "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_MURDER_FIREMINE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_SUICIDE_BLAST "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HAGAR_MURDER_BURST "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HAGAR_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HAGAR_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HLAC_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HLAC_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HOOK_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_KLEINBOTTLE_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_KLEINBOTTLE_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_LASER_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_LASER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MINELAYER_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MINELAYER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MINSTANEX_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_MURDER_BOUNCE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_MURDER_EXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_NEX_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER_PIERCING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SEEKER_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SEEKER_MURDER_TAG "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SEEKER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SHOTGUN_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SHOTGUN_MURDER_SLAP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_THINKING_WITH_PORTALS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_TUBA_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_UZI_MURDER_SNIPE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_UZI_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+// MSG_INFO notifications (count = 244):
+seta notification_INFO_CHAT_NOSPECTATORS "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_BROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_BROKEN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_TIME_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_TIME_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_UNBROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_UNBROKEN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DAMAGED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DAMAGED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DROPPED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DROPPED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_LOST_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_MONSTER_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_MONSTER_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_CHEAT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_DROWN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_FIRE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_LAVA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_MONSTER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_ICE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_ICE_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_SHOOTING_STAR "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_SLIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_SWAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_TELEFRAG "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_TOUCHEXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_BUMB_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_BUMB_GUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_CRUSH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_RAPT_BOMB "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_RAPT_CANNON "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_RAPT_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_SPID_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_SPID_MINIGUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_SPID_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_WAKI_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_WAKI_GUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_WAKI_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VENGEANCE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VOID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_AUTOTEAMCHANGE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_BETRAYAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_CAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_CHEAT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_CUSTOM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_DROWN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_FIRE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_GENERIC "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_LAVA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_MAGE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SHAMBLER_CLAW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SHAMBLER_SMASH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SHAMBLER_ZAP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SPIDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_WYVERN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_ZOMBIE_JUMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_ZOMBIE_MELEE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_ICE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NOAMMO "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_ROT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SHOOTING_STAR "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SLIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SWAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TEAMCHANGE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TOUCHEXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_EWHEEL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_FLAC "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_HELLION "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_HK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_MACHINEGUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_MLRS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_PHASER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_PLASMA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_TESLA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_WALK_GUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_WALK_MEELE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_WALK_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_BUMB_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_CRUSH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_RAPT_BOMB "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_RAPT_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_SPID_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_SPID_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_WAKI_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_WAKI_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VOID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DOMINATION_CAPTURE_TIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_REVIVED_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_REVIVED_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_PLAYER_WIN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TIED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_OVER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_SELF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_GODMODE_OFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF_LOST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF_DROP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF_GOT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_DONTHAVE "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_DROP "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_GOT "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_NOAMMO "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_PRIMORSEC "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_UNAVAILABLE "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_BLUE "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_YELLOW "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_PINK "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_PLAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEEPAWAY_DROPPED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEEPAWAY_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_LMS_FORFEIT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_LMS_NOLIVES "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_MONSTERS_DISABLED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_INVISIBILITY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_SHIELD "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_SPEED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_STRENGTH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_DISCONNECT "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_KICK_IDLING "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_KICK_SPECTATING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_SPECTATE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_ABANDONED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_FAIL_RANKED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_FAIL_UNRANKED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_FINISHED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_BROKEN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_IMPROVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_MISSING_UID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_SET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SPECTATE_WARNING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SUPERWEAPON_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_TEAMCHANGE_LARGERTEAM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_TEAMCHANGE_NOTALLOWED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_VERSION_BETA "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_VERSION_OLD "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_VERSION_OUTDATED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WATERMARK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ACCORDEON_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ACCORDEON_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_CRYLINK_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_CRYLINK_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_MURDER_BOLT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_MURDER_COMBO "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_MURDER_ORBS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_SUICIDE_BOLT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_SUICIDE_ORBS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_MURDER_BLAST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_MURDER_FIREMINE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_SUICIDE_BLAST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HAGAR_MURDER_BURST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HAGAR_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HAGAR_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HLAC_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HLAC_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HOOK_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_KLEINBOTTLE_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_KLEINBOTTLE_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_LASER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_LASER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MINELAYER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MINELAYER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MINSTANEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_MURDER_BOUNCE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_MURDER_EXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_NEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER_PIERCING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SEEKER_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SEEKER_MURDER_TAG "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SEEKER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SHOTGUN_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SHOTGUN_MURDER_SLAP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_THINKING_WITH_PORTALS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_TUBA_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_UZI_MURDER_SNIPE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_UZI_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-// MSG_CENTER notifications (count = 146):
-seta notification_CENTER_ASSAULT_ATTACKING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ASSAULT_DEFENDING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_BEGIN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_GAMESTART "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_ROUNDSTART "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_ROUNDSTOP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TIED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_OVER "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CAMPCHECK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURESHIELD_FREE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURESHIELD_SHIELDED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURE_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURE_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_FLAG_THROW_PUNISH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_OTHER_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_OTHER_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_RECEIVED_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_RECEIVED_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_REQUESTED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_REQUESTING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_SENT_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_SENT_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_ENEMY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_ENEMY_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_TEAM "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_RETURN_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_RETURN_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_STALEMATE_CARRIER "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_STALEMATE_OTHER "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAGGED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAGGED_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAG_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NADE_THROW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_AUTOTEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_BETRAYAL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_CAMP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_CHEAT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_CUSTOM "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_DROWN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_FALL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_FIRE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_GENERIC "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_LAVA "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_NADE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_NOAMMO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_ROT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SLIME "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SUICIDE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SWAMP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TURRET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TURRET_EWHEEL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TURRET_WALK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VOID "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_TEAMKILL_FRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_TEAMKILL_FRAGGED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DISCONNECT_IDLING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_EXTRALIVES "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_FREEZE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_FROZEN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_REVIVE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_REVIVE_FALL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_REVIVED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_AUTO_REVIVED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_PLAYER_WIN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_SELF "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_SPAWN_LATE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_DONTHAVE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_DROP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_GOT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_NOAMMO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_PRIMORSEC "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_UNAVAILABLE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_JOIN_NOSPAWNS "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_JOIN_PREVENT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEEPAWAY_DROPPED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEEPAWAY_PICKUP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEEPAWAY_WARN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_HELP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_MEET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_ROUNDSTART "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_SCAN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_WAIT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MISSING_TEAMS "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MISSING_PLAYERS "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_FINDAMMO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_FINDAMMO_FIRST "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_LIVES_REMAINING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_SECONDARY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MOTD "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NIX_COUNTDOWN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NIX_NEWWEAPON "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NADE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_OVERTIME_FRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_OVERTIME_TIME "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_INVISIBILITY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_SHIELD "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_SPEED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_STRENGTH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_INVISIBILITY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_SHIELD "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_SPEED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_STRENGTH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_RACE_FINISHLAP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_SUPERWEAPON_BROKEN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_SUPERWEAPON_LOST "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_SUPERWEAPON_PICKUP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_AUTO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_SPECTATE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TIMEOUT_BEGINNING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TIMEOUT_ENDING "1" "Notification control cvar: 0 = off, 1 = centerprint"
+// MSG_CENTER notifications (count = 161):
+seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_GAMESTART "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_ROUNDSTART "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_ROUNDSTOP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TIED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_OVER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURESHIELD_FREE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURESHIELD_SHIELDED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURE_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURE_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_FLAG_THROW_PUNISH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_OTHER_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_OTHER_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_RECEIVED_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_RECEIVED_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_REQUESTED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_REQUESTING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_SENT_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_SENT_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_ENEMY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_ENEMY_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_TEAM "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_RETURN_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_RETURN_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_STALEMATE_CARRIER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_STALEMATE_OTHER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAGGED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAGGED_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAG_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NADE_THROW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NADE_BONUS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_AUTOTEAMCHANGE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_BETRAYAL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_CAMP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_CHEAT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_CUSTOM "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_DROWN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_FALL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_FIRE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_GENERIC "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_LAVA "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_MONSTER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NOAMMO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_ROT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SHOOTING_STAR "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SLIME "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SUICIDE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SWAMP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TEAMCHANGE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TOUCHEXPLODE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TURRET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TURRET_EWHEEL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TURRET_WALK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_BUMB_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_CRUSH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_RAPT_BOMB "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_RAPT_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_SPID_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_SPID_ROCKET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_WAKI_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_WAKI_ROCKET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VOID "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_TEAMKILL_FRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_TEAMKILL_FRAGGED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DISCONNECT_IDLING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DOOR_LOCKED_NEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DOOR_LOCKED_ALSONEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DOOR_UNLOCKED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_EXTRALIVES "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_FREEZE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_FROZEN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_REVIVE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_REVIVE_SELF "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_REVIVED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_PLAYER_WIN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_SELF "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_SPAWN_LATE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_INVASION_SUPERMONSTER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_BUFF_DROP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_BUFF_GOT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_DONTHAVE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_DROP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_GOT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_NOAMMO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_PRIMORSEC "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_UNAVAILABLE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_JOIN_NOSPAWNS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_JOIN_PREVENT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_DROPPED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_PICKUP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_PICKUP_SELF "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_WARN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_HELP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_MEET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_ROUNDSTART "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_SCAN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_WAIT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MISSING_TEAMS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MISSING_PLAYERS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_FINDAMMO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_FINDAMMO_FIRST "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_LIVES_REMAINING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_SECONDARY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MOTD "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NIX_COUNTDOWN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NIX_NEWWEAPON "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NADE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_OVERTIME_FRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_OVERTIME_TIME "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_INVISIBILITY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_SHIELD "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_SPEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_STRENGTH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_INVISIBILITY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_SHIELD "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_SPEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_STRENGTH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_RACE_FINISHLAP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SEQUENCE_COMPLETED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SEQUENCE_COUNTER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SEQUENCE_COUNTER_FEWMORE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SUPERWEAPON_BROKEN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SUPERWEAPON_LOST "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SUPERWEAPON_PICKUP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_AUTO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_SPECTATE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TIMEOUT_BEGINNING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TIMEOUT_ENDING "1" "0 = off, 1 = centerprint"
-// MSG_MULTI notifications (count = 121):
-seta notification_DEATH_MURDER_CHEAT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_DROWN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_FALL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_FIRE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_LAVA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_NADE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_SLIME "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_SWAMP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_TELEFRAG "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_BUMB_GUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_RAPT_CANNON "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_SPID_MINIGUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_WAKI_GUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VOID "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_AUTOTEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_BETRAYAL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_CAMP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_CHEAT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_CUSTOM "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_DROWN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_FALL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_FIRE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_GENERIC "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_LAVA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_NADE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_NOAMMO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_ROT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SLIME "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SWAMP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_EWHEEL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_FLAC "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_HELLION "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_HK "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_MACHINEGUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_MLRS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_PHASER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_PLASMA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_TESLA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_WALK_GUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_WALK_MEELE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_WALK_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VOID "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_DONTHAVE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_DROP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_GOT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_NOAMMO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_PRIMORSEC "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_UNAVAILABLE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_MULTI_COUNTDOWN_BEGIN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_MULTI_MINSTA_FINDAMMO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ACCORDEON_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ACCORDEON_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_CRYLINK_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_CRYLINK_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_MURDER_BOLT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_MURDER_COMBO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_MURDER_ORBS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_SUICIDE_BOLT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_SUICIDE_ORBS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_MURDER_BLAST "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_MURDER_FIREMINE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_SUICIDE_BLAST "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HAGAR_MURDER_BURST "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HAGAR_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HAGAR_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HLAC_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HLAC_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HOOK_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_KLEINBOTTLE_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_KLEINBOTTLE_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_LASER_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_LASER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MINELAYER_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MINELAYER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MINSTANEX_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_MURDER_BOUNCE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_MURDER_EXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_NEX_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER_HAIL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER_PIERCING "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SEEKER_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SEEKER_MURDER_TAG "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SEEKER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SHOTGUN_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SHOTGUN_MURDER_SLAP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_THINKING_WITH_PORTALS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_TUBA_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_TUBA_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_UZI_MURDER_SNIPE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_UZI_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
+// MSG_MULTI notifications (count = 141):
+seta notification_DEATH_MURDER_CHEAT "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_DROWN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_FALL "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_FIRE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_LAVA "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_MONSTER "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_NAPALM "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_ICE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_ICE_FREEZE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_HEAL "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_SHOOTING_STAR "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_SLIME "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_SWAMP "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_TELEFRAG "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_TOUCHEXPLODE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_BUMB_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_BUMB_GUN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_CRUSH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_RAPT_BOMB "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_RAPT_CANNON "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_RAPT_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_SPID_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_SPID_MINIGUN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_SPID_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_WAKI_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_WAKI_GUN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_WAKI_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VENGEANCE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VOID "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_AUTOTEAMCHANGE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_BETRAYAL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_CAMP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_CHEAT "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_CUSTOM "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_DROWN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_FALL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_FIRE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_GENERIC "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_LAVA "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_MAGE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SHAMBLER_CLAW "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SHAMBLER_SMASH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SHAMBLER_ZAP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SPIDER "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_WYVERN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_ZOMBIE_JUMP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_ZOMBIE_MELEE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_NAPALM "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_ICE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_ICE_FREEZE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_HEAL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NOAMMO "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_ROT "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SHOOTING_STAR "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SLIME "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SUICIDE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SWAMP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TEAMCHANGE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TOUCHEXPLODE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_EWHEEL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_FLAC "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_HELLION "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_HK "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_MACHINEGUN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_MLRS "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_PHASER "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_PLASMA "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_TESLA "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_WALK_GUN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_WALK_MEELE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_WALK_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_BUMB_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_CRUSH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_RAPT_BOMB "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_RAPT_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_SPID_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_SPID_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_WAKI_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_WAKI_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VOID "1" "Enable this multiple notification"
+seta notification_ITEM_BUFF_DROP "1" "Enable this multiple notification"
+seta notification_ITEM_BUFF_GOT "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_DONTHAVE "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_DROP "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_GOT "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_NOAMMO "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_PRIMORSEC "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_UNAVAILABLE "1" "Enable this multiple notification"
+seta notification_MULTI_COUNTDOWN_BEGIN "1" "Enable this multiple notification"
+seta notification_MULTI_MINSTA_FINDAMMO "1" "Enable this multiple notification"
+seta notification_WEAPON_ACCORDEON_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_ACCORDEON_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_CRYLINK_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_CRYLINK_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_MURDER_BOLT "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_MURDER_COMBO "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_MURDER_ORBS "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_SUICIDE_BOLT "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_SUICIDE_ORBS "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_MURDER_BLAST "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_MURDER_FIREMINE "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_SUICIDE_BLAST "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "Enable this multiple notification"
+seta notification_WEAPON_HAGAR_MURDER_BURST "1" "Enable this multiple notification"
+seta notification_WEAPON_HAGAR_MURDER_SPRAY "1" "Enable this multiple notification"
+seta notification_WEAPON_HAGAR_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_HLAC_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_HLAC_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_HOOK_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_KLEINBOTTLE_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_KLEINBOTTLE_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_LASER_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_LASER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_MINELAYER_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_MINELAYER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_MINSTANEX_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_MURDER_BOUNCE "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_MURDER_EXPLODE "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "Enable this multiple notification"
+seta notification_WEAPON_NEX_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER_HAIL "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER_PIERCING "1" "Enable this multiple notification"
+seta notification_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "Enable this multiple notification"
+seta notification_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "Enable this multiple notification"
+seta notification_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_SEEKER_MURDER_SPRAY "1" "Enable this multiple notification"
+seta notification_WEAPON_SEEKER_MURDER_TAG "1" "Enable this multiple notification"
+seta notification_WEAPON_SEEKER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_SHOTGUN_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_SHOTGUN_MURDER_SLAP "1" "Enable this multiple notification"
+seta notification_WEAPON_THINKING_WITH_PORTALS "1" "Enable this multiple notification"
+seta notification_WEAPON_TUBA_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_TUBA_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_UZI_MURDER_SNIPE "1" "Enable this multiple notification"
+seta notification_WEAPON_UZI_MURDER_SPRAY "1" "Enable this multiple notification"
// MSG_CHOICE notifications (count = 12):
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_TIME_RED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_TIME_RED_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_PICKUP_TEAM "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_PICKUP_TEAM_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_PICKUP_ENEMY "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_PICKUP_ENEMY_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_FRAG "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_FRAG_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_FRAGGED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_FRAGGED_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_TYPEFRAG "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_TYPEFRAG_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_TYPEFRAGGED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_TYPEFRAGGED_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_TIME_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_TIME_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_PICKUP_TEAM "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_PICKUP_TEAM_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_PICKUP_ENEMY "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_PICKUP_ENEMY_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_FRAG "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_FRAG_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_FRAGGED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_FRAGGED_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_TYPEFRAG "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_TYPEFRAG_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_TYPEFRAGGED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_TYPEFRAGGED_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
// HARD CODED notification variables:
-seta notification_allow_chatboxprint "1" "Allow notifications to be printed to chat box by setting notification cvar to 2 (You can also set this cvar to 2 to force ALL notifications to be printed to the chatbox)"
+seta notification_allow_chatboxprint "1" "Allow INFO notifications to be printed to chat box0 = do not allow, 1 = allow only if allowed by individual notification_INFO* cvars, 2 = force all INFO notifications to be printed to the chatbox"
seta notification_debug "0" "Print extra debug information on all notification function calls (Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... 0 = disabled, 1 = dprint, 2 = print"
seta notification_errors_are_fatal "1" "If a notification fails upon initialization, cause a Host_Error to stop the program"
seta notification_item_centerprinttime "1.5" "How long to show item information centerprint messages (like 'You got the Electro' or such)"
seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
-// Notification counts (total = 582): MSG_ANNCE = 89, MSG_INFO = 214, MSG_CENTER = 146, MSG_MULTI = 121, MSG_CHOICE = 12
+// Notification counts (total = 647): MSG_ANNCE = 89, MSG_INFO = 244, MSG_CENTER = 161, MSG_MULTI = 141, MSG_CHOICE = 12
QCCFLAGS_WATERMARK ?= -DWATERMARK='"$(shell git describe)"'
QCC ?= gmqcc
-QCCVERSIONFILE := qccversion.$(shell $(QCC) --version > qccversion.txt && git hash-object qccversion.txt)
+QCCVERSIONFILE := qccversion.$(shell (cd server && $(QCC) --version) > qccversion.txt && git hash-object qccversion.txt)
# We eventually need to get rid of these.
QCCFLAGS_WTFS ?= \
registercvar("hud_usecsqc", "1");
registercvar("scoreboard_columns", "default");
+ registercvar("cl_nade_type", "3");
+ registercvar("cl_pokenade_type", "zombie");
+
gametype = 0;
// hud_fields uses strunzone on the titles!
for(i = 0; i < MAX_HUD_FIELDS; ++i)
hud_title[i] = strzone("(null)");
+ Cmd_HUD_SetFields(0);
+
postinit = false;
calledhooks = 0;
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
+ CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
WaypointSprite_Load();
void TrueAim_Init();
void PostInit(void)
{
- localcmd(strcat("\nscoreboard_columns_set ", autocvar_scoreboard_columns, ";\n"));
-
entity playerchecker;
playerchecker = spawn();
playerchecker.think = Playerchecker_Think;
warmup_stage = (nags & 16);
}
+void Ent_EliminatedPlayers()
+{
+ float sf, i, j, b, f;
+
+ sf = ReadByte();
+ if(sf & 1)
+ {
+ for(j = 0; j < maxclients; ++j)
+ if(playerslots[j])
+ playerslots[j].eliminated = 1;
+ for(i = 1; i <= maxclients; i += 8)
+ {
+ f = ReadByte();
+ for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+ if (!(f & b))
+ if(playerslots[j])
+ playerslots[j].eliminated = 0;
+ }
+ }
+}
+
void Ent_RandomSeed()
{
float s;
case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
case ENT_CLIENT_LASER: Ent_Laser(); break;
case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
+ case ENT_CLIENT_ELIMINATEDPLAYERS: Ent_EliminatedPlayers(); break;
case ENT_CLIENT_WAYPOINT: Ent_WaypointSprite(); break;
case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break;
case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break;
+ case ENT_CLIENT_HEALING_ORB: ent_healer(); break;
default:
//error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
HUD_ModIcons_SetFunc();
for(i = 0; i < MAX_SCORE; ++i)
{
+ if(scores_label[i])
+ strunzone(scores_label[i]);
scores_label[i] = strzone(ReadString());
scores_flags[i] = ReadByte();
}
for(i = 0; i < MAX_TEAMSCORE; ++i)
{
+ if(teamscores_label[i])
+ strunzone(teamscores_label[i]);
teamscores_label[i] = strzone(ReadString());
teamscores_flags[i] = ReadByte();
}
#define MAX_TIME_DIFF 5
float pickup_crosshair_time, pickup_crosshair_size;
-float hit_time, typehit_time;
-float nextsound_hit_time, nextsound_typehit_time;
-float hitindication_crosshair_time, hitindication_crosshair_size;
+float hitsound_time_prev;
+float spectatee_status_prev; // for preventing hitsound when switching spectatee
+float damage_dealt_total, damage_dealt_total_prev;
+float typehit_time, typehit_time_prev;
+float hitindication_crosshair_size;
float use_nex_chargepool;
float myhealth, myhealth_prev;
scoreboard_active = HUD_WouldDrawScoreboard();
- hit_time = getstatf(STAT_HIT_TIME);
- if(hit_time > nextsound_hit_time && autocvar_cl_hitsound)
+ // varying sound pitch
+ damage_dealt_total = getstati(STAT_DAMAGE_DEALT_TOTAL);
+
+ // detect overflow on server side
+ if (damage_dealt_total < damage_dealt_total_prev)
{
- if(time - hit_time < MAX_TIME_DIFF) // don't play the sound if it's too old.
- sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE);
+ dprint("resetting dmg total: ", ftos(damage_dealt_total), " prev: ", ftos(damage_dealt_total_prev), "\n");
+ damage_dealt_total_prev = 0;
+ }
+
+ // prevent hitsound when switching spectatee
+ if (spectatee_status != spectatee_status_prev)
+ {
+ damage_dealt_total_prev = damage_dealt_total;
+ }
+ spectatee_status_prev = spectatee_status;
+
+ // amount of damage since last hit sound
+ float unaccounted_damage = damage_dealt_total - damage_dealt_total_prev;
+
- nextsound_hit_time = time + autocvar_cl_hitsound_antispam_time;
+ if (autocvar_cl_hitsound == 1)
+ {
+ if ( time - hitsound_time_prev > autocvar_cl_hitsound_antispam_time )
+ if ( damage_dealt_total > 0 )
+ {
+ sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE);
+ hitsound_time_prev = time;
+ }
+ }
+ else if (unaccounted_damage > 0 && autocvar_cl_hitsound > 0 && time - hitsound_time_prev > autocvar_cl_hitsound_antispam_time)
+ {
+ // customizable gradient function that crosses (0,a), (c,1) and asymptotically approaches b
+ float a, b, c, x;
+ a = autocvar_cl_hitsound_max_pitch;
+ b = autocvar_cl_hitsound_min_pitch;
+ c = autocvar_cl_hitsound_nom_damage;
+ x = unaccounted_damage;
+ float pitch_shift = (b*x*(a-1) + a*c*(1-b)) / (x*(a-1) + c*(1-b));
+
+ // if sound variation is disabled, set pitch_shift to 1
+ if (autocvar_cl_hitsound == 1)
+ {
+ pitch_shift = 1;
+ }
+
+ // if pitch shift is reversed, mirror in (max-min)/2 + min
+ if (autocvar_cl_hitsound == 3)
+ {
+ float mirror_value = (a-b)/2 + b;
+ pitch_shift = mirror_value + (mirror_value - pitch_shift);
+ }
+
+ dprint("dmg total (dmg): ", ftos(damage_dealt_total), " (+", ftos(unaccounted_damage), "), pitch shift: ", ftos(pitch_shift), "\n");
+
+ // todo: avoid very long and very short sounds from wave stretching using different sound files? seems unnecessary
+ // todo: normalize sound pressure levels? seems unnecessary
+
+ // scale to fit function interface
+ float param_pitch_shift = pitch_shift * 100;
+
+ // play sound
+ sound7(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTN_NONE, param_pitch_shift, 0);
+
+ // track damage accounted for
+ damage_dealt_total_prev = damage_dealt_total;
+
+ // remember when this sound was played to prevent sound spam
+ hitsound_time_prev = time;
+ }
+ else if (autocvar_cl_hitsound == 0)
+ {
+ // forget the damage to prevent hitsound when enabling it
+ damage_dealt_total_prev = damage_dealt_total;
}
+
typehit_time = getstatf(STAT_TYPEHIT_TIME);
- if(typehit_time > nextsound_typehit_time)
+ if(typehit_time - typehit_time_prev > autocvar_cl_hitsound_antispam_time)
{
- if(time - typehit_time < MAX_TIME_DIFF) // don't play the sound if it's too old.
- sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTEN_NONE);
-
- nextsound_typehit_time = time + autocvar_cl_hitsound_antispam_time;
+ sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTN_NONE);
+ typehit_time_prev = typehit_time;
}
//else
{
- if(gametype == MAPINFO_TYPE_FREEZETAG)
+ if(getstati(STAT_FROZEN))
+ drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((getstatf(STAT_REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * getstatf(STAT_REVIVE_PROGRESS)) + ('0 1 1' * getstatf(STAT_REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ else if (getstatf(STAT_HEALING_ORB)>time)
+ drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, Nade_Color(NADE_TYPE_HEAL), autocvar_hud_colorflash_alpha*getstatf(STAT_HEALING_ORB_ALPHA), DRAWFLAG_ADDITIVE);
+ if(!intermission)
+ if(getstatf(STAT_NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
{
- if(getstati(STAT_FROZEN))
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
- if(getstatf(STAT_REVIVE_PROGRESS))
- {
- DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
- drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
- }
+ DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * getstatf(STAT_NADE_TIMER)) - ('0 1 1' * getstatf(STAT_NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+ }
+ else if(getstatf(STAT_REVIVE_PROGRESS))
+ {
+ DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
}
if(autocvar_r_letterbox == 0)
wcross_scale += sin(pickup_crosshair_size) * autocvar_crosshair_pickup;
}
+ // todo: make crosshair hit indication dependent on damage dealt
if(autocvar_crosshair_hitindication)
{
vector hitindication_color = ((autocvar_crosshair_color_special == 1) ? stov(autocvar_crosshair_hitindication_per_weapon_color) : stov(autocvar_crosshair_hitindication_color));
- if(hitindication_crosshair_time < hit_time)
+ if(unaccounted_damage)
{
- if(time - hit_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old
- hitindication_crosshair_size = 1;
-
- hitindication_crosshair_time = hit_time;
+ hitindication_crosshair_size = 1;
}
if(hitindication_crosshair_size > 0)
float autocvar_hud_panel_notify_flip;
float autocvar_hud_panel_notify_fontsize;
float autocvar_hud_panel_notify_time;
+float autocvar_hud_panel_notify_icon_aspect;
float autocvar_hud_panel_physics;
float autocvar_hud_panel_physics_acceleration_progressbar_mode;
float autocvar_hud_panel_physics_acceleration_progressbar_scale;
float autocvar_hud_panel_powerups_flip;
float autocvar_hud_panel_powerups_iconalign;
float autocvar_hud_panel_powerups_progressbar;
+float autocvar_hud_panel_buffs;
+//float autocvar_hud_panel_buffs_iconalign;
string autocvar_hud_panel_powerups_progressbar_shield;
string autocvar_hud_panel_powerups_progressbar_strength;
string autocvar_hud_panel_powerups_progressbar_superweapons;
float autocvar_vid_pixelheight;
float autocvar_viewsize;
float autocvar_cl_hitsound;
+var float autocvar_cl_hitsound_min_pitch = 0.75; // minimal difference in minsta
+var float autocvar_cl_hitsound_max_pitch = 1.5;
+var float autocvar_cl_hitsound_nom_damage = 25;
float autocvar_cl_hitsound_antispam_time;
var float autocvar_cl_eventchase_death = 1;
var float autocvar_cl_eventchase_nexball = 1;
float autocvar_cl_deathglow;
float autocvar_developer_csqcentities;
float autocvar_g_jetpack_attenuation;
+float autocvar_cl_nade_timer;
const float VF_CL_VIEWANGLES_Y = 35; //(float)
const float VF_CL_VIEWANGLES_Z = 36; //(float)
-// Server Autosent Stat Constants
-const float STAT_HEALTH = 0;
-const float STAT_WEAPONMODEL = 2;
-const float STAT_AMMO = 3;
-const float STAT_ARMOR = 4;
-const float STAT_WEAPONFRAME = 5;
-const float STAT_SHELLS = 6;
-const float STAT_NAILS = 7;
-const float STAT_ROCKETS = 8;
-const float STAT_CELLS = 9;
-const float STAT_ACTIVEWEAPON = 10;
-const float STAT_TOTALSECRETS = 11;
-const float STAT_TOTALMONSTERS = 12;
-const float STAT_SECRETS = 13;
-const float STAT_MONSTERS = 14;
-const float STAT_ITEMS = 15;
-const float STAT_VIEWHEIGHT = 16;
-const float STAT_MOVEVARS_TICRATE = 240;
-const float STAT_MOVEVARS_TIMESCALE = 241;
-const float STAT_FRAGLIMIT = 235;
-const float STAT_TIMELIMIT = 236;
-const float STAT_MOVEVARS_GRAVITY = 242;
-
// Quake-style Point Contents
const float CONTENT_EMPTY = -1;
const float CONTENT_SOLID = -2;
}
}
+void DrawNadeScoreBar(vector myPos, vector mySize, vector color)
+{
+
+ HUD_Panel_DrawProgressBar(
+ myPos + eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x,
+ mySize - eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x,
+ autocvar_hud_panel_ammo_progressbar_name,
+ getstatf(STAT_NADE_BONUS_SCORE), 0, 0, color,
+ autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+
+}
+
+void DrawAmmoNades(vector myPos, vector mySize, float draw_expanding, float expand_time)
+{
+ float theAlpha = 1, a, b;
+ vector nade_color, picpos, numpos;
+
+ nade_color = Nade_Color(getstati(STAT_NADE_BONUS_TYPE));
+
+ a = getstatf(STAT_NADE_BONUS);
+ b = getstatf(STAT_NADE_BONUS_SCORE);
+
+ if(autocvar_hud_panel_ammo_iconalign)
+ {
+ numpos = myPos;
+ picpos = myPos + eX * 2 * mySize_y;
+ }
+ else
+ {
+ numpos = myPos + eX * mySize_y;
+ picpos = myPos;
+ }
+
+ DrawNadeScoreBar(myPos, mySize, nade_color);
+
+ if(b > 0 || a > 0)
+ {
+ if(autocvar_hud_panel_ammo_text)
+ drawstring_aspect(numpos, ftos(a), eX * (2/3) * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+
+ if(draw_expanding)
+ drawpic_aspect_skin_expanding(picpos, "nade_nbg", '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL, expand_time);
+
+ drawpic_aspect_skin(picpos, "nade_bg" , '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(picpos, "nade_nbg" , '1 1 0' * mySize_y, nade_color, panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+ }
+}
+
void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected, float infinite_ammo)
{
float a;
drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * mySize_y, '0 0 0', panel_fg_alpha * theAlpha * 0.5, DRAWFLAG_NORMAL);
}
+float nade_prevstatus;
+float nade_prevframe;
+float nade_statuschange_time;
void HUD_Ammo(void)
{
if(hud != HUD_NORMAL) return;
mySize -= '2 2 0' * panel_bg_padding;
}
- const float AMMO_COUNT = 4;
float rows = 0, columns, row, column;
+ float nade_cnt = getstatf(STAT_NADE_BONUS), nade_score = getstatf(STAT_NADE_BONUS_SCORE);
+ float draw_nades = (nade_cnt > 0 || nade_score > 0), nade_statuschange_elapsedtime;
+ float total_ammo_count;
+
vector ammo_size;
+ float AMMO_COUNT = 4;
if (autocvar_hud_panel_ammo_onlycurrent)
- ammo_size = mySize;
+ total_ammo_count = 1;
else
+ total_ammo_count = AMMO_COUNT - 1; // fuel
+
+ if(draw_nades)
{
- rows = mySize_y/mySize_x;
- rows = bound(1, floor((sqrt(4 * (3/1) * rows * AMMO_COUNT + rows * rows) + rows + 0.5) / 2), AMMO_COUNT);
- // ^^^ ammo item aspect goes here
+ ++total_ammo_count;
+ if (nade_cnt != nade_prevframe)
+ {
+ nade_statuschange_time = time;
+ nade_prevstatus = nade_prevframe;
+ nade_prevframe = nade_cnt;
+ }
+ }
+ else
+ nade_prevstatus = nade_prevframe = nade_statuschange_time = 0;
- columns = ceil(AMMO_COUNT/rows);
+ rows = mySize_y/mySize_x;
+ rows = bound(1, floor((sqrt(4 * (3/1) * rows * (total_ammo_count) + rows * rows) + rows + 0.5) / 2), (total_ammo_count));
+ // ^^^ ammo item aspect goes here
- ammo_size = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
- }
+ columns = ceil((total_ammo_count)/rows);
+
+ ammo_size = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
+
local vector offset = '0 0 0'; // fteqcc sucks
float newSize;
float i, stat_items, currently_selected, infinite_ammo;
infinite_ammo = FALSE;
+
+ row = column = 0;
+
if (autocvar_hud_panel_ammo_onlycurrent)
{
if(autocvar__hud_configure)
}
}
}
+
+ ++row;
+ if(row >= rows)
+ {
+ row = 0;
+ column = column + 1;
+ }
}
else
{
stat_items = getstati(STAT_ITEMS, 0, 24);
if (stat_items & IT_UNLIMITED_WEAPON_AMMO)
infinite_ammo = TRUE;
- row = column = 0;
for (i = 0; i < AMMO_COUNT; ++i) {
currently_selected = stat_items & GetAmmoItemCode(i);
DrawAmmoItem(pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y), ammo_size, i, currently_selected, infinite_ammo);
}
}
+ if (draw_nades)
+ {
+ nade_statuschange_elapsedtime = time - nade_statuschange_time;
+
+ float f = bound(0, nade_statuschange_elapsedtime*2, 1);
+
+ DrawAmmoNades(pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y), ammo_size, nade_prevstatus < nade_cnt && nade_cnt != 0 && f < 1, f);
+ }
+
draw_endBoldFont();
}
void HUD_Notify_Push(string icon, string attacker, string victim)
{
- if(icon != "")
- {
- --kn_index;
- if (kn_index == -1) { kn_index = KN_MAX_ENTRIES-1; }
- notify_times[kn_index] = time;
+ if (icon == "")
+ return;
+
+ ++notify_count;
+ --notify_index;
+
+ if (notify_index == -1)
+ notify_index = NOTIFY_MAX_ENTRIES-1;
+
+ // Free old strings
+ if (notify_attackers[notify_index])
+ strunzone(notify_attackers[notify_index]);
- // icon
- if(notify_icon[kn_index]) { strunzone(notify_icon[kn_index]); }
- notify_icon[kn_index] = strzone(icon);
+ if (notify_victims[notify_index])
+ strunzone(notify_victims[notify_index]);
- // attacker
- if(notify_attackers[kn_index]) { strunzone(notify_attackers[kn_index]); }
- notify_attackers[kn_index] = strzone(attacker);
+ if (notify_icons[notify_index])
+ strunzone(notify_icons[notify_index]);
- // victim
- if(notify_victims[kn_index]) { strunzone(notify_victims[kn_index]); }
- notify_victims[kn_index] = strzone(victim);
+ // Allocate new strings
+ if (victim != "")
+ {
+ notify_attackers[notify_index] = strzone(attacker);
+ notify_victims[notify_index] = strzone(victim);
+ }
+ else
+ {
+ // In case of a notification without a victim, the attacker
+ // is displayed on the victim's side. Instead of special
+ // treatment later on, we can simply switch them here.
+ notify_attackers[notify_index] = string_null;
+ notify_victims[notify_index] = strzone(attacker);
}
+
+ notify_icons[notify_index] = strzone(icon);
+ notify_times[notify_index] = time;
}
void HUD_Notify(void)
{
- if(!autocvar__hud_configure)
- {
- if(!autocvar_hud_panel_notify) return;
- }
+ if (!autocvar__hud_configure)
+ if (!autocvar_hud_panel_notify)
+ return;
HUD_Panel_UpdateCvars();
- vector pos, mySize;
- pos = panel_pos;
- mySize = panel_size;
-
HUD_Panel_DrawBg(1);
- if(panel_bg_padding)
+
+ if (!autocvar__hud_configure)
+ if (notify_count == 0)
+ return;
+
+ vector pos, size;
+ pos = panel_pos;
+ size = panel_size;
+
+ if (panel_bg_padding)
{
- pos += '1 1 0' * panel_bg_padding;
- mySize -= '2 2 0' * panel_bg_padding;
+ pos += '1 1 0' * panel_bg_padding;
+ size -= '2 2 0' * panel_bg_padding;
}
- float entries, height;
- entries = bound(1, floor(KN_MAX_ENTRIES * mySize_y/mySize_x), KN_MAX_ENTRIES);
- height = mySize_y/entries;
+ float fade_start = max(0, autocvar_hud_panel_notify_time);
+ float fade_time = max(0, autocvar_hud_panel_notify_fadetime);
+ float icon_aspect = max(1, autocvar_hud_panel_notify_icon_aspect);
- vector fontsize;
- float fontheight = height * autocvar_hud_panel_notify_fontsize;
- fontsize = '0.5 0.5 0' * fontheight;
+ float entry_count = bound(1, floor(NOTIFY_MAX_ENTRIES * size_y / size_x), NOTIFY_MAX_ENTRIES);
+ float entry_height = size_y / entry_count;
- float a;
- float when;
- when = autocvar_hud_panel_notify_time;
- float fadetime;
- fadetime = autocvar_hud_panel_notify_fadetime;
+ float panel_width_half = size_x * 0.5;
+ float icon_width_half = entry_height * icon_aspect / 2;
+ float name_maxwidth = panel_width_half - icon_width_half - size_x * NOTIFY_ICON_MARGIN;
- vector pos_attacker, pos_victim, pos_icon;
- float width_attacker;
+ vector font_size = '0.5 0.5 0' * entry_height * autocvar_hud_panel_notify_fontsize;
+ vector icon_size = (eX * icon_aspect + eY) * entry_height;
+ vector icon_left = eX * (panel_width_half - icon_width_half);
+ vector attacker_right = eX * name_maxwidth;
+ vector victim_left = eX * (size_x - name_maxwidth);
+
+ vector attacker_pos, victim_pos, icon_pos;
string attacker, victim, icon;
+ float i, j, count, step, limit, alpha;
- float i, j, step, limit;
- if(autocvar_hud_panel_notify_flip) //order items from the top down
+ if (autocvar_hud_panel_notify_flip)
{
+ // Order items from the top down
i = 0;
step = +1;
- limit = entries;
+ limit = entry_count;
}
- else //order items from the bottom up
+ else
{
- i = entries - 1;
+ // Order items from the bottom up
+ i = entry_count - 1;
step = -1;
limit = -1;
}
- for(j = kn_index; i != limit; i += step, ++j)
+ for (j = notify_index, count = 0; i != limit; i += step, ++j, ++count)
{
if(autocvar__hud_configure)
{
- if (step == +1)
- a = i;
- else // inverse order
- a = entries - 1 - i;
- attacker = textShortenToWidth(sprintf(_("Player %d"), a+1), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
- victim = textShortenToWidth(sprintf(_("Player %d"), a+2), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
- icon = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
- a = bound(0, (when - a) / 4, 1);
- goto hud_config_notifyprint;
+ attacker = sprintf(_("Player %d"), count + 1);
+ victim = sprintf(_("Player %d"), count + 2);
+ icon = strcat("weapon", get_weaponinfo(min(WEP_FIRST + count * 2, WEP_LAST)).netname);
+ alpha = bound(0, 1.2 - count / entry_count, 1);
}
else
{
- if (j == KN_MAX_ENTRIES)
+ if (j == NOTIFY_MAX_ENTRIES)
j = 0;
- if(notify_times[j] + when > time)
- a = 1;
- else if(fadetime)
+ if (notify_times[j] + fade_start > time)
+ alpha = 1;
+ else if (fade_time != 0)
{
- a = bound(0, (notify_times[j] + when + fadetime - time) / fadetime, 1);
- if(!a)
- {
+ alpha = bound(0, (notify_times[j] + fade_start + fade_time - time) / fade_time, 1);
+ if (alpha == 0)
break;
- }
}
else
- {
break;
- }
attacker = notify_attackers[j];
victim = notify_victims[j];
- icon = notify_icon[j];
+ icon = notify_icons[j];
}
- //type = notify_deathtype[j];
- //w = DEATH_WEAPONOF(type);
-
- if(icon != "")
+ if (icon != "" && victim != "")
{
- if((attacker != "") && (victim == ""))
- {
- // Y [used by] X
- attacker = textShortenToWidth(attacker, 0.73 * mySize_x - height, fontsize, stringwidth_colors);
- pos_attacker = pos + eX * (0.27 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
- pos_icon = pos + eX * 0.25 * mySize_x - eX * height + eY * i * height;
+ vector name_top = eY * (i * entry_height + 0.5 * (entry_height - font_size_y));
- drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- }
- else if((attacker != "") && (victim != ""))
+ icon_pos = pos + icon_left + eY * i * entry_height;
+ drawpic_aspect_skin(icon_pos, icon, icon_size, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
+
+ victim = textShortenToWidth(victim, name_maxwidth, font_size, stringwidth_colors);
+ victim_pos = pos + victim_left + name_top;
+ drawcolorcodedstring(victim_pos, victim, font_size, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
+
+ if (attacker != "")
{
- // X [did action to] Y
- attacker = textShortenToWidth(attacker, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
- victim = textShortenToWidth(victim, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-:hud_config_notifyprint
- width_attacker = stringwidth(attacker, TRUE, fontsize);
- pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
- pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
- pos_icon = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
-
- drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
- drawcolorcodedstring(pos_victim, victim, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+ attacker = textShortenToWidth(attacker, name_maxwidth, font_size, stringwidth_colors);
+ attacker_pos = pos + attacker_right - eX * stringwidth(attacker, TRUE, font_size) + name_top;
+ drawcolorcodedstring(attacker_pos, attacker, font_size, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
}
}
}
+
+ notify_count = count;
}
// Timer (#5)
}
}
+// Buffs (#18)
+//
+void HUD_Buffs(void)
+{
+ float buffs = getstati(STAT_BUFFS, 0, 24);
+ if(!autocvar__hud_configure)
+ {
+ if(!autocvar_hud_panel_buffs) return;
+ if(spectatee_status == -1) return;
+ if(getstati(STAT_HEALTH) <= 0) return;
+ if(!buffs) return;
+ }
+ else
+ {
+ buffs = Buff_Type_first.items; // force first buff
+ }
+
+ float b = 0; // counter to tell other functions that we have buffs
+ entity e;
+ string s = "";
+ for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
+ {
+ ++b;
+ string o = strcat(rgb_to_hexcolor(Buff_Color(e.items)), Buff_PrettyName(e.items));
+ if(s == "")
+ s = o;
+ else
+ s = strcat(s, " ", o);
+ }
+
+ HUD_Panel_UpdateCvars();
+
+ draw_beginBoldFont();
+
+ vector pos, mySize;
+ pos = panel_pos;
+ mySize = panel_size;
+
+ HUD_Panel_DrawBg(bound(0, b, 1));
+ if(panel_bg_padding)
+ {
+ pos += '1 1 0' * panel_bg_padding;
+ mySize -= '2 2 0' * panel_bg_padding;
+ }
+
+ //float panel_ar = mySize_x/mySize_y;
+ //float is_vertical = (panel_ar < 1);
+ //float buff_iconalign = autocvar_hud_panel_buffs_iconalign;
+ vector buff_offset = '0 0 0';
+
+ for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
+ {
+ //DrawNumIcon(pos + buff_offset, mySize, shield, "shield", is_vertical, buff_iconalign, '1 1 1', 1);
+ drawcolorcodedstring_aspect(pos + buff_offset, s, mySize, panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+ }
+
+ draw_endBoldFont();
+}
+
+
/*
==================
Main HUD system
HUD_PANEL(ENGINEINFO , HUD_EngineInfo , engineinfo) \
HUD_PANEL(INFOMESSAGES , HUD_InfoMessages , infomessages) \
HUD_PANEL(PHYSICS , HUD_Physics , physics) \
- HUD_PANEL(CENTERPRINT , HUD_CenterPrint , centerprint)
+ HUD_PANEL(CENTERPRINT , HUD_CenterPrint , centerprint) \
+ HUD_PANEL(BUFFS , HUD_Buffs , buffs)
#define HUD_PANEL(NAME,draw_func,name) \
float HUD_PANEL_##NAME; \
HUD_Panel_GetBorder() \
} ENDS_WITH_CURLY_BRACE
+#define NOTIFY_MAX_ENTRIES 10
+#define NOTIFY_ICON_MARGIN 0.02
-#define KN_MAX_ENTRIES 10
+float notify_index;
+float notify_count;
+float notify_times[NOTIFY_MAX_ENTRIES];
+string notify_attackers[NOTIFY_MAX_ENTRIES];
+string notify_victims[NOTIFY_MAX_ENTRIES];
+string notify_icons[NOTIFY_MAX_ENTRIES];
-float kn_index;
-float notify_times[KN_MAX_ENTRIES];
-string notify_icon[KN_MAX_ENTRIES];
-string notify_attackers[KN_MAX_ENTRIES];
-string notify_victims[KN_MAX_ENTRIES];
void HUD_Notify_Push(string icon, string attacker, string victim);
var void HUD_ModIcons_GameType(vector pos, vector size);
HUD_Write_PanelCvar_q("_fontsize");
HUD_Write_PanelCvar_q("_time");
HUD_Write_PanelCvar_q("_fadetime");
+ HUD_Write_PanelCvar_q("_icon_aspect");
break;
case HUD_PANEL_TIMER:
HUD_Write_PanelCvar_q("_increment");
.float gotscores;
.entity owner;
.float ready;
+.float eliminated;
.void(void) draw;
.void(void) draw2d;
string mv_pk3[MAPVOTE_COUNT];
float mv_preview[MAPVOTE_COUNT];
float mv_votes[MAPVOTE_COUNT];
+float mv_avail[MAPVOTE_COUNT];
+float mv_avail_start[MAPVOTE_COUNT];
entity mv_pk3list;
float mv_abstain;
float mv_ownvote;
float mv_detail;
float mv_timeout;
-float mv_maps_mask;
float mv_top2_time;
float mv_top2_alpha;
vector mv_mousepos;
float mv_selection;
+float mv_columns;
+float mv_mouse_selection;
+float mv_selection_keyboard;
+
+float gametypevote;
+string mapvote_chosenmap;
+vector gtv_text_size;
+vector gtv_text_size_small;
string MapVote_FormatMapItem(float id, string map, float count, float maxwidth, vector fontsize)
{
{
if(count == 1)
post = _(" (1 vote)");
- else if(count >= 0)
+ else if(count >= 0 && mv_avail[id] == GTV_AVAILABLE)
post = sprintf(_(" (%d votes)"), count);
else
post = "";
return strcat(pre, map, post);
}
-vector MapVote_RGB(float id, float count)
+string GameTypeVote_DescriptionByID(float id)
+{
+ return MapInfo_Type_Description(MapInfo_Type_FromString(mv_maps[id]));
+}
+
+vector MapVote_RGB(float id)
{
- if(count < 0)
+ if(mv_avail[id] != GTV_AVAILABLE)
return '1 1 1';
if(id == mv_ownvote)
return '0 1 0';
return '1 1 1';
}
+void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string gtype, string pic, float count, float id)
+{
+ float alpha;
+ float desc_padding = gtv_text_size_x * 3;
+ float rect_margin = hud_fontsize_y / 2;
+ vector rect_pos = pos - '0.5 0.5 0' * rect_margin;
+ vector rect_size = '1 1 0';
+ rect_size_x = tsize + rect_margin;
+ rect_size_y = maxh + rect_margin;
+ vector rgb = MapVote_RGB(id);
+ vector offset = pos;
+ float nlines = 0;
+
+ if(mv_avail_start[id] != GTV_AVAILABLE)
+ alpha = 0.2;
+ else if ( mv_avail[id] != GTV_AVAILABLE && mv_top2_alpha)
+ alpha = mv_top2_alpha;
+ else
+ alpha = 1;
+
+ if(id == mv_selection && mv_avail[id] == GTV_AVAILABLE)
+ {
+ drawfill(rect_pos, rect_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
+ }
+ if(id == mv_ownvote)
+ {
+ drawfill(rect_pos, rect_size, rgb, 0.1*alpha, DRAWFLAG_NORMAL);
+ drawborderlines(autocvar_scoreboard_border_thickness, rect_pos, rect_size, rgb, alpha, DRAWFLAG_NORMAL);
+ }
+
+ entity title;
+ title = spawn();
+ title.message = MapVote_FormatMapItem(id, MapInfo_Type_ToText(MapInfo_Type_FromString(gtype)),
+ count, tsize, gtv_text_size);
+ title.origin = pos-offset;
+
+ pos_y += gtv_text_size_small_y;
+ pos_y += gtv_text_size_y/2;
+
+ maxh -= gtv_text_size_y;
+
+ entity picent = spawn();
+ picent.origin = pos-offset;
+ picent.maxs = '1 1 0 ' * min(maxh, desc_padding) * 0.8;
+
+ pos_x += desc_padding;
+ tsize -= desc_padding;
+
+ string thelabel = GameTypeVote_DescriptionByID(id), ts;
+ entity last = title;
+ entity next = world;
+ if( thelabel != "")
+ {
+ float i,n = tokenizebyseparator(thelabel, "\n");
+ for(i = 0; i < n && maxh > (nlines+1)*gtv_text_size_small_y; ++i)
+ {
+ getWrappedLine_remaining = argv(i);
+ while(getWrappedLine_remaining && maxh > (nlines+1)*gtv_text_size_small_y)
+ {
+ ts = getWrappedLine(tsize, gtv_text_size_small, stringwidth_colors);
+ if (ts != "")
+ {
+ next = spawn();
+ next.message = ts;
+ next.origin = pos-offset;
+ last.chain = next;
+ last = next;
+ pos_y += gtv_text_size_small_y;
+ nlines++;
+ }
+ }
+ }
+ }
+
+ maxh -= max(nlines*gtv_text_size_small_y,picent.maxs_y);
+ if ( maxh > 0 )
+ offset_y += maxh/2;
+ drawstring(title.origin+offset, title.message, gtv_text_size, rgb, alpha, DRAWFLAG_NORMAL);
+
+ if(pic != "")
+ drawpic(picent.origin+offset, pic, picent.maxs, '1 1 1', alpha, DRAWFLAG_NORMAL);
+
+ for ( last = title.chain; last ; )
+ {
+ drawstring(last.origin+offset, last.message, gtv_text_size_small, '1 1 1', alpha, DRAWFLAG_NORMAL);
+ next = last;
+ last = last.chain;
+ remove(next);
+ }
+
+ remove(picent);
+ remove(title);
+}
+
void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float count, float id)
{
vector img_size = '0 0 0';
isize -= hud_fontsize_y; // respect the text when calculating the image size
- rgb = MapVote_RGB(id, count);
+ rgb = MapVote_RGB(id);
img_size_y = isize;
img_size_x = isize / 0.75; // 4:3 x can be stretched easily, height is defined in isize
text_size = stringwidth(label, false, hud_fontsize);
float theAlpha;
- if (count < 0 && mv_top2_alpha)
+ if (mv_avail[id] != GTV_AVAILABLE && mv_top2_alpha)
theAlpha = mv_top2_alpha;
else
theAlpha = 1;
else
drawborderlines(autocvar_scoreboard_border_thickness, pos, img_size, '0 0 0', theAlpha, DRAWFLAG_NORMAL);
- if(id == mv_selection && count >= 0)
+ if(id == mv_selection && mv_avail[id] == GTV_AVAILABLE)
drawfill(pos, img_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
}
float text_size;
string label;
- rgb = MapVote_RGB(id, count);
+ rgb = MapVote_RGB(id);
pos_y = pos_y + hud_fontsize_y;
float MapVote_Selection(vector topleft, vector cellsize, float rows, float columns)
{
- float cell;
+
float c, r;
- cell = -1;
+ mv_mouse_selection = -1;
for (r = 0; r < rows; ++r)
for (c = 0; c < columns; ++c)
mv_mousepos_y >= topleft_y + cellsize_y * r &&
mv_mousepos_y <= topleft_y + cellsize_y * (r + 1))
{
- cell = r * columns + c;
+ mv_mouse_selection = r * columns + c;
break;
}
}
- if (cell >= mv_num_maps)
- cell = -1;
+ if (mv_mouse_selection >= mv_num_maps)
+ mv_mouse_selection = -1;
- if (mv_abstain && cell < 0)
- return mv_num_maps;
+ if (mv_abstain && mv_mouse_selection < 0)
+ mv_mouse_selection = mv_num_maps;
- return cell;
+ if ( mv_selection_keyboard )
+ return mv_selection;
+
+ return mv_mouse_selection;
}
void MapVote_Draw()
vector pos;
float isize;
float center;
- float columns, rows;
+ float rows;
float tsize;
vector dist = '0 0 0';
if (!autocvar_hud_cursormode)
{
- mv_mousepos = mv_mousepos + getmousepos();
+ vector mpos = mv_mousepos + getmousepos();
+ mpos_x = bound(0, mpos_x, vid_conwidth);
+ mpos_y = bound(0, mpos_y, vid_conheight);
+
+ if ( mpos_x != mv_mousepos_x || mpos_y != mv_mousepos_y )
+ mv_selection_keyboard = 0;
+ mv_mousepos = mpos;
- mv_mousepos_x = bound(0, mv_mousepos_x, vid_conwidth);
- mv_mousepos_y = bound(0, mv_mousepos_y, vid_conheight);
}
center = (vid_conwidth - 1)/2;
pos_z = 0;
draw_beginBoldFont();
- map = _("Vote for a map");
+ map = ((gametypevote) ? _("Decide the gametype") : _("Vote for a map"));
pos_x = center - stringwidth(map, false, '12 0 0');
drawstring(pos, map, '24 24 0', '1 1 1', 1, DRAWFLAG_NORMAL);
pos_y += 26;
+ if( mapvote_chosenmap != "" )
+ {
+ pos_x = center - stringwidth(mapvote_chosenmap, false, hud_fontsize*1.5/2);
+ drawstring(pos, mapvote_chosenmap, hud_fontsize*1.5, '1 1 1', 1, DRAWFLAG_NORMAL);
+ pos_y += hud_fontsize_y*2;
+ }
+
i = ceil(max(0, mv_timeout - time));
map = sprintf(_("%d seconds left"), i);
pos_x = center - stringwidth(map, false, '8 0 0');
if(mv_abstain)
mv_num_maps -= 1;
- if(mv_num_maps > 3)
- {
- columns = 3;
- } else {
- columns = mv_num_maps;
- }
- rows = ceil(mv_num_maps / columns);
+ rows = ceil(mv_num_maps / mv_columns);
- dist_x = (xmax - xmin) / columns;
+ dist_x = (xmax - xmin) / mv_columns;
dist_y = (ymax - pos_y) / rows;
- tsize = dist_x - 10;
- isize = min(dist_y - 10, 0.75 * tsize);
- mv_selection = MapVote_Selection(pos, dist, rows, columns);
+ if ( gametypevote )
+ {
+ tsize = dist_x - hud_fontsize_y;
+ isize = dist_y;
+ float maxheight = (ymax - pos_y) / 3;
+ if ( isize > maxheight )
+ {
+ pos_x += (isize - maxheight)/2;
+ isize = maxheight;
+ }
+ else
+ dist_y += hud_fontsize_y;
+ pos_x = ( vid_conwidth - dist_x * mv_columns ) / 2;
+ }
+ else
+ {
+ tsize = dist_x - 10;
+ isize = min(dist_y - 10, 0.75 * tsize);
+ }
+
+ mv_selection = MapVote_Selection(pos, dist, rows, mv_columns);
- pos_x += (xmax - xmin) / (2 * columns);
+ if ( !gametypevote )
+ pos_x += dist_x / 2;
pos_y += (dist_y - isize) / 2;
ymax -= isize;
if (mv_top2_time)
mv_top2_alpha = max(0.2, 1 - (time - mv_top2_time)*(time - mv_top2_time));
+ void (vector, float, float, string, string, float, float) DrawItem;
+
+ if(gametypevote)
+ DrawItem = GameTypeVote_DrawGameTypeItem;
+ else
+ DrawItem = MapVote_DrawMapItem;
+
for(i = 0; i < mv_num_maps; ++i)
{
tmp = mv_votes[i]; // FTEQCC bug: too many array accesses in the function call screw it up
map = mv_maps[i];
if(mv_preview[i])
- MapVote_DrawMapItem(pos + MapVote_GridVec(dist, i, columns), isize, tsize, map, mv_pics[i], tmp, i);
+ DrawItem(pos + MapVote_GridVec(dist, i, mv_columns), isize, tsize, map, mv_pics[i], tmp, i);
else
- MapVote_DrawMapItem(pos + MapVote_GridVec(dist, i, columns), isize, tsize, map, "", tmp, i);
+ DrawItem(pos + MapVote_GridVec(dist, i, mv_columns), isize, tsize, map, "", tmp, i);
}
if(mv_abstain)
MapVote_CheckPK3(pic, pk3, id);
}
+void MapVote_ReadMask()
+{
+ float i;
+ if ( mv_num_maps < 24 )
+ {
+ float mask, power;
+ if(mv_num_maps < 8)
+ mask = ReadByte();
+ else if(mv_num_maps < 16)
+ mask = ReadShort();
+ else
+ mask = ReadLong();
+
+ for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+ mv_avail[i] = (mask & power) ? GTV_AVAILABLE : GTV_FORBIDDEN;
+ }
+ else
+ {
+ for(i = 0; i < mv_num_maps; ++i )
+ mv_avail[i] = ReadByte();
+ }
+}
+
#define NUM_SSDIRS 4
string ssdirs[NUM_SSDIRS];
float n_ssdirs;
void MapVote_Init()
{
- float i, j, power;
+ float i, j;
string map, pk3, s;
precache_sound ("misc/invshot.wav");
if(autocvar_hud_cursormode) { setcursormode(1); }
else { mv_mousepos = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; }
mv_selection = -1;
+ mv_selection_keyboard = 0;
for(n_ssdirs = 0; ; ++n_ssdirs)
{
mv_ownvote = -1;
mv_timeout = ReadCoord();
- if(mv_num_maps <= 8)
- mv_maps_mask = ReadByte();
- else
- mv_maps_mask = ReadShort();
+ gametypevote = ReadByte();
+
+ float mv_real_num_maps = mv_num_maps - mv_abstain;
+
+ if(gametypevote)
+ {
+ mapvote_chosenmap = strzone(ReadString());
+ if ( gametypevote == 2 )
+ gametypevote = 0;
+
+ gtv_text_size = hud_fontsize*1.4;
+ gtv_text_size_small = hud_fontsize*1.1;
+
+ if (mv_real_num_maps > 8 )
+ mv_columns = 3;
+ else
+ mv_columns = min(2, mv_real_num_maps);
+ }
+ else
+ {
+ if (mv_real_num_maps > 16)
+ mv_columns = 5;
+ else if (mv_real_num_maps > 9)
+ mv_columns = 4;
+ else if(mv_real_num_maps > 3)
+ mv_columns = 3;
+ else
+ mv_columns = mv_real_num_maps;
+ }
+
+ MapVote_ReadMask();
+ for(i = 0; i < mv_num_maps; ++i )
+ mv_avail_start[i] = mv_avail[i];
// Assume mv_pk3list is world, there should only be 1 mapvote per round
mv_pk3list = world; // I'm still paranoid!
- for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+ for(i = 0; i < mv_num_maps; ++i)
{
mv_votes[i] = 0;
- if(mv_maps_mask & power)
- {
- map = strzone(ReadString());
- pk3 = strzone(ReadString());
- j = bound(0, ReadByte(), n_ssdirs - 1);
-
- mv_maps[i] = map;
- mv_pk3[i] = pk3;
- map = strzone(strcat(ssdirs[j], "/", map));
- mv_pics[i] = map;
+ map = strzone(ReadString());
+ pk3 = strzone(ReadString());
+ j = bound(0, ReadByte(), n_ssdirs - 1);
- mv_preview[i] = false;
+ mv_maps[i] = map;
+ mv_pk3[i] = pk3;
+ mv_avail[i] = ReadByte();
- MapVote_CheckPic(map, pk3, i);
+ if(gametypevote)
+ {
+ //map = strzone(strcat("gfx/menu/default/gametype_", map));
+ //map = strzone(sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, map));
+ string mv_picpath = sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, map);
+ if(precache_pic(mv_picpath) == "")
+ mv_picpath = strcat("gfx/menu/default/gametype_", map);
+ map = strzone(mv_picpath);
+ mv_pics[i] = map;
+ mv_preview[i] = PreviewExists(map);
}
else
{
- mv_maps[i] = strzone("if-you-see-this-the-code-is-broken");
- mv_pk3[i] = strzone("if-you-see-this-the-code-is-broken");
- mv_pics[i] = strzone("if-you-see-this-the-code-is-broken");
+ map = strzone(strcat(ssdirs[j], "/", map));
+ mv_pics[i] = map;
mv_preview[i] = false;
+ MapVote_CheckPic(map, pk3, i);
}
}
n_ssdirs = 0;
}
+void MapVote_SendChoice(float index)
+{
+ localcmd(strcat("\nimpulse ", ftos(index+1), "\n"));
+}
+
+float MapVote_MoveLeft(float pos)
+{
+ float imp;
+ if ( pos < 0 )
+ imp = mv_num_maps - 1;
+ else
+ imp = pos < 1 ? mv_num_maps - 1 : pos - 1;
+ if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+ imp = MapVote_MoveLeft(imp);
+ return imp;
+}
+float MapVote_MoveRight(float pos)
+{
+ float imp;
+ if ( pos < 0 )
+ imp = 0;
+ else
+ imp = pos >= mv_num_maps - 1 ? 0 : pos + 1;
+ if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+ imp = MapVote_MoveRight(imp);
+ return imp;
+}
+float MapVote_MoveUp(float pos)
+{
+ float imp;
+ if ( pos < 0 )
+ imp = mv_num_maps - 1;
+ else
+ {
+ imp = pos - mv_columns;
+ if ( imp < 0 )
+ {
+ imp = floor(mv_num_maps/mv_columns)*mv_columns + pos % mv_columns;
+ if ( imp >= mv_num_maps )
+ imp -= mv_columns;
+ }
+ }
+ if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+ imp = MapVote_MoveUp(imp);
+ return imp;
+}
+float MapVote_MoveDown(float pos)
+{
+ float imp;
+ if ( pos < 0 )
+ imp = 0;
+ else
+ {
+ imp = pos + mv_columns;
+ if ( imp >= mv_num_maps )
+ imp = imp % mv_columns;
+ }
+ if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+ imp = MapVote_MoveDown(imp);
+ return imp;
+}
+
float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary)
{
float imp;
{
mv_mousepos_x = nPrimary;
mv_mousepos_y = nSecondary;
+ mv_selection_keyboard = 0;
return true;
}
case K_KP_8: localcmd("\nimpulse 8\n"); return true;
case K_KP_9: localcmd("\nimpulse 9\n"); return true;
case K_KP_0: localcmd("\nimpulse 10\n"); return true;
+
+ case K_RIGHTARROW:
+ mv_selection_keyboard = 1;
+ mv_selection = MapVote_MoveRight(mv_selection);
+ return true;
+ case K_LEFTARROW:
+ mv_selection_keyboard = 1;
+ mv_selection = MapVote_MoveLeft(mv_selection);
+ return true;
+ case K_DOWNARROW:
+ mv_selection_keyboard = 1;
+ mv_selection = MapVote_MoveDown(mv_selection);
+ return true;
+ case K_UPARROW:
+ mv_selection_keyboard = 1;
+ mv_selection = MapVote_MoveUp(mv_selection);
+ return true;
+ case K_KP_ENTER:
+ case K_ENTER:
+ case K_SPACE:
+ if ( mv_selection_keyboard )
+ MapVote_SendChoice(mv_selection);
+ return true;
}
if (nPrimary == K_MOUSE1)
+ {
+ mv_selection_keyboard = 0;
+ mv_selection = mv_mouse_selection;
if (mv_selection >= 0)
{
imp = min(mv_selection + 1, mv_num_maps);
localcmd(strcat("\nimpulse ", ftos(imp), "\n"));
return true;
}
+ }
return false;
}
void MapVote_UpdateMask()
{
- float i, power;
- float oldmask;
-
- oldmask = mv_maps_mask;
- if(mv_num_maps <= 8)
- mv_maps_mask = ReadByte();
- else
- mv_maps_mask = ReadShort();
-
- if((oldmask & mv_maps_mask) != oldmask)
- if((oldmask & mv_maps_mask) == mv_maps_mask)
- sound(world, CH_INFO, "misc_invshot.wav", VOL_BASE, ATTEN_NONE);
-
- // remove votes that no longer apply
- for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
- if (!(mv_maps_mask & power))
- mv_votes[i] = -1;
-
+ MapVote_ReadMask();
mv_top2_time = time;
}
void MapVote_UpdateVotes()
{
- float i, power;
- for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+ float i;
+ for(i = 0; i < mv_num_maps; ++i)
{
- if(mv_maps_mask & power)
+ if(mv_avail[i] == GTV_AVAILABLE)
{
if(mv_detail)
mv_votes[i] = ReadByte();
-const float STAT_MOVEFLAGS = 225;
const float MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE = 4;
#define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
Defs.qc
../dpdefs/keycodes.qc
../common/constants.qh
+../common/stats.qh
../warpzonelib/anglestransform.qh
../warpzonelib/mathlib.qh
../common/teams.qh
../common/util.qh
+../common/nades.qh
+../common/buffs.qh
../common/test.qh
../common/counting.qh
../common/items.qh
../common/monsters/monsters.qc
+../common/nades.qc
+../common/buffs.qc
+
../warpzonelib/anglestransform.qc
../warpzonelib/mathlib.qc
../warpzonelib/common.qc
case PROJECTILE_GRENADE_BOUNCING:
rot = '0 -1000 0'; // sideways
break;
- case PROJECTILE_NADE_RED_BURN:
- case PROJECTILE_NADE_RED:
- case PROJECTILE_NADE_BLUE_BURN:
- case PROJECTILE_NADE_BLUE:
- case PROJECTILE_NADE_YELLOW_BURN:
- case PROJECTILE_NADE_YELLOW:
- case PROJECTILE_NADE_PINK_BURN:
- case PROJECTILE_NADE_PINK:
- case PROJECTILE_NADE_BURN:
- case PROJECTILE_NADE:
- rot = self.avelocity;
- break;
case PROJECTILE_HOOKBOMB:
rot = '1000 0 0'; // forward
break;
default:
break;
}
+
+ if(Nade_IDFromProjectile(self.cnt) != 0)
+ rot = self.avelocity;
+
self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
}
trailorigin = self.origin;
switch(self.cnt)
{
- case PROJECTILE_NADE_RED_BURN:
- case PROJECTILE_NADE_RED:
- case PROJECTILE_NADE_BLUE_BURN:
- case PROJECTILE_NADE_BLUE:
- case PROJECTILE_NADE_YELLOW_BURN:
- case PROJECTILE_NADE_YELLOW:
- case PROJECTILE_NADE_PINK_BURN:
- case PROJECTILE_NADE_PINK:
- case PROJECTILE_NADE_BURN:
- case PROJECTILE_NADE:
- trailorigin += v_up * 4;
- break;
case PROJECTILE_GRENADE:
case PROJECTILE_GRENADE_BOUNCING:
trailorigin += v_right * 1 + v_forward * -10;
default:
break;
}
+
+ if(Nade_IDFromProjectile(self.cnt) != 0)
+ trailorigin += v_up * 4;
+
if(drawn)
Projectile_DrawTrail(trailorigin);
else
self.fade_time = 0;
self.fade_rate = 0;
}
+
+ self.team = ReadByte() - 1;
}
if(f & 2)
case PROJECTILE_HOOKBOMB: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_KNIGHTSPIKE"); break;
case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
+ case PROJECTILE_NAPALM_FOUNTAIN: //self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("torch_small"); break;
case PROJECTILE_FIREBALL: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("fireball"); break; // particle effect is good enough
case PROJECTILE_FIREMINE: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("firemine"); break; // particle effect is good enough
case PROJECTILE_TAG: setmodel(self, "models/laser.mdl"); self.traileffect = particleeffectnum("TR_ROCKET"); break;
case PROJECTILE_BUMBLE_GUN: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
case PROJECTILE_BUMBLE_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
- case PROJECTILE_NADE_RED: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red"); break;
- case PROJECTILE_NADE_RED_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red_burn"); break;
- case PROJECTILE_NADE_BLUE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue"); break;
- case PROJECTILE_NADE_BLUE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue_burn"); break;
- case PROJECTILE_NADE_YELLOW: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow"); break;
- case PROJECTILE_NADE_YELLOW_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow_burn"); break;
- case PROJECTILE_NADE_PINK: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink"); break;
- case PROJECTILE_NADE_PINK_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink_burn"); break;
- case PROJECTILE_NADE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade"); break;
- case PROJECTILE_NADE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_burn"); break;
-
default:
+ if(Nade_IDFromProjectile(self.cnt) != 0) { setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum(Nade_TrailEffect(self.cnt, self.team)); break; }
error("Received invalid CSQC projectile, can't work with this!");
break;
}
self.mins = '-3 -3 -3';
self.maxs = '3 3 3';
break;
- case PROJECTILE_NADE_RED_BURN:
- case PROJECTILE_NADE_RED:
- case PROJECTILE_NADE_BLUE_BURN:
- case PROJECTILE_NADE_BLUE:
- self.mins = '-3 -3 -3';
- self.maxs = '3 3 3';
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_touch = func_null;
- self.scale = 1.5;
- self.avelocity = randomvec() * 720;
- break;
case PROJECTILE_GRENADE_BOUNCING:
self.mins = '-3 -3 -3';
self.maxs = '3 3 3';
self.move_bounce_factor = g_balance_grenadelauncher_bouncefactor;
self.move_bounce_stopspeed = g_balance_grenadelauncher_bouncestop;
break;
- case PROJECTILE_NADE_RED_BURN:
- case PROJECTILE_NADE_RED:
- case PROJECTILE_NADE_BLUE_BURN:
- case PROJECTILE_NADE_BLUE:
- case PROJECTILE_NADE_YELLOW_BURN:
- case PROJECTILE_NADE_YELLOW:
- case PROJECTILE_NADE_PINK_BURN:
- case PROJECTILE_NADE_PINK:
- case PROJECTILE_NADE_BURN:
- case PROJECTILE_NADE:
- self.mins = '-16 -16 -16';
- self.maxs = '16 16 16';
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_touch = func_null;
- self.scale = 1.5;
- self.avelocity = randomvec() * 720;
- break;
case PROJECTILE_SHAMBLER_LIGHTNING:
self.mins = '-8 -8 -8';
self.maxs = '8 8 8';
self.move_movetype = MOVETYPE_BOUNCE;
self.move_touch = func_null;
break;
+ case PROJECTILE_NAPALM_FOUNTAIN:
case PROJECTILE_FIREBALL:
loopsound(self, CH_SHOTS_SINGLE, "weapons/fireball_fly2.wav", VOL_BASE, ATTEN_NORM);
self.mins = '-16 -16 -16';
default:
break;
}
+
+ if(Nade_IDFromProjectile(self.cnt) != 0)
+ {
+ self.mins = '-16 -16 -16';
+ self.maxs = '16 16 16';
+ self.colormod = Nade_Color(Nade_IDFromProjectile(self.cnt));
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+ self.move_movetype = MOVETYPE_BOUNCE;
+ self.move_touch = func_null;
+ self.scale = 1.5;
+ self.avelocity = randomvec() * 720;
+
+ if(Nade_IDFromProjectile(self.cnt) == NADE_TYPE_TRANSLOCATE)
+ self.solid = SOLID_TRIGGER;
+ }
+
setsize(self, self.mins, self.maxs);
}
precache_model("models/rocket.md3");
precache_model("models/tagrocket.md3");
precache_model("models/tracer.mdl");
+ precache_model("models/sphere/sphere.md3");
precache_model("models/weapons/v_ok_grenade.md3");
"other gamemodes except DM.\n"));
}
-string HUD_DefaultColumnLayout()
-{
- return strcat( // fteqcc sucks
- "ping pl name | ",
- "-teams,race,lms/kills +freezetag/kills -teams,lms/deaths +freezetag/deaths -teams,lms,race,ka/suicides +freezetag/suicides -race,dm,tdm,ka,freezetag/frags ", // tdm already has this in "score"
- "+tdm/kills +tdm/deaths +tdm/suicides ",
- "+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns ",
- "+lms/lives +lms/rank ",
- "+kh/caps +kh/pushes +kh/destroyed ",
- "?+race/laps ?+race/time ?+race/fastest ",
- "+as/objectives +nexball/faults +nexball/goals +ka/pickups +ka/bckills +ka/bctime +freezetag/revivals ",
- "-lms,race,nexball/score");
-}
+#define HUD_DefaultColumnLayout() \
+"ping pl name | " \
+"-teams,race,lms/kills +ft,tdm/kills -teams,lms/deaths +ft,tdm/deaths -teams,lms,race,ka/suicides +ft,tdm/suicides -race,dm,tdm,ka,ft/frags " /* tdm already has this in "score" */ \
+"+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns " \
+"+lms/lives +lms/rank " \
+"+kh/caps +kh/pushes +kh/destroyed " \
+"?+race/laps ?+race/time ?+race/fastest " \
+"+as/objectives +nb/faults +nb/goals +ka/pickups +ka/bckills +ka/bctime +ft/revivals " \
+"-lms,race,nb/score"
void Cmd_HUD_SetFields(float argc)
{
float have_name = 0, have_primary = 0, have_secondary = 0, have_separator = 0;
float missing;
+ if(!gametype)
+ {
+ // set up a temporary scoreboard layout
+ // no layout can be properly set up until score_info data haven't been received
+ argc = tokenizebyseparator("0 1 ping pl name | score", " ");
+ ps_primary = 0;
+ scores_label[ps_primary] = strzone("score");
+ scores_flags[ps_primary] = SFL_ALLOW_HIDE;
+ }
+
// TODO: re enable with gametype dependant cvars?
if(argc < 3) // no arguments provided
argc = tokenizebyseparator(strcat("0 1 ", autocvar_scoreboard_columns), " ");
hud_field[hud_num_fields] = SP_PL;
} else if(str == "kd" || str == "kdr" || str == "kdratio" || str == "k/d") {
hud_field[hud_num_fields] = SP_KDRATIO;
- } else if(str == "sum" || str == "diff" || str == "f-d") {
+ } else if(str == "sum" || str == "diff" || str == "k-d") {
hud_field[hud_num_fields] = SP_SUM;
} else if(str == "name" || str == "nick") {
hud_field[hud_num_fields] = SP_NAME;
return str;
}
-void HUD_PrintScoreboardItem(vector pos, entity pl, float is_self, float pl_number)
+void HUD_PrintScoreboardItem(vector pos, vector item_size, entity pl, float is_self, float pl_number)
{
vector tmp, rgb;
rgb = Team_ColorRGB(pl.team);
rgb_y = autocvar_scoreboard_color_bg_g + 0.5;
rgb_z = autocvar_scoreboard_color_bg_b + 0.5; }
- // Layout:
- tmp_x = sbwidth;
- tmp_y = hud_fontsize_y * 1.25;
- tmp_z = 0;
-
+ vector h_pos = pos - '1 1 0';
+ vector h_size = item_size + '2 0 0';
// alternated rows highlighting
if(is_self)
- drawfill(pos - '1 1 0', tmp + '2 0 0', rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
+ drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
else if((scoreboard_highlight) && (!mod(pl_number,2)))
- drawfill(pos - '1 1 0', tmp + '2 0 0', rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+ drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+ tmp_x = item_size_x;
tmp_y = 0;
+ tmp_z = 0;
for(i = 0; i < hud_num_fields; ++i)
{
pos_x -= hud_size[i] + hud_fontsize_x;
}
}
+
+ if(pl.eliminated)
+ drawfill(h_pos, h_size, '0 0 0', 0.5, DRAWFLAG_NORMAL);
}
/*
pos_y += 1.25 * hud_fontsize_y; // skip the header
pos_y += autocvar_scoreboard_border_thickness;
+ // item size
+ tmp_x = sbwidth;
+ tmp_y = hud_fontsize_y * 1.25;
+
// fill the table and draw the rows
i = 0;
if (teamplay)
{
if(pl.team != tm.team)
continue;
- HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
+ HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
pos_y += 1.25 * hud_fontsize_y;
++i;
}
{
if(pl.team == NUM_SPECTATOR)
continue;
- HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
+ HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
pos_y += 1.25 * hud_fontsize_y;
++i;
}
float fontsize = height * 1/3;
float weapon_height = height * 2/3;
float weapon_width = sbwidth / weapon_cnt;
- float g_minstagib = 0;
+ float g_instagib = 0;
drawstring(pos, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
pos_y += 1.25 * hud_fontsize_y + autocvar_scoreboard_border_thickness;
pos_x += weapon_width / 2;
if(switchweapon == WEP_MINSTANEX)
- g_minstagib = 1; // TODO: real detection for minstagib?
+ g_instagib = 1; // TODO: real detection for instagib?
float weapon_stats;
if(autocvar_scoreboard_accuracy_nocolors)
self = get_weaponinfo(i);
if (!self.weapon)
continue;
- if ((i == WEP_NEX && g_minstagib) || i == WEP_PORTO || (i == WEP_MINSTANEX && !g_minstagib) || i == WEP_TUBA) // skip port-o-launch, nex || minstanex and tuba
+ if ((i == WEP_NEX && g_instagib) || i == WEP_PORTO || (i == WEP_MINSTANEX && !g_instagib) || i == WEP_TUBA) // skip port-o-launch, vortex || vaporizer and tuba
continue;
weapon_stats = weapon_accuracy[i-WEP_FIRST];
float specs;
specs = 0;
tmp = pos;
+ vector item_size;
+ item_size_x = sbwidth;
+ item_size_y = hud_fontsize_y * 1.25;
+ item_size_z = 0;
for(pl = players.sort_next; pl; pl = pl.sort_next)
{
if(pl.team != NUM_SPECTATOR)
continue;
pos_y += 1.25 * hud_fontsize_y;
- HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), specs);
+ HUD_PrintScoreboardItem(pos, item_size, pl, (pl.sv_entnum == player_localnum), specs);
++specs;
}
if(!ent.sameteam || (ent.sv_entnum == player_localentnum))
ent.alpha *= getplayeralpha(ent.sv_entnum-1);
- if(ent.alpha < ALPHA_MIN_VISIBLE)
+ if(ent.alpha < ALPHA_MIN_VISIBLE && gametype != MAPINFO_TYPE_CTS)
return;
float dist;
snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
}
- sound7(e, CH_TUBA, snd1, e.cnt * f1, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p1, 0);
+ sound7(e, CH_TUBA_SINGLE, snd1, e.cnt * f1, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p1, 0);
if(f2)
- sound7(e.enemy, CH_TUBA, snd2, e.cnt * f2, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p2, 0);
+ sound7(e.enemy, CH_TUBA_SINGLE, snd2, e.cnt * f2, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p2, 0);
}
else
{
if(restart)
snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
- sound(e, CH_TUBA, snd1, e.cnt, e.attenuate * autocvar_g_balance_tuba_attenuation);
+ sound(e, CH_TUBA_SINGLE, snd1, e.cnt, e.attenuate * autocvar_g_balance_tuba_attenuation);
}
}
self.nextthink = time;
if(self.cnt <= 0)
{
- sound(self, CH_TUBA, "misc/null.wav", 0, 0);
+ sound(self, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
if(self.enemy)
{
- sound(self.enemy, CH_TUBA, "misc/null.wav", 0, 0);
+ sound(self.enemy, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
remove(self.enemy);
}
remove(self);
}
string spritelookuptext(string s)
{
+ if(substring(s, 0, 5) == "buff-") { return Buff_PrettyName(Buff_Type_FromSprite(s)); }
switch(s)
{
case "as-push": return _("Push");
case "item-shield": return _("Shield");
case "item-fuelregen": return _("Fuel regen");
case "item-jetpack": return _("Jet Pack");
- case "freezetag_frozen": return _("Frozen!");
+ case "frozen": return _("Frozen!");
case "tagged-target": return _("Tagged");
case "vehicle": return _("Vehicle");
default: return s;
--- /dev/null
+vector Buff_Color(float buff_id)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_id == e.items)
+ return e.colormod;
+ return '1 1 1';
+}
+
+string Buff_PrettyName(float buff_id)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_id == e.items)
+ return e.message;
+ return "";
+}
+
+string Buff_Name(float buff_id)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_id == e.items)
+ return e.netname;
+ return "";
+}
+
+float Buff_Type_FromName(string buff_name)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_name == e.netname)
+ return e.items;
+ return 0;
+}
+
+float Buff_Type_FromSprite(string buff_sprite)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_sprite == e.model2)
+ return e.items;
+ return 0;
+}
+
+
+float Buff_Skin(float buff_id)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_id == e.items)
+ return e.skin;
+ return 0;
+}
+
+string Buff_Sprite(float buff_id)
+{
+ entity e;
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_id == e.items)
+ return e.model2;
+ return "";
+}
--- /dev/null
+entity Buff_Type_first;
+entity Buff_Type_last;
+.entity enemy; // internal next pointer
+
+var float BUFF_LAST = 1;
+
+.float items; // buff ID
+.string netname; // buff name
+.string message; // human readable name
+.vector colormod; // buff color
+.string model2; // buff sprite
+.float skin; // buff skin
+
+#define REGISTER_BUFF(hname,sname,NAME,bskin,bcolor) \
+ var float BUFF_##NAME; \
+ var entity Buff_Type##sname; \
+ void RegisterBuffs_##sname() \
+ { \
+ BUFF_##NAME = BUFF_LAST * 2; \
+ BUFF_LAST = BUFF_##NAME; \
+ Buff_Type##sname = spawn(); \
+ Buff_Type##sname.items = BUFF_##NAME; \
+ Buff_Type##sname.netname = #sname; \
+ Buff_Type##sname.message = hname; \
+ Buff_Type##sname.skin = bskin; \
+ Buff_Type##sname.colormod = bcolor; \
+ Buff_Type##sname.model2 = strzone(strcat("buff-", #sname)); \
+ if(!Buff_Type_first) \
+ Buff_Type_first = Buff_Type##sname; \
+ if(Buff_Type_last) \
+ Buff_Type_last.enemy = Buff_Type##sname; \
+ Buff_Type_last = Buff_Type##sname; \
+ } \
+ ACCUMULATE_FUNCTION(RegisterBuffs, RegisterBuffs_##sname)
+
+REGISTER_BUFF(_("Ammo"),ammo,AMMO,3,'0.2 1 0.2');
+REGISTER_BUFF(_("Resistance"),resistance,RESISTANCE,0,'0.3 0.2 1');
+REGISTER_BUFF(_("Speed"),speed,SPEED,9,'1 1 0.2');
+REGISTER_BUFF(_("Medic"),medic,MEDIC,1,'1 0.3 1');
+REGISTER_BUFF(_("Bash"),bash,BASH,5,'1 0.4 0');
+REGISTER_BUFF(_("Vampire"),vampire,VAMPIRE,2,'1 0.15 0');
+REGISTER_BUFF(_("Disability"),disability,DISABILITY,7,'0.66 0.66 0.73');
+REGISTER_BUFF(_("Vengeance"),vengeance,VENGEANCE,15,'0.55 0.5 1');
+REGISTER_BUFF(_("Jump"),jump,JUMP,10,'0.7 0.2 1');
+REGISTER_BUFF(_("Flight"),flight,FLIGHT,11,'1 0.2 0.5');
+REGISTER_BUFF(_("Invisible"),invisible,INVISIBLE,12,'0.9 0.9 0.9');
+#undef REGISTER_BUFF
+
+#ifdef SVQC
+.float buffs;
+void buff_Init(entity ent);
+void buff_Init_Compat(entity ent, float replacement);
+
+#define BUFF_SPAWNFUNC(e,b,t) void spawnfunc_item_buff_##e() { self.buffs = b; self.team = t; buff_Init(self); }
+#define BUFF_SPAWNFUNC_Q3TA_COMPAT(o,r) void spawnfunc_item_##o() { buff_Init_Compat(self,r); }
+#define BUFF_SPAWNFUNCS(e,b) \
+ BUFF_SPAWNFUNC(e, b, 0) \
+ BUFF_SPAWNFUNC(e##_team1, b, NUM_TEAM_1) \
+ BUFF_SPAWNFUNC(e##_team2, b, NUM_TEAM_2) \
+ BUFF_SPAWNFUNC(e##_team3, b, NUM_TEAM_3) \
+ BUFF_SPAWNFUNC(e##_team4, b, NUM_TEAM_4)
+
+BUFF_SPAWNFUNCS(resistance, BUFF_RESISTANCE)
+BUFF_SPAWNFUNCS(ammo, BUFF_AMMO)
+BUFF_SPAWNFUNCS(speed, BUFF_SPEED)
+BUFF_SPAWNFUNCS(medic, BUFF_MEDIC)
+BUFF_SPAWNFUNCS(bash, BUFF_BASH)
+BUFF_SPAWNFUNCS(vampire, BUFF_VAMPIRE)
+BUFF_SPAWNFUNCS(disability, BUFF_DISABILITY)
+BUFF_SPAWNFUNCS(vengeance, BUFF_VENGEANCE)
+BUFF_SPAWNFUNCS(jump, BUFF_JUMP)
+BUFF_SPAWNFUNCS(flight, BUFF_FLIGHT)
+BUFF_SPAWNFUNCS(invisible, BUFF_INVISIBLE)
+BUFF_SPAWNFUNCS(random, 0)
+
+BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler, BUFF_MEDIC)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(scout, BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(ammoregen, BUFF_AMMO)
+
+// actually Q3
+BUFF_SPAWNFUNC_Q3TA_COMPAT(haste, BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(invis, BUFF_INVISIBLE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(medic, BUFF_MEDIC)
+#endif
+
+vector Buff_Color(float buff_id);
+string Buff_PrettyName(float buff_id);
+string Buff_Name(float buff_id);
+float Buff_Type_FromName(string buff_name);
+float Buff_Type_FromSprite(string buff_sprite);
+float Buff_Skin(float buff_id);
+string Buff_Sprite(float buff_id);
const float ENT_CLIENT_SPAWNPOINT = 36;
const float ENT_CLIENT_SPAWNEVENT = 37;
const float ENT_CLIENT_NOTIFICATION = 38;
-
+const float ENT_CLIENT_ELIMINATEDPLAYERS = 39;
const float ENT_CLIENT_TURRET = 40;
const float ENT_CLIENT_AUXILIARYXHAIR = 50;
const float ENT_CLIENT_VEHICLE = 60;
+const float ENT_CLIENT_HEALING_ORB = 80;
+
const float SPRITERULE_DEFAULT = 0;
const float SPRITERULE_TEAMPLAY = 1;
///////////////////////////
// csqc communication stuff
-const float STAT_KH_KEYS = 32;
-const float STAT_CTF_STATE = 33;
-const float STAT_WEAPONS = 35;
-const float STAT_SWITCHWEAPON = 36;
-const float STAT_GAMESTARTTIME = 37;
-const float STAT_STRENGTH_FINISHED = 38;
-const float STAT_INVINCIBLE_FINISHED = 39;
-const float STAT_PRESSED_KEYS = 42;
-const float STAT_ALLOW_OLDNEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config
-const float STAT_FUEL = 44;
-const float STAT_NB_METERSTART = 45;
-const float STAT_SHOTORG = 46; // compressShotOrigin
-const float STAT_LEADLIMIT = 47;
-const float STAT_WEAPON_CLIPLOAD = 48;
-const float STAT_WEAPON_CLIPSIZE = 49;
-const float STAT_NEX_CHARGE = 50;
-const float STAT_LAST_PICKUP = 51;
-const float STAT_HUD = 52;
-const float STAT_NEX_CHARGEPOOL = 53;
-const float STAT_HIT_TIME = 54;
-const float STAT_TYPEHIT_TIME = 55;
-const float STAT_LAYED_MINES = 56;
-const float STAT_HAGAR_LOAD = 57;
-const float STAT_SWITCHINGWEAPON = 58;
-const float STAT_SUPERWEAPONS_FINISHED = 59;
-
-const float STAT_VEHICLESTAT_HEALTH = 60;
-const float STAT_VEHICLESTAT_SHIELD = 61;
-const float STAT_VEHICLESTAT_ENERGY = 62;
-const float STAT_VEHICLESTAT_AMMO1 = 63;
-const float STAT_VEHICLESTAT_RELOAD1 = 64;
-const float STAT_VEHICLESTAT_AMMO2 = 65;
-const float STAT_VEHICLESTAT_RELOAD2 = 66;
-
-const float STAT_SECRETS_TOTAL = 70;
-const float STAT_SECRETS_FOUND = 71;
-
-const float STAT_RESPAWN_TIME = 72;
-const float STAT_ROUNDSTARTTIME = 73;
-
-const float STAT_WEAPONS2 = 74;
-const float STAT_WEAPONS3 = 75;
-
-const float STAT_MONSTERS_TOTAL = 76;
-const float STAT_MONSTERS_KILLED = 77;
-
-// mod stats (1xx)
-const float STAT_REDALIVE = 100;
-const float STAT_BLUEALIVE = 101;
-const float STAT_YELLOWALIVE = 102;
-const float STAT_PINKALIVE = 103;
-
-// freeze tag
-const float STAT_FROZEN = 104;
-const float STAT_REVIVE_PROGRESS = 105;
-
-// domination
-const float STAT_DOM_TOTAL_PPS = 100;
-const float STAT_DOM_PPS_RED = 101;
-const float STAT_DOM_PPS_BLUE = 102;
-const float STAT_DOM_PPS_PINK = 103;
-const float STAT_DOM_PPS_YELLOW = 104;
-
-//const float STAT_SPIDERBOT_AIM 53 // compressShotOrigin
-//const float STAT_SPIDERBOT_TARGET 54 // compressShotOrigin
-
-// see DP source, quakedef.h
-const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
-const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223;
-const float STAT_MOVEVARS_MAXSPEED = 244;
-const float STAT_MOVEVARS_AIRACCEL_QW = 254;
-
-// new properties
-const float STAT_MOVEVARS_JUMPVELOCITY = 250;
-const float STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR = 220;
-const float STAT_MOVEVARS_MAXAIRSTRAFESPEED = 233;
-const float STAT_MOVEVARS_MAXAIRSPEED = 252;
-const float STAT_MOVEVARS_AIRSTRAFEACCELERATE = 232;
-const float STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL = 229;
-const float STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION = 255;
-const float STAT_MOVEVARS_AIRCONTROL = 234;
-const float STAT_MOVEVARS_AIRCONTROL_POWER = 224;
-const float STAT_MOVEVARS_AIRCONTROL_PENALTY = 221;
-const float STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL = 226;
-const float STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED = 228;
-const float STAT_MOVEVARS_WARSOWBUNNY_ACCEL = 227;
-const float STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO = 230;
-const float STAT_MOVEVARS_FRICTION = 238;
-const float STAT_MOVEVARS_ACCELERATE = 246;
-const float STAT_MOVEVARS_STOPSPEED = 243;
-const float STAT_MOVEVARS_AIRACCELERATE = 247;
-const float STAT_MOVEVARS_AIRSTOPACCELERATE = 231;
-
const float CTF_STATE_ATTACK = 1;
const float CTF_STATE_DEFEND = 2;
const float CTF_STATE_COMMANDER = 3;
// moved that here so the client knows the max.
// # of maps, I'll use arrays for them :P
-#define MAPVOTE_COUNT 10
+#define MAPVOTE_COUNT 30
/**
* Lower scores are better (e.g. suicides)
#define SP_SCORE 3
// game mode specific indices are not in common/, but in server/scores_rules.qc!
-#ifdef COMPAT_XON010_CHANNELS
-const float CH_INFO = 0; // only on world and csqc
-const float CH_TRIGGER = 0; // only on players; compat: FALSELY CONTROLLED BY "Info"
-const float CH_WEAPON_A = 1; // only on players and entities
-const float CH_WEAPON_SINGLE = 5; // only on players and entities
-const float CH_VOICE = 2; // only on players
-const float CH_BGM_SINGLE = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
-const float CH_AMBIENT = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
-const float CH_TRIGGER_SINGLE = 3; // only on players, entities, csqc
-const float CH_SHOTS = 4; // only on players, entities, csqc
-const float CH_SHOTS_SINGLE = 4; // only on players, entities, csqc
-const float CH_WEAPON_B = 5; // only on players and entities
-const float CH_PAIN = 6; // only on players and csqc
-const float CH_PAIN_SINGLE = 6; // only on players and csqc
-const float CH_PLAYER = 7; // only on players and entities
-const float CH_TUBA = 5; // only on csqc
-#else
const float CH_INFO = 0;
const float CH_TRIGGER = -3;
const float CH_WEAPON_A = -1;
const float CH_PAIN = -6;
const float CH_PAIN_SINGLE = 6;
const float CH_PLAYER = -7;
-const float CH_TUBA = 5;
-#endif
+const float CH_PLAYER_SINGLE = 7;
+const float CH_TUBA_SINGLE = 5;
const float ATTEN_NONE = 0;
const float ATTEN_MIN = 0.015625;
const float PROJECTILE_MAGE_SPIKE = 32;
const float PROJECTILE_SHAMBLER_LIGHTNING = 33;
-const float PROJECTILE_NADE_RED = 50;
-const float PROJECTILE_NADE_RED_BURN = 51;
-const float PROJECTILE_NADE_BLUE = 52;
-const float PROJECTILE_NADE_BLUE_BURN = 53;
-const float PROJECTILE_NADE_YELLOW = 54;
-const float PROJECTILE_NADE_YELLOW_BURN = 55;
-const float PROJECTILE_NADE_PINK = 56;
-const float PROJECTILE_NADE_PINK_BURN = 57;
-const float PROJECTILE_NADE = 58;
-const float PROJECTILE_NADE_BURN = 59;
-
const float SPECIES_HUMAN = 0;
const float SPECIES_ROBOT_SOLID = 1;
const float SPECIES_ALIEN = 2;
#define URI_GET_UPDATENOTIFICATION 33
#define URI_GET_URLLIB 128
#define URI_GET_URLLIB_END 191
+
+// gametype votes
+#define GTV_AVAILABLE 0
+// for later use in per-map gametype filtering
+#define GTV_FORBIDDEN 2
#define DEATHTYPES \
DEATHTYPE(DEATH_AUTOTEAMCHANGE, DEATH_SELF_AUTOTEAMCHANGE, NO_MSG, DEATH_SPECIAL_START) \
+ DEATHTYPE(DEATH_BUFF_VENGEANCE, NO_MSG, DEATH_MURDER_VENGEANCE, NORMAL_POS) \
DEATHTYPE(DEATH_CAMP, DEATH_SELF_CAMP, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_CHEAT, DEATH_SELF_CHEAT, DEATH_MURDER_CHEAT, NORMAL_POS) \
DEATHTYPE(DEATH_CUSTOM, DEATH_SELF_CUSTOM, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_WYVERN, DEATH_SELF_MON_WYVERN, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_ZOMBIE_JUMP, DEATH_SELF_MON_ZOMBIE_JUMP, DEATH_MURDER_MONSTER, NORMAL_POS) \
DEATHTYPE(DEATH_MONSTER_ZOMBIE_MELEE, DEATH_SELF_MON_ZOMBIE_MELEE, DEATH_MURDER_MONSTER, DEATH_MONSTER_LAST) \
- DEATHTYPE(DEATH_NADE, DEATH_SELF_NADE, DEATH_MURDER_NADE, NORMAL_POS) \
+ DEATHTYPE(DEATH_NADE, DEATH_SELF_NADE, DEATH_MURDER_NADE, NORMAL_POS) \
+ DEATHTYPE(DEATH_NADE_NAPALM, DEATH_SELF_NADE_NAPALM, DEATH_MURDER_NADE_NAPALM, NORMAL_POS) \
+ DEATHTYPE(DEATH_NADE_ICE, DEATH_SELF_NADE_ICE, DEATH_MURDER_NADE_ICE, NORMAL_POS) \
+ DEATHTYPE(DEATH_NADE_ICE_FREEZE, DEATH_SELF_NADE_ICE_FREEZE, DEATH_MURDER_NADE_ICE_FREEZE, NORMAL_POS) \
+ DEATHTYPE(DEATH_NADE_HEAL, DEATH_SELF_NADE_HEAL, DEATH_MURDER_NADE_HEAL, NORMAL_POS) \
DEATHTYPE(DEATH_NOAMMO, DEATH_SELF_NOAMMO, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_ROT, DEATH_SELF_ROT, NO_MSG, NORMAL_POS) \
DEATHTYPE(DEATH_SHOOTING_STAR, DEATH_SELF_SHOOTING_STAR, DEATH_MURDER_SHOOTING_STAR, NORMAL_POS) \
t = "inv";
print("'. Should use '", t, "'.\n");
}
+ if(t == "assault")
+ {
+ print("MapInfo_Type_FromString (probably ", MapInfo_Map_bspname, "): using deprecated name '", t);
+ t = "as";
+ print("'. Should use '", t, "'.\n");
+ }
+ if(t == "race")
+ {
+ print("MapInfo_Type_FromString (probably ", MapInfo_Map_bspname, "): using deprecated name '", t);
+ t = "rc";
+ print("'. Should use '", t, "'.\n");
+ }
if(t == "all")
return MAPINFO_TYPE_ALL;
for(e = MapInfo_Type_first; e; e = e.enemy)
return 0;
}
+string MapInfo_Type_Description(float t)
+{
+ entity e;
+ for(e = MapInfo_Type_first; e; e = e.enemy)
+ if(t == e.items)
+ return e.gametype_description;
+ return "";
+}
+
string MapInfo_Type_ToString(float t)
{
entity e;
{
t = car(s); s = cdr(s);
f = MapInfo_Type_FromString(t);
- print("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.\n");
+ dprint("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.\n");
if(f)
_MapInfo_Map_ApplyGametype (s, pGametypeToSet, f, TRUE);
else
{
float req;
req = 0;
- if(!(cvar("g_lms") || cvar("g_minstagib") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") || cvar("g_race") || cvar("g_cts") || cvar("g_nexball")))
+ if(!(cvar("g_lms") || cvar("g_instagib") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") || cvar("g_race") || cvar("g_cts") || cvar("g_nexball")))
req |= MAPINFO_FEATURE_WEAPONS;
return req;
}
localcmd(strcat("\nchangelevel ", s, "\n"));
}
-string MapInfo_ListAllowedMaps(float pRequiredFlags, float pForbiddenFlags)
+string MapInfo_ListAllowedMaps(float type, float pRequiredFlags, float pForbiddenFlags)
{
string out;
float i;
// to make absolutely sure:
MapInfo_Enumerate();
- MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
+ MapInfo_FilterGametype(type, MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
out = "";
for(i = 0; i < MapInfo_count; ++i)
.string mdl; // game type short name
.string message; // human readable name
.string model2; // game type defaults
+.string gametype_description; // game type description
-#define REGISTER_GAMETYPE(hname,sname,g_name,NAME,defaults) \
+#define REGISTER_GAMETYPE(hname,sname,g_name,NAME,defaults,gdescription) \
var float MAPINFO_TYPE_##NAME; \
var entity MapInfo_Type##g_name; \
void RegisterGametypes_##g_name() \
MapInfo_Type##g_name.mdl = #sname; \
MapInfo_Type##g_name.message = hname; \
MapInfo_Type##g_name.model2 = defaults; \
+ MapInfo_Type##g_name.gametype_description = gdescription; \
if(!MapInfo_Type_first) \
MapInfo_Type_first = MapInfo_Type##g_name; \
if(MapInfo_Type_last) \
#define IS_GAMETYPE(NAME) \
(MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME)
-REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,"timelimit=20 pointlimit=30 leadlimit=0");
+REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,"timelimit=20 pointlimit=30 leadlimit=0",_("Kill all enemies"));
#define g_dm IS_GAMETYPE(DEATHMATCH)
-REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 leadlimit=0");
+REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
#define g_lms IS_GAMETYPE(LMS)
-REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0");
+REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"));
#define g_race IS_GAMETYPE(RACE)
-REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,"timelimit=20 skill=-1");
+REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,"timelimit=20 skill=-1",_("Race for fastest time"));
#define g_cts IS_GAMETYPE(CTS)
-REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,"timelimit=20 pointlimit=50 teams=2 leadlimit=0");
+REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Kill all enemy teammates"));
#define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
-REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,"timelimit=20 caplimit=10 leadlimit=0");
+REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,"timelimit=20 caplimit=10 leadlimit=0",_("Find and bring the enemy flag to your base to capture it"));
#define g_ctf IS_GAMETYPE(CTF)
-REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,"timelimit=20 pointlimit=10 leadlimit=0");
+REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round"));
#define g_ca IS_GAMETYPE(CA)
-REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,"timelimit=20 pointlimit=200 teams=2 leadlimit=0");
+REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture all the control points to win"));
#define g_domination IS_GAMETYPE(DOMINATION)
-REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0");
+REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"));
#define g_keyhunt IS_GAMETYPE(KEYHUNT)
-REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,"timelimit=20");
+REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
#define g_assault IS_GAMETYPE(ASSAULT)
-REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,"timelimit=20");
+REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,"timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
#define g_onslaught IS_GAMETYPE(ONSLAUGHT)
-REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,"timelimit=20 pointlimit=5 leadlimit=0");
+REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,"timelimit=20 pointlimit=5 leadlimit=0",_("XonSports"));
#define g_nexball IS_GAMETYPE(NEXBALL)
-REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,"timelimit=20 pointlimit=10 teams=2 leadlimit=0");
+REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them"));
#define g_freezetag IS_GAMETYPE(FREEZETAG)
-REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,"timelimit=20 pointlimit=30");
+REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
#define g_keepaway IS_GAMETYPE(KEEPAWAY)
-REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,"pointlimit=50 teams=0");
+REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,"pointlimit=50 teams=0",_("Survive against waves of monsters"));
#define g_invasion IS_GAMETYPE(INVASION)
-const float MAPINFO_FEATURE_WEAPONS = 1; // not defined for minstagib-only maps
+const float MAPINFO_FEATURE_WEAPONS = 1; // not defined for instagib-only maps
const float MAPINFO_FEATURE_VEHICLES = 2;
const float MAPINFO_FEATURE_TURRETS = 4;
const float MAPINFO_FEATURE_MONSTERS = 8;
void MapInfo_LoadMap(string s, float reinit);
// list all maps for the current game type
-string MapInfo_ListAllowedMaps(float pFlagsRequired, float pFlagsForbidden);
+string MapInfo_ListAllowedMaps(float type, float pFlagsRequired, float pFlagsForbidden);
// list all allowed maps (for any game type)
string MapInfo_ListAllAllowedMaps(float pFlagsRequired, float pFlagsForbidden);
// gets a gametype from a string
string _MapInfo_GetDefaultEx(float t);
float MapInfo_Type_FromString(string t);
+string MapInfo_Type_Description(float t);
string MapInfo_Type_ToString(float t);
string MapInfo_Type_ToText(float t);
void MapInfo_SwitchGameType(float t);
return FALSE;
if(DIFF_TEAM(e, self) && e != self.monster_owner)
return FALSE;
- if(e.freezetag_frozen)
+ if(e.frozen)
return FALSE;
if(!IS_PLAYER(e))
return ((e.flags & FL_MONSTER) && e.health < e.max_health);
if(SAME_TEAM(targ, ent))
return FALSE; // enemy is on our team
- if (targ.freezetag_frozen)
+ if (targ.frozen)
return FALSE; // ignore frozen
if(autocvar_g_monsters_target_infront || (ent.spawnflags & MONSTERFLAG_INFRONT))
if((self.enemy == world)
|| (self.enemy.deadflag != DEAD_NO || self.enemy.health < 1)
- || (self.enemy.freezetag_frozen)
+ || (self.enemy.frozen)
|| (self.enemy.flags & FL_NOTARGET)
|| (self.enemy.alpha < 0.5)
|| (self.enemy.takedamage == DAMAGE_NO)
entity targ;
+ if(self.frozen == 2)
+ {
+ self.revive_progress = bound(0, self.revive_progress + self.ticrate * self.revive_speed, 1);
+ self.health = max(1, self.revive_progress * self.max_health);
+ self.iceblock.alpha = bound(0.2, 1 - self.revive_progress, 1);
+
+ WaypointSprite_UpdateHealth(self.sprite, self.health);
+
+ movelib_beak_simple(stopspeed);
+ self.frame = manim_idle;
+
+ self.enemy = world;
+ self.nextthink = time + self.ticrate;
+
+ if(self.revive_progress >= 1)
+ Unfreeze(self);
+
+ return;
+ }
+ else if(self.frozen == 3)
+ {
+ self.revive_progress = bound(0, self.revive_progress - self.ticrate * self.revive_speed, 1);
+ self.health = max(0, autocvar_g_nades_ice_health + (self.max_health-autocvar_g_nades_ice_health) * self.revive_progress );
+
+ WaypointSprite_UpdateHealth(self.sprite, self.health);
+
+ movelib_beak_simple(stopspeed);
+ self.frame = manim_idle;
+
+ self.enemy = world;
+ self.nextthink = time + self.ticrate;
+
+ if(self.health < 1)
+ {
+ Unfreeze(self);
+ self.health = 0;
+ self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0');
+ }
+
+ else if ( self.revive_progress <= 0 )
+ Unfreeze(self);
+
+ return;
+ }
+
if(self.flags & FL_SWIM)
{
if(self.waterlevel < WATERLEVEL_WETFEET)
if(mon.weaponentity)
remove(mon.weaponentity);
+ if(mon.iceblock)
+ remove(mon.iceblock);
+
WaypointSprite_Kill(mon.sprite);
remove(mon);
setorigin(self, self.pos1);
self.angles = self.pos2;
+ Unfreeze(self); // remove any icy remains
+
self.health = self.max_health;
self.velocity = '0 0 0';
self.enemy = world;
self.nextthink = time;
self.monster_lifetime = time + 5;
+ if(self.frozen)
+ {
+ Unfreeze(self); // remove any icy remains
+ self.health = 0; // reset by Unfreeze
+ }
+
monster_dropitem();
MonsterSound(monstersound_death, 0, FALSE, CH_VOICE);
void monsters_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
+ if(self.frozen && deathtype != DEATH_KILL && deathtype != DEATH_NADE_ICE_FREEZE)
+ return;
+
if((self.spawnflags & MONSTERFLAG_INVINCIBLE) && deathtype != DEATH_KILL)
return;
--- /dev/null
+.float healer_lifetime;
+.float healer_radius;
+
+#ifdef SVQC
+float healer_send(entity to, float sf)
+{
+ WriteByte(MSG_ENTITY, ENT_CLIENT_HEALING_ORB);
+ WriteByte(MSG_ENTITY, sf);
+
+ if(sf & 1)
+ {
+ WriteCoord(MSG_ENTITY, self.origin_x);
+ WriteCoord(MSG_ENTITY, self.origin_y);
+ WriteCoord(MSG_ENTITY, self.origin_z);
+
+ WriteByte(MSG_ENTITY, self.healer_lifetime);
+ //WriteByte(MSG_ENTITY, self.ltime - time + 1);
+ WriteShort(MSG_ENTITY, self.healer_radius);
+ // round time delta to a 1/10th of a second
+ WriteByte(MSG_ENTITY, (self.ltime - time)*10.0+0.5);
+ }
+
+ return TRUE;
+}
+#endif // SVQC
+
+#ifdef CSQC
+.float ltime;
+void healer_draw()
+{
+ float dt = time - self.move_time;
+ self.move_time = time;
+ if(dt <= 0)
+ return;
+
+ self.alpha = (self.ltime - time) / self.healer_lifetime;
+ self.scale = min((1 - self.alpha)*self.healer_lifetime*4,1)*self.healer_radius;
+
+}
+
+void healer_setup()
+{
+ setmodel(self, "models/ctf/shield.md3");
+
+ setorigin(self, self.origin);
+
+ float model_radius = self.maxs_x;
+ vector size = '1 1 1' * self.healer_radius / 2;
+ setsize(self,-size,size);
+ self.healer_radius = self.healer_radius/model_radius*0.6;
+
+ self.draw = healer_draw;
+ self.health = 255;
+ self.movetype = MOVETYPE_NONE;
+ self.solid = SOLID_NOT;
+ self.drawmask = MASK_NORMAL;
+ self.scale = 0.01;
+ self.avelocity = self.move_avelocity = '7 0 11';
+ self.colormod = '1 0 0';
+ self.renderflags |= RF_ADDITIVE;
+}
+
+void ent_healer()
+{
+ float sf = ReadByte();
+
+ if(sf & TNSF_SETUP)
+ {
+ self.origin_x = ReadCoord();
+ self.origin_y = ReadCoord();
+ self.origin_z = ReadCoord();
+ setorigin(self, self.origin);
+
+ self.healer_lifetime = ReadByte();
+ self.healer_radius = ReadShort();
+ self.ltime = time + ReadByte()/10.0;
+ //self.ltime = time + self.healer_lifetime;
+
+ healer_setup();
+ }
+}
+#endif // CSQC
\ No newline at end of file
--- /dev/null
+// use slots 70-100
+const float PROJECTILE_NADE = 71;
+const float PROJECTILE_NADE_BURN = 72;
+const float PROJECTILE_NADE_NAPALM = 73;
+const float PROJECTILE_NADE_NAPALM_BURN = 74;
+const float PROJECTILE_NAPALM_FOUNTAIN = 75;
+const float PROJECTILE_NADE_ICE = 76;
+const float PROJECTILE_NADE_ICE_BURN = 77;
+const float PROJECTILE_NADE_TRANSLOCATE = 78;
+const float PROJECTILE_NADE_SPAWN = 79;
+const float PROJECTILE_NADE_HEAL = 80;
+const float PROJECTILE_NADE_HEAL_BURN = 81;
+const float PROJECTILE_NADE_MONSTER = 82;
+const float PROJECTILE_NADE_MONSTER_BURN = 83;
+
+const float NADE_TYPE_NORMAL = 1;
+const float NADE_TYPE_NAPALM = 2;
+const float NADE_TYPE_ICE = 3;
+const float NADE_TYPE_TRANSLOCATE = 4;
+const float NADE_TYPE_SPAWN = 5;
+const float NADE_TYPE_HEAL = 6;
+const float NADE_TYPE_MONSTER = 7;
+
+const float NADE_TYPE_LAST = 7; // a check to prevent using higher values & crashing
+
+vector Nade_Color(float nadeid)
+{
+ switch(nadeid)
+ {
+ case NADE_TYPE_NORMAL: return '1 1 1';
+ case NADE_TYPE_NAPALM: return '2 0.5 0';
+ case NADE_TYPE_ICE: return '0 0.5 2';
+ case NADE_TYPE_TRANSLOCATE: return '1 0.0625 1';
+ case NADE_TYPE_SPAWN: return '1 0.9 0.06';
+ case NADE_TYPE_HEAL: return '1 0 0';
+ case NADE_TYPE_MONSTER: return '1 0.5 0';
+ }
+
+ return '0 0 0';
+}
+
+float Nade_IDFromProjectile(float proj)
+{
+ switch(proj)
+ {
+ case PROJECTILE_NADE:
+ case PROJECTILE_NADE_BURN: return NADE_TYPE_NORMAL;
+ case PROJECTILE_NADE_NAPALM:
+ case PROJECTILE_NADE_NAPALM_BURN: return NADE_TYPE_NAPALM;
+ case PROJECTILE_NADE_ICE:
+ case PROJECTILE_NADE_ICE_BURN: return NADE_TYPE_ICE;
+ case PROJECTILE_NADE_TRANSLOCATE: return NADE_TYPE_TRANSLOCATE;
+ case PROJECTILE_NADE_SPAWN: return NADE_TYPE_SPAWN;
+ case PROJECTILE_NADE_HEAL:
+ case PROJECTILE_NADE_HEAL_BURN: return NADE_TYPE_HEAL;
+ case PROJECTILE_NADE_MONSTER:
+ case PROJECTILE_NADE_MONSTER_BURN: return NADE_TYPE_MONSTER;
+ }
+
+ return 0;
+}
+
+float Nade_ProjectileFromID(float proj, float burn)
+{
+ switch(proj)
+ {
+ case NADE_TYPE_NORMAL: return (burn) ? PROJECTILE_NADE_BURN : PROJECTILE_NADE;
+ case NADE_TYPE_NAPALM: return (burn) ? PROJECTILE_NADE_NAPALM_BURN : PROJECTILE_NADE_NAPALM;
+ case NADE_TYPE_ICE: return (burn) ? PROJECTILE_NADE_ICE_BURN : PROJECTILE_NADE_ICE;
+ case NADE_TYPE_TRANSLOCATE: return PROJECTILE_NADE_TRANSLOCATE;
+ case NADE_TYPE_SPAWN: return PROJECTILE_NADE_SPAWN;
+ case NADE_TYPE_HEAL: return (burn) ? PROJECTILE_NADE_HEAL_BURN : PROJECTILE_NADE_HEAL;
+ case NADE_TYPE_MONSTER: return (burn) ? PROJECTILE_NADE_MONSTER_BURN : PROJECTILE_NADE_MONSTER;
+ }
+
+ return 0;
+}
+
+string Nade_TrailEffect(float proj, float nade_team)
+{
+ switch(proj)
+ {
+ case PROJECTILE_NADE: return strcat("nade_", Static_Team_ColorName_Lower(nade_team));
+ case PROJECTILE_NADE_BURN: return strcat("nade_", Static_Team_ColorName_Lower(nade_team), "_burn");
+ case PROJECTILE_NADE_NAPALM: return "TR_ROCKET";
+ case PROJECTILE_NADE_NAPALM_BURN: return "spiderbot_rocket_thrust";
+ case PROJECTILE_NADE_ICE: return "TR_NEXUIZPLASMA";
+ case PROJECTILE_NADE_ICE_BURN: return "wakizashi_rocket_thrust";
+ case PROJECTILE_NADE_TRANSLOCATE: return "TR_CRYLINKPLASMA";
+ case PROJECTILE_NADE_SPAWN: return "nade_yellow";
+ case PROJECTILE_NADE_HEAL: return "nade_red";
+ case PROJECTILE_NADE_HEAL_BURN: return "nade_red_burn";
+ case PROJECTILE_NADE_MONSTER: return "nade_red";
+ case PROJECTILE_NADE_MONSTER_BURN: return "nade_red_burn";
+ }
+
+ return "";
+}
+
+#ifdef CSQC
+// misc functions
+void ent_healer();
+#endif // CSQC
if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
NOTIF_WRITE_ENTITY(
- "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
+ "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
);
}
if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
NOTIF_WRITE_ENTITY(
- "Notification control cvar: 0 = off, 1 = print to console, "
+ "0 = off, 1 = print to console, "
"2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
);
}
if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
NOTIF_WRITE_ENTITY(
- "Notification control cvar: 0 = off, 1 = centerprint"
+ "0 = off, 1 = centerprint"
);
}
if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
NOTIF_WRITE_ENTITY(
- "Notification control cvar: 0 = off, 1 = trigger subcalls"
+ "Enable this multiple notification"
);
}
if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
NOTIF_WRITE_ENTITY_CHOICE(
- "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall",
- "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
+ "Choice for this notification 0 = off, 1 = default message, 2 = verbose message",
+ "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
);
}
NOTIF_WRITE_HARDCODED(
"allow_chatboxprint", "1",
- "Allow notifications to be printed to chat box by setting notification cvar to 2 "
- "(You can also set this cvar to 2 to force ALL notifications to be printed to the chatbox)"
+ "Allow INFO notifications to be printed to chat box"
+ "0 = do not allow, "
+ "1 = allow only if allowed by individual notification_INFO* cvars, "
+ "2 = force all INFO notifications to be printed to the chatbox"
);
NOTIF_WRITE_HARDCODED(
#define RECURSE_FROM_CHOICE(ent,action) \
if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) \
{ \
- switch(ent.msg_choice_choices[net_name]) \
+ switch(ent.msg_choice_choices[net_name - 1]) \
{ \
case 1: found_choice = notif.nent_optiona; break; \
case 2: found_choice = notif.nent_optionb; break; \
MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_20, CH_INFO, "20kills", VOL_BASEVOICE, ATTEN_NONE) \
MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_25, CH_INFO, "25kills", VOL_BASEVOICE, ATTEN_NONE) \
MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_30, CH_INFO, "30kills", VOL_BASEVOICE, ATTEN_NONE) \
- MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_LASTSECOND, CH_INFO, "lastsecond", VOL_BASEVOICE, ATTEN_NONE) \
- MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_NARROWLY, CH_INFO, "narrowly", VOL_BASEVOICE, ATTEN_NONE) \
- MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_TERMINATED, CH_INFO, "terminated", VOL_BASEVOICE, ATTEN_NONE) \
+ MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_LASTSECOND, CH_INFO, "lastsecond", VOL_BASEVOICE, ATTEN_NONE) \
+ MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_NARROWLY, CH_INFO, "narrowly", VOL_BASEVOICE, ATTEN_NONE) \
+ MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_TERMINATED, CH_INFO, "terminated", VOL_BASEVOICE, ATTEN_NONE) \
MSG_ANNCE_NOTIF(0, ANNCE_MULTIFRAG, CH_INFO, "multifrag", VOL_BASEVOICE, ATTEN_NONE) \
MSG_ANNCE_NOTIF(2, ANNCE_NUM_1, CH_INFO, "1", VOL_BASEVOICE, ATTEN_NONE) \
MSG_ANNCE_NOTIF(2, ANNCE_NUM_2, CH_INFO, "2", VOL_BASEVOICE, ATTEN_NONE) \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_lava", _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_MONSTER, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") \
- MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_NAPALM, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_napalm", _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_ice", _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE_FREEZE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_ice", _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_HEAL, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_nade_heal", _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_shootingstar", _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_slime", _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VENGEANCE, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_death", _("^BG%s%s^K1 was destroyed by the vengeful ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID, 3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1", "notify_void", _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE, 2, 1, "s1 s2loc death_team", "", "", _("^BG%s^K1 was moved into the %s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_teamkill_red", _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC, 2, 1, "s1 s2loc spree_lost", "s1", "notify_selfkill", _("^BG%s^K1 died%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA, 2, 1, "s1 s2loc spree_lost", "s1", "notify_lava", _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) \
- MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_MAGE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was exploded by a Mage%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_CLAW, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_SMASH, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was smashed by a Shambler%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 joins the Zombies%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_NAPALM, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_napalm", _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_ice", _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE_FREEZE, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_ice", _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) \
+ MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_HEAL, 2, 1, "s1 s2loc spree_lost", "s1", "notify_nade_heal", _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO, 2, 1, "s1 s2loc spree_lost", "s1", "notify_outofammo", _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 rotted away%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR, 2, 1, "s1 s2loc spree_lost", "s1", "notify_shootingstar", _("^BG%s^K1 became a shooting star%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_ROCKET, 2, 1, "s1 s2loc spree_lost", "s1", "notify_death", _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") \
MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID, 2, 1, "s1 s2loc spree_lost", "s1", "notify_void", _("^BG%s^K1 was in the wrong place%s%s"), "") \
MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4, 3, 1, "s1 s2 s3loc spree_end", "s2 s1", "notify_teamkill_%s", _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") \
+ MSG_INFO_NOTIF(1, INFO_CA_JOIN_LATE, 0, 0, "", "", "", _("^F1Round already started, you will join the game in the next round"), "") \
+ MSG_INFO_NOTIF(1, INFO_CA_LEAVE, 0, 0, "", "", "", _("^F2You will spectate in the next round"), "") \
+ MSG_INFO_NOTIF(1, INFO_DOMINATION_CAPTURE_TIME, 2, 2, "s1 s2 f1 f2", "", "", _("^BG%s^BG%s^BG (%s points every %s seconds)"), "") \
MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE, 2, 0, "s1 s2", "", "", _("^BG%s^K1 was frozen by ^BG%s"), "") \
MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED, 2, 0, "s1 s2", "", "", _("^BG%s^K3 was revived by ^BG%s"), "") \
MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_FALL, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by falling"), "") \
+ MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_NADE, 1, 0, "s1", "", "", _("^BG%s^K3 was revived by their Nade explosion"), "") \
MSG_INFO_NOTIF(1, INFO_FREEZETAG_AUTO_REVIVED, 1, 1, "s1 f1", "", "", _("^BG%s^K3 was automatically revived after %s second(s)"), "") \
MULTITEAM_INFO(1, INFO_ROUND_TEAM_WIN_, 4, 0, 0, "", "", "", _("^TC^TT^BG team wins the round"), "") \
MSG_INFO_NOTIF(1, INFO_ROUND_PLAYER_WIN, 1, 0, "s1", "", "", _("^BG%s^BG wins the round"), "") \
MSG_INFO_NOTIF(1, INFO_ROUND_OVER, 0, 0, "", "", "", _("^BGRound over, there's no winner"), "") \
MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF, 1, 0, "s1", "", "", _("^BG%s^K1 froze themself"), "") \
MSG_INFO_NOTIF(1, INFO_GODMODE_OFF, 0, 1, "f1", "", "", _("^BGGodmode saved you %s units of damage, cheater!"), "") \
+ MSG_INFO_NOTIF(1, INFO_ITEM_BUFF, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG got the %s^BG Buff!"), "") \
+ MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_LOST, 1, 1, "s1 item_buffname", "", "", _("^BG%s^BG lost the %s^BG Buff!"), "") \
+ MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_DROP, 0, 1, "item_buffname", "", "", _("^BGYou dropped the %s^BG Buff!"), "") \
+ MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_GOT, 0, 1, "item_buffname", "", "", _("^BGYou got the %s^BG Buff!"), "") \
MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DONTHAVE, 0, 1, "item_wepname", "", "", _("^BGYou do not have the ^F1%s"), "") \
MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DROP, 1, 1, "item_wepname item_wepammo", "", "", _("^BGYou dropped the ^F1%s^BG%s"), "") \
MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_GOT, 0, 1, "item_wepname", "", "", _("^BGYou got the ^F1%s"), "") \
MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET, 1, 2, "s1 race_col f1ord race_col f2race_time", "s1 f2race_time", "race_newrecordserver", _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") \
MULTITEAM_INFO(1, INFO_SCORES_, 4, 0, 0, "", "", "", _("^TC^TT ^BGteam scores!"), "") \
MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING, 0, 1, "f1secs", "", "", _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") \
- MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP, 1, 0, "s1", "s1", "strength", _("^BG%s^K1 picked up a Superweapon"), "") \
+ MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP, 1, 0, "s1", "s1", "superweapons", _("^BG%s^K1 picked up a Superweapon"), "") \
+ MSG_INFO_NOTIF(1, INFO_TEAMCHANGE_LARGERTEAM, 0, 0, "", "", "", _("^BGYou cannot change to a larger team"), "") \
+ MSG_INFO_NOTIF(1, INFO_TEAMCHANGE_NOTALLOWED, 0, 0, "", "", "", _("^BGYou are not allowed to change teams"), "") \
MSG_INFO_NOTIF(2, INFO_VERSION_BETA, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") \
MSG_INFO_NOTIF(2, INFO_VERSION_OLD, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") \
MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED, 2, 0, "s1 s2", "", "", _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") \
MULTITEAM_CENTER##teams(default,prefix,strnum,flnum,args,cpid,durcnt,normal,gentle)
#define MSG_CENTER_NOTIFICATIONS \
+ MSG_CENTER_NOTIF(1, CENTER_ALONE, 0, 0, "", NO_CPID, "0 0", _("^F4You are now alone!"), "") \
MSG_CENTER_NOTIF(1, CENTER_ASSAULT_ATTACKING, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are attacking!"), "") \
MSG_CENTER_NOTIF(1, CENTER_ASSAULT_DEFENDING, 0, 0, "", CPID_ASSAULT_ROLE, "0 0", _("^BGYou are defending!"), "") \
MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_BEGIN, 0, 0, "", CPID_ROUND, "2 0", _("^F4Begin!"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE, 1, 4, "spree_cen s1 frag_stats", NO_CPID, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE, 1, 2, "spree_cen s1 frag_ping", NO_CPID, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) \
MSG_CENTER_NOTIF(1, CENTER_NADE_THROW, 0, 0, "", CPID_NADES, "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the nade!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_NADE_BONUS, 0, 0, "", CPID_NADES, "0 0", _("^F2You got a ^K1BONUS GRENADE^F2!"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_AUTOTEAMCHANGE, 0, 1, "death_team", NO_CPID, "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_BETRAYAL, 0, 0, "", NO_CPID, "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CAMP, 0, 0, "", NO_CPID, "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_LAVA, 0, 0, "", NO_CPID, "0 0", _("^K1You couldn't stand the heat!"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_MONSTER, 0, 0, "", NO_CPID, "0 0", _("^K1You were killed by a monster!"), _("^K1You need to watch out for monsters!")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE, 0, 0, "", NO_CPID, "0 0", _("^K1You forgot to put the pin back in!"), _("^K1Tastes like chicken!")) \
+ MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_NAPALM, 0, 0, "", NO_CPID, "0 0", _("^K1Hanging around a napalm explosion is bad!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_ICE_FREEZE, 0, 0, "", NO_CPID, "0 0", _("^K1You got a little bit too cold!"), _("^K1You felt a little chilly!")) \
+ MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_HEAL, 0, 0, "", NO_CPID, "0 0", _("^K1Your Healing Nade is a bit defective"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NOAMMO, 0, 0, "", NO_CPID, "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_ROT, 0, 0, "", NO_CPID, "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SHOOTING_STAR, 0, 0, "", NO_CPID, "0 0", _("^K1You became a shooting star!"), "") \
MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAG, 1, 0, "s1", NO_CPID, "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) \
MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAGGED, 1, 0, "s1", NO_CPID, "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) \
MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING, 0, 1, "", CPID_IDLING, "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") \
+ MSG_CENTER_NOTIF(1, CENTER_DOOR_LOCKED_NEED, 0, 0, "", NO_CPID, "0 0", _("^BGYou need %s^BG!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_DOOR_LOCKED_ALSONEED, 0, 0, "", NO_CPID, "0 0", _("^BGYou also need %s^BG!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_DOOR_UNLOCKED, 0, 0, "", NO_CPID, "0 0", _("^BGDoor unlocked!"), "") \
MSG_CENTER_NOTIF(1, CENTER_EXTRALIVES, 0, 0, "", NO_CPID, "0 0", _("^F2You picked up some extra lives"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE, 1, 0, "s1", NO_CPID, "0 0", _("^K3You froze ^BG%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN, 1, 0, "s1", NO_CPID, "0 0", _("^K1You were frozen by ^BG%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE, 1, 0, "s1", NO_CPID, "0 0", _("^K3You revived ^BG%s"), "") \
- MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE_FALL, 0, 0, "", NO_CPID, "0 0", _("^K3You revived yourself"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE_SELF, 0, 0, "", NO_CPID, "0 0", _("^K3You revived yourself"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED, 1, 0, "s1", NO_CPID, "0 0", _("^K3You were revived by ^BG%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_AUTO_REVIVED, 0, 1, "f1", NO_CPID, "0 0", _("^K3You were automatically revived after %s second(s)"), "") \
MULTITEAM_CENTER(1, CENTER_ROUND_TEAM_WIN_, 4, 0, 0, "", CPID_ROUND, "0 0", _("^TC^TT^BG team wins the round"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF, 0, 0, "", NO_CPID, "0 0", _("^K1You froze yourself"), "") \
MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SPAWN_LATE, 0, 0, "", NO_CPID, "0 0", _("^K1Round already started, you spawn as frozen"), "") \
MSG_CENTER_NOTIF(1, CENTER_INVASION_SUPERMONSTER, 1, 0, "s1", NO_CPID, "0 0", _("^K1A %s has arrived!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_ITEM_BUFF_DROP, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou dropped the %s^BG Buff!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_ITEM_BUFF_GOT, 0, 1, "item_buffname", CPID_ITEM, "item_centime 0", _("^BGYou got the %s^BG Buff!"), "") \
MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DONTHAVE, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DROP, 1, 1, "item_wepname item_wepammo", CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_GOT, 0, 1, "item_wepname", CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") \
MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_ROUNDSTART, 0, 1, "", CPID_KEYHUNT_OTHER, "1 f1", _("^F4Round will start in ^COUNT"), "") \
MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_SCAN, 0, 1, "", CPID_KEYHUNT_OTHER, "f1 0", _("^BGScanning frequency range..."), "") \
MULTITEAM_CENTER(1, CENTER_KEYHUNT_START_, 4, 0, 0, "", CPID_KEYHUNT, "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") \
- MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_WAIT, 0, 4, "missing_teams", CPID_KEYHUNT_OTHER, "0 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
- MSG_CENTER_NOTIF(1, CENTER_MISSING_TEAMS, 0, 4, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_WAIT, 0, 1, "missing_teams", CPID_KEYHUNT_OTHER, "0 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_MISSING_TEAMS, 0, 1, "missing_teams", CPID_MISSING_TEAMS, "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
MSG_CENTER_NOTIF(1, CENTER_MISSING_PLAYERS, 0, 1, "f1", CPID_MISSING_PLAYERS, "-1 0", _("^BGWaiting for %s player(s) to join..."), "") \
MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO, 0, 0, "", CPID_MINSTA_FINDAMMO, "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") \
MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO_FIRST, 0, 0, "", CPID_MINSTA_FINDAMMO, "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) \
MSG_CENTER_NOTIF(1, CENTER_POWERUP_SPEED, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You are on speed"), "") \
MSG_CENTER_NOTIF(1, CENTER_POWERUP_STRENGTH, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Strength infuses your weapons with devastating power"), "") \
MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP, 0, 0, "", CPID_RACE_FINISHLAP, "0 0", _("^F2The race is over, finish your lap!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COMPLETED, 0, 0, "", NO_CPID, "0 0", _("^BGSequence completed!"), "") \
+ MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COUNTER, 0, 0, "", NO_CPID, "0 0", _("^BGThere are more to go..."), "") \
+ MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COUNTER_FEWMORE, 0, 1, "f1", NO_CPID, "0 0", _("^BGOnly %s^BG more to go..."), "") \
MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_BROKEN, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have broken down"), "") \
MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_LOST, 0, 0, "", CPID_POWERUP, "0 0", _("^F2Superweapons have been lost"), "") \
MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_PICKUP, 0, 0, "", CPID_POWERUP, "0 0", _("^F2You now have a superweapon"), "") \
MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA, NO_MSG, INFO_DEATH_MURDER_LAVA, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_MONSTER, NO_MSG, INFO_DEATH_MURDER_MONSTER, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE, NO_MSG, INFO_DEATH_MURDER_NADE, NO_MSG) \
+ MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_NAPALM, NO_MSG, INFO_DEATH_MURDER_NADE_NAPALM, NO_MSG) \
+ MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_ICE, NO_MSG, INFO_DEATH_MURDER_NADE_ICE, NO_MSG) \
+ MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_ICE_FREEZE, NO_MSG, INFO_DEATH_MURDER_NADE_ICE_FREEZE, NO_MSG) \
+ MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_HEAL, NO_MSG, INFO_DEATH_MURDER_NADE_HEAL, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_SHOOTING_STAR, NO_MSG, INFO_DEATH_MURDER_SHOOTING_STAR, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_SLIME, NO_MSG, INFO_DEATH_MURDER_SLIME, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_SWAMP, NO_MSG, INFO_DEATH_MURDER_SWAMP, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_DEATH, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_GUN, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET, NO_MSG, INFO_DEATH_MURDER_VH_WAKI_ROCKET, NO_MSG) \
+ MSG_MULTI_NOTIF(1, DEATH_MURDER_VENGEANCE, NO_MSG, INFO_DEATH_MURDER_VENGEANCE, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_MURDER_VOID, NO_MSG, INFO_DEATH_MURDER_VOID, NO_MSG) \
MSG_MULTI_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE, NO_MSG, INFO_DEATH_SELF_AUTOTEAMCHANGE, CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
MSG_MULTI_NOTIF(1, DEATH_SELF_BETRAYAL, NO_MSG, INFO_DEATH_SELF_BETRAYAL, CENTER_DEATH_SELF_BETRAYAL) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_JUMP, NO_MSG, INFO_DEATH_SELF_MON_ZOMBIE_JUMP, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_MELEE, NO_MSG, INFO_DEATH_SELF_MON_ZOMBIE_MELEE, CENTER_DEATH_SELF_MONSTER) \
MSG_MULTI_NOTIF(1, DEATH_SELF_NADE, NO_MSG, INFO_DEATH_SELF_NADE, CENTER_DEATH_SELF_NADE) \
+ MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_NAPALM, NO_MSG, INFO_DEATH_SELF_NADE_NAPALM, CENTER_DEATH_SELF_NADE_NAPALM) \
+ MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_ICE, NO_MSG, INFO_DEATH_SELF_NADE_ICE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) \
+ MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_ICE_FREEZE, NO_MSG, INFO_DEATH_SELF_NADE_ICE_FREEZE, CENTER_DEATH_SELF_NADE_ICE_FREEZE) \
+ MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_HEAL, NO_MSG, INFO_DEATH_SELF_NADE_HEAL, CENTER_DEATH_SELF_NADE_HEAL) \
MSG_MULTI_NOTIF(1, DEATH_SELF_NOAMMO, NO_MSG, INFO_DEATH_SELF_NOAMMO, CENTER_DEATH_SELF_NOAMMO) \
MSG_MULTI_NOTIF(1, DEATH_SELF_ROT, NO_MSG, INFO_DEATH_SELF_ROT, CENTER_DEATH_SELF_ROT) \
MSG_MULTI_NOTIF(1, DEATH_SELF_SHOOTING_STAR, NO_MSG, INFO_DEATH_SELF_SHOOTING_STAR, CENTER_DEATH_SELF_SHOOTING_STAR) \
MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_DEATH, NO_MSG, INFO_DEATH_SELF_VH_WAKI_DEATH, CENTER_DEATH_SELF_VH_WAKI_DEATH) \
MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_ROCKET, NO_MSG, INFO_DEATH_SELF_VH_WAKI_ROCKET, CENTER_DEATH_SELF_VH_WAKI_ROCKET) \
MSG_MULTI_NOTIF(1, DEATH_SELF_VOID, NO_MSG, INFO_DEATH_SELF_VOID, CENTER_DEATH_SELF_VOID) \
+ MSG_MULTI_NOTIF(1, ITEM_BUFF_DROP, NO_MSG, INFO_ITEM_BUFF_DROP, CENTER_ITEM_BUFF_DROP) \
+ MSG_MULTI_NOTIF(1, ITEM_BUFF_GOT, NO_MSG, INFO_ITEM_BUFF_GOT, CENTER_ITEM_BUFF_GOT) \
MSG_MULTI_NOTIF(1, ITEM_WEAPON_DONTHAVE, NO_MSG, INFO_ITEM_WEAPON_DONTHAVE, CENTER_ITEM_WEAPON_DONTHAVE) \
MSG_MULTI_NOTIF(1, ITEM_WEAPON_DROP, NO_MSG, INFO_ITEM_WEAPON_DROP, CENTER_ITEM_WEAPON_DROP) \
MSG_MULTI_NOTIF(1, ITEM_WEAPON_GOT, NO_MSG, INFO_ITEM_WEAPON_GOT, CENTER_ITEM_WEAPON_GOT) \
item_wepname: return full name of a weapon from weaponid
item_wepammo: ammo display for weapon from string
item_centime: amount of time to display weapon message in centerprint
+ item_buffname: return full name of a buff from buffid
death_team: show the full name of the team a player is switching from
*/
ARG_CASE(ARG_CS_SV_HA, "f3race_time", mmssss(f3)) \
ARG_CASE(ARG_CS_SV, "race_col", CCR(((f1 == 1) ? "^F1" : "^F2"))) \
ARG_CASE(ARG_CS_SV, "race_diff", ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \
- ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1, f2, f3, f4)) \
+ ARG_CASE(ARG_CS, "missing_teams", notif_arg_missing_teams(f1)) \
ARG_CASE(ARG_CS, "pass_key", ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \
ARG_CASE(ARG_CS, "frag_ping", notif_arg_frag_ping(TRUE, f2)) \
ARG_CASE(ARG_CS, "frag_stats", notif_arg_frag_stats(f2, f3, f4)) \
ARG_CASE(ARG_CS_SV, "spree_end", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "spree_lost", (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
ARG_CASE(ARG_CS_SV, "item_wepname", W_Name(f1)) \
+ ARG_CASE(ARG_CS_SV, "item_buffname", sprintf("%s%s", rgb_to_hexcolor(Buff_Color(f1)), Buff_PrettyName(f1))) \
ARG_CASE(ARG_CS_SV, "item_wepammo", (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
ARG_CASE(ARG_DC, "item_centime", ftos(autocvar_notification_item_centerprinttime)) \
ARG_CASE(ARG_SV, "death_team", Team_ColoredFullName(f1)) \
return sprintf(CCR(_("\n(^F4Dead^BG)%s")), notif_arg_frag_ping(FALSE, fping));
}
-string notif_arg_missing_teams(float f1, float f2, float f3, float f4)
+string notif_arg_missing_teams(float f1)
{
return sprintf("%s%s%s%s",
- (f1 ?
- sprintf("%s%s", Team_ColoredFullName(f1 - 1), ((f2 + f3 + f4) ? ", " : ""))
+ ((f1 & 1) ?
+ sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_1), ((f1 & (2 + 4 + 8)) ? ", " : ""))
:
""
),
- (f2 ?
- sprintf("%s%s", Team_ColoredFullName(f2 - 1), ((f3 + f4) ? ", " : ""))
+ ((f1 & 2) ?
+ sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_2), ((f1 & (4 + 8)) ? ", " : ""))
:
""
),
- (f3 ?
- sprintf("%s%s", Team_ColoredFullName(f3 - 1), (f4 ? ", " : ""))
+ ((f1 & 4) ?
+ sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_3), ((f1 & 8) ? ", " : ""))
:
""
),
- (f4 ?
- Team_ColoredFullName(f4 - 1)
+ ((f1 & 8) ?
+ Team_ColoredFullName(NUM_TEAM_4)
:
""
)
#endif
printf("Beginning notification initialization on %s%s program...\n", dedi, PROGNAME);
+ #undef dedi
// maybe do another implementation of this with checksums? for now, we don't need versioning
/*if(autocvar_notification_version != NOTIF_VERSION)
--- /dev/null
+// Full list of all stat constants, icnluded in a single location for easy reference
+// 255 is the current limit (MAX_CL_STATS - 1), engine will need to be modified if you wish to add more stats
+
+const float MAX_CL_STATS = 256;
+const float STAT_HEALTH = 0;
+// 1 empty?
+const float STAT_WEAPON = 2;
+const float STAT_AMMO = 3;
+const float STAT_ARMOR = 4;
+const float STAT_WEAPONFRAME = 5;
+const float STAT_SHELLS = 6;
+const float STAT_NAILS = 7;
+const float STAT_ROCKETS = 8;
+const float STAT_CELLS = 9;
+const float STAT_ACTIVEWEAPON = 10;
+const float STAT_TOTALSECRETS = 11;
+const float STAT_TOTALMONSTERS = 12;
+const float STAT_SECRETS = 13;
+const float STAT_MONSTERS = 14;
+const float STAT_ITEMS = 15;
+const float STAT_VIEWHEIGHT = 16;
+// 17 empty?
+// 18 empty?
+// 19 empty?
+// 20 empty?
+const float STAT_VIEWZOOM = 21;
+// 22 empty?
+// 23 empty?
+// 24 empty?
+// 25 empty?
+// 26 empty?
+// 27 empty?
+// 28 empty?
+// 29 empty?
+// 30 empty?
+// 31 empty?
+const float STAT_KH_KEYS = 32;
+const float STAT_CTF_STATE = 33;
+// 34 empty?
+const float STAT_WEAPONS = 35;
+const float STAT_SWITCHWEAPON = 36;
+const float STAT_GAMESTARTTIME = 37;
+const float STAT_STRENGTH_FINISHED = 38;
+const float STAT_INVINCIBLE_FINISHED = 39;
+// 40 empty?
+// 41 empty?
+const float STAT_PRESSED_KEYS = 42;
+const float STAT_ALLOW_OLDNEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config
+const float STAT_FUEL = 44;
+const float STAT_NB_METERSTART = 45;
+const float STAT_SHOTORG = 46; // compressShotOrigin
+const float STAT_LEADLIMIT = 47;
+const float STAT_WEAPON_CLIPLOAD = 48;
+const float STAT_WEAPON_CLIPSIZE = 49;
+const float STAT_NEX_CHARGE = 50;
+const float STAT_LAST_PICKUP = 51;
+const float STAT_HUD = 52;
+const float STAT_NEX_CHARGEPOOL = 53;
+const float STAT_DAMAGE_DEALT_TOTAL = 54;
+const float STAT_TYPEHIT_TIME = 55;
+const float STAT_LAYED_MINES = 56;
+const float STAT_HAGAR_LOAD = 57;
+const float STAT_SWITCHINGWEAPON = 58;
+const float STAT_SUPERWEAPONS_FINISHED = 59;
+const float STAT_VEHICLESTAT_HEALTH = 60;
+const float STAT_VEHICLESTAT_SHIELD = 61;
+const float STAT_VEHICLESTAT_ENERGY = 62;
+const float STAT_VEHICLESTAT_AMMO1 = 63;
+const float STAT_VEHICLESTAT_RELOAD1 = 64;
+const float STAT_VEHICLESTAT_AMMO2 = 65;
+const float STAT_VEHICLESTAT_RELOAD2 = 66;
+const float STAT_VEHICLESTAT_W2MODE = 67;
+// 68 empty?
+const float STAT_NADE_TIMER = 69;
+const float STAT_SECRETS_TOTAL = 70;
+const float STAT_SECRETS_FOUND = 71;
+const float STAT_RESPAWN_TIME = 72;
+const float STAT_ROUNDSTARTTIME = 73;
+const float STAT_WEAPONS2 = 74;
+const float STAT_WEAPONS3 = 75;
+const float STAT_MONSTERS_TOTAL = 76;
+const float STAT_MONSTERS_KILLED = 77;
+const float STAT_BUFFS = 78;
+const float STAT_NADE_BONUS = 79;
+const float STAT_NADE_BONUS_TYPE = 80;
+const float STAT_NADE_BONUS_SCORE = 81;
+const float STAT_HEALING_ORB = 82;
+const float STAT_HEALING_ORB_ALPHA = 83;
+// 84 empty?
+// 85 empty?
+// 86 empty?
+// 87 empty?
+// 88 empty?
+// 89 empty?
+// 90 empty?
+// 91 empty?
+// 92 empty?
+// 93 empty?
+// 94 empty?
+// 95 empty?
+// 96 empty?
+// 97 empty?
+// 98 empty?
+// 99 empty?
+
+
+/* The following stats change depending on the gamemode, so can share the same ID */
+// IDs 100 to 104 reserved for gamemodes
+
+// freeze tag, clan arena, jailbreak
+const float STAT_REDALIVE = 100;
+const float STAT_BLUEALIVE = 101;
+const float STAT_YELLOWALIVE = 102;
+const float STAT_PINKALIVE = 103;
+
+// domination
+const float STAT_DOM_TOTAL_PPS = 100;
+const float STAT_DOM_PPS_RED = 101;
+const float STAT_DOM_PPS_BLUE = 102;
+const float STAT_DOM_PPS_YELLOW = 103;
+const float STAT_DOM_PPS_PINK = 104;
+
+// vip
+const float STAT_VIP = 100;
+const float STAT_VIP_RED = 101;
+const float STAT_VIP_BLUE = 102;
+const float STAT_VIP_YELLOW = 103;
+const float STAT_VIP_PINK = 104;
+
+// key hunt
+const float STAT_KH_REDKEY_TEAM = 100;
+const float STAT_KH_BLUEKEY_TEAM = 101;
+const float STAT_KH_YELLOWKEY_TEAM = 102;
+const float STAT_KH_PINKKEY_TEAM = 103;
+
+/* Gamemode-specific stats end here */
+
+
+const float STAT_FROZEN = 105;
+const float STAT_REVIVE_PROGRESS = 106;
+// 107 empty?
+// 108 empty?
+// 109 empty?
+// 110 empty?
+// 111 empty?
+// 112 empty?
+// 113 empty?
+// 114 empty?
+// 115 empty?
+// 116 empty?
+// 117 empty?
+// 118 empty?
+// 119 empty?
+// 120 empty?
+// 121 empty?
+// 122 empty?
+// 123 empty?
+// 124 empty?
+// 125 empty?
+// 126 empty?
+// 127 empty?
+// 128 empty?
+// 129 empty?
+// 130 empty?
+// 131 empty?
+// 132 empty?
+// 133 empty?
+// 134 empty?
+// 135 empty?
+// 136 empty?
+// 137 empty?
+// 138 empty?
+// 139 empty?
+// 140 empty?
+// 141 empty?
+// 142 empty?
+// 143 empty?
+// 144 empty?
+// 145 empty?
+// 146 empty?
+// 147 empty?
+// 148 empty?
+// 149 empty?
+// 150 empty?
+// 151 empty?
+// 152 empty?
+// 153 empty?
+// 154 empty?
+// 155 empty?
+// 156 empty?
+// 157 empty?
+// 158 empty?
+// 159 empty?
+// 160 empty?
+// 161 empty?
+// 162 empty?
+// 162 empty?
+// 163 empty?
+// 164 empty?
+// 165 empty?
+// 166 empty?
+// 167 empty?
+// 168 empty?
+// 169 empty?
+// 170 empty?
+// 171 empty?
+// 172 empty?
+// 173 empty?
+// 174 empty?
+// 175 empty?
+// 176 empty?
+// 177 empty?
+// 178 empty?
+// 179 empty?
+// 180 empty?
+// 181 empty?
+// 182 empty?
+// 183 empty?
+// 184 empty?
+// 185 empty?
+// 186 empty?
+// 187 empty?
+// 188 empty?
+// 189 empty?
+// 190 empty?
+// 191 empty?
+// 192 empty?
+// 193 empty?
+// 194 empty?
+// 195 empty?
+// 196 empty?
+// 197 empty?
+// 198 empty?
+// 199 empty?
+// 200 empty?
+// 201 empty?
+// 202 empty?
+// 203 empty?
+// 204 empty?
+// 205 empty?
+// 206 empty?
+// 207 empty?
+// 208 empty?
+// 209 empty?
+// 210 empty?
+// 211 empty?
+// 212 empty?
+// 213 empty?
+// 214 empty?
+// 215 empty?
+// 216 empty?
+// 217 empty?
+// 218 empty?
+// 219 empty?
+const float STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR = 220;
+const float STAT_MOVEVARS_AIRCONTROL_PENALTY = 221;
+const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
+const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223;
+const float STAT_MOVEVARS_AIRCONTROL_POWER = 224;
+const float STAT_MOVEFLAGS = 225;
+const float STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL = 226;
+const float STAT_MOVEVARS_WARSOWBUNNY_ACCEL = 227;
+const float STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED = 228;
+const float STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL = 229;
+const float STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO = 230;
+const float STAT_MOVEVARS_AIRSTOPACCELERATE = 231;
+const float STAT_MOVEVARS_AIRSTRAFEACCELERATE = 232;
+const float STAT_MOVEVARS_MAXAIRSTRAFESPEED = 233;
+const float STAT_MOVEVARS_AIRCONTROL = 234;
+const float STAT_FRAGLIMIT = 235;
+const float STAT_TIMELIMIT = 236;
+const float STAT_MOVEVARS_WALLFRICTION = 237;
+const float STAT_MOVEVARS_FRICTION = 238;
+const float STAT_MOVEVARS_WATERFRICTION = 239;
+const float STAT_MOVEVARS_TICRATE = 240;
+const float STAT_MOVEVARS_TIMESCALE = 241;
+const float STAT_MOVEVARS_GRAVITY = 242;
+const float STAT_MOVEVARS_STOPSPEED = 243;
+const float STAT_MOVEVARS_MAXSPEED = 244;
+const float STAT_MOVEVARS_SPECTATORMAXSPEED = 245;
+const float STAT_MOVEVARS_ACCELERATE = 246;
+const float STAT_MOVEVARS_AIRACCELERATE = 247;
+const float STAT_MOVEVARS_WATERACCELERATE = 248;
+const float STAT_MOVEVARS_ENTGRAVITY = 249;
+const float STAT_MOVEVARS_JUMPVELOCITY = 250;
+const float STAT_MOVEVARS_EDGEFRICTION = 251;
+const float STAT_MOVEVARS_MAXAIRSPEED = 252;
+const float STAT_MOVEVARS_STEPHEIGHT = 253;
+const float STAT_MOVEVARS_AIRACCEL_QW = 254;
+const float STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION = 255;
#ifndef NOCOMPAT
//# define WORKAROUND_XON010
-//# define COMPAT_XON010_CHANNELS
//# define COMPAT_XON050_ENGINE
# define COMPAT_NO_MOD_IS_XONOTIC
# define COMPAT_XON060_DONTCRASH_CHECKPVS
get_model_parameters_weight = stof(s);
if(c == "age")
get_model_parameters_age = stof(s);
+ if(c == "description")
+ get_model_parameters_description = s;
if(c == "bone_upperbody")
get_model_parameters_bone_upperbody = s;
if(c == "bone_weapon")
string get_model_parameters_sex;
float get_model_parameters_weight;
float get_model_parameters_age;
+string get_model_parameters_description;
string get_model_parameters_bone_upperbody;
string get_model_parameters_bone_weapon;
#define MAX_AIM_BONES 4
string xencode(float f);
float xdecode(string s);
-#ifndef COMPAT_XON010_CHANNELS
+// Play all sounds via sound7, for access to the extra channels.
+// Otherwise, channels 8 to 15 would be blocked for a weird QW feature.
#define sound(e,c,s,v,a) sound7(e,c,s,v,a,0,0)
-#endif
float lowestbit(float f);
#include "xonotic/dialog_hudpanel_weapons.c"
#include "xonotic/dialog_hudpanel_physics.c"
#include "xonotic/dialog_hudpanel_centerprint.c"
+#include "xonotic/dialog_hudpanel_buffs.c"
#include "xonotic/slider_picmip.c"
+#include "xonotic/slider_particles.c"
METHOD(Container, moveItemAfter, void(entity, entity, entity))
METHOD(Container, removeItem, void(entity, entity))
METHOD(Container, setFocus, void(entity, entity))
+ METHOD(Container, saveFocus, void(entity))
METHOD(Container, setAlphaOf, void(entity, entity, float))
METHOD(Container, itemFromPoint, entity(entity, vector))
METHOD(Container, showNotify, void(entity))
ATTRIB(Container, firstChild, entity, NULL)
ATTRIB(Container, lastChild, entity, NULL)
ATTRIB(Container, focusedChild, entity, NULL)
+ ATTRIB(Container, savedFocus, entity, NULL)
ATTRIB(Container, shown, float, 0)
METHOD(Container, enterSubitem, void(entity, entity))
void Container_setFocus(entity me, entity other)
{
- if(other)
- if (!me.focused)
- error("Trying to set focus in a non-focused control!");
if(me.focusedChild == other)
return;
- //print(etos(me), ": focus changes from ", etos(me.focusedChild), " to ", etos(other), "\n");
+
if(me.focusedChild)
{
me.focusedChild.focused = 0;
me.focusedChild.focusLeave(me.focusedChild);
+ me.focusedChild = NULL;
}
+
if(other)
{
- other.focused = 1;
- other.focusEnter(other);
+ if(!me.focused)
+ error("Trying to set focus in a non-focused control!");
+
+ if(me.savedFocus)
+ {
+ me.focusedChild = me.savedFocus;
+ me.savedFocus = NULL;
+ me.focusedChild.focused = 1;
+ me.focusedChild.focusEnter(me.focusedChild);
+
+ if(me.focusedChild.instanceOfContainer)
+ me.focusedChild.setFocus(me.focusedChild, me.focusedChild.savedFocus);
+ }
+ else
+ {
+ me.focusedChild = other;
+ me.focusedChild.focused = 1;
+ me.focusedChild.focusEnter(me.focusedChild);
+ }
}
- me.focusedChild = other;
+}
+
+void Container_saveFocus(entity me)
+{
+ me.savedFocus = me.focusedChild;
+
+ if(me.focusedChild.instanceOfContainer)
+ me.focusedChild.saveFocus(me.focusedChild);
}
void Container_moveItemAfter(entity me, entity other, entity dest)
ATTRIB(Label, realFontSize, vector, '0 0 0')
ATTRIB(Label, realOrigin, vector, '0 0 0')
ATTRIB(Label, alpha, float, 0.7)
- ATTRIB(Label, colorL, vector, '1 1 1')
+ ATTRIB(Label, colorL, vector, SKINCOLOR_TEXT)
ATTRIB(Label, disabled, float, 0)
ATTRIB(Label, disabledAlpha, float, 0.3)
ATTRIB(Label, textEntity, entity, NULL)
return;
if(button)
button.forcePressed = 1;
+ if(tab.parent.focusedChild)
+ tab.parent.focusedChild.saveFocus(tab.parent.focusedChild);
tab.ModalController_controllingButton = button;
tab.parent.showChild(tab.parent, tab, theOrigin, theSize, 0);
}
while(getWrappedLine_remaining)
{
s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
- draw_Text(p, s, fontsize, '1 1 1', SKINALPHA_TOOLTIP * menuTooltipAlpha, FALSE);
+ draw_Text(p, s, fontsize, SKINCOLOR_TOOLTIP, SKINALPHA_TOOLTIP * menuTooltipAlpha, FALSE);
p_y += fontsize_y;
}
}
SKINSTRING(GFX_TOOLTIP, "tooltip");
SKINVECTOR(MARGIN_TOOLTIP, '5 5 0');
SKINVECTOR(BORDER_TOOLTIP, '1 1 0');
+ SKINVECTOR(AVOID_TOOLTIP, '8 8 0');
+ SKINFLOAT(WIDTH_TOOLTIP, 0.3);
SKINFLOAT(FONTSIZE_TOOLTIP, 12);
SKINFLOAT(ALPHA_TOOLTIP, 0.7);
- SKINFLOAT(WIDTH_TOOLTIP, 0.3);
- SKINVECTOR(AVOID_TOOLTIP, '8 8 0');
+ SKINVECTOR(COLOR_TOOLTIP, '1 1 1');
// the individual dialog background colors
SKINVECTOR(COLOR_DIALOG_FIRSTRUN, '0.7 0.7 1');
SKINFLOAT(ALPHA_DISABLED, 0.2);
SKINFLOAT(ALPHA_BEHIND, 0.5);
SKINFLOAT(ALPHA_TEXT, 0.7);
-
+ SKINVECTOR(COLOR_TEXT, '1 1 1');
+
// item: button
SKINSTRING(GFX_BUTTON, "button");
SKINSTRING(GFX_BUTTON_GRAY, "buttongray");
// item: player color button
SKINSTRING(GFX_COLORBUTTON, "colorbutton");
- SKINSTRING(GFX_COLORBUTTON_COLOR, "color");
// item: player model
SKINVECTOR(COLOR_MODELTITLE, '1 1 1');
SKINFLOAT(WIDTH_SCROLLBAR, 16);
// item: server list
+ SKINFLOAT(ALPHA_SERVERLIST_CATEGORY, 0.7);
+ SKINVECTOR(COLOR_SERVERLIST_CATEGORY, '1 1 1');
SKINFLOAT(ALPHA_SERVERLIST_FULL, 0.4);
SKINFLOAT(ALPHA_SERVERLIST_EMPTY, 0.7);
SKINVECTOR(COLOR_SERVERLIST_LOWPING, '0 1 0');
METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float))
METHOD(XonoticColorButton, setChecked, void(entity, float))
METHOD(XonoticColorButton, draw, void(entity))
- ATTRIB(XonoticColorButton, fontSize, float, SKINFONTSIZE_NORMAL)
+ ATTRIB(XonoticColorButton, fontSize, float, 0)
ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON)
- ATTRIB(XonoticColorButton, image2, string, SKINGFX_COLORBUTTON_COLOR)
ATTRIB(XonoticColorButton, useDownAsChecked, float, 1)
me.cvarPart = theColor;
me.loadCvars(me);
me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0);
- me.srcMulti = 1;
- me.src2 = me.image2;
}
void XonoticColorButton_setChecked(entity me, float val)
{
}
void XonoticColorButton_draw(entity me)
{
- me.color2 = colormapPaletteColor(me.cvarValueFloat, me.cvarPart);
+ me.color = colormapPaletteColor(me.cvarValueFloat, me.cvarPart);
+ me.colorC = me.color;
+ me.colorF = me.color;
+ me.colorD = me.color;
SUPER(XonoticColorButton).draw(me);
}
#endif
s = me.demoName(me,i);
s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
- draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
}
void XonoticDemoList_showNotify(entity me)
--- /dev/null
+#ifdef INTERFACE
+CLASS(XonoticHUDBuffsDialog) EXTENDS(XonoticRootDialog)
+ METHOD(XonoticHUDBuffsDialog, fill, void(entity))
+ ATTRIB(XonoticHUDBuffsDialog, title, string, _("Buffs Panel"))
+ ATTRIB(XonoticHUDBuffsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+ ATTRIB(XonoticHUDBuffsDialog, intendedWidth, float, 0.4)
+ ATTRIB(XonoticHUDBuffsDialog, rows, float, 15)
+ ATTRIB(XonoticHUDBuffsDialog, columns, float, 4)
+ ATTRIB(XonoticHUDBuffsDialog, name, string, "HUDbuffs")
+ ATTRIB(XonoticHUDBuffsDialog, requiresConnection, float, TRUE)
+ENDCLASS(XonoticHUDBuffsDialog)
+#endif
+
+#ifdef IMPLEMENTATION
+void XonoticHUDBuffsDialog_fill(entity me)
+{
+ entity e;
+ string panelname = "buffs";
+
+ DIALOG_HUDPANEL_COMMON();
+}
+#endif
CLASS(XonoticServerCreateTab) EXTENDS(XonoticTab)
METHOD(XonoticServerCreateTab, fill, void(entity))
METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity))
+ METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity))
ATTRIB(XonoticServerCreateTab, title, string, _("Create"))
ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9)
ATTRIB(XonoticServerCreateTab, rows, float, 22)
me.mapListBox.refilter(me.mapListBox);
}
+void XonoticServerCreateTab_gameTypeSelectNotify(entity me)
+{
+ me.setFocus(me, me.mapListBox);
+}
+
#endif
me.currentMapTitle = strzone(strdecolorize(MapInfo_Map_title));
me.currentMapAuthor = strzone(strdecolorize(MapInfo_Map_author));
me.currentMapDescription = strzone(MapInfo_Map_description);
- me.currentMapFeaturesText = strzone((MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS) ? _("Full item placement") : _("MinstaGib only"));
+ me.currentMapFeaturesText = strzone((MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS) ? _("Full item placement") : _("InstaGib only"));
me.currentMapPreviewImage = strzone(strcat("/maps/", MapInfo_Map_bspname));
me.frame.setText(me.frame, me.currentMapBSPName);
s = cvar_string("g_weaponarena");
if(s == "0")
return "";
- if(s == "all")
+ if(s == "all" || s == "1")
return _("All Weapons Arena");
if(s == "most")
return _("Most Weapons Arena");
s = "";
if(cvar("g_dodging"))
s = strcat(s, ", ", _("Dodging"));
- if(cvar("g_minstagib"))
- s = strcat(s, ", ", _("MinstaGib"));
+ if(cvar("g_instagib"))
+ s = strcat(s, ", ", _("InstaGib"));
if(cvar("g_new_toys"))
s = strcat(s, ", ", _("New Toys"));
if(cvar("g_nix"))
float checkCompatibility_pinata(entity me)
{
- if(cvar("g_minstagib"))
+ if(cvar("g_instagib"))
return 0;
if(cvar("g_nix"))
return 0;
}
float checkCompatibility_newtoys(entity me)
{
- if(cvar("g_minstagib"))
+ if(cvar("g_instagib"))
return 0;
if(cvar_string("g_weaponarena") == "most")
return 1;
- if(cvar_string("g_weaponarena") == "all")
+ if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1")
return 1;
if(cvar_string("g_weaponarena") != "0")
return 0;
}
float checkCompatibility_weaponarena_weapon(entity me)
{
- if(cvar("g_minstagib"))
+ if(cvar("g_instagib"))
return 0;
if(cvar_string("g_weaponarena") == "most")
return 0;
- if(cvar_string("g_weaponarena") == "all")
+ if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1")
return 0;
if(cvar_string("g_weaponarena") == "0")
return 0;
me.TR(me);
me.TDempty(me, 0.2);
me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_vampire", _("Vampire")));
- setDependent(e, "g_minstagib", 0, 0);
+ setDependent(e, "g_instagib", 0, 0);
me.TR(me);
me.TDempty(me, 0.2);
s = makeXonoticSlider(10, 50, 1, "g_bloodloss");
me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(0, 1, s, _("Blood loss")));
- setDependent(e, "g_minstagib", 0, 0);
+ setDependent(e, "g_instagib", 0, 0);
me.TR(me);
me.TDempty(me, 0.4);
me.TD(me, 1, 1.6, s);
me.TR(me);
me.TDempty(me, 0.2);
me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles")));
- setDependent(e, "g_minstagib", 0, 0);
+ setDependent(e, "g_instagib", 0, 0);
me.TR(me);
me.TDempty(me, 0.2);
me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_new_toys", _("New Toys")));
me.TR(me);
me.TDempty(me, 0.2);
me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying")));
- setDependent(e, "g_minstagib", 0, 0);
+ setDependent(e, "g_instagib", 0, 0);
me.TR(me);
me.TDempty(me, 0.2);
me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_pinata", _("Piñata")));
me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Special arenas:")));
me.TR(me);
me.TDempty(me, 0.2);
- me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_minstagib", "1", _("MinstaGib")));
+ me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_instagib", "1", _("InstaGib")));
e.cvarOffValue = "0";
me.TR(me);
me.TDempty(me, 0.2);
if(cvar("developer"))
me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultimate")), '0.5 0 0', "exec effects-ultimate.cfg", 0));
- me.TR(me);
- me.TR(me);
+ me.gotoRC(me, 1.25, 0);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Geometry detail:")));
me.TD(me, 1, 2, e = makeXonoticTextSlider("r_subdivisions_tolerance"));
e.addValue(e, ZCTX(_("DET^Lowest")), "16");
e.configureXonoticTextSliderValues(e);
me.TR(me);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player detail:")));
- me.TD(me, 1, 2, e = makeXonoticSlider(4, 0, -0.1, "cl_playerdetailreduction"));
+ me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_playerdetailreduction"));
+ e.addValue(e, ZCTX(_("PDET^Low")), "4");
+ e.addValue(e, ZCTX(_("PDET^Medium")), "3");
+ e.addValue(e, ZCTX(_("PDET^Normal")), "2");
+ e.addValue(e, ZCTX(_("PDET^Good")), "1");
+ e.addValue(e, ZCTX(_("PDET^Best")), "0");
+ e.configureXonoticTextSliderValues(e);
me.TR(me);
me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Texture resolution:")));
setDependent(e, "r_showsurfaces", 0, 0);
setDependentAND(e, "vid_gl20", 1, 1, "r_water", 1, 1);
me.TR(me);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Particles quality:")));
- me.TD(me, 1, 2, e = makeXonoticSlider(0.2, 1.0, 0.1, "cl_particles_quality"));
- me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Particles distance:")));
- me.TD(me, 1, 2, e = makeXonoticSlider(500, 2000, 100, "r_drawparticles_drawdistance"));
+ me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_decals", _("Decals")));
+ me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models")));
+ setDependent(e, "cl_decals", 1, 1);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Damage effects:")));
- me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_damageeffect"));
- e.addValue(e, ZCTX(_("DMGPRTCLS^Disabled")), "0");
- e.addValue(e, ZCTX(_("DMGPRTCLS^Skeletal")), "1");
- e.addValue(e, ZCTX(_("DMGPRTCLS^All")), "2");
- e.configureXonoticTextSliderValues(e);
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:")));
+ setDependent(e, "cl_decals", 1, 1);
+ me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawdecals_drawdistance"));
+ setDependent(e, "cl_decals", 1, 1);
me.TR(me);
- me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_spawn_point_particles", _("Particle effects for spawnpoints")));
- makeMulti(e, "cl_spawn_event_particles");
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:")));
+ setDependent(e, "cl_decals", 1, 1);
+ me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_fadetime"));
+ setDependent(e, "cl_decals", 1, 1);
- me.gotoRC(me, 2, 3.2); me.setFirstColumn(me, me.currentColumn);
+ me.gotoRC(me, 1.25, 3.2); me.setFirstColumn(me, me.currentColumn);
me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "r_coronas", "0", _("No dynamic lighting")));
me.TR(me);
me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "gl_flashblend", string_null, _("Fake corona lighting")));
me.TD(me, 1, 2, s);
me.TR(me);
me.TR(me);
- me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_decals", _("Decals")));
- me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models")));
- setDependent(e, "cl_decals", 1, 1);
+ me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_particles", _("Particles")));
+ me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_spawn_point_particles", _("Spawnpoint effects")));
+ makeMulti(e, "cl_spawn_event_particles");
+ setDependent(e, "cl_particles", 1, 1);
me.TR(me);
+ me.TDempty(me, 0.2);
+ me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Quality:")));
+ setDependent(e, "cl_particles", 1, 1);
+ me.TD(me, 1, 2, e = makeXonoticParticlesSlider());
+ setDependent(e, "cl_particles", 1, 1);
+ me.TR(me);
me.TDempty(me, 0.2);
me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:")));
setDependent(e, "cl_decals", 1, 1);
me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawdecals_drawdistance"));
setDependent(e, "cl_decals", 1, 1);
- me.TR(me);
+ me.TR(me);
me.TDempty(me, 0.2);
- me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:")));
- setDependent(e, "cl_decals", 1, 1);
- me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_time"));
- setDependent(e, "cl_decals", 1, 1);
+ me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:")));
+ setDependent(e, "cl_decals", 1, 1);
+ me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_fadetime"));
+ setDependent(e, "cl_decals", 1, 1);
me.gotoRC(me, me.rows - 1, 0);
me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "vid_restart", COMMANDBUTTON_APPLY));
METHOD(XonoticGametypeList, setSelected, void(entity, float))
METHOD(XonoticGametypeList, loadCvars, void(entity))
METHOD(XonoticGametypeList, saveCvars, void(entity))
+ METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float))
ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
ATTRIB(XonoticGametypeList, realUpperMargin1, float, 0)
draw_Picture(me.columnIconOrigin * eX, GameType_GetIcon(i), me.columnIconSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED);
s = GameType_GetName(i);
- draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.5 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.5 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
//s = GameType_GetTeams(i);
- //draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ //draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
}
void XonoticGametypeList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
{
me.columnNameOrigin = me.columnIconOrigin + me.columnIconSize;
me.columnNameSize = 1 - me.columnIconSize - 2 * me.realFontSize_x;
}
+
+float XonoticGametypeList_keyDown(entity me, float scan, float ascii, float shift)
+{
+ if(scan == K_ENTER || scan == K_KP_ENTER)
+ {
+ me.parent.gameTypeSelectNotify(me.parent);
+ return 1;
+ }
+
+ return SUPER(XonoticGametypeList).keyDown(me, scan, ascii, shift);
+}
#endif
s = me.languageParameter(me, i, LANGPARM_NAME_LOCALIZED);
s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
- draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
p = me.languageParameter(me, i, LANGPARM_PERCENTAGE);
if(p != "")
{
p = draw_TextShortenToWidth(p, me.columnPercentageSize, 0, me.realFontSize);
- draw_Text(me.realUpperMargin * eY + (me.columnPercentageOrigin + (me.columnPercentageSize - draw_TextWidth(p, 0, me.realFontSize))) * eX, p, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ draw_Text(me.realUpperMargin * eY + (me.columnPercentageOrigin + (me.columnPercentageSize - draw_TextWidth(p, 0, me.realFontSize))) * eX, p, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
}
}
i.configureDialog(i);
me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+ i = spawnXonoticHUDBuffsDialog();
+ i.configureDialog(i);
+ me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
// dialogs used by settings
me.userbindEditDialog = i = spawnXonoticUserbindEditDialog();
void XonoticMapList_clickListBoxItem(entity me, float i, vector where)
{
if(where_x <= me.columnPreviewOrigin + me.columnPreviewSize)
- {
if(where_x >= 0)
me.g_maplistCacheToggle(me, i);
- }
+
if(where_x >= me.columnNameOrigin)
if(where_x <= 1)
- {
- if(i == me.lastClickedMap)
- if(time < me.lastClickedTime + 0.3)
- {
- // DOUBLE CLICK!
- // pop up map info screen
- main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me);
- DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize));
- return;
- }
- me.lastClickedMap = i;
- me.lastClickedTime = time;
- }
+ {
+ if(i == me.lastClickedMap)
+ if(time < me.lastClickedTime + 0.3)
+ {
+ // DOUBLE CLICK!
+ // pop up map info screen
+ main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me);
+ DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize));
+ return;
+ }
+ me.lastClickedMap = i;
+ me.lastClickedTime = time;
+ }
}
void XonoticMapList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
string ch, save;
if(me.nItems <= 0)
return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift);
- if(scan == K_ENTER || scan == K_KP_ENTER)
+ if(scan == K_MOUSE2 || scan == K_SPACE || scan == K_ENTER || scan == K_KP_ENTER)
{
// pop up map info screen
main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, me.selectedItem, me);
DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize));
}
- else if(scan == K_SPACE)
+ else if(scan == K_MOUSE3 || scan == K_INS || scan == K_KP_INS)
{
me.g_maplistCacheToggle(me, me.selectedItem);
}
else if(t == 4)
rgb = colormapPaletteColor(9, 0);
else
- rgb = '1 1 1';
+ rgb = SKINCOLOR_TEXT;
s = me.getPlayerList(me, i, PLAYERPARM_NAME);
score = me.getPlayerList(me, i, PLAYERPARM_SCORE);
METHOD(XonoticPlayerModelSelector, saveCvars, void(entity))
METHOD(XonoticPlayerModelSelector, draw, void(entity))
METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector))
+ METHOD(XonoticPlayerModelSelector, showNotify, void(entity))
ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null)
ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0)
ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null)
#define BUFMODELS_DESC 4
#define BUFMODELS_COUNT 5
+#define XONVOTE186 1 // (nyov) removal of model text description
+
void XonoticPlayerModelSelector_configureXonoticPlayerModelSelector(entity me)
{
float sortbuf, glob, i;
bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname);
bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN, ftos(get_model_parameters_modelskin));
get_model_parameters_desc = strcat(get_model_parameters_desc, "\n");
+#if XONVOTE186
+ if(get_model_parameters_sex)
+ get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s", get_model_parameters_sex));
+#else
+ if(get_model_parameters_description)
+ get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s\n", get_model_parameters_description));
if(get_model_parameters_sex)
get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nSex: %s", get_model_parameters_sex));
if(get_model_parameters_weight)
get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nWeight: %g kg", get_model_parameters_weight));
if(get_model_parameters_age)
get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nAge: %g", get_model_parameters_age));
+#endif
while(substring(get_model_parameters_desc, -1, 1) == "\n")
get_model_parameters_desc = substring(get_model_parameters_desc, 0, -2);
bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_DESC, get_model_parameters_desc);
if (me.numModels <= 0)
{
- draw_CenterText('0.5 0.5 0', _("<no model found>"), me.realFontSize, '1 1 1', 0.6, FALSE);
+ draw_CenterText('0.5 0.5 0', _("<no model found>"), me.realFontSize, SKINCOLOR_TEXT, 0.6, FALSE);
return;
}
draw_beginBoldFont();
+#if XONVOTE186 // (nyov) lower name display looks better when there is no description text
+ draw_CenterText('0.5 0.8 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE);
+#else
draw_CenterText('0.5 0 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE);
+#endif
draw_endBoldFont();
o = '0.5 1 0' - eY * me.realFontSize_y * ((n = tokenizebyseparator(me.currentModelDescription, "\n")) + 0.5);
for(i = 0; i < n; ++i)
{
- draw_CenterText(o, argv(i), me.realFontSize, '1 1 1', 1, FALSE);
+ draw_CenterText(o, argv(i), me.realFontSize, SKINCOLOR_TEXT, 1, FALSE);
o += eY * me.realFontSize_y;
}
}
me.realFontSize_y = me.fontSize / absSize_y;
me.realFontSize_x = me.fontSize / absSize_x;
}
+
+void XonoticPlayerModelSelector_showNotify(entity me)
+{
+ me.configureXonoticPlayerModelSelector(me);
+}
#endif
SLIST_CATEGORY(CAT_XPM, "CAT_NORMAL", "CAT_SERVERS", ZCTX(_("SLCAT^Competitive Mode"))) \
SLIST_CATEGORY(CAT_MODIFIED, "", "CAT_SERVERS", ZCTX(_("SLCAT^Modified Servers"))) \
SLIST_CATEGORY(CAT_OVERKILL, "", "CAT_SERVERS", ZCTX(_("SLCAT^Overkill Mode"))) \
- SLIST_CATEGORY(CAT_MINSTAGIB, "", "CAT_SERVERS", ZCTX(_("SLCAT^MinstaGib Mode"))) \
+ SLIST_CATEGORY(CAT_INSTAGIB, "", "CAT_SERVERS", ZCTX(_("SLCAT^InstaGib Mode"))) \
SLIST_CATEGORY(CAT_DEFRAG, "", "CAT_SERVERS", ZCTX(_("SLCAT^Defrag Mode")))
#define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override
// old servers which don't report their mod name are considered modified now
case "": { return CAT_MODIFIED; }
- case "xpm": { return CAT_XPM; }
- case "minstagib": { return CAT_MINSTAGIB; }
+ case "xpm": { return CAT_XPM; }
+ case "minstagib":
+ case "instagib": { return CAT_INSTAGIB; }
case "overkill": { return CAT_OVERKILL; }
//case "nix": { return CAT_NIX; }
//case "newtoys": { return CAT_NEWTOYS; }
strcat(catent.cat_string, ":"),
#endif
me.realFontSize,
- '1 1 1',
- SKINALPHA_TEXT,
+ SKINCOLOR_SERVERLIST_CATEGORY,
+ SKINALPHA_SERVERLIST_CATEGORY,
0
);
SET_YRANGE(me.categoriesHeight / (me.categoriesHeight + 1), 1);
// list the mods here on which the pure server check actually works
if(modname != "Xonotic")
- if(modname != "MinstaGib")
+ if(modname != "InstaGib" || modname != "MinstaGib")
if(modname != "CTS")
if(modname != "NIX")
if(modname != "NewToys")
s = me.skinParameter(me, i, SKINPARM_PREVIEW);
draw_Picture(me.columnPreviewOrigin * eX, s, me.columnPreviewSize * eX + eY, '1 1 1', 1);
- s = me.skinParameter(me, i, SKINPARM_NAME);
- s = sprintf(_("%s: %s"), s, me.skinParameter(me, i, SKINPARM_TITLE));
+ s = me.skinParameter(me, i, SKINPARM_TITLE);
s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_TITLE, SKINALPHA_TEXT, 0);
}
void XonoticSlider_configureXonoticSlider(entity me, float theValueMin, float theValueMax, float theValueStep, string theCvar)
{
- float v, vk, vp;
- v = theValueMin;
- vk = theValueStep;
+ float vp;
vp = theValueStep * 10;
while(fabs(vp) < fabs(theValueMax - theValueMin) / 40)
vp *= 10;
+
me.configureSliderVisuals(me, me.fontSize, me.align, me.valueSpace, me.image);
- me.configureSliderValues(me, theValueMin, v, theValueMax, theValueStep, vk, vp);
+
if(theCvar)
{
+ // Prevent flickering of the slider button by initialising the
+ // slider out of bounds to hide the button before loading the cvar
+ me.configureSliderValues(me, theValueMin, theValueMin-theValueStep, theValueMax, theValueStep, theValueStep, vp);
me.cvarName = theCvar;
me.loadCvars(me);
me.tooltip = getZonedTooltipForIdentifier(theCvar);
}
+ else
+ me.configureSliderValues(me, theValueMin, theValueMin, theValueMax, theValueStep, theValueStep, vp);
}
void XonoticSlider_setValue(entity me, float val)
{
--- /dev/null
+#ifdef INTERFACE
+CLASS(XonoticParticlesSlider) EXTENDS(XonoticTextSlider)
+ METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity))
+ METHOD(XonoticParticlesSlider, loadCvars, void(entity))
+ METHOD(XonoticParticlesSlider, saveCvars, void(entity))
+ENDCLASS(XonoticParticlesSlider)
+entity makeXonoticParticlesSlider();
+#endif
+
+#ifdef IMPLEMENTATION
+entity makeXonoticParticlesSlider()
+{
+ entity me;
+ me = spawnXonoticParticlesSlider();
+ me.configureXonoticParticlesSlider(me);
+ return me;
+}
+void XonoticParticlesSlider_configureXonoticParticlesSlider(entity me)
+{
+ me.configureXonoticTextSlider(me, "cl_particles_quality");
+ if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^OMG")), "0.4 250 0"); }
+ me.addValue(me, ZCTX(_("PART^Low")), "0.4 500 0");
+ me.addValue(me, ZCTX(_("PART^Medium")), "0.8 750 0");
+ me.addValue(me, ZCTX(_("PART^Normal")), "1.0 1000 1");
+ me.addValue(me, ZCTX(_("PART^High")), "1.0 1500 1");
+ me.addValue(me, ZCTX(_("PART^Ultra")), "1.0 2000 2");
+ if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^Ultimate")), "1.0 3000 2"); }
+ me.configureXonoticTextSliderValues(me);
+}
+void XonoticParticlesSlider_loadCvars(entity me)
+{
+ me.setValueFromIdentifier(me, sprintf("%s %s %s",
+ cvar_string("cl_particles_quality"),
+ cvar_string("r_drawparticles_drawdistance"),
+ cvar_string("cl_damageeffect")
+ ));
+}
+void XonoticParticlesSlider_saveCvars(entity me)
+{
+ if(me.value >= 0 || me.value < me.nValues)
+ {
+ tokenize_console(me.getIdentifier(me));
+ cvar_set("cl_particles_quality", argv(0));
+ cvar_set("r_drawparticles_drawdistance", argv(1));
+ cvar_set("cl_damageeffect", argv(2));
+ }
+}
+#endif
string msg = e.message;
if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
msg = sprintf(_("%s (mutator weapon)"), msg);
- draw_Text(me.realUpperMargin * eY, msg, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+ draw_Text(me.realUpperMargin * eY, msg, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
}
float XonoticWeaponsList_keyDown(entity me, float scan, float ascii, float shift)
void anticheat_physics()
{
- float f, wishspeed;
- vector wishvel;
+ float f;
// div0_evade -> SPECTATORS
makevectors(self.v_angle);
self.anticheat_speedhack_accu = 1;
self.anticheat_speedhack_lasttime = servertime;
}
-
- // race/CTS: force kbd movement for fairness
- if(g_race || g_cts)
- {
- // if record times matter
- // ensure nothing EVIL is being done (i.e. div0_evade)
- // this hinders joystick users though
- // but it still gives SOME analog control
- wishvel_x = fabs(self.movement_x);
- wishvel_y = fabs(self.movement_y);
- if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y)
- {
- wishvel_z = 0;
- wishspeed = vlen(wishvel);
- if(wishvel_x >= 2 * wishvel_y)
- {
- // pure X motion
- if(self.movement_x > 0)
- self.movement_x = wishspeed;
- else
- self.movement_x = -wishspeed;
- self.movement_y = 0;
- }
- else if(wishvel_y >= 2 * wishvel_x)
- {
- // pure Y motion
- self.movement_x = 0;
- if(self.movement_y > 0)
- self.movement_y = wishspeed;
- else
- self.movement_y = -wishspeed;
- }
- else
- {
- // diagonal
- if(self.movement_x > 0)
- self.movement_x = M_SQRT1_2 * wishspeed;
- else
- self.movement_x = -M_SQRT1_2 * wishspeed;
- if(self.movement_y > 0)
- self.movement_y = M_SQRT1_2 * wishspeed;
- else
- self.movement_y = -M_SQRT1_2 * wishspeed;
- }
- }
- }
}
void anticheat_spectatecopy(entity spectatee)
float autocvar_g_domination_point_amt;
float autocvar_g_domination_point_fullbright;
float autocvar_g_domination_point_leadlimit;
+float autocvar_g_domination_roundbased;
+float autocvar_g_domination_roundbased_point_limit;
+float autocvar_g_domination_round_timelimit;
+float autocvar_g_domination_warmup;
#define autocvar_g_domination_point_limit cvar("g_domination_point_limit")
float autocvar_g_domination_point_rate;
float autocvar_g_domination_teams_override;
string autocvar_g_forced_team_pink;
string autocvar_g_forced_team_red;
string autocvar_g_forced_team_yellow;
+float autocvar_g_freezetag_frozen_damage_trigger;
float autocvar_g_freezetag_frozen_force;
float autocvar_g_freezetag_frozen_maxtime;
float autocvar_g_freezetag_revive_falldamage;
float autocvar_g_freezetag_revive_falldamage_health;
+float autocvar_g_freezetag_revive_nade;
+float autocvar_g_freezetag_revive_nade_health;
float autocvar_g_freezetag_point_leadlimit;
float autocvar_g_freezetag_point_limit;
float autocvar_g_freezetag_revive_extra_size;
float autocvar_g_maxpushtime;
float autocvar_g_maxspeed;
float autocvar_g_midair_shieldtime;
-#define autocvar_g_minstagib cvar("g_minstagib")
-float autocvar_g_minstagib_ammo_drop;
-float autocvar_g_minstagib_extralives;
-float autocvar_g_minstagib_speed_highspeed;
-float autocvar_g_minstagib_invis_alpha;
+#define autocvar_g_instagib cvar("g_instagib")
+float autocvar_g_instagib_ammo_drop;
+float autocvar_g_instagib_extralives;
+float autocvar_g_instagib_speed_highspeed;
+float autocvar_g_instagib_invis_alpha;
#define autocvar_g_mirrordamage cvar("g_mirrordamage")
#define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
#define autocvar_g_spawnshieldtime cvar("g_spawnshieldtime")
#define autocvar_g_start_weapon_laser cvar("g_start_weapon_laser")
float autocvar_g_tdm_team_spawns;
+float autocvar_g_tdm_point_limit;
+float autocvar_g_tdm_point_leadlimit;
float autocvar_g_tdm_teams;
float autocvar_g_tdm_teams_override;
float autocvar_g_teamdamage_resetspeed;
float autocvar_sv_dodging_wall_distance_threshold;
float autocvar_sv_dodging_wall_dodging;
float autocvar_sv_dodging_frozen;
+float autocvar_sv_dodging_frozen_doubletap;
float autocvar_sv_doublejump;
float autocvar_sv_eventlog;
float autocvar_sv_eventlog_console;
float autocvar_sv_vote_call;
float autocvar_sv_vote_change;
string autocvar_sv_vote_commands;
+float autocvar_sv_vote_gametype;
+float autocvar_sv_vote_gametype_timeout;
+string autocvar_sv_vote_gametype_options;
+float autocvar_sv_vote_gametype_keeptwotime;
+float autocvar_sv_vote_gametype_default_current;
float autocvar_sv_vote_limit;
float autocvar_sv_vote_majority_factor;
float autocvar_sv_vote_majority_factor_of_voted;
float autocvar_g_random_gravity_delay;
float autocvar_g_nades;
float autocvar_g_nades_spawn;
+float autocvar_g_nades_spawn_count;
+float autocvar_g_nades_client_select;
float autocvar_g_nades_nade_lifetime;
float autocvar_g_nades_nade_minforce;
float autocvar_g_nades_nade_maxforce;
float autocvar_g_nades_nade_radius;
float autocvar_g_nades_nade_force;
float autocvar_g_nades_nade_newton_style;
+float autocvar_g_nades_napalm_ball_count;
+float autocvar_g_nades_napalm_ball_spread;
+float autocvar_g_nades_napalm_ball_damage;
+float autocvar_g_nades_napalm_ball_damageforcescale;
+float autocvar_g_nades_napalm_ball_lifetime;
+float autocvar_g_nades_napalm_ball_radius;
+float autocvar_g_nades_napalm_blast;
+float autocvar_g_nades_napalm_fountain_lifetime;
+float autocvar_g_nades_napalm_fountain_delay;
+float autocvar_g_nades_napalm_fountain_radius;
+float autocvar_g_nades_napalm_fountain_damage;
+float autocvar_g_nades_napalm_fountain_edgedamage;
+float autocvar_g_nades_napalm_burntime;
+float autocvar_g_nades_napalm_selfdamage;
+float autocvar_g_nades_nade_type;
+float autocvar_g_nades_bonus_type;
+float autocvar_g_nades_bonus;
+float autocvar_g_nades_bonus_onstrength;
+float autocvar_g_nades_bonus_client_select;
+float autocvar_g_nades_bonus_max;
+float autocvar_g_nades_bonus_score_max;
+float autocvar_g_nades_bonus_score_time;
+float autocvar_g_nades_bonus_score_time_flagcarrier;
+float autocvar_g_nades_bonus_score_minor;
+float autocvar_g_nades_bonus_score_low;
+float autocvar_g_nades_bonus_score_high;
+float autocvar_g_nades_bonus_score_medium;
+float autocvar_g_nades_bonus_score_spree;
+float autocvar_g_nades_ice_freeze_time;
+float autocvar_g_nades_ice_health;
+float autocvar_g_nades_ice_explode;
+float autocvar_g_nades_ice_teamcheck;
+float autocvar_g_nades_heal_time;
+float autocvar_g_nades_heal_rate;
+float autocvar_g_nades_heal_friend;
+float autocvar_g_nades_heal_foe;
+string autocvar_g_nades_pokenade_monster_type;
+float autocvar_g_nades_pokenade_monster_lifetime;
float autocvar_g_campcheck_damage;
float autocvar_g_campcheck_distance;
float autocvar_g_campcheck_interval;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
float autocvar_g_physics_clientselect;
string autocvar_g_physics_clientselect_options;
-
+float autocvar_g_buffs_waypoint_distance;
+float autocvar_g_buffs_randomize;
+float autocvar_g_buffs_random_lifetime;
+float autocvar_g_buffs_random_location;
+float autocvar_g_buffs_random_location_attempts;
+float autocvar_g_buffs_spawn_count;
+float autocvar_g_buffs_replace_powerups;
+float autocvar_g_buffs_cooldown_activate;
+float autocvar_g_buffs_cooldown_respawn;
+float autocvar_g_buffs_resistance_blockpercent;
+float autocvar_g_buffs_medic_survive_chance;
+float autocvar_g_buffs_medic_survive_health;
+float autocvar_g_buffs_medic_rot;
+float autocvar_g_buffs_medic_max;
+float autocvar_g_buffs_medic_regen;
+float autocvar_g_buffs_vengeance_damage_multiplier;
+float autocvar_g_buffs_bash_force;
+float autocvar_g_buffs_bash_force_self;
+float autocvar_g_buffs_disability_time;
+float autocvar_g_buffs_disability_speed;
+float autocvar_g_buffs_disability_rate;
+float autocvar_g_buffs_speed_speed;
+float autocvar_g_buffs_speed_rate;
+float autocvar_g_buffs_speed_damage_take;
+float autocvar_g_buffs_speed_regen;
+float autocvar_g_buffs_vampire_damage_steal;
+float autocvar_g_buffs_invisible_alpha;
+float autocvar_g_buffs_flight_gravity;
+float autocvar_g_buffs_jump_height;
return FALSE;
}
- if(e.freezetag_frozen)
+ if(e.frozen)
return FALSE;
// If neither player has ball then don't attack unless the ball is on the
//self.bot_painintensity = self.bot_painintensity + self.bot_oldhealth - self.health;
//self.bot_painintensity = bound(0, self.bot_painintensity, 100);
- if (autocvar_g_campaign && !campaign_bots_may_start)
+ if (!IS_PLAYER(self) || (autocvar_g_campaign && !campaign_bots_may_start))
{
self.bot_nextthink = time + 0.5;
return;
}
}
-//Race:
-//go to next checkpoint, and annoy enemies
-.float race_checkpoint;
-void havocbot_role_race()
-{
- if(self.deadflag != DEAD_NO)
- return;
-
- entity e;
- if (self.bot_strategytime < time)
- {
- self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
- navigation_goalrating_start();
- /*
- havocbot_goalrating_items(100, self.origin, 10000);
- havocbot_goalrating_enemyplayers(500, self.origin, 20000);
- */
-
- for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
- {
- if(e.cnt == self.race_checkpoint)
- {
- navigation_routerating(e, 1000000, 5000);
- }
- else if(self.race_checkpoint == -1)
- {
- navigation_routerating(e, 1000000, 5000);
- }
- }
-
- navigation_goalrating_end();
- }
-}
-
void havocbot_chooserole_dm()
{
self.havocbot_role = havocbot_role_dm;
}
-void havocbot_chooserole_race()
-{
- self.havocbot_role = havocbot_role_race;
-}
-
void havocbot_chooserole()
{
dprint("choosing a role...\n");
return;
else if (g_keyhunt)
havocbot_chooserole_kh();
- else if (g_race || g_cts)
- havocbot_chooserole_race();
else if (g_onslaught)
havocbot_chooserole_ons();
else // assume anything else is deathmatch
-void race_send_recordtime(float msg);
-void race_SendRankings(float pos, float prevpos, float del, float msg);
-
void send_CSQC_teamnagger() {
WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
{
entity spot;
self.hud = HUD_NORMAL;
- race_PreSpawnObserver();
+
+ if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
spot = SelectSpawnPoint (TRUE);
if(!spot)
WriteEntity(MSG_ONE, self);
}
- if((g_race && g_race_qualifying) || g_cts)
- {
- if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
- self.frags = FRAGS_LMS_LOSER;
- else
- self.frags = FRAGS_SPECTATOR;
- }
- else
- self.frags = FRAGS_SPECTATOR;
+ self.frags = FRAGS_SPECTATOR;
MUTATOR_CALLHOOK(MakePlayerObserver);
Portal_ClearAll(self);
+ Unfreeze(self);
+
if(self.alivetime)
{
if(!warmup_stage)
self.angles_z = 0;
self.fixangle = TRUE;
self.crouch = FALSE;
+ self.revival_time = 0;
setorigin (self, (spot.origin + PL_VIEW_OFS)); // offset it so that the spectator spawns higher off the ground, looks better this way
self.prevorigin = self.origin;
self.punchvector = '0 0 0';
self.oldvelocity = self.velocity;
self.fire_endtime = -1;
+ self.event_damage = func_null;
}
.float model_randomizer;
if(self.team < 0)
JoinBestTeam(self, FALSE, TRUE);
- race_PreSpawn();
-
spot = SelectSpawnPoint (FALSE);
if(!spot)
{
self.angles = spot.angles;
self.angles_z = 0; // never spawn tilted even if the spot says to
+ if(IS_BOT_CLIENT(self))
+ self.v_angle = self.angles;
self.fixangle = TRUE; // turn this way immediately
self.velocity = '0 0 0';
self.avelocity = '0 0 0';
self.punchvector = '0 0 0';
self.oldvelocity = self.velocity;
self.fire_endtime = -1;
+ self.revival_time = 0;
entity spawnevent = spawn();
spawnevent.owner = self;
Net_LinkEntity(spawnevent, FALSE, 0.5, SpawnEvent_Send);
+ // Cut off any still running player sounds.
+ stopsound(self, CH_PLAYER_SINGLE);
+
self.model = "";
FixPlayermodel();
self.drawonlytoclient = world;
self.speedrunning = FALSE;
- race_PostSpawn(spot);
-
//stuffcmd(self, "chase_active 0");
//stuffcmd(self, "set viewsize $tmpviewsize \n");
activator = world;
self = oldself;
+ Unfreeze(self);
+
spawn_spot = spot;
MUTATOR_CALLHOOK(PlayerSpawn);
if(self.killindicator_teamchange)
ClientKill_Now_TeamChange();
- // in any case:
- Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
+ if(IS_PLAYER(self))
+ Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
// now I am sure the player IS dead
}
{
if(gameover) return;
if(self.player_blocked) return;
- if(self.freezetag_frozen) return;
+ if(self.frozen) return;
ClientKill_TeamChange(0);
}
anticheat_init();
- race_PreSpawnObserver();
-
// identify the right forced team
if(autocvar_g_campaign)
{
else
self.hitplotfh = -1;
- if(g_race || g_cts) {
- string rr;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
-
- msg_entity = self;
- race_send_recordtime(MSG_ONE);
- race_send_speedaward(MSG_ONE);
-
- speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
- speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
- race_send_speedaward_alltimebest(MSG_ONE);
-
- float i;
- for (i = 1; i <= RANKINGS_CNT; ++i) {
- race_SendRankings(i, 0, 0, MSG_ONE);
- }
- }
- else if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca
+ if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca && !g_cts && !g_race) // teamnagger is currently bad for ca, race & cts
send_CSQC_teamnagger();
CheatInitClient();
return;
}
+ if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
+
PlayerStats_AddGlobalInfo(self);
CheatShutdownClient();
Portal_ClearAll(self);
+ Unfreeze(self);
+
RemoveGrapplingHook(self);
// Here, everything has been done that requires this player to be a client.
Fire_ApplyDamage(self);
Fire_ApplyEffect(self);
- if (!g_minstagib)
+ if (!g_instagib)
{
if (self.items & IT_STRENGTH)
{
void player_regen (void)
{
+ float max_mod, regen_mod, rot_mod, limit_mod;
+ max_mod = regen_mod = rot_mod = limit_mod = 1;
+ regen_mod_max = max_mod;
+ regen_mod_regen = regen_mod;
+ regen_mod_rot = rot_mod;
+ regen_mod_limit = limit_mod;
if(!MUTATOR_CALLHOOK(PlayerRegen))
+ if(!self.frozen)
{
- float minh, mina, maxh, maxa, limith, limita, max_mod, regen_mod, rot_mod, limit_mod;
+ float minh, mina, maxh, maxa, limith, limita;
maxh = autocvar_g_balance_health_rotstable;
maxa = autocvar_g_balance_armor_rotstable;
minh = autocvar_g_balance_health_regenstable;
mina = autocvar_g_balance_armor_regenstable;
limith = autocvar_g_balance_health_limit;
limita = autocvar_g_balance_armor_limit;
-
- max_mod = regen_mod = rot_mod = limit_mod = 1;
+
+ max_mod = regen_mod_max;
+ regen_mod = regen_mod_regen;
+ rot_mod = regen_mod_rot;
+ limit_mod = regen_mod_limit;
maxh = maxh * max_mod;
minh = minh * max_mod;
self.dmg_inflictor = spectatee.dmg_inflictor;
self.v_angle = spectatee.v_angle;
self.angles = spectatee.v_angle;
+ self.frozen = spectatee.frozen;
+ self.revive_progress = spectatee.revive_progress;
if(!self.BUTTON_USE)
self.fixangle = TRUE;
setorigin(self, spectatee.origin);
if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
{
self.classname = "player";
+ nades_RemoveBonus(self);
if(autocvar_g_campaign || autocvar_g_balance_teams)
{ JoinBestTeam(self, FALSE, TRUE); }
float currentlyPlaying = 0;
FOR_EACH_REALCLIENT(e)
- if(IS_PLAYER(e) || e.caplayer == 1)
+ if(IS_PLAYER(e) || e.caplayer)
currentlyPlaying += 1;
if(currentlyPlaying < autocvar_g_maxplayers)
* g_maxplayers_spectator_blocktime seconds
*/
void checkSpectatorBlock() {
- if(IS_SPEC(self) || IS_OBSERVER(self)) {
+ if(IS_SPEC(self) || IS_OBSERVER(self))
+ if(!self.caplayer)
+ if(IS_REAL_CLIENT(self))
+ {
if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
dropclient(self);
return;
#endif
+ if(self.frozen == 2)
+ {
+ self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1);
+ self.health = max(1, self.revive_progress * start_health);
+ self.iceblock.alpha = bound(0.2, 1 - self.revive_progress, 1);
+
+ if(self.revive_progress >= 1)
+ Unfreeze(self);
+ }
+ else if(self.frozen == 3)
+ {
+ self.revive_progress = bound(0, self.revive_progress - frametime * self.revive_speed, 1);
+ self.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * self.revive_progress );
+
+ if(self.health < 1)
+ {
+ if(self.vehicle)
+ vehicles_exit(VHEF_RELESE);
+ self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0');
+ }
+ else if ( self.revive_progress <= 0 )
+ Unfreeze(self);
+ }
+
MUTATOR_CALLHOOK(PlayerPreThink);
if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
do_crouch = 0;
if(self.vehicle)
do_crouch = 0;
- if(self.freezetag_frozen)
+ if(self.frozen)
do_crouch = 0;
if(self.weapon == WEP_SHOTGUN && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
do_crouch = 0;
if(self.spectatee_status != oldspectatee_status)
{
ClientData_Touch(self);
- if(g_race || g_cts)
- race_InitSpectator();
}
if(self.teamkill_soundtime)
playerdemo_write();
- if((g_cts || g_race) && self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
- {
- if (!self.stored_netname)
- self.stored_netname = strzone(uid2name(self.crypto_idfp));
- if(self.stored_netname != self.netname)
- {
- db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
- strunzone(self.stored_netname);
- self.stored_netname = strzone(self.netname);
- }
- }
-
- /*
- if(g_race)
- dprintf("%f %.6f\n", time, race_GetFractionalLapCount(self));
- */
-
CSQCMODEL_AUTOUPDATE();
}
*/
void PlayerJump (void)
{
+ if(self.frozen)
+ return; // no jumping in freezetag when frozen
+
if(self.player_blocked)
return; // no jumping while blocked
float doublejump = FALSE;
+ float mjumpheight = self.stat_sv_jumpvelocity;
player_multijump = doublejump;
+ player_jumpheight = mjumpheight;
if(MUTATOR_CALLHOOK(PlayerJump))
return;
doublejump = player_multijump;
-
- float mjumpheight;
+ mjumpheight = player_jumpheight;
if (autocvar_sv_doublejump)
{
}
}
- mjumpheight = self.stat_sv_jumpvelocity;
if (self.waterlevel >= WATERLEVEL_SWIMMING)
{
self.velocity_z = self.stat_sv_maxspeed * 0.7;
self.stat_sv_airspeedlimit_nonqw *= 0.5;
}
+ if(self.frozen)
+ {
+ if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
+ {
+ self.movement_x = bound(-5, self.movement_x, 5);
+ self.movement_y = bound(-5, self.movement_y, 5);
+ self.movement_z = bound(-5, self.movement_z, 5);
+ }
+ else
+ self.movement = '0 0 0';
+ self.disableclientprediction = 1;
+
+ vector midpoint = ((self.absmin + self.absmax) * 0.5);
+ if(pointcontents(midpoint) == CONTENT_WATER)
+ {
+ self.velocity = self.velocity * 0.5;
+
+ if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
+ { self.velocity_z = 200; }
+ }
+ }
+
MUTATOR_CALLHOOK(PlayerPhysics);
if(self.player_blocked)
PM_Accelerate(wishdir, wishspeed, wishspeed, self.stat_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
}
}
- else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.freezetag_frozen)
+ else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.frozen)
{
//makevectors(self.v_angle_y * '0 1 0');
makevectors(self.v_angle);
}
}
- if((g_cts || g_race) && !IS_OBSERVER(self)) {
- if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed) {
+ if((g_cts || g_race) && !IS_OBSERVER(self))
+ {
+ if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed)
+ {
speedaward_speed = vlen(self.velocity - self.velocity_z * '0 0 1');
speedaward_holder = self.netname;
speedaward_uid = self.crypto_idfp;
speedaward_lastupdate = time;
}
- if(speedaward_speed > speedaward_lastsent && time - speedaward_lastupdate > 1) {
- string rr;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
+ if(speedaward_speed > speedaward_lastsent && time - speedaward_lastupdate > 1)
+ {
+ string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
race_send_speedaward(MSG_ALL);
speedaward_lastsent = speedaward_speed;
- if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "") {
+ if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "")
+ {
speedaward_alltimebest = speedaward_speed;
speedaward_alltimebest_holder = speedaward_holder;
speedaward_alltimebest_uid = speedaward_uid;
void player_anim (void)
{
float deadbits = (self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
- if(self.deadflag && !deadbits)
- if(random() < 0.5)
- deadbits = ANIMSTATE_DEAD1;
- else
- deadbits = ANIMSTATE_DEAD2;
+ if(self.deadflag) {
+ if (!deadbits) {
+ // Decide on which death animation to use.
+ if(random() < 0.5)
+ deadbits = ANIMSTATE_DEAD1;
+ else
+ deadbits = ANIMSTATE_DEAD2;
+ }
+ } else {
+ // Clear a previous death animation.
+ deadbits = 0;
+ }
float animbits = deadbits;
- if(self.freezetag_frozen)
+ if(self.frozen)
animbits |= ANIMSTATE_FROZEN;
if(self.crouch)
animbits |= ANIMSTATE_DUCK;
void calculate_player_respawn_time()
{
+ if(g_ca)
+ return;
+
float gametype_setting_tmp;
float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max);
float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small);
else
self.respawn_countdown = -1; // do not count down
- if(g_cts || autocvar_g_forced_respawn)
+ if(autocvar_g_forced_respawn)
self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
}
self.health = self.health - take;
// pause regeneration for 5 seconds
if(take)
- self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
+ self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
if (time > self.pain_finished) //Don't switch pain sequences like crazy
{
PlayerSound(playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND);
}
}
+ }
- // throw off bot aim temporarily
- float shake;
+ // throw off bot aim temporarily
+ float shake;
+ if(IS_BOT_CLIENT(self) && self.health >= 1)
+ {
shake = damage * 5 / (bound(0,skill,100) + 1);
self.v_angle_x = self.v_angle_x + (random() * 2 - 1) * shake;
self.v_angle_y = self.v_angle_y + (random() * 2 - 1) * shake;
+ self.v_angle_x = bound(-90, self.v_angle_x, 90);
}
}
else
// print an obituary message
Obituary (attacker, inflictor, self, deathtype);
- race_PreDie();
// increment frag counter for used weapon type
float w;
// when we get here, player actually dies
+ Unfreeze(self); // remove any icy remains
+ self.health = 0; // Unfreeze resets health, so we need to set it back
+
// clear waypoints
WaypointSprite_PlayerDead();
// throw a weapon
self.flags &= ~FL_ONGROUND;
// dying animation
self.deadflag = DEAD_DYING;
+
// when to allow respawn
calculate_player_respawn_time();
return 0;
if (g_weaponarena)
return 0;
- if (g_cts)
- return 0;
if (g_nexball && w == WEP_GRENADE_LAUNCHER)
return 0;
if(w == 0)
w = self.weapon;
if (w == 0)
return; // just in case
+ if(self.frozen)
+ return;
if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon))
return;
if(!autocvar_g_weapon_throwable)
return 1;
if(self.player_blocked)
return 1;
- if(self.freezetag_frozen)
+ if(self.frozen)
return 1;
return 0;
}
float t;
t = 1.0 / g_weaponratefactor;
+ weapon_rate = t;
+ MUTATOR_CALLHOOK(WeaponRateFactor);
+ t = weapon_rate;
+
return t;
}
{
if(!IS_PLAYER(self) && !lockteams)
{
+ if(self.caplayer)
+ return;
if(nJoinAllowed(self))
{
if(autocvar_g_campaign) { campaign_bots_may_start = 1; }
else if(MUTATOR_CALLHOOK(AllowMobSpawning)) { sprint(self, "Monster spawning is currently disabled by a mutator.\n"); return; }
else if(!autocvar_g_monsters) { Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_MONSTERS_DISABLED); return; }
else if(self.vehicle) { sprint(self, "You can't spawn monsters while driving a vehicle.\n"); return; }
- else if(self.freezetag_frozen) { sprint(self, "You can't spawn monsters while frozen.\n"); return; }
+ else if(self.frozen) { sprint(self, "You can't spawn monsters while frozen.\n"); return; }
else if(autocvar_g_campaign) { sprint(self, "You can't spawn monsters in campaign mode.\n"); return; }
else if(self.deadflag != DEAD_NO) { sprint(self, "You can't spawn monsters while dead.\n"); return; }
else if(monstercount >= autocvar_g_monsters_max_perplayer) { sprint(self, "You have spawned too many monsters, kill some before trying to spawn any more.\n"); return; }
}
}
- if(IS_PLAYER(self) && autocvar_sv_spectate == 1)
- ClientKill_TeamChange(-2); // observe
-
- // in CA, allow a dead player to move to spectators (without that, caplayer!=0 will be moved back to the player list)
- // note: if arena game mode is ever done properly, this needs to be removed.
- if(self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
+ if((IS_PLAYER(self) || self.caplayer) && autocvar_sv_spectate == 1)
{
- sprint(self, "WARNING: you will spectate in the next round.\n");
- self.caplayer = 0;
+ if(self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_LEAVE);
+ ClientKill_TeamChange(-2); // observe
}
}
return; // never fall through to usage
float i, j, k, uidcnt = 0, thiscnt;
string s, temp_s, rr, myuid, thisuid;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
+ rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
for(k = 0; k < MapInfo_count; ++k)
{
FOR_EACH_REALPLAYER(client)
{
self = client;
+ if(self.caplayer)
+ self.caplayer = 0;
PutObserverInServer();
++i;
}
if(!IS_SPEC(client) && !IS_OBSERVER(client))
{
self = client;
+ if(self.caplayer)
+ self.caplayer = 0;
PutObserverInServer();
successful = strcat(successful, (successful ? ", " : ""), client.netname);
{
blockSpectators = 1;
entity plr;
- FOR_EACH_CLIENT(plr) //give every spectator <g_maxplayers_spectator_blocktime> seconds time to become a player
+ FOR_EACH_REALCLIENT(plr) //give every spectator <g_maxplayers_spectator_blocktime> seconds time to become a player
{
if(IS_SPEC(plr) || IS_OBSERVER(plr))
+ if(!plr.caplayer)
{
plr.spectatortime = time;
Send_Notification(NOTIF_ONE_ONLY, plr, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
if(time <= game_starttime && round_handler_IsActive())
round_handler_Reset(game_starttime);
- if(g_race || g_cts)
- race_ReadyRestart();
- else MUTATOR_CALLHOOK(reset_map_global);
+ MUTATOR_CALLHOOK(reset_map_global);
for(self = world; (self = nextent(self)); )
if(IS_NOT_A_CLIENT(self))
WriteByte(MSG_ENTITY, ft);
WriteByte(MSG_ENTITY, fr);
}
+
+ WriteByte(MSG_ENTITY, self.realowner.team);
}
if(sf & 2)
// Globals
-float g_cloaked, g_footsteps, g_grappling_hook, g_minstagib;
+float g_cloaked, g_footsteps, g_grappling_hook, g_instagib;
float g_warmup_limit;
float g_warmup_allguns;
float g_warmup_allow_timeout;
-float g_race_qualifying;
float warmup_stage;
float g_pickup_respawntime_weapon;
float g_pickup_respawntime_superweapon;
.float dmgtime;
.float killcount;
-.float hitsound, typehitsound;
+.float damage_dealt, typehitsound;
.float watersound_finished;
.float iscreature;
.float hit_time;
.float typehit_time;
+.float damage_dealt_total;
+
.float stat_leadlimit;
float radar_showennemies;
.float player_blocked;
-.float freezetag_frozen;
+.float frozen; // for freeze attacks
+.float revive_progress;
+.float revival_time; // time at which player was last revived
+.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
+.entity iceblock;
+.entity frozen_by; // for ice fields
.entity muzzle_flash;
.float misc_bulletcounter; // replaces uzi & hlac bullet counter.
if(targ.killcount) { targ.killcount = 0; }
}
+void Ice_Think()
+{
+ if(!self.owner.frozen || self.owner.iceblock != self)
+ {
+ remove(self);
+ return;
+ }
+ setorigin(self, self.owner.origin - '0 0 16');
+ self.nextthink = time;
+}
+
+void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint)
+{
+ if(!IS_PLAYER(targ) && !(targ.flags & FL_MONSTER)) // only specified entities can be freezed
+ return;
+
+ if(targ.frozen)
+ return;
+
+ float targ_maxhealth = ((targ.flags & FL_MONSTER) ? targ.max_health : start_health);
+
+ targ.frozen = frozen_type;
+ targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
+ targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
+ targ.revive_speed = freeze_time;
+
+ entity ice, head;
+ ice = spawn();
+ ice.owner = targ;
+ ice.classname = "ice";
+ ice.scale = targ.scale;
+ ice.think = Ice_Think;
+ ice.nextthink = time;
+ ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+ setmodel(ice, "models/ice/ice.md3");
+ ice.alpha = 1;
+ ice.colormod = Team_ColorRGB(targ.team);
+ ice.glowmod = ice.colormod;
+ targ.iceblock = ice;
+ targ.revival_time = 0;
+
+ entity oldself;
+ oldself = self;
+ self = ice;
+ Ice_Think();
+ self = oldself;
+
+ RemoveGrapplingHook(targ);
+
+ FOR_EACH_PLAYER(head)
+ if(head.hook.aiment == targ)
+ RemoveGrapplingHook(head);
+
+ // add waypoint
+ if(show_waypoint)
+ WaypointSprite_Spawn("frozen", 0, 0, targ, '0 0 64', world, targ.team, targ, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
+}
+
+void Unfreeze (entity targ)
+{
+ if(targ.frozen && targ.frozen != 3) // only reset health if target was frozen
+ targ.health = ((IS_PLAYER(targ)) ? start_health : targ.max_health);
+
+ entity head;
+ targ.frozen = 0;
+ targ.revive_progress = 0;
+ targ.revival_time = time;
+
+ WaypointSprite_Kill(targ.waypointsprite_attached);
+
+ FOR_EACH_PLAYER(head)
+ if(head.hook.aiment == targ)
+ RemoveGrapplingHook(head);
+
+ // remove the ice block
+ if(targ.iceblock)
+ remove(targ.iceblock);
+ targ.iceblock = world;
+}
+
// these are updated by each Damage call for use in button triggering and such
entity damage_targ;
entity damage_inflictor;
mirrordamage = frag_mirrordamage;
force = frag_force;
- if (!g_minstagib)
+ if(targ.frozen)
+ if(deathtype != DEATH_HURTTRIGGER && deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_AUTOTEAMCHANGE)
+ {
+ if(autocvar_g_freezetag_revive_falldamage > 0)
+ if(deathtype == DEATH_FALL)
+ if(damage >= autocvar_g_freezetag_revive_falldamage)
+ {
+ Unfreeze(targ);
+ targ.health = autocvar_g_freezetag_revive_falldamage_health;
+ pointparticles(particleeffectnum("iceorglass"), targ.origin, '0 0 0', 3);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, targ.netname);
+ Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
+ }
+
+ damage = 0;
+ force *= autocvar_g_freezetag_frozen_force;
+ }
+
+ if(targ.frozen && deathtype == DEATH_HURTTRIGGER && !autocvar_g_freezetag_frozen_damage_trigger)
+ {
+ pointparticles(particleeffectnum("teleport"), targ.origin, '0 0 0', 1);
+
+ entity oldself = self;
+ self = targ;
+ entity spot = SelectSpawnPoint (FALSE);
+
+ if(spot)
+ {
+ damage = 0;
+ self.deadflag = DEAD_NO;
+
+ self.angles = spot.angles;
+
+ self.effects = 0;
+ self.effects |= EF_TELEPORT_BIT;
+
+ self.angles_z = 0; // never spawn tilted even if the spot says to
+ self.fixangle = TRUE; // turn this way immediately
+ self.velocity = '0 0 0';
+ self.avelocity = '0 0 0';
+ self.punchangle = '0 0 0';
+ self.punchvector = '0 0 0';
+ self.oldvelocity = self.velocity;
+
+ self.spawnorigin = spot.origin;
+ setorigin (self, spot.origin + '0 0 1' * (1 - self.mins_z - 24));
+ // don't reset back to last position, even if new position is stuck in solid
+ self.oldorigin = self.origin;
+ self.prevorigin = self.origin;
+
+ pointparticles(particleeffectnum("teleport"), self.origin, '0 0 0', 1);
+ }
+
+ self = oldself;
+ }
+
+ if(!g_instagib)
{
// apply strength multiplier
if (attacker.items & IT_STRENGTH)
}
if (targ == attacker)
- {
- if(g_cts && !autocvar_g_cts_selfdamage)
- damage = 0;
- else
- damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
- }
+ damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
// count the damage
if(attacker)
if(victim.BUTTON_CHAT)
attacker.typehitsound += 1;
else
- attacker.hitsound += 1;
+ attacker.damage_dealt += damage;
}
damage_goodhits += 1;
e.fire_endtime = 0;
// ice stops fire
- if(e.freezetag_frozen)
+ if(e.frozen)
e.fire_endtime = 0;
t = min(frametime, e.fire_endtime - time);
d = e.fire_damagepersec * t;
- hi = e.fire_owner.hitsound;
+ hi = e.fire_owner.damage_dealt;
ty = e.fire_owner.typehitsound;
Damage(e, e, e.fire_owner, d, e.fire_deathtype, e.origin, '0 0 0');
if(e.fire_hitsound && e.fire_owner)
{
- e.fire_owner.hitsound = hi;
+ e.fire_owner.damage_dealt = hi;
e.fire_owner.typehitsound = ty;
}
e.fire_hitsound = TRUE;
if (!IS_INDEPENDENT_PLAYER(e))
- if(!e.freezetag_frozen)
+ if(!e.frozen)
FOR_EACH_PLAYER(other) if(e != other)
{
if(IS_PLAYER(other))
string redirection_target;
float world_initialized;
-string GetMapname();
string GetGametype();
void GotoNextMap(float reinit);
void ShuffleMaplist();
// private
BADCVAR("developer");
BADCVAR("log_dest_udp");
- BADCVAR("log_file");
BADCVAR("net_address");
BADCVAR("net_address_ipv6");
BADCVAR("port");
BADPREFIX("g_playerstats_");
BADPREFIX("g_respawn_ghosts");
BADPREFIX("g_voice_flood_");
+ BADPREFIX("log_file");
BADPREFIX("rcon_");
BADPREFIX("sv_allowdownloads");
BADPREFIX("sv_autodemo");
BADPREFIX("sv_ready_restart_");
// mutators that announce themselves properly to the server browser
- BADCVAR("g_minstagib");
+ BADCVAR("g_instagib");
BADCVAR("g_new_toys");
BADCVAR("g_nix");
BADCVAR("g_grappling_hook");
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
MapInfo_Enumerate();
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
+ CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load);
addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size);
addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup);
- addstat(STAT_HIT_TIME, AS_FLOAT, hit_time);
+ addstat(STAT_DAMAGE_DEALT_TOTAL, AS_INT, damage_dealt_total);
addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time);
addstat(STAT_LAYED_MINES, AS_INT, minelayer_mines);
addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
+ // freeze attacks
+ addstat(STAT_FROZEN, AS_INT, frozen);
+ addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress);
+
// g_movementspeed hack
addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
return MapInfo_Type_ToString(MapInfo_LoadedGametype);
}
-string getmapname_stored;
string GetMapname()
{
return mapname;
return TRUE;
}
if(autocvar_nextmap != "")
- if(MapInfo_CheckMap(autocvar_nextmap))
+ {
+ string m;
+ m = GameTypeVote_MapInfo_FixName(autocvar_nextmap);
+ cvar_set("nextmap",m);
+
+ if(!m || gametypevote)
+ return FALSE;
+ if(autocvar_sv_vote_gametype)
+ {
+ Map_Goto_SetStr(m);
+ return FALSE;
+ }
+
+ if(MapInfo_CheckMap(m))
{
- Map_Goto_SetStr(autocvar_nextmap);
+ Map_Goto_SetStr(m);
Map_Goto(reinit);
alreadychangedlevel = TRUE;
return TRUE;
}
+ }
if(!reinit && autocvar_lastlevel)
{
cvar_settemp_restore();
============
*/
.float autoscreenshot;
-void() MapVote_Start;
-void() MapVote_Think;
-float mapvote_initialized;
void IntermissionThink()
{
FixIntermissionClient(self);
SetDefaultAlpha();
- /*
- MapVote_Think should now do that part
- if (intermission_running)
- if (time >= intermission_exittime + 60)
- {
- if(!DoNextMapOverride())
- GotoNextMap();
- return;
- }
- */
-
if (gameover) // someone else quit the game already
{
if(player_count == 0) // Nobody there? Then let's go to the next map
}
}
-float mapvote_nextthink;
-float mapvote_initialized;
-float mapvote_keeptwotime;
-float mapvote_timeout;
-string mapvote_message;
-#define MAPVOTE_SCREENSHOT_DIRS_COUNT 4
-string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT];
-float mapvote_screenshot_dirs_count;
-
-float mapvote_count;
-float mapvote_count_real;
-string mapvote_maps[MAPVOTE_COUNT];
-float mapvote_maps_screenshot_dir[MAPVOTE_COUNT];
-string mapvote_maps_pakfile[MAPVOTE_COUNT];
-float mapvote_maps_suggested[MAPVOTE_COUNT];
-string mapvote_suggestions[MAPVOTE_COUNT];
-float mapvote_suggestion_ptr;
-float mapvote_voters;
-float mapvote_selections[MAPVOTE_COUNT];
-float mapvote_run;
-float mapvote_detail;
-float mapvote_abstain;
-.float mapvote;
-
-void MapVote_ClearAllVotes()
-{
- FOR_EACH_CLIENT(other)
- other.mapvote = 0;
-}
-
-string MapVote_Suggest(string m)
+string GotoMap(string m)
{
- float i;
- if(m == "")
- return "That's not how to use this command.";
- if(!autocvar_g_maplist_votable_suggestions)
- return "Suggestions are not accepted on this server.";
- if(mapvote_initialized)
- return "Can't suggest - voting is already in progress!";
- m = MapInfo_FixName(m);
+ m = GameTypeVote_MapInfo_FixName(m);
if (!m)
return "The map you suggested is not available on this server.";
- if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
- if(Map_IsRecent(m))
- return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
-
+ if (!autocvar_sv_vote_gametype)
if(!MapInfo_CheckMap(m))
return "The map you suggested does not support the current game mode.";
- for(i = 0; i < mapvote_suggestion_ptr; ++i)
- if(mapvote_suggestions[i] == m)
- return "This map was already suggested.";
- if(mapvote_suggestion_ptr >= MAPVOTE_COUNT)
- {
- i = floor(random() * mapvote_suggestion_ptr);
- }
- else
- {
- i = mapvote_suggestion_ptr;
- mapvote_suggestion_ptr += 1;
- }
- if(mapvote_suggestions[i] != "")
- strunzone(mapvote_suggestions[i]);
- mapvote_suggestions[i] = strzone(m);
- if(autocvar_sv_eventlog)
- GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid)));
- return strcat("Suggestion of ", m, " accepted.");
-}
-
-void MapVote_AddVotable(string nextMap, float isSuggestion)
-{
- float j, i, o;
- string pakfile, mapfile;
-
- if(nextMap == "")
- return;
- for(j = 0; j < mapvote_count; ++j)
- if(mapvote_maps[j] == nextMap)
- return;
- // suggestions might be no longer valid/allowed after gametype switch!
- if(isSuggestion)
- if(!MapInfo_CheckMap(nextMap))
- return;
- mapvote_maps[mapvote_count] = strzone(nextMap);
- mapvote_maps_suggested[mapvote_count] = isSuggestion;
-
- pakfile = string_null;
- for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
- {
- mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);
- pakfile = whichpack(strcat(mapfile, ".tga"));
- if(pakfile == "")
- pakfile = whichpack(strcat(mapfile, ".jpg"));
- if(pakfile == "")
- pakfile = whichpack(strcat(mapfile, ".png"));
- if(pakfile != "")
- break;
- }
- if(i >= mapvote_screenshot_dirs_count)
- i = 0; // FIXME maybe network this error case, as that means there is no mapshot on the server?
- for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1)
- pakfile = substring(pakfile, o, -1);
-
- mapvote_maps_screenshot_dir[mapvote_count] = i;
- mapvote_maps_pakfile[mapvote_count] = strzone(pakfile);
-
- mapvote_count += 1;
-}
-
-void MapVote_Spawn();
-void MapVote_Init()
-{
- float i;
- float nmax, smax;
-
- MapVote_ClearAllVotes();
-
- mapvote_count = 0;
- mapvote_detail = !autocvar_g_maplist_votable_nodetail;
- mapvote_abstain = autocvar_g_maplist_votable_abstain;
-
- if(mapvote_abstain)
- nmax = min(MAPVOTE_COUNT - 1, autocvar_g_maplist_votable);
- else
- nmax = min(MAPVOTE_COUNT, autocvar_g_maplist_votable);
- smax = min3(nmax, autocvar_g_maplist_votable_suggestions, mapvote_suggestion_ptr);
-
- // we need this for AddVotable, as that cycles through the screenshot dirs
- mapvote_screenshot_dirs_count = tokenize_console(autocvar_g_maplist_votable_screenshot_dir);
- if(mapvote_screenshot_dirs_count == 0)
- mapvote_screenshot_dirs_count = tokenize_console("maps levelshots");
- mapvote_screenshot_dirs_count = min(mapvote_screenshot_dirs_count, MAPVOTE_SCREENSHOT_DIRS_COUNT);
- for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
- mapvote_screenshot_dirs[i] = strzone(argv(i));
-
- if(mapvote_suggestion_ptr)
- for(i = 0; i < 100 && mapvote_count < smax; ++i)
- MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], TRUE);
-
- for(i = 0; i < 100 && mapvote_count < nmax; ++i)
- MapVote_AddVotable(GetNextMap(), FALSE);
-
- if(mapvote_count == 0)
- {
- bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
- cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
- if(autocvar_g_maplist_shuffle)
- ShuffleMaplist();
- localcmd("\nmenu_cmd sync\n");
- for(i = 0; i < 100 && mapvote_count < nmax; ++i)
- MapVote_AddVotable(GetNextMap(), FALSE);
- }
-
- mapvote_count_real = mapvote_count;
- if(mapvote_abstain)
- MapVote_AddVotable("don't care", 0);
-
- //dprint("mapvote count is ", ftos(mapvote_count), "\n");
-
- mapvote_keeptwotime = time + autocvar_g_maplist_votable_keeptwotime;
- mapvote_timeout = time + autocvar_g_maplist_votable_timeout;
- if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
- mapvote_keeptwotime = 0;
- mapvote_message = "Choose a map and press its key!";
-
- MapVote_Spawn();
-}
-
-void MapVote_SendPicture(float id)
-{
- msg_entity = self;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_PICTURE);
- WriteByte(MSG_ONE, id);
- WritePicture(MSG_ONE, strcat(mapvote_screenshot_dirs[mapvote_maps_screenshot_dir[id]], "/", mapvote_maps[id]), 3072);
-}
-
-float MapVote_GetMapMask()
-{
- float mask, i, power;
- mask = 0;
- for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
- if(mapvote_maps[i] != "")
- mask |= power;
- return mask;
-}
-
-entity mapvote_ent;
-float MapVote_SendEntity(entity to, float sf)
-{
- float i;
-
- if(sf & 1)
- sf &= ~2; // if we send 1, we don't need to also send 2
-
- WriteByte(MSG_ENTITY, ENT_CLIENT_MAPVOTE);
- WriteByte(MSG_ENTITY, sf);
-
- if(sf & 1)
- {
- // flag 1 == initialization
- for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
- WriteString(MSG_ENTITY, mapvote_screenshot_dirs[i]);
- WriteString(MSG_ENTITY, "");
- WriteByte(MSG_ENTITY, mapvote_count);
- WriteByte(MSG_ENTITY, mapvote_abstain);
- WriteByte(MSG_ENTITY, mapvote_detail);
- WriteCoord(MSG_ENTITY, mapvote_timeout);
- if(mapvote_count <= 8)
- WriteByte(MSG_ENTITY, MapVote_GetMapMask());
- else
- WriteShort(MSG_ENTITY, MapVote_GetMapMask());
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- {
- if(mapvote_abstain && i == mapvote_count - 1)
- {
- WriteString(MSG_ENTITY, ""); // abstain needs no text
- WriteString(MSG_ENTITY, ""); // abstain needs no pack
- WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir
- }
- else
- {
- WriteString(MSG_ENTITY, mapvote_maps[i]);
- WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]);
- WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]);
- }
- }
- }
-
- if(sf & 2)
- {
- // flag 2 == update of mask
- if(mapvote_count <= 8)
- WriteByte(MSG_ENTITY, MapVote_GetMapMask());
- else
- WriteShort(MSG_ENTITY, MapVote_GetMapMask());
- }
-
- if(sf & 4)
- {
- if(mapvote_detail)
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- WriteByte(MSG_ENTITY, mapvote_selections[i]);
-
- WriteByte(MSG_ENTITY, to.mapvote);
- }
-
- return TRUE;
-}
-
-void MapVote_Spawn()
-{
- Net_LinkEntity(mapvote_ent = spawn(), FALSE, 0, MapVote_SendEntity);
-}
-
-void MapVote_TouchMask()
-{
- mapvote_ent.SendFlags |= 2;
-}
-
-void MapVote_TouchVotes(entity voter)
-{
- mapvote_ent.SendFlags |= 4;
-}
-
-float MapVote_Finished(float mappos)
-{
- string result;
- float i;
- float didntvote;
-
- if(autocvar_sv_eventlog)
- {
- result = strcat(":vote:finished:", mapvote_maps[mappos]);
- result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::");
- didntvote = mapvote_voters;
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- {
- didntvote -= mapvote_selections[i];
- if(i != mappos)
- {
- result = strcat(result, ":", mapvote_maps[i]);
- result = strcat(result, ":", ftos(mapvote_selections[i]));
- }
- }
- result = strcat(result, ":didn't vote:", ftos(didntvote));
-
- GameLogEcho(result);
- if(mapvote_maps_suggested[mappos])
- GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]));
- }
-
- FOR_EACH_REALCLIENT(other)
- FixClientCvars(other);
-
- Map_Goto_SetStr(mapvote_maps[mappos]);
- Map_Goto(0);
- alreadychangedlevel = TRUE;
- return TRUE;
-}
-void MapVote_CheckRules_1()
-{
- float i;
-
- for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "")
- {
- //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
- mapvote_selections[i] = 0;
- }
-
- mapvote_voters = 0;
- FOR_EACH_REALCLIENT(other)
- {
- ++mapvote_voters;
- if(other.mapvote)
- {
- i = other.mapvote - 1;
- //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n");
- mapvote_selections[i] = mapvote_selections[i] + 1;
- }
- }
-}
-
-float MapVote_CheckRules_2()
-{
- float i;
- float firstPlace, secondPlace;
- float firstPlaceVotes, secondPlaceVotes;
- float mapvote_voters_real;
- string result;
-
- if(mapvote_count_real == 1)
- return MapVote_Finished(0);
-
- mapvote_voters_real = mapvote_voters;
- if(mapvote_abstain)
- mapvote_voters_real -= mapvote_selections[mapvote_count - 1];
-
- RandomSelection_Init();
- for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
- RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
- firstPlace = RandomSelection_chosen_float;
- firstPlaceVotes = RandomSelection_best_priority;
- //dprint("First place: ", ftos(firstPlace), "\n");
- //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
-
- RandomSelection_Init();
- for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
- if(i != firstPlace)
- RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
- secondPlace = RandomSelection_chosen_float;
- secondPlaceVotes = RandomSelection_best_priority;
- //dprint("Second place: ", ftos(secondPlace), "\n");
- //dprint("Second place votes: ", ftos(secondPlaceVotes), "\n");
-
- if(firstPlace == -1)
- error("No first place in map vote... WTF?");
-
- if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes)
- return MapVote_Finished(firstPlace);
-
- if(mapvote_keeptwotime)
- if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
- {
- float didntvote;
- MapVote_TouchMask();
- mapvote_message = "Now decide between the TOP TWO!";
- mapvote_keeptwotime = 0;
- result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]);
- result = strcat(result, ":", ftos(firstPlaceVotes));
- result = strcat(result, ":", mapvote_maps[secondPlace]);
- result = strcat(result, ":", ftos(secondPlaceVotes), "::");
- didntvote = mapvote_voters;
- for(i = 0; i < mapvote_count; ++i)
- if(mapvote_maps[i] != "")
- {
- didntvote -= mapvote_selections[i];
- if(i != firstPlace)
- if(i != secondPlace)
- {
- result = strcat(result, ":", mapvote_maps[i]);
- result = strcat(result, ":", ftos(mapvote_selections[i]));
- if(i < mapvote_count_real)
- {
- strunzone(mapvote_maps[i]);
- mapvote_maps[i] = "";
- strunzone(mapvote_maps_pakfile[i]);
- mapvote_maps_pakfile[i] = "";
- }
- }
- }
- result = strcat(result, ":didn't vote:", ftos(didntvote));
- if(autocvar_sv_eventlog)
- GameLogEcho(result);
- }
-
- return FALSE;
-}
-void MapVote_Tick()
-{
- float keeptwo;
- float totalvotes;
-
- keeptwo = mapvote_keeptwotime;
- MapVote_CheckRules_1(); // count
- if(MapVote_CheckRules_2()) // decide
- return;
-
- totalvotes = 0;
- FOR_EACH_REALCLIENT(other)
- {
- // hide scoreboard again
- if(other.health != 2342)
- {
- other.health = 2342;
- other.impulse = 0;
- if(IS_REAL_CLIENT(other))
- {
- msg_entity = other;
- WriteByte(MSG_ONE, SVC_FINALE);
- WriteString(MSG_ONE, "");
- }
- }
-
- // clear possibly invalid votes
- if(mapvote_maps[other.mapvote - 1] == "")
- other.mapvote = 0;
- // use impulses as new vote
- if(other.impulse >= 1 && other.impulse <= mapvote_count)
- if(mapvote_maps[other.impulse - 1] != "")
- {
- other.mapvote = other.impulse;
- MapVote_TouchVotes(other);
- }
- other.impulse = 0;
-
- if(other.mapvote)
- ++totalvotes;
- }
-
- MapVote_CheckRules_1(); // just count
-}
-void MapVote_Start()
-{
- if(mapvote_run)
- return;
-
- // wait for stats to be sent first
- if(!playerstats_waitforme)
- return;
-
- MapInfo_Enumerate();
- if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
- mapvote_run = TRUE;
-}
-void MapVote_Think()
-{
- if(!mapvote_run)
- return;
-
- if(alreadychangedlevel)
- return;
-
- if(time < mapvote_nextthink)
- return;
- //dprint("tick\n");
-
- mapvote_nextthink = time + 0.5;
-
- if(!mapvote_initialized)
- {
- if(autocvar_rescan_pending == 1)
- {
- cvar_set("rescan_pending", "2");
- localcmd("fs_rescan\nrescan_pending 3\n");
- return;
- }
- else if(autocvar_rescan_pending == 2)
- {
- return;
- }
- else if(autocvar_rescan_pending == 3)
- {
- // now build missing mapinfo files
- if(!MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
- return;
-
- // we're done, start the timer
- cvar_set("rescan_pending", "0");
- }
-
- mapvote_initialized = TRUE;
- if(DoNextMapOverride(0))
- return;
- if(!autocvar_g_maplist_votable || player_count <= 0)
- {
- GotoNextMap(0);
- return;
- }
- MapVote_Init();
- }
-
- MapVote_Tick();
-}
-
-string GotoMap(string m)
-{
- if(!MapInfo_CheckMap(m))
- return "The map you chose is not available on this server.";
cvar_set("nextmap", m);
cvar_set("timelimit", "-1");
if(mapvote_initialized || alreadychangedlevel)
float altime;
FOR_EACH_REALCLIENT(self)
{
+ self.damage_dealt_total = 0;
+
if(IS_SPEC(self))
{
if(self.enemy.typehitsound)
self.typehit_time = time;
- else if(self.enemy.hitsound)
- self.hit_time = time;
+ else if(self.enemy.damage_dealt)
+ self.damage_dealt_total = ceil(self.enemy.damage_dealt);
}
else
{
if(self.typehitsound)
self.typehit_time = time;
- else if(self.hitsound)
- self.hit_time = time;
+ else if(self.damage_dealt)
+ self.damage_dealt_total = ceil(self.damage_dealt);
}
}
altime = time + frametime * (1 + autocvar_g_antilag_nudge);
// needed!
FOR_EACH_CLIENT(self)
{
- self.hitsound = FALSE;
self.typehitsound = FALSE;
+ self.damage_dealt = 0;
antilag_record(self, altime);
}
+ FOR_EACH_MONSTER(self)
+ antilag_record(self, altime);
}
--- /dev/null
+float GameTypeVote_AvailabilityStatus(string gtname)
+{
+ float type = MapInfo_Type_FromString(gtname);
+ if( type == 0 )
+ return GTV_FORBIDDEN;
+
+ if ( autocvar_nextmap != "" )
+ {
+ if ( !MapInfo_Get_ByName(autocvar_nextmap, FALSE, 0) )
+ return GTV_FORBIDDEN;
+ if (!(MapInfo_Map_supportedGametypes & type))
+ return GTV_FORBIDDEN;
+ }
+
+ return GTV_AVAILABLE;
+}
+
+float GameTypeVote_GetMask()
+{
+ float n, j, gametype_mask;
+ n = tokenizebyseparator(autocvar_sv_vote_gametype_options, " ");
+ n = min(MAPVOTE_COUNT, n);
+ gametype_mask = 0;
+ for(j = 0; j < n; ++j)
+ gametype_mask |= MapInfo_Type_FromString(argv(j));
+ return gametype_mask;
+}
+
+string GameTypeVote_MapInfo_FixName(string m)
+{
+ if ( autocvar_sv_vote_gametype )
+ {
+ MapInfo_Enumerate();
+ MapInfo_FilterGametype(GameTypeVote_GetMask(), 0, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+ }
+ return MapInfo_FixName(m);
+}
+
+void MapVote_ClearAllVotes()
+{
+ FOR_EACH_CLIENT(other)
+ other.mapvote = 0;
+}
+
+void MapVote_UnzoneStrings()
+{
+ float j;
+ for(j = 0; j < mapvote_count; ++j)
+ {
+ if ( mapvote_maps[j] )
+ {
+ strunzone(mapvote_maps[j]);
+ mapvote_maps[j] = string_null;
+ }
+ if ( mapvote_maps_pakfile[j] )
+ {
+ strunzone(mapvote_maps_pakfile[j]);
+ mapvote_maps_pakfile[j] = string_null;
+ }
+ }
+}
+
+string MapVote_Suggest(string m)
+{
+ float i;
+ if(m == "")
+ return "That's not how to use this command.";
+ if(!autocvar_g_maplist_votable_suggestions)
+ return "Suggestions are not accepted on this server.";
+ if(mapvote_initialized)
+ if(!gametypevote)
+ return "Can't suggest - voting is already in progress!";
+ m = GameTypeVote_MapInfo_FixName(m);
+ if (!m)
+ return "The map you suggested is not available on this server.";
+ if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
+ if(Map_IsRecent(m))
+ return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
+
+ if (!autocvar_sv_vote_gametype)
+ if(!MapInfo_CheckMap(m))
+ return "The map you suggested does not support the current game mode.";
+ for(i = 0; i < mapvote_suggestion_ptr; ++i)
+ if(mapvote_suggestions[i] == m)
+ return "This map was already suggested.";
+ if(mapvote_suggestion_ptr >= MAPVOTE_COUNT)
+ {
+ i = floor(random() * mapvote_suggestion_ptr);
+ }
+ else
+ {
+ i = mapvote_suggestion_ptr;
+ mapvote_suggestion_ptr += 1;
+ }
+ if(mapvote_suggestions[i] != "")
+ strunzone(mapvote_suggestions[i]);
+ mapvote_suggestions[i] = strzone(m);
+ if(autocvar_sv_eventlog)
+ GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid)));
+ return strcat("Suggestion of ", m, " accepted.");
+}
+
+void MapVote_AddVotable(string nextMap, float isSuggestion)
+{
+ float j, i, o;
+ string pakfile, mapfile;
+
+ if(nextMap == "")
+ return;
+ for(j = 0; j < mapvote_count; ++j)
+ if(mapvote_maps[j] == nextMap)
+ return;
+ // suggestions might be no longer valid/allowed after gametype switch!
+ if(isSuggestion)
+ if(!MapInfo_CheckMap(nextMap))
+ return;
+ mapvote_maps[mapvote_count] = strzone(nextMap);
+ mapvote_maps_suggested[mapvote_count] = isSuggestion;
+
+ pakfile = string_null;
+ for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
+ {
+ mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);
+ pakfile = whichpack(strcat(mapfile, ".tga"));
+ if(pakfile == "")
+ pakfile = whichpack(strcat(mapfile, ".jpg"));
+ if(pakfile == "")
+ pakfile = whichpack(strcat(mapfile, ".png"));
+ if(pakfile != "")
+ break;
+ }
+ if(i >= mapvote_screenshot_dirs_count)
+ i = 0; // FIXME maybe network this error case, as that means there is no mapshot on the server?
+ for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1)
+ pakfile = substring(pakfile, o, -1);
+
+ mapvote_maps_screenshot_dir[mapvote_count] = i;
+ mapvote_maps_pakfile[mapvote_count] = strzone(pakfile);
+ mapvote_maps_availability[mapvote_count] = GTV_AVAILABLE;
+
+ mapvote_count += 1;
+}
+
+void MapVote_Init()
+{
+ float i;
+ float nmax, smax;
+
+ MapVote_ClearAllVotes();
+ MapVote_UnzoneStrings();
+
+ mapvote_count = 0;
+ mapvote_detail = !autocvar_g_maplist_votable_nodetail;
+ mapvote_abstain = autocvar_g_maplist_votable_abstain;
+
+ if(mapvote_abstain)
+ nmax = min(MAPVOTE_COUNT - 1, autocvar_g_maplist_votable);
+ else
+ nmax = min(MAPVOTE_COUNT, autocvar_g_maplist_votable);
+ smax = min3(nmax, autocvar_g_maplist_votable_suggestions, mapvote_suggestion_ptr);
+
+ // we need this for AddVotable, as that cycles through the screenshot dirs
+ mapvote_screenshot_dirs_count = tokenize_console(autocvar_g_maplist_votable_screenshot_dir);
+ if(mapvote_screenshot_dirs_count == 0)
+ mapvote_screenshot_dirs_count = tokenize_console("maps levelshots");
+ mapvote_screenshot_dirs_count = min(mapvote_screenshot_dirs_count, MAPVOTE_SCREENSHOT_DIRS_COUNT);
+ for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
+ mapvote_screenshot_dirs[i] = strzone(argv(i));
+
+ if(mapvote_suggestion_ptr)
+ for(i = 0; i < 100 && mapvote_count < smax; ++i)
+ MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], TRUE);
+
+ for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+ MapVote_AddVotable(GetNextMap(), FALSE);
+
+ if(mapvote_count == 0)
+ {
+ bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" );
+ cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_CurrentGametype(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
+ if(autocvar_g_maplist_shuffle)
+ ShuffleMaplist();
+ localcmd("\nmenu_cmd sync\n");
+ for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+ MapVote_AddVotable(GetNextMap(), FALSE);
+ }
+
+ mapvote_count_real = mapvote_count;
+ if(mapvote_abstain)
+ MapVote_AddVotable("don't care", 0);
+
+ //dprint("mapvote count is ", ftos(mapvote_count), "\n");
+
+ mapvote_keeptwotime = time + autocvar_g_maplist_votable_keeptwotime;
+ mapvote_timeout = time + autocvar_g_maplist_votable_timeout;
+ if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
+ mapvote_keeptwotime = 0;
+ mapvote_message = "Choose a map and press its key!";
+
+ MapVote_Spawn();
+}
+
+void MapVote_SendPicture(float id)
+{
+ msg_entity = self;
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_PICTURE);
+ WriteByte(MSG_ONE, id);
+ WritePicture(MSG_ONE, strcat(mapvote_screenshot_dirs[mapvote_maps_screenshot_dir[id]], "/", mapvote_maps[id]), 3072);
+}
+
+
+void MapVote_WriteMask()
+{
+ float i;
+ if ( mapvote_count < 24 )
+ {
+ float mask,power;
+ mask = 0;
+ for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
+ if(mapvote_maps_availability[i] == GTV_AVAILABLE )
+ mask |= power;
+
+ if(mapvote_count < 8)
+ WriteByte(MSG_ENTITY, mask);
+ else if (mapvote_count < 16)
+ WriteShort(MSG_ENTITY,mask);
+ else
+ WriteLong(MSG_ENTITY, mask);
+ }
+ else
+ {
+ for ( i = 0; i < mapvote_count; ++i )
+ WriteByte(MSG_ENTITY, mapvote_maps_availability[i]);
+ }
+}
+
+float MapVote_SendEntity(entity to, float sf)
+{
+ float i;
+
+ if(sf & 1)
+ sf &= ~2; // if we send 1, we don't need to also send 2
+
+ WriteByte(MSG_ENTITY, ENT_CLIENT_MAPVOTE);
+ WriteByte(MSG_ENTITY, sf);
+
+ if(sf & 1)
+ {
+ // flag 1 == initialization
+ for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
+ WriteString(MSG_ENTITY, mapvote_screenshot_dirs[i]);
+ WriteString(MSG_ENTITY, "");
+ WriteByte(MSG_ENTITY, mapvote_count);
+ WriteByte(MSG_ENTITY, mapvote_abstain);
+ WriteByte(MSG_ENTITY, mapvote_detail);
+ WriteCoord(MSG_ENTITY, mapvote_timeout);
+
+ if ( gametypevote )
+ {
+ // gametype vote
+ WriteByte(MSG_ENTITY, 1);
+ WriteString(MSG_ENTITY, autocvar_nextmap);
+ }
+ else if ( autocvar_sv_vote_gametype )
+ {
+ // map vote but gametype has been chosen via voting screen
+ WriteByte(MSG_ENTITY, 2);
+ WriteString(MSG_ENTITY, MapInfo_Type_ToText(MapInfo_CurrentGametype()));
+ }
+ else
+ WriteByte(MSG_ENTITY, 0); // map vote
+
+ MapVote_WriteMask();
+
+ for(i = 0; i < mapvote_count; ++i)
+ {
+ if(mapvote_abstain && i == mapvote_count - 1)
+ {
+ WriteString(MSG_ENTITY, ""); // abstain needs no text
+ WriteString(MSG_ENTITY, ""); // abstain needs no pack
+ WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir
+ WriteByte(MSG_ENTITY, GTV_AVAILABLE);
+ }
+ else
+ {
+ WriteString(MSG_ENTITY, mapvote_maps[i]);
+ WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]);
+ WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]);
+ WriteByte(MSG_ENTITY, mapvote_maps_availability[i]);
+ }
+ }
+ }
+
+ if(sf & 2)
+ {
+ // flag 2 == update of mask
+ MapVote_WriteMask();
+ }
+
+ if(sf & 4)
+ {
+ if(mapvote_detail)
+ for(i = 0; i < mapvote_count; ++i)
+ if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+ WriteByte(MSG_ENTITY, mapvote_selections[i]);
+
+ WriteByte(MSG_ENTITY, to.mapvote);
+ }
+
+ return TRUE;
+}
+
+void MapVote_Spawn()
+{
+ Net_LinkEntity(mapvote_ent = spawn(), FALSE, 0, MapVote_SendEntity);
+}
+
+void MapVote_TouchMask()
+{
+ mapvote_ent.SendFlags |= 2;
+}
+
+void MapVote_TouchVotes(entity voter)
+{
+ mapvote_ent.SendFlags |= 4;
+}
+
+float MapVote_Finished(float mappos)
+{
+ if(alreadychangedlevel)
+ return FALSE;
+
+ string result;
+ float i;
+ float didntvote;
+
+ if(autocvar_sv_eventlog)
+ {
+ result = strcat(":vote:finished:", mapvote_maps[mappos]);
+ result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::");
+ didntvote = mapvote_voters;
+ for(i = 0; i < mapvote_count; ++i)
+ if(mapvote_maps_availability[i] == GTV_AVAILABLE )
+ {
+ didntvote -= mapvote_selections[i];
+ if(i != mappos)
+ {
+ result = strcat(result, ":", mapvote_maps[i]);
+ result = strcat(result, ":", ftos(mapvote_selections[i]));
+ }
+ }
+ result = strcat(result, ":didn't vote:", ftos(didntvote));
+
+ GameLogEcho(result);
+ if(mapvote_maps_suggested[mappos])
+ GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]));
+ }
+
+ FOR_EACH_REALCLIENT(other)
+ FixClientCvars(other);
+
+ if(gametypevote)
+ {
+ if ( GameTypeVote_Finished(mappos) )
+ {
+ gametypevote = FALSE;
+ if(autocvar_nextmap != "")
+ {
+ Map_Goto_SetStr(autocvar_nextmap);
+ Map_Goto(0);
+ alreadychangedlevel = TRUE;
+ return TRUE;
+ }
+ else
+ MapVote_Init();
+ }
+ return FALSE;
+ }
+
+ Map_Goto_SetStr(mapvote_maps[mappos]);
+ Map_Goto(0);
+ alreadychangedlevel = TRUE;
+
+ return TRUE;
+}
+
+void MapVote_CheckRules_1()
+{
+ float i;
+
+ for(i = 0; i < mapvote_count; ++i)
+ if( mapvote_maps_availability[i] == GTV_AVAILABLE )
+ {
+ //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
+ mapvote_selections[i] = 0;
+ }
+
+ mapvote_voters = 0;
+ FOR_EACH_REALCLIENT(other)
+ {
+ ++mapvote_voters;
+ if(other.mapvote)
+ {
+ i = other.mapvote - 1;
+ //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n");
+ mapvote_selections[i] = mapvote_selections[i] + 1;
+ }
+ }
+}
+
+float MapVote_CheckRules_2()
+{
+ float i;
+ float firstPlace, secondPlace, currentPlace;
+ float firstPlaceVotes, secondPlaceVotes, currentVotes;
+ float mapvote_voters_real;
+ string result;
+
+ if(mapvote_count_real == 1)
+ return MapVote_Finished(0);
+
+ mapvote_voters_real = mapvote_voters;
+ if(mapvote_abstain)
+ mapvote_voters_real -= mapvote_selections[mapvote_count - 1];
+
+ RandomSelection_Init();
+ currentPlace = 0;
+ currentVotes = -1;
+ for(i = 0; i < mapvote_count_real; ++i)
+ if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+ {
+ RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
+ if ( gametypevote && mapvote_maps[i] == MapInfo_Type_ToString(MapInfo_CurrentGametype()) )
+ {
+ currentVotes = mapvote_selections[i];
+ currentPlace = i;
+ }
+ }
+ firstPlaceVotes = RandomSelection_best_priority;
+ if ( autocvar_sv_vote_gametype_default_current && currentVotes == firstPlaceVotes )
+ firstPlace = currentPlace;
+ else
+ firstPlace = RandomSelection_chosen_float;
+
+ //dprint("First place: ", ftos(firstPlace), "\n");
+ //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
+
+ RandomSelection_Init();
+ for(i = 0; i < mapvote_count_real; ++i)
+ if(i != firstPlace)
+ if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+ RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
+ secondPlace = RandomSelection_chosen_float;
+ secondPlaceVotes = RandomSelection_best_priority;
+ //dprint("Second place: ", ftos(secondPlace), "\n");
+ //dprint("Second place votes: ", ftos(secondPlaceVotes), "\n");
+
+ if(firstPlace == -1)
+ error("No first place in map vote... WTF?");
+
+ if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes)
+ return MapVote_Finished(firstPlace);
+
+ if(mapvote_keeptwotime)
+ if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
+ {
+ float didntvote;
+ MapVote_TouchMask();
+ mapvote_message = "Now decide between the TOP TWO!";
+ mapvote_keeptwotime = 0;
+ result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]);
+ result = strcat(result, ":", ftos(firstPlaceVotes));
+ result = strcat(result, ":", mapvote_maps[secondPlace]);
+ result = strcat(result, ":", ftos(secondPlaceVotes), "::");
+ didntvote = mapvote_voters;
+ for(i = 0; i < mapvote_count; ++i)
+ {
+ didntvote -= mapvote_selections[i];
+ if(i != firstPlace)
+ if(i != secondPlace)
+ {
+ result = strcat(result, ":", mapvote_maps[i]);
+ result = strcat(result, ":", ftos(mapvote_selections[i]));
+ if(i < mapvote_count_real)
+ {
+ mapvote_maps_availability[i] = GTV_FORBIDDEN;
+ }
+ }
+ }
+ result = strcat(result, ":didn't vote:", ftos(didntvote));
+ if(autocvar_sv_eventlog)
+ GameLogEcho(result);
+ }
+
+ return FALSE;
+}
+
+void MapVote_Tick()
+{
+ float keeptwo;
+ float totalvotes;
+
+ keeptwo = mapvote_keeptwotime;
+ MapVote_CheckRules_1(); // count
+ if(MapVote_CheckRules_2()) // decide
+ return;
+
+ totalvotes = 0;
+ FOR_EACH_REALCLIENT(other)
+ {
+ // hide scoreboard again
+ if(other.health != 2342)
+ {
+ other.health = 2342;
+ other.impulse = 0;
+ if(IS_REAL_CLIENT(other))
+ {
+ msg_entity = other;
+ WriteByte(MSG_ONE, SVC_FINALE);
+ WriteString(MSG_ONE, "");
+ }
+ }
+
+ // clear possibly invalid votes
+ if ( mapvote_maps_availability[other.mapvote-1] != GTV_AVAILABLE )
+ other.mapvote = 0;
+ // use impulses as new vote
+ if(other.impulse >= 1 && other.impulse <= mapvote_count)
+ if( mapvote_maps_availability[other.impulse - 1] == GTV_AVAILABLE )
+ {
+ other.mapvote = other.impulse;
+ MapVote_TouchVotes(other);
+ }
+ other.impulse = 0;
+
+ if(other.mapvote)
+ ++totalvotes;
+ }
+
+ MapVote_CheckRules_1(); // just count
+}
+
+void MapVote_Start()
+{
+ if(mapvote_run)
+ return;
+
+ // wait for stats to be sent first
+ if(!playerstats_waitforme)
+ return;
+
+ MapInfo_Enumerate();
+ if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
+ mapvote_run = TRUE;
+}
+
+void MapVote_Think()
+{
+ if(!mapvote_run)
+ return;
+
+ if(alreadychangedlevel)
+ return;
+
+ if(time < mapvote_nextthink)
+ return;
+ //dprint("tick\n");
+
+ mapvote_nextthink = time + 0.5;
+
+ if(!mapvote_initialized)
+ {
+ if(autocvar_rescan_pending == 1)
+ {
+ cvar_set("rescan_pending", "2");
+ localcmd("fs_rescan\nrescan_pending 3\n");
+ return;
+ }
+ else if(autocvar_rescan_pending == 2)
+ {
+ return;
+ }
+ else if(autocvar_rescan_pending == 3)
+ {
+ // now build missing mapinfo files
+ if(!MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
+ return;
+
+ // we're done, start the timer
+ cvar_set("rescan_pending", "0");
+ }
+
+ mapvote_initialized = TRUE;
+ if(DoNextMapOverride(0))
+ return;
+ if(!autocvar_g_maplist_votable || player_count <= 0)
+ {
+ GotoNextMap(0);
+ return;
+ }
+
+ if(autocvar_sv_vote_gametype) { GameTypeVote_Start(); }
+ else if(autocvar_nextmap == "") { MapVote_Init(); }
+ }
+
+ MapVote_Tick();
+}
+
+float GameTypeVote_SetGametype(float type)
+{
+ if (MapInfo_CurrentGametype() == type)
+ return TRUE;
+
+ float tsave = MapInfo_CurrentGametype();
+
+ MapInfo_SwitchGameType(type);
+
+ MapInfo_Enumerate();
+ MapInfo_FilterGametype(type, MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+ if(MapInfo_count > 0)
+ {
+ // update lsmaps in case the gametype changed, this way people can easily list maps for it
+ if(lsmaps_reply != "") { strunzone(lsmaps_reply); }
+ lsmaps_reply = strzone(getlsmaps());
+ bprint("Game type successfully switched to ", MapInfo_Type_ToString(type), "\n");
+ }
+ else
+ {
+ bprint("Cannot use this game type: no map for it found\n");
+ MapInfo_SwitchGameType(tsave);
+ MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+ return FALSE;
+ }
+
+ //localcmd("gametype ", MapInfo_Type_ToString(type), "\n");
+
+ cvar_set("g_maplist", MapInfo_ListAllowedMaps(type, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()) );
+ if(autocvar_g_maplist_shuffle)
+ ShuffleMaplist();
+
+ return TRUE;
+}
+
+float gametypevote_finished;
+float GameTypeVote_Finished(float pos)
+{
+ if(!gametypevote || gametypevote_finished)
+ return FALSE;
+
+ if ( !GameTypeVote_SetGametype(MapInfo_Type_FromString(mapvote_maps[pos])) )
+ {
+ dprint("Selected gametype is not supported by any map");
+ }
+
+ localcmd("sv_vote_gametype_hook_all\n");
+ localcmd("sv_vote_gametype_hook_", mapvote_maps[pos], "\n");
+
+ gametypevote_finished = TRUE;
+
+ return TRUE;
+}
+
+float GameTypeVote_AddVotable(string nextMode)
+{
+ float j;
+ if ( nextMode == "" || MapInfo_Type_FromString(nextMode) == 0 )
+ return FALSE;
+ for(j = 0; j < mapvote_count; ++j)
+ if(mapvote_maps[j] == nextMode)
+ return FALSE;
+
+ mapvote_maps[mapvote_count] = strzone(nextMode);
+ mapvote_maps_suggested[mapvote_count] = FALSE;
+
+ mapvote_maps_screenshot_dir[mapvote_count] = 0;
+ mapvote_maps_pakfile[mapvote_count] = strzone("");
+ mapvote_maps_availability[mapvote_count] = GameTypeVote_AvailabilityStatus(nextMode);
+
+ mapvote_count += 1;
+
+ return TRUE;
+
+}
+
+float GameTypeVote_Start()
+{
+ float j;
+ MapVote_ClearAllVotes();
+ MapVote_UnzoneStrings();
+
+ mapvote_count = 0;
+ mapvote_timeout = time + autocvar_sv_vote_gametype_timeout;
+ mapvote_abstain = 0;
+ mapvote_detail = !autocvar_g_maplist_votable_nodetail;
+
+ float n = tokenizebyseparator(autocvar_sv_vote_gametype_options, " ");
+ n = min(MAPVOTE_COUNT, n);
+
+ float really_available, which_available;
+ really_available = 0;
+ which_available = -1;
+ for(j = 0; j < n; ++j)
+ {
+ if ( GameTypeVote_AddVotable(argv(j)) )
+ if ( mapvote_maps_availability[j] == GTV_AVAILABLE )
+ {
+ really_available++;
+ which_available = j;
+ }
+ }
+
+ mapvote_count_real = mapvote_count;
+
+ gametypevote = 1;
+
+ if ( really_available == 0 )
+ {
+ if ( mapvote_count > 0 )
+ strunzone(mapvote_maps[0]);
+ mapvote_maps[0] = strzone(MapInfo_Type_ToString(MapInfo_CurrentGametype()));
+ //GameTypeVote_Finished(0);
+ MapVote_Finished(0);
+ return FALSE;
+ }
+ if ( really_available == 1 )
+ {
+ //GameTypeVote_Finished(which_available);
+ MapVote_Finished(which_available);
+ return FALSE;
+ }
+
+ mapvote_count_real = mapvote_count;
+
+ mapvote_keeptwotime = time + autocvar_sv_vote_gametype_keeptwotime;
+ if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
+ mapvote_keeptwotime = 0;
+
+ MapVote_Spawn();
+
+ return TRUE;
+}
--- /dev/null
+// definitions for functions used outside mapvoting.qc
+void MapVote_Start();
+void MapVote_Spawn();
+void MapVote_Think();
+float GameTypeVote_Start();
+float GameTypeVote_Finished(float pos);
+string GameTypeVote_MapInfo_FixName(string m);
+
+// definitions
+float gametypevote;
+string getmapname_stored;
+float mapvote_initialized;
+
+float mapvote_nextthink;
+float mapvote_initialized;
+float mapvote_keeptwotime;
+float mapvote_timeout;
+string mapvote_message;
+#define MAPVOTE_SCREENSHOT_DIRS_COUNT 4
+string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT];
+float mapvote_screenshot_dirs_count;
+
+float mapvote_count;
+float mapvote_count_real;
+string mapvote_maps[MAPVOTE_COUNT];
+float mapvote_maps_screenshot_dir[MAPVOTE_COUNT];
+string mapvote_maps_pakfile[MAPVOTE_COUNT];
+float mapvote_maps_suggested[MAPVOTE_COUNT];
+string mapvote_suggestions[MAPVOTE_COUNT];
+float mapvote_suggestion_ptr;
+float mapvote_voters;
+float mapvote_selections[MAPVOTE_COUNT];
+float mapvote_maps_availability[MAPVOTE_COUNT];
+float mapvote_run;
+float mapvote_detail;
+float mapvote_abstain;
+.float mapvote;
+
+entity mapvote_ent;
{
// forcibly turn off weaponarena
}
- else if (s == "all")
+ else if (s == "all" || s == "1")
{
g_weaponarena = 1;
g_weaponarena_list = "All Weapons";
float sv_taunt;
string GetGametype(); // g_world.qc
+void mutators_add(); // mutators.qc
void readlevelcvars(void)
{
// load mutators
- #define CHECK_MUTATOR_ADD(mut_cvar,mut_name,dependence) \
- { if(cvar(mut_cvar) && dependence) { MUTATOR_ADD(mut_name); } }
-
- CHECK_MUTATOR_ADD("g_dodging", mutator_dodging, 1);
- CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, teamplay);
- CHECK_MUTATOR_ADD("g_physical_items", mutator_physical_items, 1);
- CHECK_MUTATOR_ADD("g_touchexplode", mutator_touchexplode, 1);
- CHECK_MUTATOR_ADD("g_minstagib", mutator_minstagib, 1);
- CHECK_MUTATOR_ADD("g_invincible_projectiles", mutator_invincibleprojectiles, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_new_toys", mutator_new_toys, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_nix", mutator_nix, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_rocket_flying", mutator_rocketflying, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_vampire", mutator_vampire, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_superspectate", mutator_superspec, 1);
- CHECK_MUTATOR_ADD("g_pinata", mutator_pinata, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_midair", mutator_midair, 1);
- CHECK_MUTATOR_ADD("g_bloodloss", mutator_bloodloss, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_random_gravity", mutator_random_gravity, 1);
- CHECK_MUTATOR_ADD("g_multijump", mutator_multijump, 1);
- CHECK_MUTATOR_ADD("g_melee_only", mutator_melee_only, !cvar("g_minstagib"));
- CHECK_MUTATOR_ADD("g_nades", mutator_nades, 1);
- CHECK_MUTATOR_ADD("g_sandbox", sandbox, 1);
- CHECK_MUTATOR_ADD("g_campcheck", mutator_campcheck, 1);
-
- #undef CHECK_MUTATOR_ADD
+ mutators_add();
if(cvar("sv_allow_fullbright"))
serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
g_bugrigs_steer = cvar("g_bugrigs_steer");
- g_minstagib = cvar("g_minstagib");
+ g_instagib = cvar("g_instagib");
sv_clones = cvar("sv_clones");
sv_foginterval = cvar("sv_foginterval");
g_cloaked = cvar("g_cloaked");
- if(g_cts)
- g_cloaked = 1; // always enable cloak in CTS
g_footsteps = cvar("g_footsteps");
g_grappling_hook = cvar("g_grappling_hook");
g_jetpack = cvar("g_jetpack");
return TRUE;
}
-#ifdef COMPAT_XON010_CHANNELS
-void(entity e, float chan, string samp, float vol, float atten) builtin_sound = #8;
-void sound(entity e, float chan, string samp, float vol, float atten)
-{
- if (!sound_allowed(MSG_BROADCAST, e))
- return;
- builtin_sound(e, chan, samp, vol, atten);
-}
-#else
#undef sound
void sound(entity e, float chan, string samp, float vol, float atten)
{
return;
sound7(e, chan, samp, vol, atten, 0, 0);
}
-#endif
void soundtoat(float dest, entity e, vector o, float chan, string samp, float vol, float atten)
{
{
// gamemode related things
precache_model ("models/misc/chatbubble.spr");
+ precache_model("models/ice/ice.md3");
#ifdef TTURRETS_ENABLED
if (autocvar_g_turrets)
}
}
+
+entity eliminatedPlayers;
+.float(entity) isEliminated;
+float EliminatedPlayers_SendEntity(entity to, float sendflags)
+{
+ float i, f, b;
+ entity e;
+ WriteByte(MSG_ENTITY, ENT_CLIENT_ELIMINATEDPLAYERS);
+ WriteByte(MSG_ENTITY, sendflags);
+
+ if(sendflags & 1)
+ {
+ for(i = 1; i <= maxclients; i += 8)
+ {
+ for(f = 0, e = edict_num(i), b = 1; b < 256; b *= 2, e = nextent(e))
+ {
+ if(eliminatedPlayers.isEliminated(e))
+ f |= b;
+ }
+ WriteByte(MSG_ENTITY, f);
+ }
+ }
+
+ return TRUE;
+}
+
+void EliminatedPlayers_Init(float(entity) isEliminated_func)
+{
+ if(eliminatedPlayers)
+ {
+ backtrace("Can't spawn eliminatedPlayers again!");
+ return;
+ }
+ Net_LinkEntity(eliminatedPlayers = spawn(), FALSE, 0, EliminatedPlayers_SendEntity);
+ eliminatedPlayers.isEliminated = isEliminated_func;
+}
+
+
void adaptor_think2touch()
{
entity o;
return s;
}
-float race_readTime(string map, float pos)
-{
- string rr;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
-
- return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos))));
-}
-
-string race_readUID(string map, float pos)
-{
- string rr;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
-
- return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)));
-}
-
-float race_readPos(string map, float t) {
- float i;
- for (i = 1; i <= RANKINGS_CNT; ++i)
- if (race_readTime(map, i) == 0 || race_readTime(map, i) > t)
- return i;
-
- return 0; // pos is zero if unranked
-}
-
-void race_writeTime(string map, float t, string myuid)
-{
- string rr;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
-
- float newpos;
- newpos = race_readPos(map, t);
-
- float i, prevpos = 0;
- for(i = 1; i <= RANKINGS_CNT; ++i)
- {
- if(race_readUID(map, i) == myuid)
- prevpos = i;
- }
- if (prevpos) { // player improved his existing record, only have to iterate on ranks between new and old recs
- for (i = prevpos; i > newpos; --i) {
- db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
- db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
- }
- } else { // player has no ranked record yet
- for (i = RANKINGS_CNT; i > newpos; --i) {
- db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
- db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
- }
- }
-
- // store new time itself
- db_put(ServerProgsDB, strcat(map, rr, "time", ftos(newpos)), ftos(t));
- db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(newpos)), myuid);
-}
-
-string race_readName(string map, float pos)
-{
- string rr;
- if(g_cts)
- rr = CTS_RECORD;
- else
- rr = RACE_RECORD;
-
- return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
-}
-
float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
{
float m, i;
return r; // callbacks return an error status, so 0 is default return value
}
-#define MAX_MUTATORS 8
+#define MAX_MUTATORS 15
string loaded_mutators[MAX_MUTATORS];
float Mutator_Add(mutatorfunc_t func, string name)
{
// called when a player presses the jump key
// INPUT, OUTPUT:
float player_multijump;
+ float player_jumpheight;
MUTATOR_HOOKABLE(GiveFragsForKill);
// called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill
MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon);
// returns 1 if throwing the current weapon shall not be allowed
+MUTATOR_HOOKABLE(WeaponRateFactor);
+ // allows changing attack rate
+ // INPUT, OUTPUT:
+ float weapon_rate;
+
MUTATOR_HOOKABLE(SetStartItems);
// adjusts {warmup_}start_{items,weapons,ammo_{cells,rockets,nails,shells,fuel}}
MUTATOR_HOOKABLE(PlayerRegen);
// called every player think frame
// return 1 to disable regen
+ // INPUT, OUTPUT:
+ float regen_mod_max;
+ float regen_mod_regen;
+ float regen_mod_rot;
+ float regen_mod_limit;
MUTATOR_HOOKABLE(PlayerUseKey);
// called when the use key is pressed
#define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == ca_teams)
float CA_CheckWinner()
{
+ entity e;
if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
{
Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
allowed_to_spawn = FALSE;
round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
+ FOR_EACH_PLAYER(e)
+ nades_Clear(e);
return 1;
}
allowed_to_spawn = FALSE;
round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
+
+ FOR_EACH_PLAYER(e)
+ nades_Clear(e);
+
return 1;
}
allowed_to_spawn = FALSE;
}
-float prev_total_players;
+float prev_missing_teams_mask;
float CA_CheckTeams()
{
allowed_to_spawn = TRUE;
CA_count_alive_players();
if(CA_ALIVE_TEAMS_OK())
{
- if(prev_total_players > 0)
+ if(prev_missing_teams_mask > 0)
Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
- prev_total_players = -1;
+ prev_missing_teams_mask = -1;
return 1;
}
- if(prev_total_players != total_players)
+ if(total_players == 0)
+ {
+ if(prev_missing_teams_mask > 0)
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+ prev_missing_teams_mask = -1;
+ return 0;
+ }
+ float missing_teams_mask = (!redalive) + (!bluealive) * 2;
+ if(ca_teams >= 3) missing_teams_mask += (!yellowalive) * 4;
+ if(ca_teams >= 4) missing_teams_mask += (!pinkalive) * 8;
+ if(prev_missing_teams_mask != missing_teams_mask)
{
- float p1 = 0, p2 = 0, p3 = 0, p4 = 0;
- if(!redalive) p1 = NUM_TEAM_1;
- if(!bluealive) p2 = NUM_TEAM_2;
- if(ca_teams >= 3)
- if(!yellowalive) p3 = NUM_TEAM_3;
- if(ca_teams >= 4)
- if(!pinkalive) p4 = NUM_TEAM_4;
- Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, p1, p2, p3, p4);
- prev_total_players = total_players;
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+ prev_missing_teams_mask = missing_teams_mask;
}
return 0;
}
+float ca_isEliminated(entity e)
+{
+ if(e.caplayer == 1 && (e.deadflag != DEAD_NO || e.frags == FRAGS_LMS_LOSER))
+ return TRUE;
+ if(e.caplayer == 0.5)
+ return TRUE;
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(ca_PlayerSpawn)
{
self.caplayer = 1;
+ if(!warmup_stage)
+ eliminatedPlayers.SendFlags |= 1;
return 1;
}
MUTATOR_HOOKFUNCTION(ca_PutClientInServer)
{
if(!allowed_to_spawn)
+ if(IS_PLAYER(self)) // this is true even when player is trying to join
{
self.classname = "observer";
if(self.jointime != time) //not when connecting
{
self.caplayer = 0.5;
if(IS_REAL_CLIENT(self))
- sprint(self, "You will join the game in the next round.\n");
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_JOIN_LATE);
}
}
return 1;
FOR_EACH_CLIENT(self)
{
self.killcount = 0;
+ if(!self.caplayer && IS_BOT_CLIENT(self))
+ {
+ self.team = -1;
+ self.caplayer = 1;
+ }
if(self.caplayer)
{
self.classname = "player";
return 0;
}
+entity ca_LastPlayerForTeam()
+{
+ entity pl, last_pl = world;
+ FOR_EACH_PLAYER(pl)
+ {
+ if(pl.health >= 1)
+ if(pl != self)
+ if(pl.team == self.team)
+ if(!last_pl)
+ last_pl = pl;
+ else
+ return world;
+ }
+ return last_pl;
+}
+
+void ca_LastPlayerForTeam_Notify()
+{
+ if(round_handler_IsActive())
+ if(round_handler_IsRoundStarted())
+ {
+ entity pl = ca_LastPlayerForTeam();
+ if(pl)
+ Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
+ }
+}
+
MUTATOR_HOOKFUNCTION(ca_PlayerDies)
{
+ ca_LastPlayerForTeam_Notify();
if(!allowed_to_spawn)
self.respawn_flags = RESPAWN_SILENT;
+ if(!warmup_stage)
+ eliminatedPlayers.SendFlags |= 1;
+ return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca_ClientDisconnect)
+{
+ if(self.caplayer == 1)
+ ca_LastPlayerForTeam_Notify();
return 1;
}
MUTATOR_HOOKFUNCTION(ca_MakePlayerObserver)
{
+ if(self.caplayer == 1)
+ ca_LastPlayerForTeam_Notify();
if(self.killindicator_teamchange == -2)
self.caplayer = 0;
if(self.caplayer)
self.frags = FRAGS_LMS_LOSER;
+ if(!warmup_stage)
+ eliminatedPlayers.SendFlags |= 1;
return 1;
}
addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
+
+ EliminatedPlayers_Init(ca_isEliminated);
}
MUTATOR_DEFINITION(gamemode_ca)
MUTATOR_HOOK(reset_map_players, ca_reset_map_players, CBC_ORDER_ANY);
MUTATOR_HOOK(GetTeamCount, ca_GetTeamCount, CBC_ORDER_EXCLUSIVE);
MUTATOR_HOOK(PlayerDies, ca_PlayerDies, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ClientDisconnect, ca_ClientDisconnect, CBC_ORDER_ANY);
MUTATOR_HOOK(ForbidPlayerScore_Clear, ca_ForbidPlayerScore_Clear, CBC_ORDER_ANY);
MUTATOR_HOOK(ForbidThrowCurrentWeapon, ca_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
MUTATOR_HOOK(GiveFragsForKill, ca_GiveFragsForKill, CBC_ORDER_FIRST);
vector othermid = (other.absmin + other.absmax) * 0.5;
Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
- Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED);
+ if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
}
void ctf_CaptureShield_Spawn(entity flag)
flag.owner.flagcarried = flag;
// reset flag
- setattachment(flag, player, "");
- setorigin(flag, FLAG_CARRY_OFFSET);
+ if(player.vehicle)
+ {
+ setattachment(flag, player.vehicle, "");
+ setorigin(flag, VEHICLE_FLAG_OFFSET);
+ flag.scale = VEHICLE_FLAG_SCALE;
+ }
+ else
+ {
+ setattachment(flag, player, "");
+ setorigin(flag, FLAG_CARRY_OFFSET);
+ }
flag.movetype = MOVETYPE_NONE;
flag.takedamage = DAMAGE_NO;
flag.solid = SOLID_NOT;
if (!player) { return; } // without someone to give the reward to, we can't possibly cap
+ nades_GiveBonus(player, autocvar_g_nades_bonus_score_high );
+
// messages and sounds
Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(enemy_flag, CENTER_CTF_CAPTURE_));
ctf_CaptureRecord(enemy_flag, player);
{
PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_return); // reward for return
PlayerScore_Add(player, SP_CTF_RETURNS, 1); // add to count of returns
+
+ nades_GiveBonus(player,autocvar_g_nades_bonus_score_medium);
}
TeamScore_AddToTeam(flag.team, ST_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the team who was last carrying it
// attach the flag to the player
flag.owner = player;
player.flagcarried = flag;
- setattachment(flag, player, "");
- setorigin(flag, FLAG_CARRY_OFFSET);
+ if(player.vehicle)
+ {
+ setattachment(flag, player.vehicle, "");
+ setorigin(flag, VEHICLE_FLAG_OFFSET);
+ flag.scale = VEHICLE_FLAG_SCALE;
+ }
+ else
+ {
+ setattachment(flag, player, "");
+ setorigin(flag, FLAG_CARRY_OFFSET);
+ }
// flag setup
flag.movetype = MOVETYPE_NONE;
// scoring
PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
+ nades_GiveBonus(player, autocvar_g_nades_bonus_score_minor);
switch(pickuptype)
{
case PICKUP_BASE:
if((self.pass_target == world)
|| (self.pass_target.deadflag != DEAD_NO)
+ || (self.pass_target.flagcarried)
|| (vlen(self.origin - targ_origin) > autocvar_g_ctf_pass_radius)
|| ((trace_fraction < 1) && (trace_ent != self.pass_target))
|| (time > self.ctf_droptime + autocvar_g_ctf_pass_timelimit))
void ctf_FlagTouch()
{
if(gameover) { return; }
+ if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
entity toucher = other;
float is_not_monster = (!(toucher.flags & FL_MONSTER));
}
// special touch behaviors
- if(toucher.vehicle_flags & VHF_ISVEHICLE)
+ if(toucher.frozen) { return; }
+ else if(toucher.vehicle_flags & VHF_ISVEHICLE)
{
if(autocvar_g_ctf_allow_vehicle_touch && toucher.owner)
toucher = toucher.owner; // the player is actually the vehicle owner, not other
ctf_FakeTimeLimit(flag.owner, -1);
}
+ if((flag.owner) && (flag.owner.vehicle))
+ flag.scale = FLAG_SCALE;
+
if((flag.ctf_status == FLAG_DROPPED) && (flag.wps_flagdropped))
{ WaypointSprite_Kill(flag.wps_flagdropped); }
flag.ctf_dropper = world;
flag.ctf_pickuptime = 0;
flag.ctf_droptime = 0;
+
+ ctf_CheckStalemate();
}
void ctf_Reset()
// if there is only me on the team switch to offense
c = 0;
FOR_EACH_PLAYER(head)
- if(head.team==bot.team)
+ if(SAME_TEAM(head, bot))
++c;
if(c==1)
}
if(closestplayer)
- if(closestplayer.team!=self.team)
+ if(DIFF_TEAM(closestplayer, self))
if(vlen(org - self.origin)>1000)
if(checkpvs(self.origin,closestplayer)||random()<0.5)
havocbot_goalrating_ctf_ourbase(30000);
--- /dev/null
+// legacy bot roles
+.float race_checkpoint;
+void havocbot_role_cts()
+{
+ if(self.deadflag != DEAD_NO)
+ return;
+
+ entity e;
+ if (self.bot_strategytime < time)
+ {
+ self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start();
+
+ for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
+ {
+ if(e.cnt == self.race_checkpoint)
+ {
+ navigation_routerating(e, 1000000, 5000);
+ }
+ else if(self.race_checkpoint == -1)
+ {
+ navigation_routerating(e, 1000000, 5000);
+ }
+ }
+
+ navigation_goalrating_end();
+ }
+}
+
+void cts_ScoreRules()
+{
+ ScoreRules_basics(0, 0, 0, FALSE);
+ if(g_race_qualifying)
+ {
+ ScoreInfo_SetLabel_PlayerScore(SP_CTS_FASTEST, "fastest", SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+ }
+ else
+ {
+ ScoreInfo_SetLabel_PlayerScore(SP_CTS_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTS_TIME, "time", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+ ScoreInfo_SetLabel_PlayerScore(SP_CTS_FASTEST, "fastest", SFL_LOWER_IS_BETTER | SFL_TIME);
+ }
+ ScoreRules_basics_end();
+}
+
+void cts_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
+{
+ if(autocvar_sv_eventlog)
+ GameLogEcho(strcat(":cts:", mode, ":", ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerPhysics)
+{
+ // force kbd movement for fairness
+ float wishspeed;
+ vector wishvel;
+
+ // if record times matter
+ // ensure nothing EVIL is being done (i.e. div0_evade)
+ // this hinders joystick users though
+ // but it still gives SOME analog control
+ wishvel_x = fabs(self.movement_x);
+ wishvel_y = fabs(self.movement_y);
+ if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y)
+ {
+ wishvel_z = 0;
+ wishspeed = vlen(wishvel);
+ if(wishvel_x >= 2 * wishvel_y)
+ {
+ // pure X motion
+ if(self.movement_x > 0)
+ self.movement_x = wishspeed;
+ else
+ self.movement_x = -wishspeed;
+ self.movement_y = 0;
+ }
+ else if(wishvel_y >= 2 * wishvel_x)
+ {
+ // pure Y motion
+ self.movement_x = 0;
+ if(self.movement_y > 0)
+ self.movement_y = wishspeed;
+ else
+ self.movement_y = -wishspeed;
+ }
+ else
+ {
+ // diagonal
+ if(self.movement_x > 0)
+ self.movement_x = M_SQRT1_2 * wishspeed;
+ else
+ self.movement_x = -M_SQRT1_2 * wishspeed;
+ if(self.movement_y > 0)
+ self.movement_y = M_SQRT1_2 * wishspeed;
+ else
+ self.movement_y = -M_SQRT1_2 * wishspeed;
+ }
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ResetMap)
+{
+ float s;
+
+ Score_NicePrint(world);
+
+ race_ClearRecords();
+ PlayerScore_Sort(race_place, 0, 1, 0);
+
+ entity e;
+ FOR_EACH_CLIENT(e)
+ {
+ if(e.race_place)
+ {
+ s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
+ if(!s)
+ e.race_place = 0;
+ }
+ cts_EventLog(ftos(e.race_place), e);
+ }
+
+ if(g_race_qualifying == 2)
+ {
+ g_race_qualifying = 0;
+ independent_players = 0;
+ cvar_set("fraglimit", ftos(race_fraglimit));
+ cvar_set("leadlimit", ftos(race_leadlimit));
+ cvar_set("timelimit", ftos(race_timelimit));
+ cts_ScoreRules();
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerPreThink)
+{
+ if(IS_SPEC(self) || IS_OBSERVER(self))
+ if(g_race_qualifying)
+ if(msg_entity.enemy.race_laptime)
+ race_SendNextCheckpoint(msg_entity.enemy, 1);
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ClientConnect)
+{
+ race_PreparePlayer();
+ self.race_checkpoint = -1;
+
+ if(IS_REAL_CLIENT(self))
+ {
+ string rr = CTS_RECORD;
+
+ msg_entity = self;
+ race_send_recordtime(MSG_ONE);
+ race_send_speedaward(MSG_ONE);
+
+ speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
+ speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
+ race_send_speedaward_alltimebest(MSG_ONE);
+
+ float i;
+ for (i = 1; i <= RANKINGS_CNT; ++i)
+ {
+ race_SendRankings(i, 0, 0, MSG_ONE);
+ }
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_MakePlayerObserver)
+{
+ if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+ self.frags = FRAGS_LMS_LOSER;
+ else
+ self.frags = FRAGS_SPECTATOR;
+
+ race_PreparePlayer();
+ self.race_checkpoint = -1;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerSpawn)
+{
+ if(spawn_spot.target == "")
+ // Emergency: this wasn't a real spawnpoint. Can this ever happen?
+ race_PreparePlayer();
+
+ // if we need to respawn, do it right
+ self.race_respawn_checkpoint = self.race_checkpoint;
+ self.race_respawn_spotref = spawn_spot;
+
+ self.race_place = 0;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PutClientInServer)
+{
+ if(IS_PLAYER(self))
+ if(!gameover)
+ {
+ if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
+ race_PreparePlayer();
+ else // respawn
+ race_RetractPlayer();
+
+ race_AbandonRaceCheck(self);
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerDies)
+{
+ self.respawn_flags |= RESPAWN_FORCE;
+ race_AbandonRaceCheck(self);
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_BotRoles)
+{
+ self.havocbot_role = havocbot_role_cts;
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerPostThink)
+{
+ if(self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
+ {
+ if (!self.stored_netname)
+ self.stored_netname = strzone(uid2name(self.crypto_idfp));
+ if(self.stored_netname != self.netname)
+ {
+ db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
+ strunzone(self.stored_netname);
+ self.stored_netname = strzone(self.netname);
+ }
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ForbidThrowing)
+{
+ // no weapon dropping in CTS
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_FilterItem)
+{
+ if(self.classname == "droppedweapon")
+ return TRUE;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerDamage)
+{
+ if(frag_target == frag_attacker || frag_deathtype == DEATH_FALL)
+ if(!autocvar_g_cts_selfdamage)
+ frag_damage = 0;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ForbidClearPlayerScore)
+{
+ return TRUE; // in CTS, you don't lose score by observing
+}
+
+MUTATOR_HOOKFUNCTION(cts_SetMods)
+{
+ g_cloaked = 1; // always enable cloak in CTS
+
+ return FALSE;
+}
+
+void cts_Initialize()
+{
+ cts_ScoreRules();
+}
+
+MUTATOR_DEFINITION(gamemode_cts)
+{
+ MUTATOR_HOOK(PlayerPhysics, cts_PlayerPhysics, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_global, cts_ResetMap, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPreThink, cts_PlayerPreThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ClientConnect, cts_ClientConnect, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MakePlayerObserver, cts_MakePlayerObserver, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerSpawn, cts_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PutClientInServer, cts_PutClientInServer, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDies, cts_PlayerDies, CBC_ORDER_ANY);
+ MUTATOR_HOOK(HavocBot_ChooseRole, cts_BotRoles, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetPressedKeys, cts_PlayerPostThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ForbidThrowCurrentWeapon, cts_ForbidThrowing, CBC_ORDER_ANY);
+ MUTATOR_HOOK(FilterItem, cts_FilterItem, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDamage_Calculate, cts_PlayerDamage, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ForbidPlayerScore_Clear, cts_ForbidClearPlayerScore, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SetModname, cts_SetMods, CBC_ORDER_ANY);
+
+ MUTATOR_ONADD
+ {
+ if(time > 1) // game loads at time 1
+ error("This is a game type and it cannot be added at runtime.");
+ cts_Initialize();
+ }
+
+ MUTATOR_ONROLLBACK_OR_REMOVE
+ {
+ // we actually cannot roll back cts_Initialize here
+ // BUT: we don't need to! If this gets called, adding always
+ // succeeds.
+ }
+
+ MUTATOR_ONREMOVE
+ {
+ print("This is a game type and it cannot be removed at runtime.");
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+float g_race_qualifying;
+
+// scores
+#define ST_CTS_LAPS 1
+#define SP_CTS_LAPS 4
+#define SP_CTS_TIME 5
+#define SP_CTS_FASTEST 6
e.dom_total_pps = total_pps;
e.dom_pps_red = pps_red;
e.dom_pps_blue = pps_blue;
- if(c3 >= 0)
+ if(domination_teams >= 3)
e.dom_pps_yellow = pps_yellow;
- if(c4 >= 0)
+ if(domination_teams >= 4)
e.dom_pps_pink = pps_pink;
}
else
wait_time = self.wait;
- bprint("^3", head.netname, "^3", self.message);
- if (points != 1)
- bprint(" ^7(", ftos(points), " points every ", ftos(wait_time), " seconds)\n");
+ if(domination_roundbased)
+ bprint(sprintf("^3%s^3%s\n", head.netname, self.message));
else
- bprint(" ^7(", ftos(points), " point every ", ftos(wait_time), " seconds)\n");
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_DOMINATION_CAPTURE_TIME, head.netname, self.message, points, wait_time);
if(self.enemy.playerid == self.enemy_playerid)
PlayerScore_Add(self.enemy, SP_DOM_TAKES, 1);
break;
case NUM_TEAM_4:
pps_pink += points/wait_time;
+ break;
}
total_pps += points/wait_time;
}
// give credit to the team
// NOTE: this defaults to 0
+ if (!domination_roundbased)
if (self.goalentity.netname != "")
{
if(autocvar_g_domination_point_amt)
if (other.health < 1)
return;
+ if(round_handler_IsActive() && !round_handler_IsRoundStarted())
+ return;
+
if(time < self.captime + 0.3)
return;
WaypointSprite_SpawnFixed("dom-neut", self.origin + '0 0 32', self, sprite, RADARICON_DOMPOINT, '0 1 1');
}
+float total_controlpoints, redowned, blueowned, yellowowned, pinkowned;
+void Domination_count_controlpoints()
+{
+ entity e;
+ total_controlpoints = redowned = blueowned = yellowowned = pinkowned = 0;
+ for(e = world; (e = find(e, classname, "dom_controlpoint")) != world; )
+ {
+ ++total_controlpoints;
+ redowned += (e.goalentity.team == NUM_TEAM_1);
+ blueowned += (e.goalentity.team == NUM_TEAM_2);
+ yellowowned += (e.goalentity.team == NUM_TEAM_3);
+ pinkowned += (e.goalentity.team == NUM_TEAM_4);
+ }
+}
+
+float Domination_GetWinnerTeam()
+{
+ float winner_team = 0;
+ if(redowned == total_controlpoints)
+ winner_team = NUM_TEAM_1;
+ if(blueowned == total_controlpoints)
+ {
+ if(winner_team) return 0;
+ winner_team = NUM_TEAM_2;
+ }
+ if(yellowowned == total_controlpoints)
+ {
+ if(winner_team) return 0;
+ winner_team = NUM_TEAM_3;
+ }
+ if(pinkowned == total_controlpoints)
+ {
+ if(winner_team) return 0;
+ winner_team = NUM_TEAM_4;
+ }
+ if(winner_team)
+ return winner_team;
+ return -1; // no control points left?
+}
+
+#define DOM_OWNED_CONTROLPOINTS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
+#define DOM_OWNED_CONTROLPOINTS_OK() (DOM_OWNED_CONTROLPOINTS() < total_controlpoints)
+float Domination_CheckWinner()
+{
+ if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
+ round_handler_Init(5, autocvar_g_domination_warmup, autocvar_g_domination_round_timelimit);
+ return 1;
+ }
+
+ Domination_count_controlpoints();
+
+ float winner_team = Domination_GetWinnerTeam();
+
+ if(winner_team == -1)
+ return 0;
+
+ if(winner_team > 0)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_));
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_));
+ TeamScore_AddToTeam(winner_team, ST_DOM_CAPS, +1);
+ }
+ else if(winner_team == -1)
+ {
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_TIED);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_TIED);
+ }
+
+ round_handler_Init(5, autocvar_g_domination_warmup, autocvar_g_domination_round_timelimit);
+
+ return 1;
+}
+
+float Domination_CheckPlayers()
+{
+ return 1;
+}
+
+void Domination_RoundStart()
+{
+ entity e;
+ FOR_EACH_PLAYER(e)
+ e.player_blocked = 0;
+}
+
//go to best items, or control points you don't own
void havocbot_role_dom()
{
}
}
+MUTATOR_HOOKFUNCTION(dom_GetTeamCount)
+{
+ ret_float = domination_teams;
+ return 0;
+}
+
+MUTATOR_HOOKFUNCTION(dom_ResetMap)
+{
+ total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
+ FOR_EACH_PLAYER(self)
+ {
+ PutClientInServer();
+ self.player_blocked = 1;
+ if(IS_REAL_CLIENT(self))
+ set_dom_state(self);
+ }
+ return 1;
+}
+
+MUTATOR_HOOKFUNCTION(dom_PlayerSpawn)
+{
+ if(domination_roundbased)
+ if(!round_handler_IsRoundStarted())
+ self.player_blocked = 1;
+ else
+ self.player_blocked = 0;
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(dom_ClientConnect)
{
set_dom_state(self);
}
// scoreboard setup
-void ScoreRules_dom()
+void ScoreRules_dom(float teams)
{
- float sp_domticks, sp_score;
- sp_score = sp_domticks = 0;
- if(autocvar_g_domination_disable_frags)
- sp_domticks = SFL_SORT_PRIO_PRIMARY;
+ if(domination_roundbased)
+ {
+ ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, TRUE);
+ ScoreInfo_SetLabel_TeamScore (ST_DOM_CAPS, "caps", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES, "takes", 0);
+ ScoreRules_basics_end();
+ }
else
- sp_score = SFL_SORT_PRIO_PRIMARY;
- CheckAllowedTeams(world);
- ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), sp_score, sp_score, TRUE);
- ScoreInfo_SetLabel_TeamScore (ST_DOM_TICKS, "ticks", sp_domticks);
- ScoreInfo_SetLabel_PlayerScore(SP_DOM_TICKS, "ticks", sp_domticks);
- ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES, "takes", 0);
- ScoreRules_basics_end();
+ {
+ float sp_domticks, sp_score;
+ sp_score = sp_domticks = 0;
+ if(autocvar_g_domination_disable_frags)
+ sp_domticks = SFL_SORT_PRIO_PRIMARY;
+ else
+ sp_score = SFL_SORT_PRIO_PRIMARY;
+ ScoreRules_basics(teams, sp_score, sp_score, TRUE);
+ ScoreInfo_SetLabel_TeamScore (ST_DOM_TICKS, "ticks", sp_domticks);
+ ScoreInfo_SetLabel_PlayerScore(SP_DOM_TICKS, "ticks", sp_domticks);
+ ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES, "takes", 0);
+ ScoreRules_basics_end();
+ }
}
// code from here on is just to support maps that don't have control point and team entities
}
// spawn some default teams if the map is not set up for domination
-void dom_spawnteams()
+void dom_spawnteams(float teams)
{
- float numteams = ((autocvar_g_domination_teams_override < 2) ? autocvar_g_domination_default_teams : autocvar_g_domination_teams_override);
-
dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
- if(numteams > 2)
+ if(teams >= 3)
dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
- if(numteams > 3)
+ if(teams >= 4)
dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
}
if(find(world, classname, "dom_team") == world || autocvar_g_domination_teams_override >= 2)
{
print("No ""dom_team"" entities found on this map, creating them anyway.\n");
- dom_spawnteams();
+ domination_teams = bound(2, ((autocvar_g_domination_teams_override < 2) ? autocvar_g_domination_default_teams : autocvar_g_domination_teams_override), 4);
+ dom_spawnteams(domination_teams);
}
+
+ CheckAllowedTeams(world);
+ domination_teams = ((c4>=0) ? 4 : (c3>=0) ? 3 : 2);
+
+ addstat(STAT_DOM_TOTAL_PPS, AS_FLOAT, dom_total_pps);
+ addstat(STAT_DOM_PPS_RED, AS_FLOAT, dom_pps_red);
+ addstat(STAT_DOM_PPS_BLUE, AS_FLOAT, dom_pps_blue);
+ if(domination_teams >= 3) addstat(STAT_DOM_PPS_YELLOW, AS_FLOAT, dom_pps_yellow);
+ if(domination_teams >= 4) addstat(STAT_DOM_PPS_PINK, AS_FLOAT, dom_pps_pink);
+
+ domination_roundbased = autocvar_g_domination_roundbased;
+
+ ScoreRules_dom(domination_teams);
- ScoreRules_dom();
+ if(domination_roundbased)
+ {
+ round_handler_Spawn(Domination_CheckPlayers, Domination_CheckWinner, Domination_RoundStart);
+ round_handler_Init(5, autocvar_g_domination_warmup, autocvar_g_domination_round_timelimit);
+ }
}
void dom_Initialize()
precache_model("models/domination/dom_unclaimed.md3");
precache_sound("domination/claim.wav");
- addstat(STAT_DOM_TOTAL_PPS, AS_FLOAT, dom_total_pps);
- addstat(STAT_DOM_PPS_RED, AS_FLOAT, dom_pps_red);
- addstat(STAT_DOM_PPS_BLUE, AS_FLOAT, dom_pps_blue);
- if(c3 >= 0) addstat(STAT_DOM_PPS_YELLOW, AS_FLOAT, dom_pps_yellow);
- if(c4 >= 0) addstat(STAT_DOM_PPS_PINK, AS_FLOAT, dom_pps_pink);
-
InitializeEntity(world, dom_DelayedInit, INITPRIO_GAMETYPE);
}
MUTATOR_DEFINITION(gamemode_domination)
{
+ MUTATOR_HOOK(GetTeamCount, dom_GetTeamCount, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_players, dom_ResetMap, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerSpawn, dom_PlayerSpawn, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientConnect, dom_ClientConnect, CBC_ORDER_ANY);
MUTATOR_HOOK(HavocBot_ChooseRole, dom_BotRoles, CBC_ORDER_ANY);
#define ST_DOM_TICKS 1
#define SP_DOM_TICKS 4
#define SP_DOM_TAKES 5
+#define ST_DOM_CAPS 1
+#define SP_DOM_CAPS 4
// pps: points per second
.float dom_total_pps;
// capture declarations
.float enemy_playerid;
.entity sprite;
-.float captime;
\ No newline at end of file
+.float captime;
+
+// misc globals
+float domination_roundbased;
+float domination_teams;
.float freezetag_frozen_time;
.float freezetag_frozen_timeout;
.float freezetag_revive_progress;
-.entity freezetag_ice;
#define ICE_MAX_ALPHA 1
#define ICE_MIN_ALPHA 0.1
float freezetag_teams;
{
entity e;
total_players = redalive = bluealive = yellowalive = pinkalive = 0;
- FOR_EACH_PLAYER(e) {
- if(e.team == NUM_TEAM_1 && e.health >= 1)
- {
- ++total_players;
- if (!e.freezetag_frozen) ++redalive;
- }
- else if(e.team == NUM_TEAM_2 && e.health >= 1)
- {
- ++total_players;
- if (!e.freezetag_frozen) ++bluealive;
- }
- else if(e.team == NUM_TEAM_3 && e.health >= 1)
- {
- ++total_players;
- if (!e.freezetag_frozen) ++yellowalive;
- }
- else if(e.team == NUM_TEAM_4 && e.health >= 1)
+ FOR_EACH_PLAYER(e)
+ {
+ switch(e.team)
{
- ++total_players;
- if (!e.freezetag_frozen) ++pinkalive;
+ case NUM_TEAM_1: ++total_players; if(e.health >= 1 && e.frozen != 1) ++redalive; break;
+ case NUM_TEAM_2: ++total_players; if(e.health >= 1 && e.frozen != 1) ++bluealive; break;
+ case NUM_TEAM_3: ++total_players; if(e.health >= 1 && e.frozen != 1) ++yellowalive; break;
+ case NUM_TEAM_4: ++total_players; if(e.health >= 1 && e.frozen != 1) ++pinkalive; break;
}
}
- FOR_EACH_REALCLIENT(e) {
+ FOR_EACH_REALCLIENT(e)
+ {
e.redalive_stat = redalive;
e.bluealive_stat = bluealive;
e.yellowalive_stat = yellowalive;
e.pinkalive_stat = pinkalive;
}
+
+ eliminatedPlayers.SendFlags |= 1;
}
#define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
#define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams)
-float prev_total_players;
+float prev_missing_teams_mask;
float freezetag_CheckTeams()
{
if(FREEZETAG_ALIVE_TEAMS_OK())
{
- if(prev_total_players > 0)
+ if(prev_missing_teams_mask > 0)
Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
- prev_total_players = -1;
+ prev_missing_teams_mask = -1;
return 1;
}
- if(prev_total_players != total_players)
+ if(total_players == 0)
+ {
+ if(prev_missing_teams_mask > 0)
+ Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+ prev_missing_teams_mask = -1;
+ return 0;
+ }
+ float missing_teams_mask = (!redalive) + (!bluealive) * 2;
+ if(freezetag_teams >= 3) missing_teams_mask += (!yellowalive) * 4;
+ if(freezetag_teams >= 4) missing_teams_mask += (!pinkalive) * 8;
+ if(prev_missing_teams_mask != missing_teams_mask)
{
- float p1 = 0, p2 = 0, p3 = 0, p4 = 0;
- if(!redalive) p1 = NUM_TEAM_1;
- if(!bluealive) p2 = NUM_TEAM_2;
- if(freezetag_teams >= 3)
- if(!yellowalive) p3 = NUM_TEAM_3;
- if(freezetag_teams >= 4)
- if(!pinkalive) p4 = NUM_TEAM_4;
- Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, p1, p2, p3, p4);
- prev_total_players = total_players;
+ Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+ prev_missing_teams_mask = missing_teams_mask;
}
return 0;
}
FOR_EACH_PLAYER(e)
{
e.freezetag_frozen_timeout = 0;
- e.freezetag_revive_progress = 0;
+ nades_Clear(e);
}
round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
return 1;
FOR_EACH_PLAYER(e)
{
e.freezetag_frozen_timeout = 0;
- e.freezetag_revive_progress = 0;
+ nades_Clear(e);
}
round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
return 1;
}
-// this is needed to allow the player to turn his view around (fixangle can't
-// be used to freeze his view, as that also changes the angles), while not
-// turning that ice object with the player
-void freezetag_Ice_Think()
+entity freezetag_LastPlayerForTeam()
{
- setorigin(self, self.owner.origin - '0 0 16');
- self.nextthink = time;
+ entity pl, last_pl = world;
+ FOR_EACH_PLAYER(pl)
+ {
+ if(pl.health >= 1)
+ if(!pl.frozen)
+ if(pl != self)
+ if(pl.team == self.team)
+ if(!last_pl)
+ last_pl = pl;
+ else
+ return world;
+ }
+ return last_pl;
+}
+
+void freezetag_LastPlayerForTeam_Notify()
+{
+ if(round_handler_IsActive())
+ if(round_handler_IsRoundStarted())
+ {
+ entity pl = freezetag_LastPlayerForTeam();
+ if(pl)
+ Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
+ }
}
void freezetag_Add_Score(entity attacker)
void freezetag_Freeze(entity attacker)
{
- if(self.freezetag_frozen)
+ if(self.frozen)
return;
- self.freezetag_frozen = 1;
- self.freezetag_frozen_time = time;
- self.freezetag_revive_progress = 0;
- self.health = 1;
+
if(autocvar_g_freezetag_frozen_maxtime > 0)
self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
- freezetag_count_alive_players();
-
- entity ice;
- ice = spawn();
- ice.owner = self;
- ice.classname = "freezetag_ice";
- ice.think = freezetag_Ice_Think;
- ice.nextthink = time;
- ice.frame = floor(random() * 21); // ice model has 20 different looking frames
- ice.alpha = ICE_MAX_ALPHA;
- ice.colormod = Team_ColorRGB(self.team);
- ice.glowmod = ice.colormod;
- setmodel(ice, "models/ice/ice.md3");
-
- self.freezetag_ice = ice;
-
- RemoveGrapplingHook(self);
+ Freeze(self, 0, 1, TRUE);
- // add waypoint
- WaypointSprite_Spawn("freezetag_frozen", 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
+ freezetag_count_alive_players();
freezetag_Add_Score(attacker);
}
void freezetag_Unfreeze(entity attacker)
{
- self.freezetag_frozen = 0;
self.freezetag_frozen_time = 0;
self.freezetag_frozen_timeout = 0;
- self.freezetag_revive_progress = 0;
- remove(self.freezetag_ice);
- self.freezetag_ice = world;
+ Unfreeze(self);
+}
- if(self.waypointsprite_attached)
- WaypointSprite_Kill(self.waypointsprite_attached);
+float freezetag_isEliminated(entity e)
+{
+ if(e.frozen == 1 || e.deadflag != DEAD_NO)
+ return TRUE;
+ return FALSE;
}
{
if ((head != self) && (head.team == self.team))
{
- if (head.freezetag_frozen)
+ if (head.frozen == 1)
{
distance = vlen(head.origin - org);
if (distance > sradius)
unfrozen = 0;
FOR_EACH_PLAYER(head)
{
- if ((head.team == self.team) && (!head.freezetag_frozen))
+ if ((head.team == self.team) && (head.frozen != 1))
unfrozen++;
}
// If only one left on team or if role has timed out then start trying to free players.
- if (((unfrozen == 0) && (!self.freezetag_frozen)) || (time > self.havocbot_role_timeout))
+ if (((unfrozen == 0) && (!self.frozen)) || (time > self.havocbot_role_timeout))
{
dprint("changing role to freeing\n");
self.havocbot_role = havocbot_role_ft_freeing;
MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
{
self.health = 0; // neccessary to update correctly alive stats
+ if(!self.frozen)
+ freezetag_LastPlayerForTeam_Notify();
freezetag_Unfreeze(world);
freezetag_count_alive_players();
return 1;
if(round_handler_IsActive())
if(round_handler_CountdownRunning())
{
- if(self.freezetag_frozen)
+ if(self.frozen)
freezetag_Unfreeze(world);
freezetag_count_alive_players();
return 1; // let the player die so that he can respawn whenever he wants
|| frag_deathtype == DEATH_TEAMCHANGE || frag_deathtype == DEATH_AUTOTEAMCHANGE)
{
// let the player die, he will be automatically frozen when he respawns
- if(!self.freezetag_frozen)
+ if(self.frozen != 1)
{
freezetag_Add_Score(frag_attacker);
freezetag_count_alive_players();
+ freezetag_LastPlayerForTeam_Notify();
}
else
freezetag_Unfreeze(world); // remove ice
+ self.health = 0; // Unfreeze resets health
self.freezetag_frozen_timeout = -2; // freeze on respawn
return 1;
}
- if(self.freezetag_frozen)
+ if(self.frozen)
return 1;
freezetag_Freeze(frag_attacker);
+ freezetag_LastPlayerForTeam_Notify();
if(frag_attacker == frag_target || frag_attacker == world)
{
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
}
- frag_target.health = 1; // "respawn" the player :P
-
return 1;
}
FOR_EACH_PLAYER(self)
{
self.killcount = 0;
- if (self.freezetag_frozen)
- freezetag_Unfreeze(world);
self.freezetag_frozen_timeout = -1;
PutClientInServer();
self.freezetag_frozen_timeout = 0;
if(gameover)
return 1;
- if(self.freezetag_frozen)
+ if(self.frozen == 1)
{
// keep health = 1
self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
entity o;
o = world;
- if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
- self.freezetag_ice.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
+ //if(self.frozen)
+ //if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
+ //self.iceblock.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
n = -1;
{
vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
n = 0;
- FOR_EACH_PLAYER(other) if(self != other)
+ FOR_EACH_PLAYER(other)
+ if(self != other)
+ if(other.frozen == 0)
+ if(other.deadflag == DEAD_NO)
+ if(SAME_TEAM(other, self))
+ if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
{
- if(other.freezetag_frozen == 0)
- {
- if(other.team == self.team)
- {
- if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
- {
- if(!o)
- o = other;
- if(self.freezetag_frozen)
- other.reviving = TRUE;
- ++n;
- }
- }
- }
+ if(!o)
+ o = other;
+ if(self.frozen == 1)
+ other.reviving = TRUE;
+ ++n;
}
}
- if(n && self.freezetag_frozen) // OK, there is at least one teammate reviving us
+ if(n && self.frozen == 1) // OK, there is at least one teammate reviving us
{
- self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
- if(warmup_stage)
- self.health = max(1, self.freezetag_revive_progress * warmup_start_health);
- else
- self.health = max(1, self.freezetag_revive_progress * start_health);
+ self.revive_progress = bound(0, self.revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
+ self.health = max(1, self.revive_progress * ((warmup_stage) ? warmup_start_health : start_health));
- if(self.freezetag_revive_progress >= 1)
+ if(self.revive_progress >= 1)
{
freezetag_Unfreeze(self);
freezetag_count_alive_players();
{
PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
PlayerScore_Add(other, SP_SCORE, +1);
+
+ nades_GiveBonus(other,autocvar_g_nades_bonus_score_low);
}
}
{
if(other.reviving)
{
- other.freezetag_revive_progress = self.freezetag_revive_progress;
+ other.revive_progress = self.revive_progress;
other.reviving = FALSE;
}
}
}
- else if(!n && self.freezetag_frozen) // only if no teammate is nearby will we reset
- {
- self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
- if(warmup_stage)
- self.health = max(1, self.freezetag_revive_progress * warmup_start_health);
- else
- self.health = max(1, self.freezetag_revive_progress * start_health);
- }
- else if(!n)
+ else if(!n && self.frozen == 1) // only if no teammate is nearby will we reset
{
- self.freezetag_revive_progress = 0; // thawing nobody
+ self.revive_progress = bound(0, self.revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
+ self.health = max(1, self.revive_progress * ((warmup_stage) ? warmup_start_health : start_health));
}
-
- return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_PlayerPhysics)
-{
- if(self.freezetag_frozen)
+ else if(!n && !self.frozen)
{
- if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
- {
- self.movement_x = bound(-5, self.movement_x, 5);
- self.movement_y = bound(-5, self.movement_y, 5);
- self.movement_z = bound(-5, self.movement_z, 5);
- }
- else
- self.movement = '0 0 0';
-
- self.disableclientprediction = 1;
+ self.revive_progress = 0; // thawing nobody
}
- return 1;
-}
-MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate)
-{
- if(frag_target.freezetag_frozen && frag_deathtype != DEATH_HURTTRIGGER)
- {
- if(autocvar_g_freezetag_revive_falldamage > 0)
- if(frag_deathtype == DEATH_FALL)
- if(frag_damage >= autocvar_g_freezetag_revive_falldamage)
- {
- freezetag_Unfreeze(frag_target);
- frag_target.health = autocvar_g_freezetag_revive_falldamage_health;
- pointparticles(particleeffectnum("iceorglass"), frag_target.origin, '0 0 0', 3);
- Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, frag_target.netname);
- Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_REVIVE_FALL);
- }
-
- frag_damage = 0;
- frag_force = frag_force * autocvar_g_freezetag_frozen_force;
- }
return 1;
}
-MUTATOR_HOOKFUNCTION(freezetag_PlayerJump)
-{
- if(self.freezetag_frozen)
- return TRUE; // no jumping in freezetag when frozen
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_ForbidThrowCurrentWeapon)
-{
- if (self.freezetag_frozen)
- return 1;
- return 0;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_ItemTouch)
-{
- if (other.freezetag_frozen)
- return MUT_ITEMTOUCH_RETURN;
- return MUT_ITEMTOUCH_CONTINUE;
-}
-
MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
{
if (!self.deadflag)
return TRUE;
}
-MUTATOR_HOOKFUNCTION(freezetag_SpectateCopy)
-{
- self.freezetag_frozen = other.freezetag_frozen;
- self.freezetag_revive_progress = other.freezetag_revive_progress;
- return 0;
-}
-
MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
{
ret_float = freezetag_teams;
return 0;
}
-MUTATOR_HOOKFUNCTION(freezetag_VehicleTouch)
-{
- if(other.freezetag_frozen)
- return TRUE;
-
- return FALSE;
-}
-
void freezetag_Initialize()
{
- precache_model("models/ice/ice.md3");
-
freezetag_teams = autocvar_g_freezetag_teams_override;
if(freezetag_teams < 2)
freezetag_teams = autocvar_g_freezetag_teams;
addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
- addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
- addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
+ EliminatedPlayers_Init(freezetag_isEliminated);
}
MUTATOR_DEFINITION(gamemode_freezetag)
MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY);
MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
- MUTATOR_HOOK(PlayerPhysics, freezetag_PlayerPhysics, CBC_ORDER_FIRST);
- MUTATOR_HOOK(PlayerDamage_Calculate, freezetag_PlayerDamage_Calculate, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerJump, freezetag_PlayerJump, CBC_ORDER_ANY);
- MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
- MUTATOR_HOOK(ItemTouch, freezetag_ItemTouch, CBC_ORDER_ANY);
MUTATOR_HOOK(HavocBot_ChooseRole, freezetag_BotRoles, CBC_ORDER_ANY);
- MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
- MUTATOR_HOOK(VehicleTouch, freezetag_VehicleTouch, CBC_ORDER_ANY);
MUTATOR_ONADD
{
round_handler_Spawn(Invasion_CheckPlayers, Invasion_CheckWinner, Invasion_RoundStart);
round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit);
- allowed_to_spawn = TRUE;
-
inv_roundcnt = 0;
inv_maxrounds = 15; // 15?
}
return;
}
if(other.deadflag != DEAD_NO) { return; }
+ if(other.frozen) { return; }
if (!IS_PLAYER(other))
{ // The ball just touched an object, most likely the world
pointparticles(particleeffectnum("kaball_sparks"), self.origin, '0 0 0', 1);
f = DistributeEvenly_Get(1);
kh_Scores_Event(key.owner, key, "capture", f, 0);
PlayerTeamScore_Add(key.owner, SP_KH_CAPS, ST_KH_CAPS, 1);
+ nades_GiveBonus(key.owner, autocvar_g_nades_bonus_score_high);
}
first = TRUE;
football_touch();
return;
}
- if(!self.cnt && IS_PLAYER(other) && (other != self.nb_dropper || time > self.nb_droptime + autocvar_g_nexball_delay_collect))
+ if(!self.cnt && IS_PLAYER(other) && !other.frozen && (other != self.nb_dropper || time > self.nb_droptime + autocvar_g_nexball_delay_collect))
{
if(other.health <= 0)
return;
--- /dev/null
+// legacy bot roles
+.float race_checkpoint;
+void havocbot_role_race()
+{
+ if(self.deadflag != DEAD_NO)
+ return;
+
+ entity e;
+ if (self.bot_strategytime < time)
+ {
+ self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_start();
+
+ for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
+ {
+ if(e.cnt == self.race_checkpoint)
+ {
+ navigation_routerating(e, 1000000, 5000);
+ }
+ else if(self.race_checkpoint == -1)
+ {
+ navigation_routerating(e, 1000000, 5000);
+ }
+ }
+
+ navigation_goalrating_end();
+ }
+}
+
+void race_ScoreRules()
+{
+ ScoreRules_basics(race_teams, 0, 0, FALSE);
+ if(race_teams)
+ {
+ ScoreInfo_SetLabel_TeamScore( ST_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME, "time", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_LOWER_IS_BETTER | SFL_TIME);
+ }
+ else if(g_race_qualifying)
+ {
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+ }
+ else
+ {
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME, "time", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+ ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_LOWER_IS_BETTER | SFL_TIME);
+ }
+ ScoreRules_basics_end();
+}
+
+void race_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
+{
+ if(autocvar_sv_eventlog)
+ GameLogEcho(strcat(":race:", mode, ":", ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerPhysics)
+{
+ // force kbd movement for fairness
+ float wishspeed;
+ vector wishvel;
+
+ // if record times matter
+ // ensure nothing EVIL is being done (i.e. div0_evade)
+ // this hinders joystick users though
+ // but it still gives SOME analog control
+ wishvel_x = fabs(self.movement_x);
+ wishvel_y = fabs(self.movement_y);
+ if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y)
+ {
+ wishvel_z = 0;
+ wishspeed = vlen(wishvel);
+ if(wishvel_x >= 2 * wishvel_y)
+ {
+ // pure X motion
+ if(self.movement_x > 0)
+ self.movement_x = wishspeed;
+ else
+ self.movement_x = -wishspeed;
+ self.movement_y = 0;
+ }
+ else if(wishvel_y >= 2 * wishvel_x)
+ {
+ // pure Y motion
+ self.movement_x = 0;
+ if(self.movement_y > 0)
+ self.movement_y = wishspeed;
+ else
+ self.movement_y = -wishspeed;
+ }
+ else
+ {
+ // diagonal
+ if(self.movement_x > 0)
+ self.movement_x = M_SQRT1_2 * wishspeed;
+ else
+ self.movement_x = -M_SQRT1_2 * wishspeed;
+ if(self.movement_y > 0)
+ self.movement_y = M_SQRT1_2 * wishspeed;
+ else
+ self.movement_y = -M_SQRT1_2 * wishspeed;
+ }
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_ResetMap)
+{
+ float s;
+
+ Score_NicePrint(world);
+
+ race_ClearRecords();
+ PlayerScore_Sort(race_place, 0, 1, 0);
+
+ entity e;
+ FOR_EACH_CLIENT(e)
+ {
+ if(e.race_place)
+ {
+ s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
+ if(!s)
+ e.race_place = 0;
+ }
+ race_EventLog(ftos(e.race_place), e);
+ }
+
+ if(g_race_qualifying == 2)
+ {
+ g_race_qualifying = 0;
+ independent_players = 0;
+ cvar_set("fraglimit", ftos(race_fraglimit));
+ cvar_set("leadlimit", ftos(race_leadlimit));
+ cvar_set("timelimit", ftos(race_timelimit));
+ race_ScoreRules();
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerPreThink)
+{
+ if(IS_SPEC(self) || IS_OBSERVER(self))
+ if(g_race_qualifying)
+ if(msg_entity.enemy.race_laptime)
+ race_SendNextCheckpoint(msg_entity.enemy, 1);
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_ClientConnect)
+{
+ race_PreparePlayer();
+ self.race_checkpoint = -1;
+
+ string rr = RACE_RECORD;
+
+ if(IS_REAL_CLIENT(self))
+ {
+ msg_entity = self;
+ race_send_recordtime(MSG_ONE);
+ race_send_speedaward(MSG_ONE);
+
+ speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
+ speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
+ race_send_speedaward_alltimebest(MSG_ONE);
+
+ float i;
+ for (i = 1; i <= RANKINGS_CNT; ++i)
+ {
+ race_SendRankings(i, 0, 0, MSG_ONE);
+ }
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_MakePlayerObserver)
+{
+ if(g_race_qualifying)
+ if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+ self.frags = FRAGS_LMS_LOSER;
+ else
+ self.frags = FRAGS_SPECTATOR;
+
+ race_PreparePlayer();
+ self.race_checkpoint = -1;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerSpawn)
+{
+ if(spawn_spot.target == "")
+ // Emergency: this wasn't a real spawnpoint. Can this ever happen?
+ race_PreparePlayer();
+
+ // if we need to respawn, do it right
+ self.race_respawn_checkpoint = self.race_checkpoint;
+ self.race_respawn_spotref = spawn_spot;
+
+ self.race_place = 0;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PutClientInServer)
+{
+ if(IS_PLAYER(self))
+ if(!gameover)
+ {
+ if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
+ race_PreparePlayer();
+ else // respawn
+ race_RetractPlayer();
+
+ race_AbandonRaceCheck(self);
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerDies)
+{
+ self.respawn_flags |= RESPAWN_FORCE;
+ race_AbandonRaceCheck(self);
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_BotRoles)
+{
+ self.havocbot_role = havocbot_role_race;
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerPostThink)
+{
+ if(self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
+ {
+ if (!self.stored_netname)
+ self.stored_netname = strzone(uid2name(self.crypto_idfp));
+ if(self.stored_netname != self.netname)
+ {
+ db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
+ strunzone(self.stored_netname);
+ self.stored_netname = strzone(self.netname);
+ }
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_ForbidClearPlayerScore)
+{
+ if(g_race_qualifying)
+ return TRUE; // in qualifying, you don't lose score by observing
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_GetTeamCount)
+{
+ ret_float = race_teams;
+ return FALSE;
+}
+
+void race_Initialize()
+{
+ race_ScoreRules();
+ if(g_race_qualifying == 2)
+ warmup_stage = 0;
+}
+
+MUTATOR_DEFINITION(gamemode_race)
+{
+ MUTATOR_HOOK(PlayerPhysics, race_PlayerPhysics, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_global, race_ResetMap, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPreThink, race_PlayerPreThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ClientConnect, race_ClientConnect, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MakePlayerObserver, race_MakePlayerObserver, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerSpawn, race_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PutClientInServer, race_PutClientInServer, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDies, race_PlayerDies, CBC_ORDER_ANY);
+ MUTATOR_HOOK(HavocBot_ChooseRole, race_BotRoles, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetPressedKeys, race_PlayerPostThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ForbidPlayerScore_Clear, race_ForbidClearPlayerScore, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetTeamCount, race_GetTeamCount, CBC_ORDER_ANY);
+
+ MUTATOR_ONADD
+ {
+ if(time > 1) // game loads at time 1
+ error("This is a game type and it cannot be added at runtime.");
+ race_Initialize();
+ }
+
+ MUTATOR_ONROLLBACK_OR_REMOVE
+ {
+ // we actually cannot roll back race_Initialize here
+ // BUT: we don't need to! If this gets called, adding always
+ // succeeds.
+ }
+
+ MUTATOR_ONREMOVE
+ {
+ print("This is a game type and it cannot be removed at runtime.");
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+float g_race_qualifying;
+float race_teams;
+
+// scores
+#define ST_RACE_LAPS 1
+#define SP_RACE_LAPS 4
+#define SP_RACE_TIME 5
+#define SP_RACE_FASTEST 6
--- /dev/null
+/*QUAKED spawnfunc_tdm_team (0 .5 .8) (-16 -16 -24) (16 16 32)
+Team declaration for TDM gameplay, this allows you to decide what team names and control point models are used in your map.
+Note: If you use spawnfunc_tdm_team entities you must define at least 2! However, unlike domination, you don't need to make a blank one too.
+Keys:
+"netname" Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc)...
+"cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
+void spawnfunc_tdm_team()
+{
+ if(!g_tdm) { remove(self); return; }
+
+ self.classname = "tdm_team";
+ self.team = self.cnt + 1;
+}
+
+// code from here on is just to support maps that don't have team entities
+void tdm_SpawnTeam (string teamname, float teamcolor)
+{
+ entity oldself;
+ oldself = self;
+ self = spawn();
+ self.classname = "tdm_team";
+ self.netname = teamname;
+ self.cnt = teamcolor;
+
+ spawnfunc_tdm_team();
+
+ self = oldself;
+}
+
+void tdm_DelayedInit()
+{
+ // if no teams are found, spawn defaults
+ if(find(world, classname, "tdm_team") == world)
+ {
+ print("No ""tdm_team"" entities found on this map, creating them anyway.\n");
+
+ float numteams = min(4, autocvar_g_tdm_teams_override);
+
+ if(numteams < 2) { numteams = autocvar_g_tdm_teams; }
+ numteams = bound(2, numteams, 4);
+
+ float i;
+ for(i = 1; i <= numteams; ++i)
+ tdm_SpawnTeam(Team_ColorName(Team_NumberToTeam(i)), Team_NumberToTeam(i) - 1);
+ }
+}
+
+MUTATOR_HOOKFUNCTION(tdm_GetTeamCount)
+{
+ ret_string = "tdm_team";
+ return TRUE;
+}
+
+MUTATOR_DEFINITION(gamemode_tdm)
+{
+ MUTATOR_HOOK(GetTeamCount, tdm_GetTeamCount, CBC_ORDER_ANY);
+
+ MUTATOR_ONADD
+ {
+ if(time > 1) // game loads at time 1
+ error("This is a game type and it cannot be added at runtime.");
+ InitializeEntity(world, tdm_DelayedInit, INITPRIO_GAMETYPE);
+ }
+
+ MUTATOR_ONROLLBACK_OR_REMOVE
+ {
+ // we actually cannot roll back tdm_Initialize here
+ // BUT: we don't need to! If this gets called, adding always
+ // succeeds.
+ }
+
+ MUTATOR_ONREMOVE
+ {
+ print("This is a game type and it cannot be removed at runtime.");
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+float buffs_BuffModel_Customize()
+{
+ entity player, myowner;
+ float same_team;
+
+ player = WaypointSprite_getviewentity(other);
+ myowner = self.owner;
+ same_team = (SAME_TEAM(player, myowner) || SAME_TEAM(player, myowner));
+
+ if(myowner.alpha <= 0.5 && !same_team && myowner.alpha != 0)
+ return FALSE;
+
+ if(player == myowner || (IS_SPEC(other) && other.enemy == myowner))
+ {
+ // somewhat hide the model, but keep the glow
+ self.effects = 0;
+ self.alpha = -1;
+ }
+ else
+ {
+ self.effects = EF_FULLBRIGHT | EF_LOWPRECISION;
+ self.alpha = 1;
+ }
+ return TRUE;
+}
+
+// buff item
+float buff_Waypoint_visible_for_player(entity plr)
+{
+ if(!self.owner.buff_active && !self.owner.buff_activetime)
+ return FALSE;
+
+ if(plr.buffs)
+ {
+ if(plr.cvar_cl_buffs_autoreplace)
+ {
+ if(plr.buffs == self.owner.buffs)
+ return FALSE;
+ }
+ else
+ return FALSE;
+ }
+
+ return WaypointSprite_visible_for_player(plr);
+}
+
+void buff_Waypoint_Spawn(entity e)
+{
+ WaypointSprite_Spawn(Buff_Sprite(e.buffs), 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs_z, world, e.team, e, buff_waypoint, TRUE, RADARICON_POWERUP, e.glowmod);
+ WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_POWERUP, e.glowmod);
+ e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
+}
+
+void buff_SetCooldown(float cd)
+{
+ cd = max(0, cd);
+
+ if(!self.buff_waypoint)
+ buff_Waypoint_Spawn(self);
+
+ WaypointSprite_UpdateBuildFinished(self.buff_waypoint, time + cd);
+ self.buff_activetime = cd;
+ self.buff_active = !cd;
+}
+
+void buff_Respawn(entity ent)
+{
+ if(gameover) { return; }
+
+ vector oldbufforigin = ent.origin;
+
+ if(!MoveToRandomMapLocation(ent, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, ((autocvar_g_buffs_random_location_attempts > 0) ? autocvar_g_buffs_random_location_attempts : 10), 1024, 256))
+ {
+ entity spot = SelectSpawnPoint(TRUE);
+ setorigin(ent, ((spot.origin + '0 0 200') + (randomvec() * 300)));
+ ent.angles = spot.angles;
+ }
+
+ tracebox(ent.origin, ent.mins * 1.5, self.maxs * 1.5, ent.origin, MOVE_NOMONSTERS, ent);
+
+ setorigin(ent, trace_endpos); // attempt to unstick
+
+ ent.movetype = MOVETYPE_TOSS;
+
+ makevectors(ent.angles);
+ ent.velocity = '0 0 200';
+ ent.angles = '0 0 0';
+ if(autocvar_g_buffs_random_lifetime > 0)
+ ent.lifetime = time + autocvar_g_buffs_random_lifetime;
+
+ pointparticles(particleeffectnum("electro_combo"), oldbufforigin + ((ent.mins + ent.maxs) * 0.5), '0 0 0', 1);
+ pointparticles(particleeffectnum("electro_combo"), CENTER_OR_VIEWOFS(ent), '0 0 0', 1);
+
+ WaypointSprite_Ping(ent.buff_waypoint);
+
+ sound(ent, CH_TRIGGER, "keepaway/respawn.wav", VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+}
+
+void buff_Touch()
+{
+ if(gameover) { return; }
+
+ if(ITEM_TOUCH_NEEDKILL())
+ {
+ buff_Respawn(self);
+ return;
+ }
+
+ if((self.team && DIFF_TEAM(other, self))
+ || (other.frozen)
+ || (other.vehicle)
+ || (!IS_PLAYER(other))
+ || (!self.buff_active)
+ )
+ {
+ // can't touch this
+ return;
+ }
+
+ if(other.buffs)
+ {
+ if(other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
+ {
+ //Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_DROP, other.buffs);
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ITEM_BUFF_LOST, other.netname, other.buffs);
+
+ other.buffs = 0;
+ //sound(other, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
+ }
+ else { return; } // do nothing
+ }
+
+ self.owner = other;
+ self.buff_active = FALSE;
+ self.lifetime = 0;
+
+ Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, self.buffs);
+ Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, self.buffs);
+
+ pointparticles(particleeffectnum("item_pickup"), CENTER_OR_VIEWOFS(self), '0 0 0', 1);
+ sound(other, CH_TRIGGER, "misc/shield_respawn.wav", VOL_BASE, ATTN_NORM);
+ other.buffs |= (self.buffs);
+}
+
+float buff_Available(float buffid)
+{
+ if(buffid == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
+ return FALSE;
+
+ if(buffid == BUFF_VAMPIRE && cvar("g_vampire"))
+ return FALSE;
+
+ if(!cvar(strcat("g_buffs_", Buff_Name(buffid))))
+ return FALSE;
+
+ return TRUE;
+}
+
+void buff_NewType(entity ent, float cb)
+{
+ entity e;
+ RandomSelection_Init();
+ for(e = Buff_Type_first; e; e = e.enemy)
+ if(buff_Available(e.items))
+ {
+ RandomSelection_Add(world, e.items, string_null, 1, 1 / e.count); // if it's already been chosen, give it a lower priority
+ e.count += 1;
+ }
+ ent.buffs = RandomSelection_chosen_float;
+}
+
+void buff_Think()
+{
+ if(self.buffs != self.oldbuffs)
+ {
+ self.color = Buff_Color(self.buffs);
+ self.glowmod = ((self.team) ? Team_ColorRGB(self.team) + '0.1 0.1 0.1' : self.color);
+ self.skin = Buff_Skin(self.buffs);
+
+ setmodel(self, "models/relics/relic.md3");
+
+ if(self.buff_waypoint)
+ {
+ //WaypointSprite_Disown(self.buff_waypoint, 1);
+ WaypointSprite_Kill(self.buff_waypoint);
+ buff_Waypoint_Spawn(self);
+ if(self.buff_activetime)
+ WaypointSprite_UpdateBuildFinished(self.buff_waypoint, time + self.buff_activetime - frametime);
+ }
+
+ self.oldbuffs = self.buffs;
+ }
+
+ if(!gameover)
+ if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
+ if(!self.buff_activetime_updated)
+ {
+ buff_SetCooldown(self.buff_activetime);
+ self.buff_activetime_updated = TRUE;
+ }
+
+ if(!self.buff_active && !self.buff_activetime)
+ if(!self.owner || self.owner.frozen || self.owner.deadflag != DEAD_NO || !self.owner.iscreature || !(self.owner.buffs & self.buffs))
+ {
+ buff_SetCooldown(autocvar_g_buffs_cooldown_respawn + frametime);
+ self.owner = world;
+ if(autocvar_g_buffs_randomize)
+ buff_NewType(self, self.buffs);
+
+ if(autocvar_g_buffs_random_location || (self.spawnflags & 1))
+ buff_Respawn(self);
+ }
+
+ if(self.buff_activetime)
+ if(!gameover)
+ if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
+ {
+ self.buff_activetime = max(0, self.buff_activetime - frametime);
+
+ if(!self.buff_activetime)
+ {
+ self.buff_active = TRUE;
+ sound(self, CH_TRIGGER, "misc/strength_respawn.wav", VOL_BASE, ATTN_NORM);
+ pointparticles(particleeffectnum("item_respawn"), CENTER_OR_VIEWOFS(self), '0 0 0', 1);
+ }
+ }
+
+ if(!self.buff_active)
+ {
+ self.alpha = 0.3;
+ self.effects &= ~(EF_FULLBRIGHT);
+ self.pflags = 0;
+ }
+ else
+ {
+ self.alpha = 1;
+ self.effects |= EF_FULLBRIGHT;
+ self.light_lev = 220 + 36 * sin(time);
+ self.pflags = PFLAGS_FULLDYNAMIC;
+
+ if(self.team && !self.buff_waypoint)
+ buff_Waypoint_Spawn(self);
+
+ if(self.lifetime)
+ if(time >= self.lifetime)
+ buff_Respawn(self);
+ }
+
+ self.nextthink = time;
+ //self.angles_y = time * 110.1;
+}
+
+void buff_Waypoint_Reset()
+{
+ WaypointSprite_Kill(self.buff_waypoint);
+
+ if(self.buff_activetime) { buff_Waypoint_Spawn(self); }
+}
+
+void buff_Reset()
+{
+ if(autocvar_g_buffs_randomize)
+ buff_NewType(self, self.buffs);
+ self.owner = world;
+ buff_SetCooldown(autocvar_g_buffs_cooldown_activate);
+ buff_Waypoint_Reset();
+ self.buff_activetime_updated = FALSE;
+
+ if(autocvar_g_buffs_random_location || (self.spawnflags & 1))
+ buff_Respawn(self);
+}
+
+void buff_Init(entity ent)
+{
+ if(!cvar("g_buffs")) { remove(self); return; }
+
+ if(!teamplay && self.team) { self.team = 0; }
+
+ entity oldself = self;
+ self = ent;
+ if(!self.buffs || buff_Available(self.buffs))
+ buff_NewType(self, 0);
+
+ self.classname = "item_buff";
+ self.solid = SOLID_TRIGGER;
+ self.flags = FL_ITEM;
+ self.think = buff_Think;
+ self.touch = buff_Touch;
+ self.reset = buff_Reset;
+ self.nextthink = time + 0.1;
+ self.gravity = 1;
+ self.movetype = MOVETYPE_TOSS;
+ self.scale = 1;
+ self.skin = Buff_Skin(self.buffs);
+ self.effects = EF_FULLBRIGHT | EF_STARDUST | EF_NOSHADOW;
+ self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+ //self.gravity = 100;
+ self.color = Buff_Color(self.buffs);
+ self.glowmod = ((self.team) ? Team_ColorRGB(self.team) + '0.1 0.1 0.1' : self.color);
+ buff_SetCooldown(autocvar_g_buffs_cooldown_activate + game_starttime);
+ self.buff_active = !self.buff_activetime;
+ self.pflags = PFLAGS_FULLDYNAMIC;
+
+ if(self.noalign)
+ self.movetype = MOVETYPE_NONE; // reset by random location
+
+ setmodel(self, "models/relics/relic.md3");
+ setsize(self, BUFF_MIN, BUFF_MAX);
+
+ if(cvar("g_buffs_random_location") || (self.spawnflags & 1))
+ buff_Respawn(self);
+
+ self = oldself;
+}
+
+void buff_Init_Compat(entity ent, float replacement)
+{
+ if(ent.spawnflags & 2)
+ ent.team = NUM_TEAM_1;
+ else if(ent.spawnflags & 4)
+ ent.team = NUM_TEAM_2;
+
+ ent.buffs = replacement;
+
+ buff_Init(ent);
+}
+
+void buff_SpawnReplacement(entity ent, entity old)
+{
+ setorigin(ent, old.origin);
+ ent.angles = old.angles;
+ ent.noalign = old.noalign;
+
+ buff_Init(ent);
+}
+
+// mutator hooks
+MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_SplitHealthArmor)
+{
+ if(frag_deathtype == DEATH_BUFF_VENGEANCE) { return FALSE; } // oh no you don't
+
+ if(frag_target.buffs & BUFF_RESISTANCE)
+ {
+ vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage);
+ damage_take = v_x;
+ damage_save = v_y;
+ }
+
+ return FALSE;
+}
+
+void buff_Vengeance_DelayedDamage()
+{
+ if(self.enemy)
+ Damage(self.enemy, self.owner, self.owner, self.dmg, DEATH_BUFF_VENGEANCE, self.enemy.origin, '0 0 0');
+
+ remove(self);
+ return;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
+{
+ if(frag_deathtype == DEATH_BUFF_VENGEANCE) { return FALSE; } // oh no you don't
+
+ if(frag_target.buffs & BUFF_SPEED)
+ if(frag_target != frag_attacker)
+ frag_damage *= autocvar_g_buffs_speed_damage_take;
+
+ if(frag_target.buffs & BUFF_MEDIC)
+ if((frag_target.health - frag_damage) <= 0)
+ if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+ if(frag_attacker)
+ if(random() <= autocvar_g_buffs_medic_survive_chance)
+ if(frag_target.health - autocvar_g_buffs_medic_survive_health > 0) // not if the final result would be less than 0, medic must get health
+ frag_damage = frag_target.health - autocvar_g_buffs_medic_survive_health;
+
+ if(frag_target.buffs & BUFF_VENGEANCE)
+ if(frag_attacker)
+ if(frag_attacker != frag_target)
+ if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+ {
+ entity dmgent = spawn();
+
+ dmgent.dmg = frag_damage * autocvar_g_buffs_vengeance_damage_multiplier;
+ dmgent.enemy = frag_attacker;
+ dmgent.owner = frag_target;
+ dmgent.think = buff_Vengeance_DelayedDamage;
+ dmgent.nextthink = time + 0.1;
+ }
+
+ if(frag_target.buffs & BUFF_BASH)
+ if(frag_attacker != frag_target)
+ if(vlen(frag_force))
+ frag_force = '0 0 0';
+
+ if(frag_attacker.buffs & BUFF_BASH)
+ if(vlen(frag_force))
+ if(frag_attacker == frag_target)
+ frag_force *= autocvar_g_buffs_bash_force_self;
+ else
+ frag_force *= autocvar_g_buffs_bash_force;
+
+ if(frag_attacker.buffs & BUFF_DISABILITY)
+ if(frag_target != frag_attacker)
+ frag_target.buff_disability_time = time + autocvar_g_buffs_disability_time;
+
+ if(frag_attacker.buffs & BUFF_MEDIC)
+ if(SAME_TEAM(frag_attacker, frag_target))
+ if(frag_attacker != frag_target)
+ {
+ frag_target.health = min(g_pickup_healthmega_max, frag_target.health + frag_damage);
+ frag_damage = 0;
+ }
+
+ // this... is ridiculous (TODO: fix!)
+ if(frag_attacker.buffs & BUFF_VAMPIRE)
+ if(!frag_target.vehicle)
+ if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+ if(frag_target.deadflag == DEAD_NO)
+ if(IS_PLAYER(frag_target) || (frag_target.flags & FL_MONSTER))
+ if(frag_attacker != frag_target)
+ if(!frag_target.frozen)
+ if(frag_target.takedamage)
+ if(DIFF_TEAM(frag_attacker, frag_target))
+ frag_attacker.health = bound(0, frag_attacker.health + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.health), g_pickup_healthsmall_max);
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerSpawn)
+{
+ self.buffs = 0;
+ // reset timers here to prevent them continuing after re-spawn
+ self.buff_disability_time = 0;
+ self.buff_disability_effect_time = 0;
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerPhysics)
+{
+ if(self.buffs & BUFF_SPEED)
+ {
+ self.stat_sv_maxspeed *= autocvar_g_buffs_speed_speed;
+ self.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_speed_speed;
+ }
+
+ if(time < self.buff_disability_time)
+ {
+ self.stat_sv_maxspeed *= autocvar_g_buffs_disability_speed;
+ self.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_disability_speed;
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerJump)
+{
+ if(self.buffs & BUFF_JUMP)
+ player_jumpheight = autocvar_g_buffs_jump_height;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_MonsterMove)
+{
+ if(time < self.buff_disability_time)
+ {
+ monster_speed_walk *= autocvar_g_buffs_disability_speed;
+ monster_speed_run *= autocvar_g_buffs_disability_speed;
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerDies)
+{
+ if(self.buffs)
+ {
+ Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+ self.buffs = 0;
+
+ if(self.buff_model)
+ {
+ remove(self.buff_model);
+ self.buff_model = world;
+ }
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerUseKey)
+{
+ if(MUTATOR_RETURNVALUE || gameover) { return FALSE; }
+ if(self.buffs)
+ {
+ Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, self.buffs);
+ Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+
+ self.buffs = 0;
+ sound(self, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_RemovePlayer)
+{
+ if(self.buff_model)
+ {
+ remove(self.buff_model);
+ self.buff_model = world;
+ }
+
+ // also reset timers here to prevent them continuing after spectating
+ self.buff_disability_time = 0;
+ self.buff_disability_effect_time = 0;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_CustomizeWaypoint)
+{
+ entity e = WaypointSprite_getviewentity(other);
+
+ // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
+ // but only apply this to real players, not to spectators
+ if((self.owner.flags & FL_CLIENT) && (self.owner.buffs & BUFF_INVISIBLE) && (e == other))
+ if(DIFF_TEAM(self.owner, e))
+ return TRUE;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_OnEntityPreSpawn)
+{
+ if(autocvar_g_buffs_replace_powerups)
+ switch(self.classname)
+ {
+ case "item_strength":
+ case "item_invincible":
+ {
+ entity e = spawn();
+ buff_SpawnReplacement(e, self);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_WeaponRate)
+{
+ if(self.buffs & BUFF_SPEED)
+ weapon_rate *= autocvar_g_buffs_speed_rate;
+
+ if(time < self.buff_disability_time)
+ weapon_rate *= autocvar_g_buffs_disability_rate;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
+{
+ if(gameover || self.deadflag != DEAD_NO) { return FALSE; }
+
+ if(time < self.buff_disability_time)
+ if(time >= self.buff_disability_effect_time)
+ {
+ pointparticles(particleeffectnum("smoking"), self.origin + ((self.mins + self.maxs) * 0.5), '0 0 0', 1);
+ self.buff_disability_effect_time = time + 0.5;
+ }
+
+ if(self.frozen)
+ {
+ if(self.buffs)
+ {
+ Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+ self.buffs = 0;
+ }
+ }
+
+ if((self.buffs & BUFF_INVISIBLE) && (self.oldbuffs & BUFF_INVISIBLE))
+ if(self.alpha != autocvar_g_buffs_invisible_alpha)
+ self.alpha = autocvar_g_buffs_invisible_alpha;
+
+ if(self.buffs != self.oldbuffs)
+ {
+ if(self.oldbuffs & BUFF_AMMO)
+ {
+ if(self.buff_ammo_prev_infitems)
+ self.items |= IT_UNLIMITED_WEAPON_AMMO;
+ else
+ self.items &= ~IT_UNLIMITED_WEAPON_AMMO;
+ }
+ else if(self.buffs & BUFF_AMMO)
+ {
+ self.buff_ammo_prev_infitems = (self.items & IT_UNLIMITED_WEAPON_AMMO);
+ self.items |= IT_UNLIMITED_WEAPON_AMMO;
+ if(!self.ammo_shells) { self.ammo_shells = 20; }
+ if(!self.ammo_cells) { self.ammo_cells = 20; }
+ if(!self.ammo_rockets) { self.ammo_rockets = 20; }
+ if(!self.ammo_nails) { self.ammo_nails = 20; }
+ if(!self.ammo_fuel) { self.ammo_fuel = 20; }
+ }
+
+ if(self.oldbuffs & BUFF_INVISIBLE)
+ {
+ if(time < self.strength_finished && g_instagib)
+ self.alpha = autocvar_g_instagib_invis_alpha;
+ else
+ self.alpha = self.buff_invisible_prev_alpha;
+ }
+ else if(self.buffs & BUFF_INVISIBLE)
+ {
+ if(time < self.strength_finished && g_instagib)
+ self.buff_invisible_prev_alpha = default_player_alpha;
+ else
+ self.buff_invisible_prev_alpha = self.alpha;
+ self.alpha = autocvar_g_buffs_invisible_alpha;
+ }
+
+ if(self.oldbuffs & BUFF_FLIGHT)
+ self.gravity = self.buff_flight_prev_gravity;
+ else if(self.buffs & BUFF_FLIGHT)
+ {
+ self.buff_flight_prev_gravity = self.gravity;
+ self.gravity = autocvar_g_buffs_flight_gravity;
+ }
+
+ self.oldbuffs = self.buffs;
+ if(self.buffs)
+ {
+ if(!self.buff_model)
+ {
+ self.buff_model = spawn();
+ setmodel(self.buff_model, "models/relics/relic.md3");
+ setsize(self.buff_model, '0 0 -40', '0 0 40');
+ setattachment(self.buff_model, self, "");
+ setorigin(self.buff_model, '0 0 1' * (self.buff_model.maxs_z * 1));
+ self.buff_model.owner = self;
+ self.buff_model.scale = 0.7;
+ self.buff_model.pflags = PFLAGS_FULLDYNAMIC;
+ self.buff_model.light_lev = 200;
+ self.buff_model.customizeentityforclient = buffs_BuffModel_Customize;
+ }
+ self.buff_model.color = Buff_Color(self.buffs);
+ self.buff_model.glowmod = ((self.buff_model.team) ? Team_ColorRGB(self.buff_model.team) + '0.1 0.1 0.1' : self.buff_model.color);
+ self.buff_model.skin = Buff_Skin(self.buffs);
+
+ self.effects |= EF_NOSHADOW;
+ }
+ else
+ {
+ remove(self.buff_model);
+ self.buff_model = world;
+
+ self.effects &= ~(EF_NOSHADOW);
+ }
+ }
+
+ if(self.buff_model)
+ {
+ self.buff_model.effects = self.effects;
+ self.buff_model.effects |= EF_LOWPRECISION;
+ self.buff_model.effects = self.buff_model.effects & EFMASK_CHEAP; // eat performance
+
+ self.buff_model.alpha = self.alpha;
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_SpectateCopy)
+{
+ self.buffs = other.buffs;
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_VehicleEnter)
+{
+ vh_vehicle.buffs = vh_player.buffs;
+ vh_player.buffs = 0;
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_VehicleExit)
+{
+ vh_player.buffs = vh_vehicle.buffs;
+ vh_vehicle.buffs = 0;
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerRegen)
+{
+ if(self.buffs & BUFF_MEDIC)
+ {
+ regen_mod_rot = autocvar_g_buffs_medic_rot;
+ regen_mod_limit = regen_mod_max = autocvar_g_buffs_medic_max;
+ regen_mod_regen = autocvar_g_buffs_medic_regen;
+ }
+
+ if(self.buffs & BUFF_SPEED)
+ regen_mod_regen = autocvar_g_buffs_speed_regen;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_GetCvars)
+{
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_buffs_autoreplace, "cl_buffs_autoreplace");
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_BuildMutatorsString)
+{
+ ret_string = strcat(ret_string, ":Buffs");
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_BuildMutatorsPrettyString)
+{
+ ret_string = strcat(ret_string, ", Buffs");
+ return FALSE;
+}
+
+void buffs_DelayedInit()
+{
+ if(autocvar_g_buffs_spawn_count > 0)
+ if(find(world, classname, "item_buff") == world)
+ {
+ float i;
+ for(i = 0; i < autocvar_g_buffs_spawn_count; ++i)
+ {
+ entity e = spawn();
+ e.spawnflags |= 1; // always randomize
+ e.velocity = randomvec() * 250; // this gets reset anyway if random location works
+ buff_Init(e);
+ }
+ }
+}
+
+void buffs_Initialize()
+{
+ precache_model("models/relics/relic.md3");
+ precache_sound("misc/strength_respawn.wav");
+ precache_sound("misc/shield_respawn.wav");
+ precache_sound("relics/relic_effect.wav");
+ precache_sound("weapons/rocket_impact.wav");
+ precache_sound("keepaway/respawn.wav");
+
+ addstat(STAT_BUFFS, AS_INT, buffs);
+
+ InitializeEntity(world, buffs_DelayedInit, INITPRIO_FINDTARGET);
+}
+
+MUTATOR_DEFINITION(mutator_buffs)
+{
+ MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, buffs_PlayerDamage_SplitHealthArmor, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDamage_Calculate, buffs_PlayerDamage_Calculate, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerSpawn, buffs_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPhysics, buffs_PlayerPhysics, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerJump, buffs_PlayerJump, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MonsterMove, buffs_MonsterMove, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SpectateCopy, buffs_SpectateCopy, CBC_ORDER_ANY);
+ MUTATOR_HOOK(VehicleEnter, buffs_VehicleEnter, CBC_ORDER_ANY);
+ MUTATOR_HOOK(VehicleExit, buffs_VehicleExit, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerRegen, buffs_PlayerRegen, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDies, buffs_PlayerDies, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerUseKey, buffs_PlayerUseKey, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MakePlayerObserver, buffs_RemovePlayer, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ClientDisconnect, buffs_RemovePlayer, CBC_ORDER_ANY);
+ MUTATOR_HOOK(OnEntityPreSpawn, buffs_OnEntityPreSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(CustomizeWaypoint, buffs_CustomizeWaypoint, CBC_ORDER_ANY);
+ MUTATOR_HOOK(WeaponRateFactor, buffs_WeaponRate, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPreThink, buffs_PlayerThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetCvars, buffs_GetCvars, CBC_ORDER_ANY);
+ MUTATOR_HOOK(BuildMutatorsString, buffs_BuildMutatorsString, CBC_ORDER_ANY);
+ MUTATOR_HOOK(BuildMutatorsPrettyString, buffs_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+
+ MUTATOR_ONADD
+ {
+ buffs_Initialize();
+ }
+
+ return FALSE;
+}
--- /dev/null
+// buff specific variables \\
+//
+// ammo
+.float buff_ammo_prev_infitems;
+// invisible
+.float buff_invisible_prev_alpha;
+// flight
+.float buff_flight_prev_gravity;
+// disability
+.float buff_disability_time;
+.float buff_disability_effect_time;
+
+// buff definitions
+.float buff_active;
+.float buff_activetime;
+.float buff_activetime_updated;
+.entity buff_waypoint;
+.float oldbuffs; // for updating effects
+.entity buff_model; // controls effects (TODO: make csqc)
+
+#define BUFF_MIN ('-16 -16 -20')
+#define BUFF_MAX ('16 16 20')
+
+// client side options
+.float cvar_cl_buffs_autoreplace;
{
if(IS_PLAYER(self))
if(self.deadflag == DEAD_NO)
+ if(!self.frozen)
if(autocvar_g_campcheck_interval)
{
vector dist;
float clean_up_and_do_nothing;
float horiz_speed = autocvar_sv_dodging_horiz_speed;
- if(self.freezetag_frozen)
+ if(self.frozen)
horiz_speed = autocvar_sv_dodging_horiz_speed_frozen;
if (self.deadflag != DEAD_NO)
tap_direction_x = 0;
tap_direction_y = 0;
- float frozen_dodging;
- frozen_dodging = (self.freezetag_frozen && autocvar_sv_dodging_frozen);
+ float frozen_dodging, frozen_no_doubletap;
+ frozen_dodging = (self.frozen && autocvar_sv_dodging_frozen);
+ frozen_no_doubletap = (frozen_dodging && !autocvar_sv_dodging_frozen_doubletap);
float dodge_detected;
if (g_dodging == 0)
if (self.movement_x > 0) {
// is this a state change?
- if (!(self.pressedkeys & KEY_FORWARD) || frozen_dodging) {
+ if (!(self.pressedkeys & KEY_FORWARD) || frozen_no_doubletap) {
if ((time - self.last_FORWARD_KEY_time) < self.cvar_cl_dodging_timeout) {
tap_direction_x = 1.0;
dodge_detected = 1;
if (self.movement_x < 0) {
// is this a state change?
- if (!(self.pressedkeys & KEY_BACKWARD) || frozen_dodging) {
+ if (!(self.pressedkeys & KEY_BACKWARD) || frozen_no_doubletap) {
tap_direction_x = -1.0;
if ((time - self.last_BACKWARD_KEY_time) < self.cvar_cl_dodging_timeout) {
dodge_detected = 1;
if (self.movement_y > 0) {
// is this a state change?
- if (!(self.pressedkeys & KEY_RIGHT) || frozen_dodging) {
+ if (!(self.pressedkeys & KEY_RIGHT) || frozen_no_doubletap) {
tap_direction_y = 1.0;
if ((time - self.last_RIGHT_KEY_time) < self.cvar_cl_dodging_timeout) {
dodge_detected = 1;
if (self.movement_y < 0) {
// is this a state change?
- if (!(self.pressedkeys & KEY_LEFT) || frozen_dodging) {
+ if (!(self.pressedkeys & KEY_LEFT) || frozen_no_doubletap) {
tap_direction_y = -1.0;
if ((time - self.last_LEFT_KEY_time) < self.cvar_cl_dodging_timeout) {
dodge_detected = 1;
--- /dev/null
+void spawnfunc_item_minst_cells (void)
+{
+ if (!g_instagib) { remove(self); return; }
+ if (!self.ammo_cells)
+ self.ammo_cells = autocvar_g_instagib_ammo_drop;
+
+ StartItem ("models/items/a_cells.md3",
+ "misc/itempickup.wav", 45, 0,
+ "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
+}
+
+void instagib_health_mega()
+{
+ self.max_health = 1;
+ StartItem ("models/items/g_h100.md3",
+ "misc/megahealth.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
+ "Extralife", IT_NAILS, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
+}
+
+.float instagib_nextthink;
+.float instagib_needammo;
+void instagib_stop_countdown(entity e)
+{
+ if (!e.instagib_needammo)
+ return;
+ Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_MINSTA_FINDAMMO);
+ e.instagib_needammo = FALSE;
+}
+void instagib_ammocheck()
+{
+ if (!IS_PLAYER(self))
+ return; // not a player
+ if (time < self.instagib_nextthink)
+ return;
+
+ if (self.deadflag || gameover)
+ instagib_stop_countdown(self);
+ else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
+ instagib_stop_countdown(self);
+ else
+ {
+ self.instagib_needammo = TRUE;
+ if (self.health == 5)
+ {
+ Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_INSTAGIB_TERMINATED);
+ }
+ else if (self.health == 10)
+ {
+ Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_1);
+ }
+ else if (self.health == 20)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_2);
+ }
+ else if (self.health == 30)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_3);
+ }
+ else if (self.health == 40)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_4);
+ }
+ else if (self.health == 50)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_5);
+ }
+ else if (self.health == 60)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_6);
+ }
+ else if (self.health == 70)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_7);
+ }
+ else if (self.health == 80)
+ {
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_8);
+ }
+ else if (self.health == 90)
+ {
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO);
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_9);
+ }
+ else if (self.health == 100)
+ {
+ Send_Notification(NOTIF_ONE_ONLY, self, MSG_MULTI, MULTI_MINSTA_FINDAMMO);
+ Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+ }
+ }
+ self.instagib_nextthink = time + 1;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MatchEnd)
+{
+ entity head;
+ FOR_EACH_PLAYER(head)
+ instagib_stop_countdown(head);
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MonsterLoot)
+{
+ other.monster_loot = spawnfunc_item_minst_cells;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MonsterSpawn)
+{
+ // always refill ammo
+ if(self.monsterid == MON_MAGE)
+ self.skin = 1;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_BotShouldAttack)
+{
+ if(checkentity.items & IT_STRENGTH)
+ return TRUE;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MakePlayerObserver)
+{
+ instagib_stop_countdown(self);
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerSpawn)
+{
+ self.effects |= EF_FULLBRIGHT;
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPreThink)
+{
+ instagib_ammocheck();
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerRegen)
+{
+ // no regeneration in instagib
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPowerups)
+{
+ if (!(self.effects & EF_FULLBRIGHT))
+ self.effects |= EF_FULLBRIGHT;
+
+ if (self.items & IT_STRENGTH)
+ {
+ play_countdown(self.strength_finished, "misc/poweroff.wav");
+ if (time > self.strength_finished)
+ {
+ self.alpha = default_player_alpha;
+ self.exteriorweaponentity.alpha = default_weapon_alpha;
+ self.items &= ~IT_STRENGTH;
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
+ }
+ }
+ else
+ {
+ if (time < self.strength_finished)
+ {
+ self.alpha = autocvar_g_instagib_invis_alpha;
+ self.exteriorweaponentity.alpha = autocvar_g_instagib_invis_alpha;
+ self.items |= IT_STRENGTH;
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
+ }
+ }
+
+ if (self.items & IT_INVINCIBLE)
+ {
+ play_countdown(self.invincible_finished, "misc/poweroff.wav");
+ if (time > self.invincible_finished)
+ {
+ self.items &= ~IT_INVINCIBLE;
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
+ }
+ }
+ else
+ {
+ if (time < self.invincible_finished)
+ {
+ self.items |= IT_INVINCIBLE;
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
+ }
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPhysics)
+{
+ if(self.items & IT_INVINCIBLE)
+ self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_instagib_speed_highspeed;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_SplitHealthArmor)
+{
+ damage_save = 0;
+ damage_take = frag_damage;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_ForbidThrowing)
+{
+ // weapon dropping on death handled by FilterItem
+
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
+{
+ if(autocvar_g_friendlyfire == 0 && SAME_TEAM(frag_target, frag_attacker) && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
+ frag_damage = 0;
+
+ if(IS_PLAYER(frag_target))
+ {
+ if ((frag_deathtype == DEATH_FALL) ||
+ (frag_deathtype == DEATH_DROWN) ||
+ (frag_deathtype == DEATH_SLIME) ||
+ (frag_deathtype == DEATH_LAVA))
+ {
+ frag_damage = 0;
+ }
+
+ if(IS_PLAYER(frag_attacker))
+ if(DEATH_ISWEAPON(frag_deathtype, WEP_MINSTANEX))
+ if(frag_target.armorvalue)
+ {
+ frag_target.armorvalue -= 1;
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_target.armorvalue);
+ frag_damage = 0;
+ frag_target.damage_dealt += 1;
+ frag_attacker.damage_dealt += 1; // TODO change this to a future specific hitsound for armor hit
+ }
+
+ if(IS_PLAYER(frag_attacker))
+ if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
+ {
+ frag_damage = 0;
+ frag_mirrordamage = 0;
+ if (frag_target != frag_attacker)
+ {
+ if (frag_target.health >= 1)
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_SECONDARY);
+ frag_force = '0 0 0';
+ // keep mirrorfrag_force
+ //frag_attacker = frag_target;
+ }
+ }
+ }
+
+ if(IS_PLAYER(frag_attacker))
+ if(frag_mirrordamage > 0)
+ {
+ // just lose extra LIVES, don't kill the player for mirror damage
+ if(frag_attacker.armorvalue > 0)
+ {
+ frag_attacker.armorvalue -= 1;
+ Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_attacker.armorvalue);
+ frag_attacker.damage_dealt += 1;
+ }
+ frag_mirrordamage = 0;
+ }
+
+ if(frag_target.items & IT_STRENGTH)
+ yoda = 1;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_SetStartItems)
+{
+ start_ammo_cells = cvar("g_instagib_ammo_start");
+
+ start_health = 100;
+ start_armorvalue = 0;
+ start_weapons = WEPSET_MINSTANEX;
+ warmup_start_weapons = WEPSET_MINSTANEX;
+ start_items |= IT_UNLIMITED_SUPERWEAPONS;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_FilterItem)
+{
+ if(self.classname == "item_cells")
+ return TRUE; // no normal cells?
+
+ if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
+ {
+ self.ammo_cells = autocvar_g_instagib_ammo_drop;
+ return FALSE;
+ }
+
+ if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
+ {
+ entity e = spawn();
+ setorigin(e, self.origin);
+ entity oldself;
+ oldself = self;
+ self = e;
+ spawnfunc_item_minst_cells();
+ self = oldself;
+ return TRUE;
+ }
+
+ if(self.flags & FL_POWERUP)
+ return FALSE;
+
+ if(self.ammo_cells > autocvar_g_instagib_ammo_drop && self.classname != "item_minst_cells")
+ self.ammo_cells = autocvar_g_instagib_ammo_drop;
+
+ if(self.ammo_cells && !self.weapon)
+ return FALSE;
+
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_CustomizeWaypoint)
+{
+ entity e = WaypointSprite_getviewentity(other);
+
+ // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
+ // but only apply this to real players, not to spectators
+ if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
+ if(DIFF_TEAM(self.owner, e))
+ return TRUE;
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_ItemCountdown)
+{
+ switch(self.items)
+ {
+ case IT_STRENGTH: item_name = "item-invis"; item_color = '0 0 1'; break;
+ case IT_NAILS: item_name = "item-extralife"; item_color = '1 0 0'; break;
+ case IT_INVINCIBLE: item_name = "item-speed"; item_color = '1 0 1'; break;
+ }
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_ItemTouch)
+{
+ if(self.ammo_cells)
+ {
+ // play some cool sounds ;)
+ if (IS_CLIENT(other))
+ {
+ if(other.health <= 5)
+ Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_INSTAGIB_LASTSECOND);
+ else if(other.health < 50)
+ Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_INSTAGIB_NARROWLY);
+ }
+
+ if(other.health < 100)
+ other.health = 100;
+
+ return MUT_ITEMTOUCH_CONTINUE;
+ }
+
+ if(self.max_health)
+ {
+ other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_instagib_extralives);
+ Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
+ return MUT_ITEMTOUCH_PICKUP;
+ }
+
+ return MUT_ITEMTOUCH_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_OnEntityPreSpawn)
+{
+ if (!autocvar_g_powerups) { return FALSE; }
+ if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
+ return FALSE;
+
+ entity e = spawn();
+
+ if(random() < 0.3)
+ e.think = spawnfunc_item_strength;
+ else if(random() < 0.6)
+ e.think = instagib_health_mega;
+ else
+ e.think = spawnfunc_item_invincible;
+
+ e.nextthink = time + 0.1;
+ e.spawnflags = self.spawnflags;
+ e.noalign = self.noalign;
+ setorigin(e, self.origin);
+
+ return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_BuildMutatorsString)
+{
+ ret_string = strcat(ret_string, ":instagib");
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_BuildMutatorsPrettyString)
+{
+ ret_string = strcat(ret_string, ", instagib");
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_SetModname)
+{
+ modname = "instagib";
+ return TRUE;
+}
+
+MUTATOR_DEFINITION(mutator_instagib)
+{
+ MUTATOR_HOOK(MatchEnd, instagib_MatchEnd, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MonsterDropItem, instagib_MonsterLoot, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MonsterSpawn, instagib_MonsterSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(BotShouldAttack, instagib_BotShouldAttack, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPhysics, instagib_PlayerPhysics, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerSpawn, instagib_PlayerSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDamage_Calculate, instagib_PlayerDamage, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MakePlayerObserver, instagib_MakePlayerObserver, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SetStartItems, instagib_SetStartItems, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ItemTouch, instagib_ItemTouch, CBC_ORDER_ANY);
+ MUTATOR_HOOK(FilterItem, instagib_FilterItem, CBC_ORDER_ANY);
+ MUTATOR_HOOK(CustomizeWaypoint, instagib_CustomizeWaypoint, CBC_ORDER_ANY);
+ MUTATOR_HOOK(Item_RespawnCountdown, instagib_ItemCountdown, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, instagib_SplitHealthArmor, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPowerups, instagib_PlayerPowerups, CBC_ORDER_ANY);
+ MUTATOR_HOOK(ForbidThrowCurrentWeapon, instagib_ForbidThrowing, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerPreThink, instagib_PlayerPreThink, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerRegen, instagib_PlayerRegen, CBC_ORDER_ANY);
+ MUTATOR_HOOK(OnEntityPreSpawn, instagib_OnEntityPreSpawn, CBC_ORDER_ANY);
+ MUTATOR_HOOK(BuildMutatorsString, instagib_BuildMutatorsString, CBC_ORDER_ANY);
+ MUTATOR_HOOK(BuildMutatorsPrettyString, instagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SetModname, instagib_SetModname, CBC_ORDER_ANY);
+
+ return FALSE;
+}
+++ /dev/null
-void spawnfunc_item_minst_cells (void)
-{
- if (!g_minstagib) { remove(self); return; }
- if (!self.ammo_cells)
- self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-
- StartItem ("models/items/a_cells.md3",
- "misc/itempickup.wav", 45, 0,
- "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
-}
-
-void minstagib_health_mega()
-{
- self.max_health = 1;
- StartItem ("models/items/g_h100.md3",
- "misc/megahealth.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
- "Extralife", IT_NAILS, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
-}
-
-.float minstagib_nextthink;
-.float minstagib_needammo;
-void minstagib_stop_countdown(entity e)
-{
- if (!e.minstagib_needammo)
- return;
- Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_MINSTA_FINDAMMO);
- e.minstagib_needammo = FALSE;
-}
-void minstagib_ammocheck()
-{
- if (!IS_PLAYER(self))
- return; // not a player
- if (time < self.minstagib_nextthink)
- return;
-
- if (self.deadflag || gameover)
- minstagib_stop_countdown(self);
- else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
- minstagib_stop_countdown(self);
- else
- {
- self.minstagib_needammo = TRUE;
- if (self.health == 5)
- {
- Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_MINSTAGIB_TERMINATED);
- }
- else if (self.health == 10)
- {
- Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_1);
- }
- else if (self.health == 20)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_2);
- }
- else if (self.health == 30)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_3);
- }
- else if (self.health == 40)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_4);
- }
- else if (self.health == 50)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_5);
- }
- else if (self.health == 60)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_6);
- }
- else if (self.health == 70)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_7);
- }
- else if (self.health == 80)
- {
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_8);
- }
- else if (self.health == 90)
- {
- Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO);
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_9);
- }
- else if (self.health == 100)
- {
- Send_Notification(NOTIF_ONE_ONLY, self, MSG_MULTI, MULTI_MINSTA_FINDAMMO);
- Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
- }
- }
- self.minstagib_nextthink = time + 1;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MatchEnd)
-{
- entity head;
- FOR_EACH_PLAYER(head)
- minstagib_stop_countdown(head);
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MonsterLoot)
-{
- other.monster_loot = spawnfunc_item_minst_cells;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MonsterSpawn)
-{
- // always refill ammo
- if(self.monsterid == MON_MAGE)
- self.skin = 1;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_BotShouldAttack)
-{
- if(checkentity.items & IT_STRENGTH)
- return TRUE;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MakePlayerObserver)
-{
- minstagib_stop_countdown(self);
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerSpawn)
-{
- self.effects |= EF_FULLBRIGHT;
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerPreThink)
-{
- minstagib_ammocheck();
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerRegen)
-{
- // no regeneration in minstagib
- return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
-{
- if (!(self.effects & EF_FULLBRIGHT))
- self.effects |= EF_FULLBRIGHT;
-
- if (self.items & IT_STRENGTH)
- {
- play_countdown(self.strength_finished, "misc/poweroff.wav");
- if (time > self.strength_finished)
- {
- self.alpha = default_player_alpha;
- self.exteriorweaponentity.alpha = default_weapon_alpha;
- self.items &= ~IT_STRENGTH;
- Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
- }
- }
- else
- {
- if (time < self.strength_finished)
- {
- self.alpha = autocvar_g_minstagib_invis_alpha;
- self.exteriorweaponentity.alpha = autocvar_g_minstagib_invis_alpha;
- self.items |= IT_STRENGTH;
- Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
- Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
- }
- }
-
- if (self.items & IT_INVINCIBLE)
- {
- play_countdown(self.invincible_finished, "misc/poweroff.wav");
- if (time > self.invincible_finished)
- {
- self.items &= ~IT_INVINCIBLE;
- Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
- }
- }
- else
- {
- if (time < self.invincible_finished)
- {
- self.items |= IT_INVINCIBLE;
- Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
- Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
- }
- }
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerPhysics)
-{
- if(self.items & IT_INVINCIBLE)
- self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_minstagib_speed_highspeed;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_SplitHealthArmor)
-{
- damage_save = 0;
- damage_take = frag_damage;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_ForbidThrowing)
-{
- // weapon dropping on death handled by FilterItem
- nades_CheckThrow();
-
- return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerDamage)
-{
- if(autocvar_g_friendlyfire == 0 && SAME_TEAM(frag_target, frag_attacker) && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
- frag_damage = 0;
-
- if(IS_PLAYER(frag_target))
- {
- if ((frag_deathtype == DEATH_FALL) ||
- (frag_deathtype == DEATH_DROWN) ||
- (frag_deathtype == DEATH_SLIME) ||
- (frag_deathtype == DEATH_LAVA))
- {
- frag_damage = 0;
- }
-
- if(IS_PLAYER(frag_attacker))
- if(DEATH_ISWEAPON(frag_deathtype, WEP_MINSTANEX))
- if(frag_target.armorvalue)
- {
- frag_target.armorvalue -= 1;
- Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_target.armorvalue);
- frag_damage = 0;
- frag_target.hitsound += 1;
- frag_attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
- }
-
- if(IS_PLAYER(frag_attacker))
- if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
- {
- frag_damage = 0;
- frag_mirrordamage = 0;
- if (frag_target != frag_attacker)
- {
- if (frag_target.health >= 1)
- Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_SECONDARY);
- frag_force = '0 0 0';
- // keep mirrorfrag_force
- //frag_attacker = frag_target;
- }
- }
- }
-
- if(IS_PLAYER(frag_attacker))
- if(frag_mirrordamage > 0)
- {
- // just lose extra LIVES, don't kill the player for mirror damage
- if(frag_attacker.armorvalue > 0)
- {
- frag_attacker.armorvalue -= 1;
- Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_attacker.armorvalue);
- frag_attacker.hitsound += 1;
- }
- frag_mirrordamage = 0;
- }
-
- if(frag_target.items & IT_STRENGTH)
- yoda = 1;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_SetStartItems)
-{
- start_ammo_cells = cvar("g_minstagib_ammo_start");
-
- start_health = 100;
- start_armorvalue = 0;
- start_weapons = WEPSET_MINSTANEX;
- warmup_start_weapons = WEPSET_MINSTANEX;
- start_items |= IT_UNLIMITED_SUPERWEAPONS;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_FilterItem)
-{
- if(self.classname == "item_cells")
- return TRUE; // no normal cells?
-
- if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
- {
- self.ammo_cells = autocvar_g_minstagib_ammo_drop;
- return FALSE;
- }
-
- if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
- {
- entity e = spawn();
- setorigin(e, self.origin);
- entity oldself;
- oldself = self;
- self = e;
- spawnfunc_item_minst_cells();
- self = oldself;
- return TRUE;
- }
-
- if(self.flags & FL_POWERUP)
- return FALSE;
-
- if(self.ammo_cells > autocvar_g_minstagib_ammo_drop && self.classname != "item_minst_cells")
- self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-
- if(self.ammo_cells && !self.weapon)
- return FALSE;
-
- return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_CustomizeWaypoint)
-{
- entity e = WaypointSprite_getviewentity(other);
-
- // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
- // but only apply this to real players, not to spectators
- if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
- if(DIFF_TEAM(self.owner, e))
- return TRUE;
-
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_ItemCountdown)
-{
- switch(self.items)
- {
- case IT_STRENGTH: item_name = "item-invis"; item_color = '0 0 1'; break;
- case IT_NAILS: item_name = "item-extralife"; item_color = '1 0 0'; break;
- case IT_INVINCIBLE: item_name = "item-speed"; item_color = '1 0 1'; break;
- }
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_ItemTouch)
-{
- if(self.ammo_cells)
- {
- // play some cool sounds ;)
- if (IS_CLIENT(other))
- {
- if(other.health <= 5)
- Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_MINSTAGIB_LASTSECOND);
- else if(other.health < 50)
- Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_MINSTAGIB_NARROWLY);
- }
-
- if(other.health < 100)
- other.health = 100;
-
- return MUT_ITEMTOUCH_CONTINUE;
- }
-
- if(self.max_health)
- {
- other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_minstagib_extralives);
- Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
- return MUT_ITEMTOUCH_PICKUP;
- }
-
- return MUT_ITEMTOUCH_CONTINUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_OnEntityPreSpawn)
-{
- if (!autocvar_g_powerups) { return FALSE; }
- if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
- return FALSE;
-
- entity e = spawn();
-
- if(random() < 0.3)
- e.think = spawnfunc_item_strength;
- else if(random() < 0.6)
- e.think = minstagib_health_mega;
- else
- e.think = spawnfunc_item_invincible;
-
- e.nextthink = time + 0.1;
- e.spawnflags = self.spawnflags;
- e.noalign = self.noalign;
- setorigin(e, self.origin);
-
- return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_BuildMutatorsString)
-{
- ret_string = strcat(ret_string, ":MinstaGib");
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_BuildMutatorsPrettyString)
-{
- ret_string = strcat(ret_string, ", MinstaGib");
- return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_SetModname)
-{
- modname = "MinstaGib";
- return TRUE;
-}
-
-MUTATOR_DEFINITION(mutator_minstagib)
-{
- MUTATOR_HOOK(MatchEnd, minstagib_MatchEnd, CBC_ORDER_ANY);
- MUTATOR_HOOK(MonsterDropItem, minstagib_MonsterLoot, CBC_ORDER_ANY);
- MUTATOR_HOOK(MonsterSpawn, minstagib_MonsterSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(BotShouldAttack, minstagib_BotShouldAttack, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerPhysics, minstagib_PlayerPhysics, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerSpawn, minstagib_PlayerSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerDamage_Calculate, minstagib_PlayerDamage, CBC_ORDER_ANY);
- MUTATOR_HOOK(MakePlayerObserver, minstagib_MakePlayerObserver, CBC_ORDER_ANY);
- MUTATOR_HOOK(SetStartItems, minstagib_SetStartItems, CBC_ORDER_ANY);
- MUTATOR_HOOK(ItemTouch, minstagib_ItemTouch, CBC_ORDER_ANY);
- MUTATOR_HOOK(FilterItem, minstagib_FilterItem, CBC_ORDER_ANY);
- MUTATOR_HOOK(CustomizeWaypoint, minstagib_CustomizeWaypoint, CBC_ORDER_ANY);
- MUTATOR_HOOK(Item_RespawnCountdown, minstagib_ItemCountdown, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, minstagib_SplitHealthArmor, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerPowerups, minstagib_PlayerPowerups, CBC_ORDER_ANY);
- MUTATOR_HOOK(ForbidThrowCurrentWeapon, minstagib_ForbidThrowing, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerPreThink, minstagib_PlayerPreThink, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerRegen, minstagib_PlayerRegen, CBC_ORDER_ANY);
- MUTATOR_HOOK(OnEntityPreSpawn, minstagib_OnEntityPreSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(BuildMutatorsString, minstagib_BuildMutatorsString, CBC_ORDER_ANY);
- MUTATOR_HOOK(BuildMutatorsPrettyString, minstagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);
- MUTATOR_HOOK(SetModname, minstagib_SetModname, CBC_ORDER_ANY);
-
- return FALSE;
-}
+.entity nade_spawnloc;
+
void nade_timer_think()
{
self.skin = 8 - (self.owner.wait - time) / (autocvar_g_nades_nade_lifetime / 10);
self.nextthink = time;
if(!self.owner || wasfreed(self.owner))
remove(self);
-
}
void nade_burn_spawn(entity _nade)
{
- float p;
-
- switch(_nade.realowner.team)
- {
- case NUM_TEAM_1: p = PROJECTILE_NADE_RED_BURN; break;
- case NUM_TEAM_2: p = PROJECTILE_NADE_BLUE_BURN; break;
- case NUM_TEAM_3: p = PROJECTILE_NADE_YELLOW_BURN; break;
- case NUM_TEAM_4: p = PROJECTILE_NADE_PINK_BURN; break;
- default: p = PROJECTILE_NADE_BURN; break;
- }
-
- CSQCProjectile(_nade, TRUE, p, TRUE);
+ CSQCProjectile(_nade, TRUE, Nade_ProjectileFromID(_nade.nade_type, TRUE), TRUE);
}
void nade_spawn(entity _nade)
{
- float p;
entity timer = spawn();
setmodel(timer, "models/ok_nade_counter/ok_nade_counter.md3");
setattachment(timer, _nade, "");
timer.owner = _nade;
timer.skin = 10;
- switch(_nade.realowner.team)
+ _nade.effects |= EF_LOWPRECISION;
+
+ CSQCProjectile(_nade, TRUE, Nade_ProjectileFromID(_nade.nade_type, FALSE), TRUE);
+}
+
+void napalm_damage(float dist, float damage, float edgedamage, float burntime)
+{
+ entity e;
+ float d;
+ vector p;
+
+ if ( damage < 0 )
+ return;
+
+ RandomSelection_Init();
+ for(e = WarpZone_FindRadius(self.origin, dist, TRUE); e; e = e.chain)
+ if(e.takedamage == DAMAGE_AIM)
+ if(self.realowner != e || autocvar_g_nades_napalm_selfdamage)
+ if(!IS_PLAYER(e) || !self.realowner || DIFF_TEAM(e, self))
+ if(!e.frozen)
+ {
+ p = e.origin;
+ p_x += e.mins_x + random() * (e.maxs_x - e.mins_x);
+ p_y += e.mins_y + random() * (e.maxs_y - e.mins_y);
+ p_z += e.mins_z + random() * (e.maxs_z - e.mins_z);
+ d = vlen(WarpZone_UnTransformOrigin(e, self.origin) - p);
+ if(d < dist)
+ {
+ e.fireball_impactvec = p;
+ RandomSelection_Add(e, 0, string_null, 1 / (1 + d), !Fire_IsBurning(e));
+ }
+ }
+ if(RandomSelection_chosen_ent)
{
- case NUM_TEAM_1: p = PROJECTILE_NADE_RED; break;
- case NUM_TEAM_2: p = PROJECTILE_NADE_BLUE; break;
- case NUM_TEAM_3: p = PROJECTILE_NADE_YELLOW; break;
- case NUM_TEAM_4: p = PROJECTILE_NADE_PINK; break;
- default: p = PROJECTILE_NADE; break;
+ d = vlen(WarpZone_UnTransformOrigin(RandomSelection_chosen_ent, self.origin) - RandomSelection_chosen_ent.fireball_impactvec);
+ d = damage + (edgedamage - damage) * (d / dist);
+ Fire_AddDamage(RandomSelection_chosen_ent, self.realowner, d * burntime, burntime, self.projectiledeathtype | HITTYPE_BOUNCE);
+ //trailparticles(self, particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.fireball_impactvec);
+ pointparticles(particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.fireball_impactvec - self.origin, 1);
}
+}
- CSQCProjectile(_nade, TRUE, p, TRUE);
+void napalm_ball_think()
+{
+ if(round_handler_IsActive())
+ if(!round_handler_IsRoundStarted())
+ {
+ remove(self);
+ return;
+ }
+
+ if(time > self.pushltime)
+ {
+ remove(self);
+ return;
+ }
+
+ vector midpoint = ((self.absmin + self.absmax) * 0.5);
+ if(pointcontents(midpoint) == CONTENT_WATER)
+ {
+ self.velocity = self.velocity * 0.5;
+
+ if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
+ { self.velocity_z = 200; }
+ }
+
+ self.angles = vectoangles(self.velocity);
+
+ napalm_damage(autocvar_g_nades_napalm_ball_radius,autocvar_g_nades_napalm_ball_damage,
+ autocvar_g_nades_napalm_ball_damage,autocvar_g_nades_napalm_burntime);
+
+ self.nextthink = time + 0.1;
+}
+
+
+void nade_napalm_ball()
+{
+ entity proj;
+ vector kick;
+
+ spamsound(self, CH_SHOTS, "weapons/fireball_fire.wav", VOL_BASE, ATTEN_NORM);
+
+ proj = spawn ();
+ proj.owner = self.owner;
+ proj.realowner = self.realowner;
+ proj.team = self.owner.team;
+ proj.classname = "grenade";
+ proj.bot_dodge = TRUE;
+ proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
+ proj.movetype = MOVETYPE_BOUNCE;
+ proj.projectiledeathtype = DEATH_NADE_NAPALM;
+ PROJECTILE_MAKETRIGGER(proj);
+ setmodel(proj, "null");
+ proj.scale = 1;//0.5;
+ setsize(proj, '-4 -4 -4', '4 4 4');
+ setorigin(proj, self.origin);
+ proj.think = napalm_ball_think;
+ proj.nextthink = time;
+ proj.damageforcescale = autocvar_g_nades_napalm_ball_damageforcescale;
+ proj.effects = EF_LOWPRECISION | EF_FLAME;
+
+ kick_x =(random() - 0.5) * 2 * autocvar_g_nades_napalm_ball_spread;
+ kick_y = (random() - 0.5) * 2 * autocvar_g_nades_napalm_ball_spread;
+ kick_z = (random()/2+0.5) * autocvar_g_nades_napalm_ball_spread;
+ proj.velocity = kick;
+
+ proj.pushltime = time + autocvar_g_nades_napalm_ball_lifetime;
+
+ proj.angles = vectoangles(proj.velocity);
+ proj.flags = FL_PROJECTILE;
+ proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
+
+ //CSQCProjectile(proj, TRUE, PROJECTILE_NAPALM_FIRE, TRUE);
+}
+
+
+void napalm_fountain_think()
+{
+
+ if(round_handler_IsActive())
+ if(!round_handler_IsRoundStarted())
+ {
+ remove(self);
+ return;
+ }
+
+ if(time >= self.ltime)
+ {
+ remove(self);
+ return;
+ }
+
+ vector midpoint = ((self.absmin + self.absmax) * 0.5);
+ if(pointcontents(midpoint) == CONTENT_WATER)
+ {
+ self.velocity = self.velocity * 0.5;
+
+ if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
+ { self.velocity_z = 200; }
+
+ UpdateCSQCProjectile(self);
+ }
+
+ napalm_damage(autocvar_g_nades_napalm_fountain_radius, autocvar_g_nades_napalm_fountain_damage,
+ autocvar_g_nades_napalm_fountain_edgedamage, autocvar_g_nades_napalm_burntime);
+
+ self.nextthink = time + 0.1;
+ if(time >= self.nade_special_time)
+ {
+ self.nade_special_time = time + autocvar_g_nades_napalm_fountain_delay;
+ nade_napalm_ball();
+ }
+}
+
+void nade_napalm_boom()
+{
+ entity fountain;
+ local float c;
+ for (c = 0; c < autocvar_g_nades_napalm_ball_count; c ++)
+ nade_napalm_ball();
+
+
+ fountain = spawn();
+ fountain.owner = self.owner;
+ fountain.realowner = self.realowner;
+ fountain.origin = self.origin;
+ setorigin(fountain, fountain.origin);
+ fountain.think = napalm_fountain_think;
+ fountain.nextthink = time;
+ fountain.ltime = time + autocvar_g_nades_napalm_fountain_lifetime;
+ fountain.pushltime = fountain.ltime;
+ fountain.team = self.team;
+ fountain.movetype = MOVETYPE_TOSS;
+ fountain.projectiledeathtype = DEATH_NADE_NAPALM;
+ fountain.bot_dodge = TRUE;
+ fountain.bot_dodgerating = autocvar_g_nades_napalm_fountain_damage;
+ fountain.nade_special_time = time;
+ setsize(fountain, '-16 -16 -16', '16 16 16');
+ CSQCProjectile(fountain, TRUE, PROJECTILE_NAPALM_FOUNTAIN, TRUE);
+}
+
+void nade_ice_freeze(entity freezefield, entity frost_target, float freeze_time)
+{
+ frost_target.frozen_by = freezefield.realowner;
+ pointparticles(particleeffectnum("electro_impact"), frost_target.origin, '0 0 0', 1);
+ Freeze(frost_target, 1/freeze_time, 3, FALSE);
+ if(frost_target.ballcarried)
+ if(g_keepaway) { ka_DropEvent(frost_target); }
+ else { DropBall(frost_target.ballcarried, frost_target.origin, frost_target.velocity);}
+ if(frost_target.flagcarried) { ctf_Handle_Throw(frost_target, world, DROP_THROW); }
+ if(frost_target.nade) { toss_nade(frost_target, '0 0 0', time + 0.05); }
+
+ kh_Key_DropAll(frost_target, FALSE);
+}
+
+void nade_ice_think()
+{
+
+ if(round_handler_IsActive())
+ if(!round_handler_IsRoundStarted())
+ {
+ remove(self);
+ return;
+ }
+
+ if(time >= self.ltime)
+ {
+ if ( autocvar_g_nades_ice_explode )
+ {
+ string expef;
+ switch(self.realowner.team)
+ {
+ case NUM_TEAM_1: expef = "nade_red_explode"; break;
+ case NUM_TEAM_2: expef = "nade_blue_explode"; break;
+ case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
+ case NUM_TEAM_4: expef = "nade_pink_explode"; break;
+ default: expef = "nade_neutral_explode"; break;
+ }
+ pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1);
+ sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
+
+ RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+ autocvar_g_nades_nade_radius, self, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
+ Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+ autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
+ }
+ remove(self);
+ return;
+ }
+
+
+ self.nextthink = time+0.1;
+
+ // gaussian
+ float randomr;
+ randomr = random();
+ randomr = exp(-5*randomr*randomr)*autocvar_g_nades_nade_radius;
+ float randomw;
+ randomw = random()*M_PI*2;
+ vector randomp;
+ randomp_x = randomr*cos(randomw);
+ randomp_y = randomr*sin(randomw);
+ randomp_z = 1;
+ pointparticles(particleeffectnum("electro_muzzleflash"), self.origin + randomp, '0 0 0', 1);
+
+ if(time >= self.nade_special_time)
+ {
+ self.nade_special_time = time+0.7;
+
+
+ pointparticles(particleeffectnum("electro_impact"), self.origin, '0 0 0', 1);
+ pointparticles(particleeffectnum("icefield"), self.origin, '0 0 0', 1);
+ }
+
+
+ float current_freeze_time = self.ltime - time - 0.1;
+
+ entity e;
+ for(e = findradius(self.origin, autocvar_g_nades_nade_radius); e; e = e.chain)
+ if(e != self)
+ if(!autocvar_g_nades_ice_teamcheck || (DIFF_TEAM(e, self.realowner) || e == self.realowner))
+ if(e.takedamage && e.deadflag == DEAD_NO)
+ if(e.health > 0)
+ if(!e.revival_time || ((time - e.revival_time) >= 1.5))
+ if(!e.frozen)
+ if(current_freeze_time > 0)
+ nade_ice_freeze(self, e, current_freeze_time);
+}
+
+void nade_ice_boom()
+{
+ entity fountain;
+ fountain = spawn();
+ fountain.owner = self.owner;
+ fountain.realowner = self.realowner;
+ fountain.origin = self.origin;
+ setorigin(fountain, fountain.origin);
+ fountain.think = nade_ice_think;
+ fountain.nextthink = time;
+ fountain.ltime = time + autocvar_g_nades_ice_freeze_time;
+ fountain.pushltime = fountain.wait = fountain.ltime;
+ fountain.team = self.team;
+ fountain.movetype = MOVETYPE_TOSS;
+ fountain.projectiledeathtype = DEATH_NADE_ICE;
+ fountain.bot_dodge = FALSE;
+ setsize(fountain, '-16 -16 -16', '16 16 16');
+ fountain.nade_special_time = time+0.3;
+ fountain.angles = self.angles;
+
+ if ( autocvar_g_nades_ice_explode )
+ {
+ setmodel(fountain, "models/grenademodel.md3");
+ entity timer = spawn();
+ setmodel(timer, "models/ok_nade_counter/ok_nade_counter.md3");
+ setattachment(timer, fountain, "");
+ timer.classname = "nade_timer";
+ timer.colormap = self.colormap;
+ timer.glowmod = self.glowmod;
+ timer.think = nade_timer_think;
+ timer.nextthink = time;
+ timer.wait = fountain.ltime;
+ timer.owner = fountain;
+ timer.skin = 10;
+ }
+ else
+ setmodel(fountain, "null");
+}
+
+void nade_translocate_boom()
+{
+ if(self.realowner.vehicle)
+ return;
+
+ vector locout = self.origin + '0 0 1' * (1 - self.realowner.mins_z - 24);
+ tracebox(locout, self.realowner.mins, self.realowner.maxs, locout, MOVE_NOMONSTERS, self.realowner);
+ locout = trace_endpos;
+
+ makevectors(self.realowner.angles);
+
+ entity oldself = self;
+ self = self.realowner;
+ MUTATOR_CALLHOOK(PortalTeleport);
+ self.realowner = self;
+ self = oldself;
+
+ TeleportPlayer(self, self.realowner, locout, self.realowner.mangle, v_forward * vlen(self.realowner.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
+}
+
+void nade_spawn_boom()
+{
+ entity spawnloc = spawn();
+ setorigin(spawnloc, self.origin);
+ setsize(spawnloc, self.realowner.mins, self.realowner.maxs);
+ spawnloc.movetype = MOVETYPE_NONE;
+ spawnloc.solid = SOLID_NOT;
+ spawnloc.drawonlytoclient = self.realowner;
+ spawnloc.effects = EF_STARDUST;
+ spawnloc.cnt = autocvar_g_nades_spawn_count;
+
+ if(self.realowner.nade_spawnloc)
+ {
+ remove(self.realowner.nade_spawnloc);
+ self.realowner.nade_spawnloc = world;
+ }
+
+ self.realowner.nade_spawnloc = spawnloc;
+}
+
+void nade_heal_think()
+{
+ if(time >= self.ltime)
+ {
+ remove(self);
+ return;
+ }
+
+ self.nextthink = time;
+
+ if(time >= self.nade_special_time)
+ {
+ self.nade_special_time = time+0.25;
+ self.nade_show_particles = 1;
+ }
+ else
+ self.nade_show_particles = 0;
+}
+
+void nade_heal_touch()
+{
+ float maxhealth;
+ float health_factor;
+ if(IS_PLAYER(other) || (other.flags & FL_MONSTER))
+ if(other.deadflag == DEAD_NO)
+ if(!other.frozen)
+ {
+ health_factor = autocvar_g_nades_heal_rate*frametime/2;
+ if ( other != self.realowner )
+ {
+ if ( SAME_TEAM(other,self) )
+ health_factor *= autocvar_g_nades_heal_friend;
+ else
+ health_factor *= autocvar_g_nades_heal_foe;
+ }
+ if ( health_factor > 0 )
+ {
+ maxhealth = (other.flags & FL_MONSTER) ? other.max_health : g_pickup_healthmega_max;
+ if ( other.health < maxhealth )
+ {
+ if ( self.nade_show_particles )
+ pointparticles(particleeffectnum("healing_fx"), other.origin, '0 0 0', 1);
+ other.health = min(other.health+health_factor, maxhealth);
+ }
+ other.pauserothealth_finished = max(other.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
+ }
+ else if ( health_factor < 0 )
+ {
+ Damage(other,self,self.realowner,-health_factor,DEATH_NADE_HEAL,other.origin,'0 0 0');
+ }
+
+ }
+
+ if ( IS_REAL_CLIENT(other) || (other.vehicle_flags & VHF_ISVEHICLE) )
+ {
+ entity show_red = (other.vehicle_flags & VHF_ISVEHICLE) ? other.owner : other;
+ show_red.stat_healing_orb = time+0.1;
+ show_red.stat_healing_orb_alpha = 0.75 * (self.ltime - time) / self.healer_lifetime;
+ }
+}
+
+void nade_heal_boom()
+{
+ entity healer;
+ healer = spawn();
+ healer.owner = self.owner;
+ healer.realowner = self.realowner;
+ setorigin(healer, self.origin);
+ healer.healer_lifetime = autocvar_g_nades_heal_time; // save the cvar
+ healer.ltime = time + healer.healer_lifetime;
+ healer.team = self.realowner.team;
+ healer.bot_dodge = FALSE;
+ healer.solid = SOLID_TRIGGER;
+ healer.touch = nade_heal_touch;
+
+ setmodel(healer, "models/ctf/shield.md3");
+ healer.healer_radius = autocvar_g_nades_nade_radius;
+ vector size = '1 1 1' * healer.healer_radius / 2;
+ setsize(healer,-size,size);
+
+ Net_LinkEntity(healer, TRUE, 0, healer_send);
+
+ healer.think = nade_heal_think;
+ healer.nextthink = time;
+ healer.SendFlags |= 1;
+}
+
+void nade_monster_boom()
+{
+ entity e = spawnmonster(self.pokenade_type, 0, self.realowner, self.realowner, self.origin, FALSE, FALSE, 1);
+
+ if(autocvar_g_nades_pokenade_monster_lifetime > 0)
+ e.monster_lifetime = time + autocvar_g_nades_pokenade_monster_lifetime;
+ e.monster_skill = MONSTER_SKILL_INSANE;
}
void nade_boom()
{
string expef;
+ float nade_blast = 1;
- switch(self.realowner.team)
+ switch ( self.nade_type )
{
- case NUM_TEAM_1: expef = "nade_red_explode"; break;
- case NUM_TEAM_2: expef = "nade_blue_explode"; break;
- case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
- case NUM_TEAM_4: expef = "nade_pink_explode"; break;
- default: expef = "nade_explode"; break;
+ case NADE_TYPE_NAPALM:
+ nade_blast = autocvar_g_nades_napalm_blast;
+ expef = "explosion_medium";
+ break;
+ case NADE_TYPE_ICE:
+ nade_blast = 0;
+ expef = "electro_combo"; // hookbomb_explode electro_combo bigplasma_impact
+ break;
+ case NADE_TYPE_TRANSLOCATE:
+ nade_blast = 0;
+ expef = "";
+ break;
+ case NADE_TYPE_MONSTER:
+ case NADE_TYPE_SPAWN:
+ nade_blast = 0;
+ switch(self.realowner.team)
+ {
+ case NUM_TEAM_1: expef = "spawn_event_red"; break;
+ case NUM_TEAM_2: expef = "spawn_event_blue"; break;
+ case NUM_TEAM_3: expef = "spawn_event_yellow"; break;
+ case NUM_TEAM_4: expef = "spawn_event_pink"; break;
+ default: expef = "spawn_event_neutral"; break;
+ }
+ break;
+ case NADE_TYPE_HEAL:
+ nade_blast = 0;
+ expef = "spawn_event_red";
+ break;
+
+ default:
+ case NADE_TYPE_NORMAL:
+ switch(self.realowner.team)
+ {
+ case NUM_TEAM_1: expef = "nade_red_explode"; break;
+ case NUM_TEAM_2: expef = "nade_blue_explode"; break;
+ case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
+ case NUM_TEAM_4: expef = "nade_pink_explode"; break;
+ default: expef = "nade_neutral_explode"; break;
+ }
}
- sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
- sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1);
- Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
+ sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
+ sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
self.takedamage = DAMAGE_NO;
- RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+
+ if(nade_blast)
+ {
+ RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
autocvar_g_nades_nade_radius, self, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
+ Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
+ }
+
+ switch ( self.nade_type )
+ {
+ case NADE_TYPE_NAPALM: nade_napalm_boom(); break;
+ case NADE_TYPE_ICE: nade_ice_boom(); break;
+ case NADE_TYPE_TRANSLOCATE: nade_translocate_boom(); break;
+ case NADE_TYPE_SPAWN: nade_spawn_boom(); break;
+ case NADE_TYPE_HEAL: nade_heal_boom(); break;
+ case NADE_TYPE_MONSTER: nade_monster_boom(); break;
+ }
remove(self);
}
void nade_touch()
{
+ if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
PROJECTILE_TOUCH;
//setsize(self, '-2 -2 -2', '2 2 2');
//UpdateCSQCProjectile(self);
void nade_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
+ if(self.nade_type == NADE_TYPE_TRANSLOCATE || self.nade_type == NADE_TYPE_SPAWN)
+ return;
+
if(DEATH_ISWEAPON(deathtype, WEP_LASER))
return;
if(DEATH_ISWEAPON(deathtype, WEP_UZI))
damage = self.max_health * 0.1;
- if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && !(deathtype & HITTYPE_SECONDARY))
- damage = self.max_health * 1.1;
-
- if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && (deathtype & HITTYPE_SECONDARY))
+ if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN))
+ if(deathtype & HITTYPE_SECONDARY)
{
damage = self.max_health * 0.1;
- force *= 15;
+ force *= 10;
}
+ else
+ damage = self.max_health * 1.1;
self.velocity += force;
self.think = nade_beep;
}
- self.health -= damage;
- self.realowner = attacker;
+ self.health -= damage;
+
+ if ( self.nade_type != NADE_TYPE_HEAL || IS_PLAYER(attacker) )
+ self.realowner = attacker;
if(self.health <= 0)
W_PrepareExplosionByDamage(attacker, nade_boom);
void toss_nade(entity e, vector _velocity, float _time)
{
+ if(e.nade == world)
+ return;
+
entity _nade = e.nade;
e.nade = world;
Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
- //setorigin(_nade, CENTER_OR_VIEWOFS(e) + (v_right * 10) * -1);
setorigin(_nade, w_shotorg + (v_right * 25) * -1);
- setmodel(_nade, "models/weapons/v_ok_grenade.md3");
- setattachment(_nade, world, "");
+ //setmodel(_nade, "models/weapons/v_ok_grenade.md3");
+ //setattachment(_nade, world, "");
PROJECTILE_MAKETRIGGER(_nade);
setsize(_nade, '-16 -16 -16', '16 16 16');
_nade.movetype = MOVETYPE_BOUNCE;
_nade.velocity = _velocity;
else
_nade.velocity = W_CalculateProjectileVelocity(e.velocity, _velocity, TRUE);
-
+
_nade.touch = nade_touch;
_nade.health = autocvar_g_nades_nade_health;
_nade.max_health = _nade.health;
_nade.takedamage = DAMAGE_AIM;
_nade.event_damage = nade_damage;
+ _nade.customizeentityforclient = func_null;
+ _nade.exteriormodeltoclient = world;
+ _nade.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+ _nade.traileffectnum = 0;
_nade.teleportable = TRUE;
_nade.pushable = TRUE;
_nade.gravity = 1;
_nade.damagedbycontents = TRUE;
_nade.angles = vectoangles(_nade.velocity);
_nade.flags = FL_PROJECTILE;
+ _nade.projectiledeathtype = DEATH_NADE;
+ _nade.toss_time = time;
+ _nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
nade_spawn(_nade);
}
e.nade_refire = time + autocvar_g_nades_nade_refire;
+ e.nade_timer = 0;
+}
+
+void nades_GiveBonus(entity player, float score)
+{
+ if (autocvar_g_nades)
+ if (autocvar_g_nades_bonus)
+ if (IS_REAL_CLIENT(player))
+ if (IS_PLAYER(player) && player.bonus_nades < autocvar_g_nades_bonus_max)
+ if (player.frozen == 0)
+ if (player.deadflag == DEAD_NO)
+ {
+ if ( player.bonus_nade_score < 1 )
+ player.bonus_nade_score += score/autocvar_g_nades_bonus_score_max;
+
+ if ( player.bonus_nade_score >= 1 )
+ {
+ Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_NADE_BONUS);
+ play2(player,"kh/alarm.wav");
+ player.bonus_nades++;
+ player.bonus_nade_score -= 1;
+ }
+ }
+}
+
+void nades_RemoveBonus(entity player)
+{
+ player.bonus_nades = player.bonus_nade_score = 0;
+}
+
+float nade_customize()
+{
+ //if(IS_SPEC(other)) { return FALSE; }
+ if(other == self.realowner || (IS_SPEC(other) && other.enemy == self.realowner))
+ {
+ // somewhat hide the model, but keep the glow
+ //self.effects = 0;
+ if(self.traileffectnum)
+ self.traileffectnum = 0;
+ self.alpha = -1;
+ }
+ else
+ {
+ //self.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+ if(!self.traileffectnum)
+ self.traileffectnum = particleeffectnum(Nade_TrailEffect(Nade_ProjectileFromID(self.nade_type, FALSE), self.team));
+ self.alpha = 1;
+ }
+
+ return TRUE;
}
void nade_prime()
if(self.fake_nade)
remove(self.fake_nade);
- self.nade = spawn();
- setmodel(self.nade, "null");
- setattachment(self.nade, self, "bip01 l hand");
- self.nade.classname = "nade";
- self.nade.realowner = self;
- self.nade.colormap = self.colormap;
- self.nade.glowmod = self.glowmod;
- self.nade.wait = time + autocvar_g_nades_nade_lifetime;
- self.nade.lifetime = time;
- self.nade.think = nade_beep;
- self.nade.nextthink = max(self.nade.wait - 3, time);
- self.nade.projectiledeathtype = DEATH_NADE;
-
- self.fake_nade = spawn();
- setmodel(self.fake_nade, "models/weapons/h_ok_grenade.iqm");
- setattachment(self.fake_nade, self.weaponentity, "");
- self.fake_nade.classname = "fake_nade";
- //self.fake_nade.viewmodelforclient = self;
- self.fake_nade.realowner = self.fake_nade.owner = self;
- self.fake_nade.colormap = self.colormap;
- self.fake_nade.glowmod = self.glowmod;
- self.fake_nade.think = SUB_Remove;
- self.fake_nade.nextthink = self.nade.wait;
+ entity n = spawn(), fn = spawn();
+
+ n.classname = "nade";
+ fn.classname = "fake_nade";
+
+ if(self.items & IT_STRENGTH && autocvar_g_nades_bonus_onstrength)
+ n.nade_type = self.nade_type;
+ else if (self.bonus_nades >= 1)
+ {
+ n.nade_type = self.nade_type;
+ n.pokenade_type = self.pokenade_type;
+ self.bonus_nades -= 1;
+ }
+ else
+ {
+ n.nade_type = ((autocvar_g_nades_client_select) ? self.cvar_cl_nade_type : autocvar_g_nades_nade_type);
+ n.pokenade_type = ((autocvar_g_nades_client_select) ? self.cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type);
+ }
+
+ n.nade_type = bound(1, n.nade_type, NADE_TYPE_LAST);
+
+ setmodel(n, "models/weapons/v_ok_grenade.md3");
+ //setattachment(n, self, "bip01 l hand");
+ n.exteriormodeltoclient = self;
+ n.customizeentityforclient = nade_customize;
+ n.traileffectnum = particleeffectnum(Nade_TrailEffect(Nade_ProjectileFromID(n.nade_type, FALSE), self.team));
+ n.colormod = Nade_Color(n.nade_type);
+ n.realowner = self;
+ n.colormap = self.colormap;
+ n.glowmod = self.glowmod;
+ n.wait = time + autocvar_g_nades_nade_lifetime;
+ n.lifetime = time;
+ n.think = nade_beep;
+ n.nextthink = max(n.wait - 3, time);
+ n.projectiledeathtype = DEATH_NADE;
+
+ setmodel(fn, "models/weapons/h_ok_grenade.iqm");
+ setattachment(fn, self.weaponentity, "");
+ fn.realowner = fn.owner = self;
+ fn.colormod = Nade_Color(n.nade_type);
+ fn.colormap = self.colormap;
+ fn.glowmod = self.glowmod;
+ fn.think = SUB_Remove;
+ fn.nextthink = n.wait;
+
+ self.nade = n;
+ self.fake_nade = fn;
}
float CanThrowNade()
}
}
+void nades_Clear(entity player)
+{
+ if(player.nade)
+ remove(player.nade);
+ if(player.fake_nade)
+ remove(player.fake_nade);
+
+ player.nade = player.fake_nade = world;
+ player.nade_timer = 0;
+}
+
+MUTATOR_HOOKFUNCTION(nades_CheckThrow)
+{
+ if(MUTATOR_RETURNVALUE) { nades_CheckThrow(); }
+ return FALSE;
+}
+
MUTATOR_HOOKFUNCTION(nades_VehicleEnter)
{
- if(other.nade)
- toss_nade(other, '0 0 100', max(other.nade.wait, time + 0.05));
+ if(vh_player.nade)
+ toss_nade(vh_player, '0 0 100', max(vh_player.nade.wait, time + 0.05));
return FALSE;
}
MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
{
- float key_pressed = ((g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK)) ? self.button16 : self.BUTTON_HOOK);
+ if(!IS_PLAYER(self)) { return FALSE; }
+
+ float key_pressed = self.BUTTON_HOOK;
+ float time_score;
+ if(g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK) || g_jetpack || self.items & IT_JETPACK)
+ key_pressed = self.button16; // if hook/jetpack is enabled, use an alternate key
+
if(self.nade)
- if(self.nade.wait - 0.1 <= time)
- toss_nade(self, '0 0 0', time + 0.05);
+ {
+ self.nade_timer = bound(0, (time - self.nade.lifetime) / autocvar_g_nades_nade_lifetime, 1);
+ //print(sprintf("%d %d\n", self.nade_timer, time - self.nade.lifetime));
+ makevectors(self.angles);
+ self.nade.velocity = self.velocity;
+
+ setorigin(self.nade, self.origin + self.view_ofs + v_forward * 8 + v_right * -8 + v_up * 0);
+ self.nade.angles_y = self.angles_y;
+ }
+
+ if(self.nade)
+ if(self.nade.wait - 0.1 <= time)
+ toss_nade(self, '0 0 0', time + 0.05);
if(CanThrowNade())
if(self.nade_refire < time)
}
}
+ if(IS_PLAYER(self))
+ {
+ if ( autocvar_g_nades_bonus && autocvar_g_nades )
+ {
+ entity key;
+ float key_count = 0;
+ FOR_EACH_KH_KEY(key) if(key.owner == self) { ++key_count; }
+
+ if(self.flagcarried || self.ballcarried) // this player is important
+ time_score = autocvar_g_nades_bonus_score_time_flagcarrier;
+ else
+ time_score = autocvar_g_nades_bonus_score_time;
+
+ if(key_count)
+ time_score = autocvar_g_nades_bonus_score_time_flagcarrier * key_count; // multiply by the number of keys the player is holding
+
+ if(autocvar_g_nades_bonus_client_select)
+ {
+ self.nade_type = self.cvar_cl_nade_type;
+ self.pokenade_type = self.cvar_cl_pokenade_type;
+ }
+ else
+ {
+ self.nade_type = autocvar_g_nades_bonus_type;
+ self.pokenade_type = autocvar_g_nades_pokenade_monster_type;
+ }
+
+ self.nade_type = bound(1, self.nade_type, NADE_TYPE_LAST);
+
+ if(self.bonus_nade_score >= 0 && autocvar_g_nades_bonus_score_max)
+ nades_GiveBonus(self, time_score / autocvar_g_nades_bonus_score_max);
+ }
+ else
+ {
+ self.bonus_nades = self.bonus_nade_score = 0;
+ }
+ }
+
+ float n = 0;
+ entity o = world;
+ if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
+ n = -1;
+ else
+ {
+ vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+ n = 0;
+ FOR_EACH_PLAYER(other) if(self != other)
+ {
+ if(other.deadflag == DEAD_NO)
+ if(other.frozen == 0)
+ if(SAME_TEAM(other, self))
+ if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
+ {
+ if(!o)
+ o = other;
+ if(self.frozen == 1)
+ other.reviving = TRUE;
+ ++n;
+ }
+ }
+ }
+
+ if(n && self.frozen == 3) // OK, there is at least one teammate reviving us
+ {
+ self.revive_progress = bound(0, self.revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
+ self.health = max(1, self.revive_progress * start_health);
+
+ if(self.revive_progress >= 1)
+ {
+ Unfreeze(self);
+
+ Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname);
+ Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname);
+ }
+
+ FOR_EACH_PLAYER(other) if(other.reviving)
+ {
+ other.revive_progress = self.revive_progress;
+ other.reviving = FALSE;
+ }
+ }
+
return FALSE;
}
else
self.nade_refire = time + autocvar_g_nades_nade_refire;
+ if(autocvar_g_nades_bonus_client_select)
+ self.nade_type = self.cvar_cl_nade_type;
+
+ self.nade_timer = 0;
+
+ if(self.nade_spawnloc)
+ {
+ setorigin(self, self.nade_spawnloc.origin);
+ self.nade_spawnloc.cnt -= 1;
+
+ if(self.nade_spawnloc.cnt <= 0)
+ {
+ remove(self.nade_spawnloc);
+ self.nade_spawnloc = world;
+ }
+ }
+
return FALSE;
}
MUTATOR_HOOKFUNCTION(nades_PlayerDies)
{
- if(self.nade)
- toss_nade(self, '0 0 100', max(self.nade.wait, time + 0.05));
+ if(frag_target.nade)
+ if(!frag_target.frozen || !autocvar_g_freezetag_revive_nade)
+ toss_nade(frag_target, '0 0 100', max(frag_target.nade.wait, time + 0.05));
+
+ float killcount_bonus = ((frag_attacker.killcount >= 1) ? bound(0, autocvar_g_nades_bonus_score_minor * frag_attacker.killcount, autocvar_g_nades_bonus_score_medium) : autocvar_g_nades_bonus_score_minor);
+
+ if(IS_PLAYER(frag_attacker))
+ {
+ if (SAME_TEAM(frag_attacker, frag_target) || frag_attacker == frag_target)
+ nades_RemoveBonus(frag_attacker);
+ else if(frag_target.flagcarried)
+ nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_medium);
+ else if(autocvar_g_nades_bonus_score_spree && frag_attacker.killcount > 1)
+ {
+ #define SPREE_ITEM(counta,countb,center,normal,gentle) \
+ case counta: { nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_spree); break; }
+ switch(frag_attacker.killcount)
+ {
+ KILL_SPREE_LIST
+ default: nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_minor); break;
+ }
+ #undef SPREE_ITEM
+ }
+ else
+ nades_GiveBonus(frag_attacker, killcount_bonus);
+ }
+
+ nades_RemoveBonus(frag_target);
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(nades_PlayerDamage)
+{
+ if(frag_target.frozen)
+ if(autocvar_g_freezetag_revive_nade)
+ if(frag_attacker == frag_target)
+ if(frag_deathtype == DEATH_NADE)
+ if(time - frag_inflictor.toss_time <= 0.1)
+ {
+ Unfreeze(frag_target);
+ frag_target.health = autocvar_g_freezetag_revive_nade_health;
+ pointparticles(particleeffectnum("iceorglass"), frag_target.origin, '0 0 0', 3);
+ frag_damage = 0;
+ frag_force = '0 0 0';
+ Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_NADE, frag_target.netname);
+ Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
+ }
+
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(nades_MonsterDies)
+{
+ if(IS_PLAYER(frag_attacker))
+ if(DIFF_TEAM(frag_attacker, self))
+ if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
+ nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_minor);
return FALSE;
}
MUTATOR_HOOKFUNCTION(nades_RemovePlayer)
{
- if(self.nade)
- remove(self.nade);
+ nades_Clear(self);
+ nades_RemoveBonus(self);
+ return FALSE;
+}
- if(self.fake_nade)
- remove(self.fake_nade);
+MUTATOR_HOOKFUNCTION(nades_SpectateCopy)
+{
+ self.nade_timer = other.nade_timer;
+ self.nade_type = other.nade_type;
+ self.pokenade_type = other.pokenade_type;
+ self.bonus_nades = other.bonus_nades;
+ self.bonus_nade_score = other.bonus_nade_score;
+ self.stat_healing_orb = other.stat_healing_orb;
+ self.stat_healing_orb_alpha = other.stat_healing_orb_alpha;
+ return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(nades_GetCvars)
+{
+ GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_nade_type, "cl_nade_type");
+ GetCvars_handleString(get_cvars_s, get_cvars_f, cvar_cl_pokenade_type, "cl_pokenade_type");
return FALSE;
}
return FALSE;
}
+void nades_Initialize()
+{
+ addstat(STAT_NADE_TIMER, AS_FLOAT, nade_timer);
+ addstat(STAT_NADE_BONUS, AS_FLOAT, bonus_nades);
+ addstat(STAT_NADE_BONUS_TYPE, AS_INT, nade_type);
+ addstat(STAT_NADE_BONUS_SCORE, AS_FLOAT, bonus_nade_score);
+ addstat(STAT_HEALING_ORB, AS_FLOAT, stat_healing_orb);
+ addstat(STAT_HEALING_ORB_ALPHA, AS_FLOAT, stat_healing_orb_alpha);
+
+ precache_model("models/ok_nade_counter/ok_nade_counter.md3");
+ precache_model("models/weapons/h_ok_grenade.iqm");
+ precache_model("models/weapons/v_ok_grenade.md3");
+ precache_model("models/ctf/shield.md3");
+
+ precache_sound("weapons/rocket_impact.wav");
+ precache_sound("weapons/grenade_bounce1.wav");
+ precache_sound("weapons/grenade_bounce2.wav");
+ precache_sound("weapons/grenade_bounce3.wav");
+ precache_sound("weapons/grenade_bounce4.wav");
+ precache_sound("weapons/grenade_bounce5.wav");
+ precache_sound("weapons/grenade_bounce6.wav");
+ precache_sound("overkill/grenadebip.ogg");
+}
+
MUTATOR_DEFINITION(mutator_nades)
{
+ MUTATOR_HOOK(ForbidThrowCurrentWeapon, nades_CheckThrow, CBC_ORDER_LAST);
MUTATOR_HOOK(VehicleEnter, nades_VehicleEnter, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerPreThink, nades_PlayerPreThink, CBC_ORDER_ANY);
MUTATOR_HOOK(PlayerSpawn, nades_PlayerSpawn, CBC_ORDER_ANY);
- MUTATOR_HOOK(PlayerDies, nades_PlayerDies, CBC_ORDER_ANY);
+ MUTATOR_HOOK(PlayerDies, nades_PlayerDies, CBC_ORDER_LAST);
+ MUTATOR_HOOK(PlayerDamage_Calculate, nades_PlayerDamage, CBC_ORDER_ANY);
+ MUTATOR_HOOK(MonsterDies, nades_MonsterDies, CBC_ORDER_ANY);
MUTATOR_HOOK(MakePlayerObserver, nades_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(ClientDisconnect, nades_RemovePlayer, CBC_ORDER_ANY);
+ MUTATOR_HOOK(SpectateCopy, nades_SpectateCopy, CBC_ORDER_ANY);
+ MUTATOR_HOOK(GetCvars, nades_GetCvars, CBC_ORDER_ANY);
+ MUTATOR_HOOK(reset_map_global, nades_RemovePlayer, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsString, nades_BuildMutatorsString, CBC_ORDER_ANY);
MUTATOR_HOOK(BuildMutatorsPrettyString, nades_BuildMutatorsPrettyString, CBC_ORDER_ANY);
MUTATOR_ONADD
{
- precache_model("models/ok_nade_counter/ok_nade_counter.md3");
-
- precache_model("models/weapons/h_ok_grenade.iqm");
- precache_model("models/weapons/v_ok_grenade.md3");
- precache_sound("weapons/rocket_impact.wav");
- precache_sound("weapons/grenade_bounce1.wav");
- precache_sound("weapons/grenade_bounce2.wav");
- precache_sound("weapons/grenade_bounce3.wav");
- precache_sound("weapons/grenade_bounce4.wav");
- precache_sound("weapons/grenade_bounce5.wav");
- precache_sound("weapons/grenade_bounce6.wav");
- precache_sound("overkill/grenadebip.ogg");
+ nades_Initialize();
}
return FALSE;
.entity nade;
.entity fake_nade;
+.float nade_timer;
.float nade_refire;
+.float bonus_nades;
+.float nade_special_time;
+.float bonus_nade_score;
+.float nade_type;
+.string pokenade_type;
+.entity nade_damage_target;
+.float cvar_cl_nade_type;
+.string cvar_cl_pokenade_type;
+.float toss_time;
+.float stat_healing_orb;
+.float stat_healing_orb_alpha;
+.float nade_show_particles;
-void() nades_CheckThrow;
+void toss_nade(entity e, vector _velocity, float _time);
+
+// Remove nades that are being thrown
+void(entity player) nades_Clear;
+
+// Give a bonus grenade to a player
+void(entity player, float score) nades_GiveBonus;
+// Remove all bonus nades from a player
+void(entity player) nades_RemoveBonus;
if(team_mate.msnt_timer < time)
if(SAME_TEAM(self, team_mate))
if(time > team_mate.spawnshieldtime) // spawn shielding
- if(team_mate.freezetag_frozen == 0)
+ if(team_mate.frozen == 0)
if(team_mate != self)
{
tracebox(team_mate.origin, PL_MIN, PL_MAX, team_mate.origin - '0 0 100', MOVE_WORLDONLY, team_mate);
MUTATOR_HOOKFUNCTION(touchexplode_PlayerThink)
{
if(time > self.touchexplode_time)
- if (!gameover)
+ if(!gameover)
+ if(!self.frozen)
if(IS_PLAYER(self))
if(self.deadflag == DEAD_NO)
if (!IS_INDEPENDENT_PLAYER(self))
FOR_EACH_PLAYER(other) if(self != other)
{
if(time > other.touchexplode_time)
+ if(!other.frozen)
if(other.deadflag == DEAD_NO)
if (!IS_INDEPENDENT_PLAYER(other))
if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
--- /dev/null
+void mutators_add()
+{
+ #define CHECK_MUTATOR_ADD(mut_cvar,mut_name,dependence) \
+ { if(cvar(mut_cvar) && dependence) { MUTATOR_ADD(mut_name); } }
+
+ CHECK_MUTATOR_ADD("g_dodging", mutator_dodging, 1);
+ CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, teamplay);
+ CHECK_MUTATOR_ADD("g_physical_items", mutator_physical_items, 1);
+ CHECK_MUTATOR_ADD("g_touchexplode", mutator_touchexplode, 1);
+ CHECK_MUTATOR_ADD("g_instagib", mutator_instagib, !g_nexball);
+ CHECK_MUTATOR_ADD("g_invincible_projectiles", mutator_invincibleprojectiles, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_new_toys", mutator_new_toys, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_nix", mutator_nix, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_rocket_flying", mutator_rocketflying, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_vampire", mutator_vampire, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_superspectate", mutator_superspec, 1);
+ CHECK_MUTATOR_ADD("g_pinata", mutator_pinata, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_midair", mutator_midair, 1);
+ CHECK_MUTATOR_ADD("g_bloodloss", mutator_bloodloss, !cvar("g_instagib"));
+ CHECK_MUTATOR_ADD("g_random_gravity", mutator_random_gravity, 1);
+ CHECK_MUTATOR_ADD("g_multijump", mutator_multijump, 1);
+ CHECK_MUTATOR_ADD("g_melee_only", mutator_melee_only, !cvar("g_instagib") && !g_nexball);
+ CHECK_MUTATOR_ADD("g_nades", mutator_nades, 1);
+ CHECK_MUTATOR_ADD("g_sandbox", sandbox, 1);
+ CHECK_MUTATOR_ADD("g_campcheck", mutator_campcheck, 1);
+ CHECK_MUTATOR_ADD("g_buffs", mutator_buffs, 1);
+
+ #undef CHECK_MUTATOR_ADD
+}
MUTATOR_DECLARATION(gamemode_domination);
MUTATOR_DECLARATION(gamemode_lms);
MUTATOR_DECLARATION(gamemode_invasion);
+MUTATOR_DECLARATION(gamemode_cts);
+MUTATOR_DECLARATION(gamemode_race);
+MUTATOR_DECLARATION(gamemode_tdm);
MUTATOR_DECLARATION(mutator_dodging);
MUTATOR_DECLARATION(mutator_invincibleprojectiles);
MUTATOR_DECLARATION(mutator_physical_items);
MUTATOR_DECLARATION(mutator_vampire);
MUTATOR_DECLARATION(mutator_superspec);
-MUTATOR_DECLARATION(mutator_minstagib);
+MUTATOR_DECLARATION(mutator_instagib);
MUTATOR_DECLARATION(mutator_touchexplode);
MUTATOR_DECLARATION(mutator_pinata);
MUTATOR_DECLARATION(mutator_midair);
MUTATOR_DECLARATION(mutator_melee_only);
MUTATOR_DECLARATION(mutator_nades);
MUTATOR_DECLARATION(mutator_campcheck);
+MUTATOR_DECLARATION(mutator_buffs);
MUTATOR_DECLARATION(sandbox);
--- /dev/null
+#include "base.qc"
+#include "gamemode_assault.qc"
+#include "gamemode_ca.qc"
+#include "gamemode_ctf.qc"
+#include "gamemode_domination.qc"
+#include "gamemode_freezetag.qc"
+#include "gamemode_keyhunt.qc"
+#include "gamemode_keepaway.qc"
+#include "gamemode_nexball.qc"
+#include "gamemode_onslaught.qc"
+#include "gamemode_lms.qc"
+#include "gamemode_invasion.qc"
+#include "gamemode_race.qc"
+#include "gamemode_cts.qc"
+#include "gamemode_tdm.qc"
+
+#include "mutator_invincibleproj.qc"
+#include "mutator_new_toys.qc"
+#include "mutator_nix.qc"
+#include "mutator_dodging.qc"
+#include "mutator_rocketflying.qc"
+#include "mutator_vampire.qc"
+#include "mutator_spawn_near_teammate.qc"
+#include "mutator_physical_items.qc"
+#include "sandbox.qc"
+#include "mutator_superspec.qc"
+#include "mutator_instagib.qc"
+#include "mutator_touchexplode.qc"
+#include "mutator_pinata.qc"
+#include "mutator_midair.qc"
+#include "mutator_bloodloss.qc"
+#include "mutator_random_gravity.qc"
+#include "mutator_multijump.qc"
+#include "mutator_melee_only.qc"
+#include "mutator_nades.qc"
+#include "mutator_campcheck.qc"
+#include "mutator_buffs.qc"
--- /dev/null
+#include "base.qh"
+#include "mutators.qh"
+#include "gamemode_assault.qh"
+#include "gamemode_ca.qh"
+#include "gamemode_ctf.qh"
+#include "gamemode_domination.qh"
+#include "gamemode_keyhunt.qh"
+#include "gamemode_keepaway.qh"
+#include "gamemode_nexball.qh"
+#include "gamemode_lms.qh"
+#include "gamemode_invasion.qh"
+#include "gamemode_race.qh"
+#include "gamemode_cts.qh"
+
+#include "mutator_dodging.qh"
+#include "mutator_nades.qh"
+#include "mutator_buffs.qh"
../warpzonelib/server.qh
../common/constants.qh
+../common/stats.qh
../common/teams.qh
../common/util.qh
+../common/nades.qh
+../common/buffs.qh
../common/test.qh
../common/counting.qh
../common/items.qh
../common/notifications.qh // must be after autocvars
../common/deathtypes.qh // must be after notifications
-mutators/base.qh
-mutators/mutators.qh
-mutators/gamemode_assault.qh
-mutators/gamemode_ca.qh
-mutators/gamemode_ctf.qh
-mutators/gamemode_domination.qh
-mutators/gamemode_keyhunt.qh // TODO fix this
-mutators/gamemode_keepaway.qh
-mutators/gamemode_nexball.qh
-mutators/gamemode_lms.qh
-mutators/gamemode_invasion.qh
-mutators/mutator_dodging.qh
-mutators/mutator_nades.qh
+mutators/mutators_include.qh
//// tZork Turrets ////
tturrets/include/turrets_early.qh
spawnpoints.qh
+mapvoting.qh
+
ipban.qh
race.qh
miscfunctions.qc
+mutators/mutators.qc
+
waypointsprites.qc
bot/bot.qc
g_world.qc
g_casings.qc
+mapvoting.qc
+
t_jumppads.qc
t_teleporters.qc
../common/items.qc
+../common/nades.qc
+../common/buffs.qc
+
accuracy.qc
../csqcmodellib/sv_model.qc
../common/monsters/spawn.qc
-mutators/base.qc
-mutators/gamemode_assault.qc
-mutators/gamemode_ca.qc
-mutators/gamemode_ctf.qc
-mutators/gamemode_domination.qc
-mutators/gamemode_freezetag.qc
-mutators/gamemode_keyhunt.qc
-mutators/gamemode_keepaway.qc
-mutators/gamemode_nexball.qc
-mutators/gamemode_onslaught.qc
-mutators/gamemode_lms.qc
-mutators/gamemode_invasion.qc
-mutators/mutator_invincibleproj.qc
-mutators/mutator_new_toys.qc
-mutators/mutator_nix.qc
-mutators/mutator_dodging.qc
-mutators/mutator_rocketflying.qc
-mutators/mutator_vampire.qc
-mutators/mutator_spawn_near_teammate.qc
-mutators/mutator_physical_items.qc
-mutators/sandbox.qc
-mutators/mutator_superspec.qc
-mutators/mutator_minstagib.qc
-mutators/mutator_touchexplode.qc
-mutators/mutator_pinata.qc
-mutators/mutator_midair.qc
-mutators/mutator_bloodloss.qc
-mutators/mutator_random_gravity.qc
-mutators/mutator_multijump.qc
-mutators/mutator_melee_only.qc
-mutators/mutator_nades.qc
-mutators/mutator_campcheck.qc
+mutators/mutators_include.qc
../warpzonelib/anglestransform.qc
../warpzonelib/mathlib.qc
+float race_readTime(string map, float pos)
+{
+ string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+ return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos))));
+}
+
+string race_readUID(string map, float pos)
+{
+ string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+ return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)));
+}
+
+float race_readPos(string map, float t)
+{
+ float i;
+ for (i = 1; i <= RANKINGS_CNT; ++i)
+ if (race_readTime(map, i) == 0 || race_readTime(map, i) > t)
+ return i;
+
+ return 0; // pos is zero if unranked
+}
+
+void race_writeTime(string map, float t, string myuid)
+{
+ string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+ float newpos;
+ newpos = race_readPos(map, t);
+
+ float i, prevpos = 0;
+ for(i = 1; i <= RANKINGS_CNT; ++i)
+ {
+ if(race_readUID(map, i) == myuid)
+ prevpos = i;
+ }
+ if (prevpos)
+ {
+ // player improved his existing record, only have to iterate on ranks between new and old recs
+ for (i = prevpos; i > newpos; --i)
+ {
+ db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
+ db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
+ }
+ }
+ else
+ {
+ // player has no ranked record yet
+ for (i = RANKINGS_CNT; i > newpos; --i)
+ {
+ db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
+ db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
+ }
+ }
+
+ // store new time itself
+ db_put(ServerProgsDB, strcat(map, rr, "time", ftos(newpos)), ftos(t));
+ db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(newpos)), myuid);
+}
+
+string race_readName(string map, float pos)
+{
+ string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+ return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
+}
+
+
#define MAX_CHECKPOINTS 255
void spawnfunc_target_checkpoint();
if(recordholder == e.netname)
recordholder = "";
+ if(!IS_REAL_CLIENT(e))
+ return;
+
if(!spec)
msg_entity = e;
WRITESPECTATABLE_MSG_ONE({
});
}
-void race_InitSpectator()
-{
- if(g_race_qualifying)
- if(msg_entity.enemy.race_laptime)
- race_SendNextCheckpoint(msg_entity.enemy, 1);
-}
-
void race_send_recordtime(float msg)
{
// send the server best time
void race_SendStatus(float id, entity e)
{
+ if(!IS_REAL_CLIENT(e))
+ return;
+
float msg;
if (id == 0)
msg = MSG_ONE;
});
}
-void race_setTime(string map, float t, string myuid, string mynetname, entity e) { // netname only used TEMPORARILY for printing
+void race_setTime(string map, float t, string myuid, string mynetname, entity e)
+{
+ // netname only used TEMPORARILY for printing
float newpos, player_prevpos;
newpos = race_readPos(map, t);
race_SendStatus(0, e); // "fail"
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
return;
- } else if (!newpos) { // no ranking, time worse than the worst ranked
+ }
+ else if (!newpos)
+ {
+ // no ranking, time worse than the worst ranked
oldrec = race_readTime(GetMapname(), RANKINGS_CNT);
race_SendStatus(0, e); // "fail"
Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FAIL_UNRANKED, mynetname, RANKINGS_CNT, t, oldrec);
// store new ranking
race_writeTime(GetMapname(), t, myuid);
- if (newpos == 1) {
+ if (newpos == 1)
+ {
write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t));
race_send_recordtime(MSG_ALL);
}
}
}
-void race_deleteTime(string map, float pos) {
+void race_deleteTime(string map, float pos)
+{
string rr;
if(g_cts)
rr = CTS_RECORD;
rr = RACE_RECORD;
float i;
- for (i = pos; i <= RANKINGS_CNT; ++i) {
- if (i == RANKINGS_CNT) {
+ for (i = pos; i <= RANKINGS_CNT; ++i)
+ {
+ if (i == RANKINGS_CNT)
+ {
db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), string_null);
db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), string_null);
}
- else {
+ else
+ {
db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(GetMapname(), i+1)));
db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(GetMapname(), i+1));
}
if(recordholder == e.netname)
recordholder = "";
- if(t != 0) {
+ if(t != 0)
+ {
if(cp == race_timed_checkpoint)
{
race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e);
recordholder = "";
}
- msg_entity = e;
- if(g_race_qualifying)
+ if(IS_REAL_CLIENT(e))
{
- WRITESPECTATABLE_MSG_ONE_VARNAME(dummy1, {
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
- WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
- WriteInt24_t(MSG_ONE, t); // time to that intermediate
- WriteInt24_t(MSG_ONE, recordtime); // previously best time
- WriteString(MSG_ONE, recordholder); // record holder
- });
+ msg_entity = e;
+ if(g_race_qualifying)
+ {
+ WRITESPECTATABLE_MSG_ONE_VARNAME(dummy1, {
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+ WriteInt24_t(MSG_ONE, t); // time to that intermediate
+ WriteInt24_t(MSG_ONE, recordtime); // previously best time
+ WriteString(MSG_ONE, recordholder); // record holder
+ });
+ }
}
}
else // RACE! Not Qualifying
else
lself = lother = othtime = 0;
- msg_entity = e;
- WRITESPECTATABLE_MSG_ONE_VARNAME(dummy2, {
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE);
- WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
- if(e == oth)
- {
- WriteInt24_t(MSG_ONE, 0);
- WriteByte(MSG_ONE, 0);
- WriteString(MSG_ONE, "");
- }
- else
- {
- WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
- WriteByte(MSG_ONE, lself - lother);
- WriteString(MSG_ONE, oth.netname); // record holder
- }
- });
+ if(IS_REAL_CLIENT(e))
+ {
+ msg_entity = e;
+ WRITESPECTATABLE_MSG_ONE_VARNAME(dummy2, {
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+ if(e == oth)
+ {
+ WriteInt24_t(MSG_ONE, 0);
+ WriteByte(MSG_ONE, 0);
+ WriteString(MSG_ONE, "");
+ }
+ else
+ {
+ WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
+ WriteByte(MSG_ONE, lself - lother);
+ WriteString(MSG_ONE, oth.netname); // record holder
+ }
+ });
+ }
race_checkpoint_lastplayers[cp] = e;
race_checkpoint_lasttimes[cp] = time;
race_checkpoint_lastlaps[cp] = lself;
- msg_entity = oth;
- WRITESPECTATABLE_MSG_ONE_VARNAME(dummy3, {
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT);
- WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
- if(e == oth)
- {
- WriteInt24_t(MSG_ONE, 0);
- WriteByte(MSG_ONE, 0);
- WriteString(MSG_ONE, "");
- }
- else
- {
- WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
- WriteByte(MSG_ONE, lother - lself);
- WriteString(MSG_ONE, e.netname); // record holder
- }
- });
+ if(IS_REAL_CLIENT(oth))
+ {
+ msg_entity = oth;
+ WRITESPECTATABLE_MSG_ONE_VARNAME(dummy3, {
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+ if(e == oth)
+ {
+ WriteInt24_t(MSG_ONE, 0);
+ WriteByte(MSG_ONE, 0);
+ WriteString(MSG_ONE, "");
+ }
+ else
+ {
+ WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
+ WriteByte(MSG_ONE, lother - lself);
+ WriteString(MSG_ONE, e.netname); // record holder
+ }
+ });
+ }
}
}
e.race_penalty_accumulator = 0;
e.race_lastpenalty = world;
+ if(!IS_REAL_CLIENT(e))
+ return;
+
msg_entity = e;
WRITESPECTATABLE_MSG_ONE({
WriteByte(MSG_ONE, SVC_TEMPENTITY);
other.porto_forbidden = 2; // decreased by 1 each StartFrame
- if(defrag_ents) {
+ if(defrag_ents)
+ {
if(self.race_checkpoint == -2)
{
self.race_checkpoint = other.race_checkpoint;
float largest_cp_id = 0;
float cp_amount = 0;
- for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ {
cp_amount += 1;
if(cp.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
{
race_highest_checkpoint = largest_cp_id + 1;
race_timed_checkpoint = largest_cp_id + 1;
- for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ {
if(cp.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
defragcpexists = -1;
}
}
}
- if(cp_amount == 0) {
+ if(cp_amount == 0)
+ {
for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
cp.race_checkpoint = 1;
race_highest_checkpoint = 1;
while((l = fgets(fh)))
{
len = tokenize_console(l);
- if(len != 2) {
+ if(len != 2)
+ {
defragcpexists = -1; // something's wrong in the defrag cp file, set defragcpexists to -1 so that it will be rewritten when someone finishes
continue;
}
g_race_qualifying = qual;
- if(race_timed_checkpoint) {
- if(defrag_ents) {
+ if(race_timed_checkpoint)
+ {
+ if(defrag_ents)
+ {
for(cp = world; (cp = find(cp, classname, "target_startTimer"));)
WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
- for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+ for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+ {
if(cp.race_checkpoint == -2) // something's wrong with the defrag cp file or it has not been written yet, set defragcpexists to -1 so that it will be rewritten when someone finishes
defragcpexists = -1;
}
- if(defragcpexists != -1){
+ if(defragcpexists != -1)
+ {
float largest_cp_id = 0;
for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
if(cp.race_checkpoint > largest_cp_id)
cp.race_checkpoint = largest_cp_id + 1; // finish line
race_highest_checkpoint = largest_cp_id + 1;
race_timed_checkpoint = largest_cp_id + 1;
- } else {
+ }
+ else
+ {
for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
cp.race_checkpoint = 255; // finish line
race_highest_checkpoint = 255;
race_timed_checkpoint = 255;
}
}
- else {
+ else
+ {
for(cp = world; (cp = find(cp, classname, "trigger_race_checkpoint")); )
if(cp.sprite)
{
}
}
- if(defrag_ents) {
+ if(defrag_ents)
+ {
entity trigger, targ;
for(trigger = world; (trigger = find(trigger, classname, "trigger_multiple")); )
for(targ = world; (targ = find(targ, targetname, trigger.target)); )
- if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer") {
+ if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer")
+ {
trigger.wait = 0;
trigger.delay = 0;
targ.wait = 0;
void spawnfunc_trigger_race_checkpoint()
{
vector o;
- if(!g_race && !g_cts)
- {
- remove(self);
- return;
- }
+ if(!g_race && !g_cts) { remove(self); return; }
EXACTTRIGGER_INIT;
void spawnfunc_target_checkpoint() // defrag entity
{
vector o;
- if(!g_race && !g_cts)
- {
- remove(self);
- return;
- }
+ if(!g_race && !g_cts) { remove(self); return; }
defrag_ents = 1;
EXACTTRIGGER_INIT;
self.race_checkpoint = self.race_respawn_checkpoint;
}
-void race_PreDie()
-{
- if(!g_race && !g_cts)
- return;
-
- race_AbandonRaceCheck(self);
-}
-
-void race_PreSpawn()
-{
- if(!g_race && !g_cts)
- return;
- if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
- race_PreparePlayer();
- else // respawn
- race_RetractPlayer();
-
- race_AbandonRaceCheck(self);
-}
-
-void race_PostSpawn(entity spot)
-{
- if(!g_race && !g_cts)
- return;
-
- if(spot.target == "")
- // Emergency: this wasn't a real spawnpoint. Can this ever happen?
- race_PreparePlayer();
-
- // if we need to respawn, do it right
- self.race_respawn_checkpoint = self.race_checkpoint;
- self.race_respawn_spotref = spot;
-
- self.race_place = 0;
-}
-
-void race_PreSpawnObserver()
-{
- if(!g_race && !g_cts)
- return;
- race_PreparePlayer();
- self.race_checkpoint = -1;
-}
-
void spawnfunc_info_player_race (void)
{
- if(!g_race && !g_cts)
- {
- remove(self);
- return;
- }
+ if(!g_race && !g_cts) { remove(self); return; }
++race_spawns;
spawnfunc_info_player_deathmatch();
self = e;
}
-void race_ReadyRestart()
-{
- float s;
-
- Score_NicePrint(world);
-
- race_ClearRecords();
- PlayerScore_Sort(race_place, 0, 1, 0);
-
- entity e;
- FOR_EACH_CLIENT(e)
- {
- if(e.race_place)
- {
- s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
- if(!s)
- e.race_place = 0;
- }
- print(e.netname, " = ", ftos(e.race_place), "\n");
- }
-
- if(g_race_qualifying == 2)
- {
- g_race_qualifying = 0;
- independent_players = 0;
- cvar_set("fraglimit", ftos(race_fraglimit));
- cvar_set("leadlimit", ftos(race_leadlimit));
- cvar_set("timelimit", ftos(race_timelimit));
- ScoreRules_race();
- }
-}
-
void race_ImposePenaltyTime(entity pl, float penalty, string reason)
{
if(g_race_qualifying)
{
pl.race_penalty_accumulator += penalty;
- msg_entity = pl;
- WRITESPECTATABLE_MSG_ONE({
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_PENALTY_QUALIFYING);
- WriteShort(MSG_ONE, TIME_ENCODE(penalty));
- WriteString(MSG_ONE, reason);
- });
+ if(IS_REAL_CLIENT(pl))
+ {
+ msg_entity = pl;
+ WRITESPECTATABLE_MSG_ONE({
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_PENALTY_QUALIFYING);
+ WriteShort(MSG_ONE, TIME_ENCODE(penalty));
+ WriteString(MSG_ONE, reason);
+ });
+ }
}
else
{
pl.race_penalty = time + penalty;
- msg_entity = pl;
- WRITESPECTATABLE_MSG_ONE_VARNAME(dummy, {
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_PENALTY_RACE);
- WriteShort(MSG_ONE, TIME_ENCODE(penalty));
- WriteString(MSG_ONE, reason);
- });
+ if(IS_REAL_CLIENT(pl))
+ {
+ msg_entity = pl;
+ WRITESPECTATABLE_MSG_ONE_VARNAME(dummy, {
+ WriteByte(MSG_ONE, SVC_TEMPENTITY);
+ WriteByte(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_PENALTY_RACE);
+ WriteShort(MSG_ONE, TIME_ENCODE(penalty));
+ WriteString(MSG_ONE, reason);
+ });
+ }
}
}
-void race_InitSpectator();
-void race_PreSpawnObserver();
-void race_PreSpawn();
-void race_PostSpawn(entity spot);
-void race_PreDie();
-void race_ReadyRestart();
-float race_teams;
float race_spawns;
-float race_PreviousCheckpoint(float f);
-float race_NextCheckpoint(float f);
-void race_AbandonRaceCheck(entity p);
float race_highest_place_spawn; // number of places; a place higher gets spawned at 0
float race_lowest_place_spawn; // where to spawn in qualifying
float race_fraglimit;
.float race_started;
.float race_completed;
float race_completing;
-void race_ImposePenaltyTime(entity pl, float penalty, string reason);
-void race_StartCompleting();
.float race_movetime; // for reading
.float race_movetime_frac; // fractional accumulator for higher accuracy (helper for writing)
.float race_respawn_checkpoint;
.entity race_respawn_spotref; // try THIS spawn in case you respawn
+// definitions for functions used outside race.qc
+float race_PreviousCheckpoint(float f);
+float race_NextCheckpoint(float f);
+void race_AbandonRaceCheck(entity p);
+void race_ImposePenaltyTime(entity pl, float penalty, string reason);
+void race_StartCompleting();
float race_GetFractionalLapCount(entity e);
+float race_readTime(string map, float pos);
+string race_readUID(string map, float pos);
+string race_readName(string map, float pos);
if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
- if(g_cts) return 0; // in CTS, you don't lose score by observing
- if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing
-
sk = player.scorekeeper;
for(i = 0; i < MAX_SCORE; ++i)
{
ScoreRules_basics_end();
}
-// Race stuff
-#define ST_RACE_LAPS 1
-#define SP_RACE_LAPS 4
-#define SP_RACE_TIME 5
-#define SP_RACE_FASTEST 6
-void ScoreRules_race()
-{
- ScoreRules_basics(race_teams, 0, 0, FALSE);
- if(race_teams)
- {
- ScoreInfo_SetLabel_TeamScore( ST_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME, "time", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_LOWER_IS_BETTER | SFL_TIME);
- }
- else if(g_race_qualifying)
- {
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
- }
- else
- {
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS, "laps", SFL_SORT_PRIO_PRIMARY);
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME, "time", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
- ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest", SFL_LOWER_IS_BETTER | SFL_TIME);
- }
- ScoreRules_basics_end();
-}
-
// Nexball stuff
#define ST_NEXBALL_GOALS 1
#define SP_NEXBALL_GOALS 4
float spawnpoint_nag;
float SpawnEvent_Send(entity to, float sf);
entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck);
-
+entity SelectSpawnPoint (float anypoint);
if (self.watersound_finished < time)
{
self.watersound_finished = time + 0.5;
- sound (self, CH_PLAYER, "player/lava.wav", VOL_BASE, ATTEN_NORM);
+ sound (self, CH_PLAYER_SINGLE, "player/lava.wav", VOL_BASE, ATTEN_NORM);
}
Damage (self, world, world, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_LAVA, self.origin, '0 0 0');
}
if (self.watersound_finished < time)
{
self.watersound_finished = time + 0.5;
- sound (self, CH_PLAYER, "player/slime.wav", VOL_BASE, ATTEN_NORM);
+ sound (self, CH_PLAYER_SINGLE, "player/slime.wav", VOL_BASE, ATTEN_NORM);
}
Damage (self, world, world, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_SLIME, self.origin, '0 0 0');
}
{
// check for falling damage
float velocity_len = vlen(self.velocity);
- if(!self.hook.state && !(g_cts && !autocvar_g_cts_selfdamage))
+ if(!self.hook.state)
{
dm = vlen(self.oldvelocity) - velocity_len; // dm is now the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
if (self.deadflag)
float game_delay_last;
float RedirectionThink();
-entity SelectSpawnPoint (float anypoint);
void StartFrame (void)
{
execute_next_frame();
var vector autocvar_cl_weapon_stay_color = '2 0.5 0.5';
var float autocvar_cl_weapon_stay_alpha = 0.75;
var float autocvar_cl_simple_items = 0;
-var string autocvr_cl_simpleitems_postfix = "_simple";
+var string autocvar_cl_simpleitems_postfix = "_simple";
.float spawntime;
.float gravity;
.vector colormod;
- if(fexists(sprintf("%s%s.md3", _fn2, autocvr_cl_simpleitems_postfix)))
- self.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvr_cl_simpleitems_postfix));
- else if(fexists(sprintf("%s%s.dpm", _fn2, autocvr_cl_simpleitems_postfix)))
- self.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvr_cl_simpleitems_postfix));
- else if(fexists(sprintf("%s%s.iqm", _fn2, autocvr_cl_simpleitems_postfix)))
- self.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvr_cl_simpleitems_postfix));
- else if(fexists(sprintf("%s%s.obj", _fn2, autocvr_cl_simpleitems_postfix)))
- self.mdl = strzone(sprintf("%s%s.obj", _fn2, autocvr_cl_simpleitems_postfix));
+ if(fexists(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix)))
+ self.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix));
+ else if(fexists(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix)))
+ self.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix));
+ else if(fexists(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix)))
+ self.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix));
+ else if(fexists(sprintf("%s%s.obj", _fn2, autocvar_cl_simpleitems_postfix)))
+ self.mdl = strzone(sprintf("%s%s.obj", _fn2, autocvar_cl_simpleitems_postfix));
else
{
self.draw = ItemDraw;
vector v;
self.nextthink = time + 0.1;
- if (!(self.owner.active == ACTIVE_ACTIVE))
+ if(self.owner.active != ACTIVE_ACTIVE)
{
self.owner.velocity = '0 0 0';
return;
void button_use()
{
- if (!(self.active == ACTIVE_ACTIVE))
+ if(self.active != ACTIVE_ACTIVE)
return;
self.enemy = activator;
"speed" override the default 40 speed
"wait" override the default 1 second wait (-1 = never return)
"lip" override the default 4 pixel lip remaining at end of move
-"health" if set, the button must be killed instead of touched. If set to -1, the button will fire on ANY attack, even damageless ones like the MinstaGib laser
+"health" if set, the button must be killed instead of touched. If set to -1, the button will fire on ANY attack, even damageless ones like the InstaGib laser
"sounds"
0) steam metal
1) wooden clunk
// some keys were used
if (other.key_door_messagetime <= time) {
play2(other, "misc/talk.wav");
- centerprint(other, strcat("You also need ", item_keys_keylist(door.itemkeys), "!"));
+ Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(door.itemkeys));
other.key_door_messagetime = time + 2;
}
} else {
// no keys were used
if (other.key_door_messagetime <= time) {
play2(other, "misc/talk.wav");
- centerprint(other, strcat("You need ", item_keys_keylist(door.itemkeys), "!"));
+ Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(door.itemkeys));
other.key_door_messagetime = time + 2;
}
}
if (door.itemkeys) {
// door is now unlocked
play2(other, "misc/talk.wav");
- centerprint(other, "Door unlocked!");
+ Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_UNLOCKED);
return TRUE;
} else
return FALSE;
float n, i, t;
self.nextthink = time + 0.1;
- if (!(self.owner.active == ACTIVE_ACTIVE))
+ if(self.owner.active != ACTIVE_ACTIVE)
{
self.owner.velocity = '0 0 0';
return;
{
self.nextthink = time + 0.1;
- if (!(self.owner.active == ACTIVE_ACTIVE))
+ if(self.owner.active != ACTIVE_ACTIVE)
{
self.owner.velocity = '0 0 0';
return;
InitializeEntity(self, target_give_init, INITPRIO_FINDTARGET);
}
-//void spawnfunc_item_flight() /* not supported */
-//void spawnfunc_item_haste() /* not supported */
+//void spawnfunc_item_flight() /* handled by buffs mutator or jetpack */
+//void spawnfunc_item_haste() /* handled by buffs mutator */
//void spawnfunc_item_health() /* handled in t_quake.qc */
//void spawnfunc_item_health_large() /* handled in t_items.qc */
//void spawnfunc_item_health_small() /* handled in t_items.qc */
//void spawnfunc_item_health_mega() /* handled in t_items.qc */
-//void spawnfunc_item_invis() /* not supported */
-//void spawnfunc_item_regen() /* not supported */
+//void spawnfunc_item_invis() /* handled by buffs mutator */
+//void spawnfunc_item_regen() /* handled by buffs mutator */
// CTF spawnfuncs handled in mutators/gamemode_ctf.qc now
-void spawnfunc_item_flight() { spawnfunc_item_jetpack(); }
+void spawnfunc_item_flight()
+{
+ if(!cvar("g_buffs") || !cvar("g_buffs_flight"))
+ spawnfunc_item_jetpack();
+ else
+ buff_Init_Compat(self, BUFF_FLIGHT);
+}
.float notteam;
.float notsingle;
{
if(!activator)
return;
- if(!IS_REAL_CLIENT(activator))
- return;
- msg_entity = activator;
- target_music_sendto(MSG_ONE, 1);
+ if(IS_REAL_CLIENT(activator))
+ {
+ msg_entity = activator;
+ target_music_sendto(MSG_ONE, 1);
+ }
entity head;
FOR_EACH_SPEC(head) if(head.enemy == activator) { msg_entity = head; target_music_sendto(MSG_ONE, 1); }
}
PlayerScore_Clear(e);
}
-void tdm_init();
void entcs_init();
void LogTeamchange(float player_id, float team_number, float type)
if(g_tdm)
{
ActivateTeamplay();
- tdm_init();
+ fraglimit_override = autocvar_g_tdm_point_limit;
+ leadlimit_override = autocvar_g_tdm_point_leadlimit;
+ MUTATOR_ADD(gamemode_tdm);
+
if(autocvar_g_tdm_team_spawns)
have_team_spawns = -1; // request team spawns
}
fraglimit_override = autocvar_g_domination_point_limit;
leadlimit_override = autocvar_g_domination_point_leadlimit;
MUTATOR_ADD(gamemode_domination);
+
+ if(autocvar_g_domination_roundbased && autocvar_g_domination_roundbased_point_limit)
+ fraglimit_override = autocvar_g_domination_roundbased_point_limit;
+
have_team_spawns = -1; // request team spawns
}
if(g_race)
{
-
if(autocvar_g_race_teams)
{
ActivateTeamplay();
qualifying_override = autocvar_g_race_qualifying_timelimit_override;
fraglimit_override = autocvar_g_race_laps_limit;
leadlimit_override = 0; // currently not supported by race
+
+ MUTATOR_ADD(gamemode_race);
}
if(g_cts)
g_race_qualifying = 1;
fraglimit_override = 0;
leadlimit_override = 0;
+ MUTATOR_ADD(gamemode_cts);
}
if(g_nexball)
}
if(g_race || g_cts)
- {
- if(g_race_qualifying)
- independent_players = 1;
-
- ScoreRules_race();
- }
+ if(g_race_qualifying)
+ independent_players = 1;
InitializeEntity(world, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
}
if (g_grappling_hook)
s = strcat(s, "\n\n^3grappling hook^8 is enabled, press 'e' to use it\n");
+ if (cvar("g_nades"))
+ s = strcat(s, "\n\n^3nades^8 are enabled, press 'g' to use them\n");
+
if(cache_lastmutatormsg != autocvar_g_mutatormsg)
{
if(cache_lastmutatormsg)
else
{
// cover anything else by treating it like tdm with no teams spawned
- if(g_race)
- dm = race_teams;
- else
- dm = 2;
+ dm = 2;
ret_float = dm;
MUTATOR_CALLHOOK(GetTeamCount);
FOR_EACH_CLIENT(head)
{
float t;
- if(IS_PLAYER(head))
+ if(IS_PLAYER(head) || head.caplayer)
t = head.team;
else if(head.team_forced > 0)
t = head.team_forced; // reserve the spot
{
if(autocvar_g_campaign && pl && IS_REAL_CLIENT(pl))
return 1; // special case for campaign and player joining
- else if(g_domination)
- error("Too few teams available for domination\n");
- else if(g_ctf)
- error("Too few teams available for ctf\n");
- else if(g_keyhunt)
- error("Too few teams available for key hunt\n");
- else if(g_freezetag)
- error("Too few teams available for freeze tag\n");
else
- error("Too few teams available for team deathmatch\n");
+ error(sprintf("Too few teams available for %s\n", MapInfo_Type_ToString(MapInfo_CurrentGametype())));
}
// count how many players are in each team
}
if((autocvar_g_campaign) || (autocvar_g_changeteam_banned && self.wasplayer)) {
- sprint(self, "Team changes not allowed\n");
+ Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_TEAMCHANGE_NOTALLOWED);
return; // changing teams is not allowed
}
GetTeamCounts(self);
if(!TeamSmallerEqThanTeam(dteam, steam, self))
{
- sprint(self, "Cannot change to a larger/better/shinier team\n");
+ Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_TEAMCHANGE_LARGERTEAM);
return;
}
}
if(selected.deadflag == DEAD_NO)
Damage(selected, selected, selected, 100000, DEATH_AUTOTEAMCHANGE, selected.origin, '0 0 0');
- centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", Team_ColoredFullName(selected.team)));
-}
-
-// code from here on is just to support maps that don't have team entities
-void tdm_spawnteam (string teamname, float teamcolor)
-{
- entity e;
- e = spawn();
- e.classname = "tdm_team";
- e.netname = teamname;
- e.cnt = teamcolor;
- e.team = e.cnt + 1;
-}
-
-// spawn some default teams if the map is not set up for tdm
-void tdm_spawnteams()
-{
- float numteams;
-
- numteams = autocvar_g_tdm_teams_override;
- if(numteams < 2)
- numteams = autocvar_g_tdm_teams;
- numteams = bound(2, numteams, 4);
-
- tdm_spawnteam("Red", NUM_TEAM_1-1);
- tdm_spawnteam("Blue", NUM_TEAM_2-1);
- if(numteams >= 3)
- tdm_spawnteam("Yellow", NUM_TEAM_3-1);
- if(numteams >= 4)
- tdm_spawnteam("Pink", NUM_TEAM_4-1);
-}
-
-void tdm_delayedinit()
-{
- // if no teams are found, spawn defaults
- if (find(world, classname, "tdm_team") == world)
- tdm_spawnteams();
-}
-
-void tdm_init()
-{
- InitializeEntity(world, tdm_delayedinit, INITPRIO_GAMETYPE);
+ Send_Notification(NOTIF_ONE, selected, MSG_CENTER, CENTER_DEATH_SELF_AUTOTEAMCHANGE, selected.team);
}
self.firecheck_flags |= TFL_FIRECHECK_AFF;
// Our fireing routine
- if(g_minstagib)
+ if(g_instagib)
self.turret_firefunc = turret_plasma_minsta_attack;
else
self.turret_firefunc = turret_plasma_attack;
if(self.phase > time)
return;
+ if(other.frozen)
+ return;
+ if(other.vehicle)
+ return;
+ if(other.deadflag != DEAD_NO)
+ return;
if(teamplay)
if(self.team)
return;
}
- if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
+ if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.frozen)
{
if(self == owner_player.lgbeam)
owner_player.lgbeam = world;
// a player's mines shall explode if he disconnects or dies
// TODO: Do this on team change too -- Samual: But isn't a player killed when they switch teams?
- if(!IS_PLAYER(self.realowner) || self.realowner.deadflag != DEAD_NO || self.realowner.freezetag_frozen)
+ if(!IS_PLAYER(self.realowner) || self.realowner.deadflag != DEAD_NO || self.realowner.frozen)
{
other = world;
self.projectiledeathtype |= HITTYPE_BOUNCE;
head = findradius(self.origin, autocvar_g_balance_minelayer_proximityradius);
while(head)
{
- if(IS_PLAYER(head) && head.deadflag == DEAD_NO && !head.freezetag_frozen)
+ if(IS_PLAYER(head) && head.deadflag == DEAD_NO && !head.frozen)
if(head != self.realowner && DIFF_TEAM(head, self.realowner)) // don't trigger for team mates
if(!self.mine_time)
{
break;
}
- W_DecreaseAmmo(ammo_cells, ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo), autocvar_g_balance_minstanex_reload_ammo);
+ W_DecreaseAmmo(ammo_cells, ((g_instagib) ? 1 : autocvar_g_balance_minstanex_ammo), autocvar_g_balance_minstanex_reload_ammo);
}
void spawnfunc_weapon_minstanex (void); // defined in t_items.qc
float minstanex_ammo;
// now multiple WR_s use this
- minstanex_ammo = ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo);
+ minstanex_ammo = ((g_instagib) ? 1 : autocvar_g_balance_minstanex_ammo);
if (req == WR_AIM)
{
if (self.jump_interval <= time)
if (weapon_prepareattack(1, -1))
{
- // handle refire manually, so that primary and secondary can be fired without conflictions (important for minstagib)
+ // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib)
self.jump_interval = time + autocvar_g_balance_minstanex_laser_refire * W_WeaponRateFactor();
// decrease ammo for the laser?
if(autocvar_g_balance_minstanex_laser_ammo)
W_DecreaseAmmo(ammo_cells, autocvar_g_balance_minstanex_laser_ammo, autocvar_g_balance_minstanex_reload_ammo);
- // ugly minstagib hack to reuse the fire mode of the laser
+ // ugly instagib hack to reuse the fire mode of the laser
float w;
w = self.weapon;
self.weapon = WEP_LASER;
////////// WEAPONS //////////
+g_arc_simple // arc
+{
+ deformVertexes autosprite
+ cull none
+ nopicmip
+
+ {
+ map models/weapons/g_arc_simple
+ blendfunc blend
+
+ }
+}
+
g_crylink_simple // crylink
{
deformVertexes autosprite
}
}
-g_nex_simple // nex
+g_nex_simple // vortex
{
deformVertexes autosprite
cull none
}
}
-g_rl_simple // rocket launcher
+g_rl_simple // devastator
{
deformVertexes autosprite
cull none
}
}
-g_uzi_simple // machine gun
-{
- deformVertexes autosprite
- cull none
- nopicmip
-
- {
- map models/weapons/g_uzi_simple
- blendfunc blend
-
- }
-}
-
g_campingrifle_simple // sniper rifle
{
deformVertexes autosprite
}
}
-g_laser_simple // laser
+g_laser_simple // blaster
{
deformVertexes autosprite
cull none
}
}
-g_minstanex_simple // minstanex
+g_minstanex_simple // vaporizer
{
deformVertexes autosprite
cull none
blendfunc blend
}
-}
\ No newline at end of file
+}
\g_pinata\Players will drop all weapons they possessed when they are killed
\g_weapon_stay\Weapons stay after they are picked up
\g_weaponarena\Selecting a weapon arena will give all players that weapon at spawn as well as unlimited ammo, and disable all other weapon pickups.
-\g_minstagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
+\g_instagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
\g_nix\No items Xonotic - instead of pickup items, everyone plays with the same weapon. After some time, a countdown will start, after which everyone will switch to another weapon.
\g_nix_with_laser\Always carry the laser as an additional weapon in Nix
\XonoticMultiplayerDialog/Select all\Select all maps
\g_weapon_stay\Alle Waffen bleiben liegen, auch wenn sie aufgenommen wurden
\g_weaponarena\Waffen-Arenen: Die Auswahl einer Waffen-Arena führt dazu, dass jeder Spieler mit der gewählten Waffe startet. Diese hat unendlich viel Munition, andere Waffen sind nicht vorhanden - Spezielle Waffen-Arenen: Spieler starten mit allen Waffen und unendlich viel Munition
\menu_weaponarena_with_laser\Aktiviere auch den Laser in der Waffen-Arena
-\g_minstagib\Alle Spieler starten mit der MinstaNex, eine elektromagnetische Schienenkanone mit unendlich viel Schaden. Wenn ein Spieler keine Munition mehr hat, bleiben ihm 10 Sekunden um neue zu finden, ansonsten stirbt er. Der 2. Feuermodus ist Laser, welcher keinen Schaden hinzufügen kann. Dieser eignet sich gut für Tricksprünge
+\g_instagib\Alle Spieler starten mit der MinstaNex, eine elektromagnetische Schienenkanone mit unendlich viel Schaden. Wenn ein Spieler keine Munition mehr hat, bleiben ihm 10 Sekunden um neue zu finden, ansonsten stirbt er. Der 2. Feuermodus ist Laser, welcher keinen Schaden hinzufügen kann. Dieser eignet sich gut für Tricksprünge
\g_nix\Es gibt keine aufzusammelnden Gegenstände in Xonotic - Anstelle der Möglichkeit Waffen aufzusammeln, spielen alle mit der gleichen Waffe. Nach einiger Zeit startet ein Countdown, danach wechseln alle Spieler zu einer neuen gleichen Waffe
\g_nix_with_laser\In Nix ist als zweite Waffe der Laser vorhanden
\XonoticMultiplayerDialog/Select all\Wähle alle Maps
\g_weapon_stay\Las armas quedan despues de que son tomadas
\g_weaponarena\Seleccionando un arma, dara a todos los jugadores cual arma se eligió asi como infinita munición, y deshabilita cualquier otra toma de arma.
\menu_weaponarena_with_laser\Tambien habilita el láser en la arena
-\g_minstagib\Los jugadores tendran Minstanex, el cual es un railgun con daño infinito. Si el jugador queda sin munición, tendra 10 segundos para buscar mas o morira. El modo de disparo secundario es un laser que no inflige daño y es bueno para hacer bromas.
+\g_instagib\Los jugadores tendran Minstanex, el cual es un railgun con daño infinito. Si el jugador queda sin munición, tendra 10 segundos para buscar mas o morira. El modo de disparo secundario es un laser que no inflige daño y es bueno para hacer bromas.
\g_nix\Xonotic sin items - en vez de recoger items, todos juegan con la misma arma. Despues de algún tiempo, comienza una cuenta regresiva, despues del cual todos juegan con otra arma.
\g_nix_with_laser\Siempre lleva el láser como arma adicional en Nix
\XonoticMultiplayerDialog/Select all\Seleccionar todos los mapas
\g_pinata\Les joueurs lâchent toutes leurs armes quand ils meurent
\g_weapon_stay\Les armes restent où elles sont lorsqu'elles sont ramassées
\g_weaponarena\Sélectionner une arène avec une seule arme fera apparaître les joueurs avec cette arme et des munitions illimitées, et désactive toutes les autres armes
-\g_minstagib\Tous les joueurs reçoivent un Minstanex, qui est un fusil de précision d'une puissance infinie. Si vous êtes à court de munition, vous mourrez dans les 10 secondes à moins de parvenir à recharger votre arme. Le tir secondaire est un laser qui n'inflige aucun dégât et qui est utile pour sauter sur de longues distances.
+\g_instagib\Tous les joueurs reçoivent un Minstanex, qui est un fusil de précision d'une puissance infinie. Si vous êtes à court de munition, vous mourrez dans les 10 secondes à moins de parvenir à recharger votre arme. Le tir secondaire est un laser qui n'inflige aucun dégât et qui est utile pour sauter sur de longues distances.
\g_nix\No Items Xonotic - tous les joueurs jouent avec la même arme, et celle-ci change régulièrement.
\g_nix_with_laser\Autoriser le laser en plus de l'arme courante dans le mode Nix
\XonoticMultiplayerDialog/Select all\Sélectionner toutes les cartes
\g_weapon_stay\A fegyverek a helyükön maradnak, még azután is, hogy valaki felvette őket
\g_weaponarena\A kiválasztott fegyver aréna minden játékosnak ugyanazt a fegyvert biztosítja korlátlan lőszerrel, és letiltja minden más fegyver felvételét
\menu_weaponarena_with_laser\A lézer is engedélyezett a fegyver arénában
-\g_minstagib\A játékosok egy Minstanex-et kapnak, ami egy azonnal ölő mesterlövész fegyver. Ha a játékos kifogy a lőszerből, 10 másodperce van muníciót találni, vagy meghal. A másodlagos tűz mód a lézer, amely nem okoz kárt, de jól jön trükkös ugrások végrehajtásánál
+\g_instagib\A játékosok egy Minstanex-et kapnak, ami egy azonnal ölő mesterlövész fegyver. Ha a játékos kifogy a lőszerből, 10 másodperce van muníciót találni, vagy meghal. A másodlagos tűz mód a lézer, amely nem okoz kárt, de jól jön trükkös ugrások végrehajtásánál
\g_nix\Xonotic felvehető fegyverek nélkül – Mindenki ugyanazzal a fegyverrel játszik. Kis idő után visszaszámlálás indul, amely végén mindenki fegyvert vált
\g_nix_with_laser\Mindig legyen a lézer a Nix mellett kiegészítésül
\g_pinata\I giocatori rilasceranno tutte le armi che possedevano appena vengono uccisi
\g_weapon_stay\Le armi rimangono dopo che vengono raccolte
\g_weaponarena\Selezionando un'arena dedicata ad un'arma si darà a tutti i giocatori quell'arma con munizioni infinite, e disabiliterà tutti gli altri raccoglimenti delle armi.
-\g_minstagib\Ai giocatori sarà dato il Minstanex, che è un railgun con danni illimitati. Se il giocatore rimane senza munizioni, avrà 10 secondi per trovarne alcune, altrimenti morirà. Il fuoco secondario è un laser che non infligge nessun danno ed è buono per effettuare vari trickjump.
+\g_instagib\Ai giocatori sarà dato il Minstanex, che è un railgun con danni illimitati. Se il giocatore rimane senza munizioni, avrà 10 secondi per trovarne alcune, altrimenti morirà. Il fuoco secondario è un laser che non infligge nessun danno ed è buono per effettuare vari trickjump.
\g_nix\"No items Xonotic" - invece di raccogliere oggetti, ognuno giocherà con la stessa arma. Dopo un pò di tempo, un conto alla rovescia inizierà, dopo il quale ognuno passerà ad un'altra arma.
\g_nix_with_laser\Porta sempre il laser come arma aggiuntiva nella modalità "No items Xonotic"
\XonoticMultiplayerDialog/Seleziona tutto\Seleziona tutte le mappe
\g_weapon_stay\Всё собранное оружие остаётся после возрождений
\g_weaponarena\Selecting a weapon arena will give all players that weapon at spawn as well as unlimited ammo, and disable all other weapon pickups.
\menu_weaponarena_with_laser\Also enable the laser in the weapon arena
-\g_minstagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
+\g_instagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
\g_nix\No items Xonotic - instead of pickup items, everyone plays with the same weapon. After some time, a countdown will start, after which everyone will switch to another weapon.
\g_nix_with_laser\Always carry the laser as an additional weapon in Nix
\XonoticMultiplayerDialog/Select all\Выбрать все карты
\g_weapon_stay\Зброя залишається після того, як була підібраною
\g_weaponarena\Вибір арени з окремою зброєю дасть гравцям цю зброю і необмежену кількість боєприпасів до неї, і прибере з мапи всю іншу зброю
\menu_weaponarena_with_laser\Зробити лазер доступним на аренах
-\g_minstagib\Гравці отримують МінстаНекс, рейкову гармату яка вбиває одним пострілом. Якщо гравець витратить усі боєприпаси, у нього буде десять секунд щоб поновити його, інакше він загине. Альтернативний вогонь гармати це лазер який не наносить шкоди, корисний для трюків
+\g_instagib\Гравці отримують МінстаНекс, рейкову гармату яка вбиває одним пострілом. Якщо гравець витратить усі боєприпаси, у нього буде десять секунд щоб поновити його, інакше він загине. Альтернативний вогонь гармати це лазер який не наносить шкоди, корисний для трюків
\g_nix\Нікс (No items Xonotic) - замість того щоб підбирати предмети, всі гравці грають з однією зброєю. Через деякий час почнеться відлік, і зброя у всіх зміниться на іншу
\g_nix_with_laser\Зробити лазер доступним у Нікс
\XonoticMultiplayerDialog/Обрати все\Обрати всі мапи
-alias weapon_laser "impulse 230"
+alias weapon_blaster "impulse 230"
alias weapon_shotgun "impulse 231"
-alias weapon_uzi "impulse 232"
-alias weapon_grenadelauncher "impulse 233"
+alias weapon_machinegun "impulse 232"
+alias weapon_mortar "impulse 233"
alias weapon_minelayer "impulse 234"
alias weapon_electro "impulse 235"
alias weapon_crylink "impulse 236"
-alias weapon_nex "impulse 237"
+alias weapon_vortex "impulse 237"
alias weapon_hagar "impulse 238"
-alias weapon_rocketlauncher "impulse 239"
+alias weapon_devastator "impulse 239"
alias weapon_porto "impulse 240"
-alias weapon_minstanex "impulse 241"
+alias weapon_vaporizer "impulse 241"
alias weapon_hook "impulse 242"
alias weapon_hlac "impulse 243"
alias weapon_tuba "impulse 244"
alias weapon_rifle "impulse 245"
alias weapon_fireball "impulse 246"
alias weapon_seeker "impulse 247"
+alias weapon_shockwave "impulse 248"
+alias weapon_arc "impulse 249"
+
+// Backwards compatibility with 0.7.0
+alias weapon_laser "weapon_blaster"
+alias weapon_uzi "weapon_machinegun"
+alias weapon_grenadelauncher "weapon_mortar"
+alias weapon_nex "weapon_vortex"
+alias weapon_rocketlauncher "weapon_devastator"
+alias weapon_minstanex "weapon_vaporizer"
Peter "Morphed" Pielak
Samual "Ares" Lenks
Tyler "-z-" Mulligan
+Zac "Mario" Jardine
**Extended Team
Debugger
Jan "zykure" Behrens
Łukasz "kuniu the frogg" Polek
-Mario
Marvin "Mirio" Beck
Matthias "matthiaskrgr" Krüger
MrBougo
Rudolf "divVerent" Polzer
Jakob "tZork" Markström Gröhn
Rasmus "FruitieX" Eskola
+Zac "Mario" Jardine
*Marketing / PR
Tyler "-z-" Mulligan
Przemysław "atheros" Grzywacz
Robert "ai" Kuroto
The player with the unnecessarily long name
+Mattia "Melanosuchus" Basaglia
+TimePath
**Translators