Merge remote-tracking branch 'origin/master' into terencehill/MOTD_bugfix
authorSamual Lenks <samual@xonotic.org>
Mon, 22 Apr 2013 20:25:55 +0000 (16:25 -0400)
committerSamual Lenks <samual@xonotic.org>
Mon, 22 Apr 2013 20:25:55 +0000 (16:25 -0400)
61 files changed:
_hud_descriptions.cfg
balanceXPM.cfg
balanceXonotic.cfg
defaultXonotic.cfg
gamemodes.cfg
gfx/menu/luminos/gametype_rune.tga [deleted file]
gfx/menu/wickedx/gametype_rune.tga [deleted file]
gfx/menu/xaw/gametype_rune.tga [deleted file]
notifications.cfg
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/announcer.qc
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/hud.qh
qcsrc/common/command/generic.qc
qcsrc/common/constants.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/notifications.qc
qcsrc/common/notifications.qh
qcsrc/common/teams.qh
qcsrc/common/util-pre.qh
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/menu/menu.qc
qcsrc/menu/xonotic/dialog_multiplayer_create.c
qcsrc/menu/xonotic/util.qc
qcsrc/server/arena.qc
qcsrc/server/attic/runematch.qc [new file with mode: 0644]
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/cl_weaponsystem.qc
qcsrc/server/command/common.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_triggers.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/mutator_new_toys.qc
qcsrc/server/mutators/sandbox.qc
qcsrc/server/portals.qc
qcsrc/server/progs.src
qcsrc/server/runematch.qc [deleted file]
qcsrc/server/scores.qc
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/t_jumppads.qc
qcsrc/server/teamplay.qc
qcsrc/server/tturrets/units/unit_plasma.qc
qcsrc/server/w_common.qc
qcsrc/server/w_electro.qc
qcsrc/server/w_grenadelauncher.qc
qcsrc/server/w_minelayer.qc
qcsrc/server/w_minstanex.qc
qcsrc/server/w_nex.qc
qcsrc/server/w_rocketlauncher.qc

index f4ecc143e522670bfe225b1f09c9ddc6831fcffc..ea7552a2a6566f7fb0631578327770a534ce4a12 100644 (file)
@@ -57,7 +57,7 @@ seta hud_panel_weapons_timeout_fadebgmin "" "minimum alpha of the panel backgrou
 seta hud_panel_weapons_timeout_fadefgmin "" "minimum alpha of the panel foreground while in effect mode 1"
 seta hud_panel_weapons_timeout_speed_in "" "speed that fading/moving onto the screen occurs"
 seta hud_panel_weapons_timeout_speed_out "" "speed that fading/moving off of the screen occurs"
-seta hud_panel_weapons_label "" "1 = show number of weapon, 2 = show bound key of weapon"
+seta hud_panel_weapons_label "" "1 = show number of weapon, 2 = show bound key of weapon, 3 = show name of weapon"
 seta hud_panel_weapons_accuracy "" "show accuracy color as the weapon icon background; colors can be configured with accuracy_color* cvars"
 seta hud_panel_weapons_ammo "" "show ammo as a status bar"
 seta hud_panel_weapons_onlyowned "" "show only owned weapons"
index fc02dc9cb2779daa53589b7916de455efcc60756..8012967ad73d324c181202296550e76605601d6e 100644 (file)
@@ -475,10 +475,10 @@ set g_balance_crylink_reload_ammo 0 //default: 10
 set g_balance_crylink_reload_time 2
 // }}}
 // {{{ nex
-set g_balance_nex_primary_damage 90
+set g_balance_nex_primary_damage 80
 set g_balance_nex_primary_force 400
 set g_balance_nex_primary_refire 1.5
-set g_balance_nex_primary_animtime 0.4
+set g_balance_nex_primary_animtime 0.5
 set g_balance_nex_primary_ammo 6
 set g_balance_nex_primary_damagefalloff_mindist 0 // 1000    For tZork ;3
 set g_balance_nex_primary_damagefalloff_maxdist 0 // 3000
index a0252cb48bfdbf89b048af8063580be3fa9c8a58..c96ea218707c446825ad3d065dda6c66c3c68232 100644 (file)
@@ -475,10 +475,10 @@ set g_balance_crylink_reload_ammo 0 //default: 10
 set g_balance_crylink_reload_time 2
 // }}}
 // {{{ nex
-set g_balance_nex_primary_damage 90
+set g_balance_nex_primary_damage 80
 set g_balance_nex_primary_force 400
 set g_balance_nex_primary_refire 1.5
-set g_balance_nex_primary_animtime 0.4
+set g_balance_nex_primary_animtime 0.5
 set g_balance_nex_primary_ammo 6
 set g_balance_nex_primary_damagefalloff_mindist 0 // 1000    For tZork ;3
 set g_balance_nex_primary_damagefalloff_maxdist 0 // 3000
index e1b16f435c8644a23202f4a8a1d6d1bfaf9bbcb3..2af290f9abd445b5170f7af1c3ed86859b6d1a9a 100644 (file)
@@ -68,6 +68,12 @@ seta cl_spawnzoom_factor 2 "factor of zoom while spawning"
 seta cl_zoomfactor 5   "how much +zoom will zoom (1-16)"
 seta cl_zoomspeed 8    "how fast it will zoom (0.5-16), negative values mean instant zoom"
 seta cl_zoomsensitivity 0      "how zoom changes sensitivity (0 = weakest, 1 = strongest)"
+
+seta cl_unpress_zoom_on_spawn 1 "automatically unpress zoom when you spawn"
+seta cl_unpress_zoom_on_death 1 "automatically unpress zoom when you die (and don't allow zoom again while dead)"
+seta cl_unpress_zoom_on_weapon_switch 1 "automatically unpress zoom when you switch a weapon"
+seta cl_unpress_attack_on_weapon_switch 1 "automatically unpress fire and fire1 attack buttons when you switch a weapon"
+
 freelook 1
 sensitivity 6
 v_gamma 1
@@ -1347,6 +1353,9 @@ set r_showbboxes 0
 // we REALLY need the end pos nudging DP bug workaround for trace-to-end-of-solid to work
 collision_endposnudge 1
 
+// FIXME remove this when the engine feature FINALLY MAYBE works
+r_glsl_skeletal 0
+
 // animation tuning
 set cl_lerpanim_maxdelta_framegroups 0.05 // must be faster than fastest weapon refire
 set cl_lerpanim_maxdelta_server 0.1 // must be slower than slowest server controlled anim (e.g. animinfo stuff)
index 05aaf3df40530d1379b0976ed83fbbb334d0b017..af8d3e83d825411b18c8b58356711a49a46be44e 100644 (file)
@@ -26,7 +26,6 @@ alias cl_hook_gamestart_dm
 alias cl_hook_gamestart_tdm
 alias cl_hook_gamestart_dom
 alias cl_hook_gamestart_ctf
-alias cl_hook_gamestart_rune
 alias cl_hook_gamestart_lms
 alias cl_hook_gamestart_arena
 alias cl_hook_gamestart_ca
@@ -48,7 +47,6 @@ alias sv_hook_gamestart_dm
 alias sv_hook_gamestart_tdm
 alias sv_hook_gamestart_dom
 alias sv_hook_gamestart_ctf
-alias sv_hook_gamestart_rune
 alias sv_hook_gamestart_lms
 alias sv_hook_gamestart_arena
 alias sv_hook_gamestart_ca
@@ -79,8 +77,6 @@ seta g_arena_point_limit -1   "Arena point limit overriding the mapinfo specified
 seta g_arena_point_leadlimit -1        "Arena point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 seta g_domination_point_limit -1       "Domination point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 seta g_domination_point_leadlimit -1   "Domination point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
-seta g_runematch_point_limit -1        "Runematch point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
-seta g_runematch_point_leadlimit -1    "Runematch point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 seta g_keyhunt_point_limit -1  "Keyhunt point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 seta g_keyhunt_point_leadlimit -1      "Keyhunt point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 seta g_race_laps_limit -1      "Race laps limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
@@ -105,9 +101,6 @@ set g_dom_weapon_stay 0
 set g_lms_respawn_delay 0
 set g_lms_respawn_waves 0
 set g_lms_weapon_stay 0
-set g_rune_respawn_delay 0
-set g_rune_respawn_waves 0
-set g_rune_weapon_stay 0
 set g_tdm_respawn_delay 0
 set g_tdm_respawn_waves 0
 set g_tdm_weapon_stay 0
@@ -417,61 +410,3 @@ set g_race 0 "Race: be faster than your opponents"
 set g_race_qualifying_timelimit 0
 set g_race_qualifying_timelimit_override -1
 set g_race_teams 0     "when 2, 3, or 4, the race is played as a team game (the team members can add up their laps)"
-
-
-// ===========
-//  runematch
-// ===========
-set g_runematch                                                0 "Runematch: pick up and hold the runes, special items that give you points, a special power (rune) and a disadvantage (curse)"
-set g_runematch_pointrate                              5
-set g_runematch_fixedspawns                            1 "use fixed runematch spawns if available"
-set g_runematch_pointamt                                       1
-set g_runematch_shuffletime                            30 "how often runes change position"
-set g_runematch_respawntime                            15 "how soon after being dropped to respawn"
-set g_runematch_frags_killedby_runeholder              4
-set g_runematch_frags_killed_runeholder                        5
-set g_runematch_frags_norune                           0
-set g_runematch_drop_runes_max                         2 "only drop up to 2 runes, the rest should respawn"
-set g_runematch_allow_same                             0 "allow matching rune-curse pairs"
-set g_runematch_rune_alpha                             0.78
-set g_runematch_rune_effects                           544 "EF_ADDITIVE + EF_FULLBRIGHT = 544"
-set g_runematch_rune_glow_size                         0
-set g_runematch_rune_glow_color                                0
-set g_runematch_rune_color_strength                    1.0
-// strength/weakness
-set g_balance_rune_strength_damage                     2.0
-set g_balance_rune_strength_force                      1.5
-set g_balance_curse_weak_damage                                0.5
-set g_balance_curse_weak_force                         0.6
-set g_balance_rune_strength_combo_damage       0.9
-set g_balance_rune_strength_combo_force                        1.0
-// defense/vulner
-set g_balance_rune_defense_takedamage                  0.5
-set g_balance_curse_vulner_takedamage                  2.0
-set g_balance_rune_defense_combo_takedamage            1.0
-// vampire/empathy
-set g_balance_rune_vampire_absorb                      0.4
-set g_balance_curse_empathy_takedamage                 -0.4
-set g_balance_rune_vampire_combo_absorb                        -0.1
-set g_balance_rune_vampire_maxhealth                   500
-set g_balance_curse_empathy_minhealth                  20
-set g_balance_rune_vampire_combo_minhealth             40
-// regen/venom
-set g_balance_rune_regen_hpmod                         1.75
-set g_balance_curse_venom_hpmod                                0.6
-set g_balance_rune_regen_combo_hpmod                   0.9
-set g_balance_rune_regen_regenrate                     3.0
-set g_balance_curse_venom_rotrate                      3.0
-set g_balance_rune_regen_combo_regenrate       0.5
-set g_balance_rune_regen_combo_rotrate                 1.5
-set g_balance_rune_regen_limitmod                      1
-set g_balance_curse_venom_limitmod                     1
-set g_balance_rune_regen_combo_limitmod                        1
-// speed/slow
-set g_balance_rune_speed_atkrate                               0.66
-set g_balance_curse_slow_atkrate                               1.5
-set g_balance_rune_speed_combo_atkrate                 1.2
-set g_balance_rune_speed_highspeed                     1.5
-set g_balance_curse_slow_highspeed                     0.6
-set g_balance_rune_speed_combo_highspeed                       0.9
-
diff --git a/gfx/menu/luminos/gametype_rune.tga b/gfx/menu/luminos/gametype_rune.tga
deleted file mode 100644 (file)
index 6906411..0000000
Binary files a/gfx/menu/luminos/gametype_rune.tga and /dev/null differ
diff --git a/gfx/menu/wickedx/gametype_rune.tga b/gfx/menu/wickedx/gametype_rune.tga
deleted file mode 100644 (file)
index 6906411..0000000
Binary files a/gfx/menu/wickedx/gametype_rune.tga and /dev/null differ
diff --git a/gfx/menu/xaw/gametype_rune.tga b/gfx/menu/xaw/gametype_rune.tga
deleted file mode 100644 (file)
index 79c8f30..0000000
Binary files a/gfx/menu/xaw/gametype_rune.tga and /dev/null differ
index 0006f6a8ea73660afcbde1f1b7b4df8c719de062..c45b04ed76e22174ebdbc2cf832f984e627bc820 100644 (file)
 // **                                          ** //
 // ********************************************** //
 
-// MSG_INFO notifications (count = 208):
+// MSG_ANNCE notifications (count = 39):
+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_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)"
+
+// MSG_INFO notifications (count = 207):
 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)"
@@ -124,7 +165,7 @@ seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "Notification control cvar: 0 =
 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 "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)"
@@ -152,7 +193,7 @@ seta notification_INFO_POWERUP_STRENGTH "1" "Notification control cvar: 0 = off,
 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 "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_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)"
@@ -205,7 +246,6 @@ seta notification_INFO_WEAPON_NEX_MURDER "1" "Notification control cvar: 0 = off
 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_HEADSHOT "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)"
@@ -356,7 +396,7 @@ seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "Notification control cvar: 0 =
 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_MULTI notifications (count = 118):
+// MSG_MULTI notifications (count = 120):
 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"
@@ -426,6 +466,9 @@ seta notification_ITEM_WEAPON_GOT "1" "Notification control cvar: 0 = off, 1 = t
 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_ARENA_BEGIN "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"
@@ -460,7 +503,6 @@ seta notification_WEAPON_NEX_MURDER "1" "Notification control cvar: 0 = off, 1 =
 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_HEADSHOT "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"
@@ -497,4 +539,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
 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 = 459): MSG_INFO = 208, MSG_CENTER = 133, MSG_MULTI = 118
+// Notification counts (total = 499): MSG_ANNCE = 39, MSG_INFO = 207, MSG_CENTER = 133, MSG_MULTI = 120
index f8b6e9cf08e1fa55b1ab3903966584e60b458fa1..ecc2000d7ccae32447fa4e78e75460a26e8f1f5a 100644 (file)
@@ -179,7 +179,6 @@ void CSQC_Init(void)
        DamageInfo_Precache();
        Vehicles_Precache();
        turrets_precache();
-    Announcer_Precache();
        Tuba_Precache();
        CSQCPlayer_Precache();
        
@@ -1106,6 +1105,12 @@ void Net_ReadSpawn()
 {
        zoomin_effect = 1;
        current_viewzoom = (1 / bound(1, autocvar_cl_spawnzoom_factor, 16));
+
+       if(autocvar_cl_unpress_zoom_on_spawn)
+       {
+               localcmd("-zoom\n");
+               button_zoom = FALSE;
+       }
 }
 
 void Net_TeamNagger()
@@ -1201,10 +1206,6 @@ float CSQC_Parse_TempEntity()
                        Net_ReadPingPLReport();
                        bHandled = true;
                        break;
-               case TE_CSQC_ANNOUNCE:
-                       Announcer_Play(ReadString());
-                       bHandled = true;
-                       break;
                case TE_CSQC_WEAPONCOMPLAIN:
                        Net_WeaponComplain();
                        bHandled = true;
index 3362ce42231193210b22b6ad0fe52f5cf8cbd1bd..4f00c55341639fbce6fd13122c29384a1db910b6 100644 (file)
@@ -414,13 +414,6 @@ void CSQC_UpdateView(float w, float h)
        button_attack2 = (input_buttons & BUTTON_3);
        button_zoom = (input_buttons & BUTTON_4);
 
-       // FIXME do we need this hack?
-       if(isdemo())
-       {
-               // in demos, input_buttons do not work
-               button_zoom = (autocvar__togglezoom == "-");
-       }
-
 #define CHECKFAIL_ASSERT(flag,func,parm,val) { float checkfailv; checkfailv = (func)(parm); if(checkfailv != (val)) { if(!checkfail[(flag)]) localcmd(sprintf("\ncmd checkfail %s %s %d %d\n", #func, parm, val, checkfailv)); checkfail[(flag)] = 1; } } ENDS_WITH_CURLY_BRACE
        CHECKFAIL_ASSERT(0, cvar_type, "\{100}\{105}\{118}\{48}\{95}\{101}\{118}\{97}\{100}\{101}", 0);
        CHECKFAIL_ASSERT(1, cvar_type, "\{97}\{97}\{95}\{101}\{110}\{97}\{98}\{108}\{101}", 0);
@@ -451,10 +444,28 @@ void CSQC_UpdateView(float w, float h)
 
        ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
 
+       float is_dead = (getstati(STAT_HEALTH) <= 0);
+
+       // FIXME do we need this hack?
+       if(isdemo())
+       {
+               // in demos, input_buttons do not work
+               button_zoom = (autocvar__togglezoom == "-");
+       }
+       else if(button_zoom
+               && autocvar_cl_unpress_zoom_on_death
+               && (spectatee_status >= 0)
+               && (is_dead || intermission))
+       {
+               // no zoom while dead or in intermission please
+               localcmd("-zoom\n");
+               button_zoom = FALSE;
+       }
+
        // event chase camera
        if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
        {
-               if(spectatee_status >= 0 && (autocvar_cl_eventchase_death && getstati(STAT_HEALTH) <= 0 && !intermission) || intermission)
+               if(spectatee_status >= 0 && (autocvar_cl_eventchase_death && is_dead) || intermission)
                {
                        // make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.)
                        vector current_view_origin = ((csqcplayer ? csqcplayer.origin : pmove_org) + autocvar_cl_eventchase_viewoffset);
@@ -604,11 +615,24 @@ void CSQC_UpdateView(float w, float h)
                HUD_InitScores();
        }
 
-       if(last_switchweapon != switchweapon) {
+       if(last_switchweapon != switchweapon)
+       {
                weapontime = time;
                last_switchweapon = switchweapon;
+               if(button_zoom && autocvar_cl_unpress_zoom_on_weapon_switch)
+               {
+                       localcmd("-zoom\n");
+                       button_zoom = FALSE;
+               }
+               if(autocvar_cl_unpress_attack_on_weapon_switch)
+               {
+                       localcmd("-fire\n");
+                       localcmd("-fire2\n");
+                       button_attack2 = FALSE;
+               }
        }
-       if(last_activeweapon != activeweapon) {
+       if(last_activeweapon != activeweapon)
+       {
                last_activeweapon = activeweapon;
 
                e = get_weaponinfo(activeweapon);
@@ -756,7 +780,7 @@ void CSQC_UpdateView(float w, float h)
        // reticle_type is changed to the item we are zooming / aiming with, to decide which reticle to use
        // It must be a persisted float for fading out to work properly (you let go of the zoom button for
        // the view to go back to normal, so reticle_type would become 0 as we fade out)
-       if(spectatee_status || getstati(STAT_HEALTH) <= 0 || hud != HUD_NORMAL)
+       if(spectatee_status || is_dead || hud != HUD_NORMAL)
                reticle_type = 0; // prevent reticle from showing during the respawn zoom effect or for spectators
        else if(activeweapon == WEP_NEX && (button_zoom || zoomscript_caught) || activeweapon == WEP_RIFLE && (button_zoom || zoomscript_caught) || activeweapon == WEP_MINSTANEX && (button_zoom || zoomscript_caught))
                reticle_type = 2; // nex zoom
index 240d424c6a5ee255eb4eb8135ff4e7137733a0c1..0409aea8bcdee9ca80b59562ba10ef1ae742e2d0 100644 (file)
@@ -1,14 +1,6 @@
-float previous_announcement_time;
-float previous_game_starttime;
-string previous_announcement;
-
-// remaining maptime announcer sounds, true when sound was already played
-float announcer_1min;
-float announcer_5min;
-
 void Announcer_Play(string announcement)
 {
-       if((announcement != previous_announcement) || (time >= (previous_announcement_time + autocvar_cl_announcer_antispam)))
+       /*if((announcement != previous_announcement) || (time >= (previous_announcement_time + autocvar_cl_announcer_antispam)))
        {
                sound(world, CH_INFO, strcat("announcer/", autocvar_cl_announcer, "/", announcement, ".wav"), VOL_BASEVOICE, ATTN_NONE);
 
@@ -16,9 +8,11 @@ void Announcer_Play(string announcement)
                
                previous_announcement = strzone(announcement);
                previous_announcement_time = time;
-       }
+       }*/
 }
 
+float announcer_1min;
+float announcer_5min;
 void Announcer_Countdown() 
 {
        float starttime = getstatf(STAT_GAMESTARTTIME);
@@ -27,21 +21,21 @@ void Announcer_Countdown()
        
        if(countdown <= 0) // countdown has finished, starttime is now
        {
-               if (!spectatee_status)
-                       Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_BEGIN); 
-
-               Announcer_Play("begin");
+               Local_Notification(MSG_MULTI, MULTI_COUNTDOWN_BEGIN); 
                announcer_5min = announcer_1min = FALSE; // reset maptime announcers now as well
                remove(self);
                return;
        }
        else // countdown is still going
        {
-               if (!spectatee_status)
-                       Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_GAMESTART, countdown_rounded);
+               Local_Notification(MSG_CENTER, CENTER_COUNTDOWN_GAMESTART, countdown_rounded);
 
-               if(countdown_rounded <= 3 && countdown_rounded >= 1) 
-                       Announcer_Play(ftos(countdown_rounded));
+               switch(countdown_rounded)
+               {
+                       case 1: Local_Notification(MSG_ANNCE, ANNCE_NUM_1); break;
+                       case 2: Local_Notification(MSG_ANNCE, ANNCE_NUM_2); break;
+                       case 3: Local_Notification(MSG_ANNCE, ANNCE_NUM_3); break;
+               }
 
                self.nextthink = (starttime - (countdown - 1));
        }
@@ -54,6 +48,7 @@ void Announcer_Countdown()
  * timelimit, fraglimit and game_starttime! Requires engine changes (remove STAT_TIMELIMIT
  * and STAT_FRAGLIMIT to be auto-sent)
  */
+ float previous_game_starttime;
 void Announcer_Gamestart() 
 {
        float startTime = getstatf(STAT_GAMESTARTTIME);
@@ -61,7 +56,7 @@ void Announcer_Gamestart()
        if(previous_game_starttime != startTime) 
        {
                if((time + 5.0) < startTime) // if connecting to server while restart was active don't always play prepareforbattle
-                       Announcer_Play("prepareforbattle");
+                       Local_Notification(MSG_ANNCE, ANNCE_PREPARE);
                
                if(time < startTime) 
                {
@@ -106,7 +101,7 @@ void Announcer_Time()
                                if not(autocvar_g_warmup_limit == -1 && warmup_stage) 
                                {
                                        announcer_5min = TRUE;
-                                       Announcer_Play("5minutesremain");
+                                       Local_Notification(MSG_ANNCE, ANNCE_REMAINING_MIN_5);
                                }
                        }
                }
@@ -128,7 +123,7 @@ void Announcer_Time()
                        if not(autocvar_g_warmup_limit == -1 && warmup_stage) 
                        {
                                announcer_1min = TRUE;
-                               Announcer_Play("1minuteremains");
+                               Local_Notification(MSG_ANNCE, ANNCE_REMAINING_MIN_1);
                        }
                }
        }
@@ -139,50 +134,3 @@ void Announcer()
        Announcer_Gamestart();
        Announcer_Time();
 }
-
-void Announcer_Precache () 
-{
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/1minuteremains.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/5minutesremain.wav"));
-
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/electrobitch.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/airshot.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/03kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/05kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/10kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/15kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/20kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/25kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/30kills.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/botlike.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/yoda.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/amazing.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/awesome.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/impressive.wav"));
-
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/prepareforbattle.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/begin.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/timeoutcalled.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/1fragleft.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/2fragsleft.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/3fragsleft.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/terminated.wav"));
-
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/1.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/2.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/3.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/4.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/5.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/6.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/7.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/8.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/9.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/10.wav"));
-
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/lastsecond.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/narrowly.wav"));
-
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/voteaccept.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/votecall.wav"));
-       precache_sound (strcat("announcer/", autocvar_cl_announcer, "/votefail.wav"));
-}
index ba6abadc018868762228d1875b5180244fe9ce2a..150efb1708ca705054fd00d2c30bbb20d6c18091 100644 (file)
@@ -78,6 +78,10 @@ string autocvar_cl_weaponpriority;
 float autocvar_cl_zoomfactor;
 float autocvar_cl_zoomsensitivity;
 float autocvar_cl_zoomspeed;
+var float autocvar_cl_unpress_zoom_on_spawn = 1;
+var float autocvar_cl_unpress_zoom_on_death = 1;
+var float autocvar_cl_unpress_zoom_on_weapon_switch = 1;
+var float autocvar_cl_unpress_attack_on_weapon_switch = 1;
 float autocvar_con_chat;
 float autocvar_con_chatpos;
 float autocvar_con_chatrect;
index 82467348e588de0b7463885bf8e6de406566fb7b..bf72c2f467bd9b08551278e36b8eb799a47e7d4b 100644 (file)
@@ -526,8 +526,7 @@ void HUD_Weapons(void)
                weaponorder_cmp_str = string_null;
        }
 
-       if(autocvar_hud_panel_weapons_complainbubble)
-       if(autocvar__hud_configure || time - complain_weapon_time >= when + fadetime)
+       if(!autocvar_hud_panel_weapons_complainbubble || autocvar__hud_configure || time - complain_weapon_time >= when + fadetime)
                complain_weapon = 0;
 
        // determine which weapons are going to be shown
@@ -734,7 +733,7 @@ void HUD_Weapons(void)
                weapon_id = self.impulse;
 
                // skip if this weapon doesn't exist
-               if (!self || self.impulse < 0) { continue; }
+               if(!self || weapon_id < 0) { continue; }
 
                // skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon
                if(autocvar_hud_panel_weapons_onlyowned)
@@ -2027,7 +2026,7 @@ void HUD_Radar(void)
        draw_teamradar_player(view_origin, view_angles, '1 1 1');
 
        drawresetcliparea();
-};
+}
 
 // Score (#7)
 //
@@ -4490,8 +4489,7 @@ void HUD_Main (void)
                vector color;
                float hud_dock_color_team = autocvar_hud_dock_color_team;
                if((teamplay) && hud_dock_color_team) {
-                       f = stof(getplayerkeyvalue(current_player - 1, "colors"));
-                       color = colormapPaletteColor(mod(f, 16), 1) * hud_dock_color_team;
+                       color = colormapPaletteColor(myteam, 1) * hud_dock_color_team;
                }
                else if(autocvar_hud_configure_teamcolorforced && autocvar__hud_configure && hud_dock_color_team) {
                        color = '1 0 0' * hud_dock_color_team;
index 90ece36ac0d77117d47fe83970f40c36585bebdd..bef2079b31920637c695ce579b4835d40281dab7 100644 (file)
@@ -126,7 +126,7 @@ if(!autocvar__hud_configure && panel_bg_str == "0") {\
 // Get value for panel_bg_color: if "" fetch default, else use panel_bg_color. Convert pants, shirt or teamcolor into a vector.
 #define HUD_Panel_GetColor()\
 if((teamplay) && panel_bg_color_team) {\
-       panel_bg_color = colormapPaletteColor(mod(stof(getplayerkeyvalue(current_player - 1, "colors")), 16), 1) * panel_bg_color_team;\
+       panel_bg_color = colormapPaletteColor(myteam, 1) * panel_bg_color_team;\
 } else if (autocvar_hud_configure_teamcolorforced && autocvar__hud_configure && panel_bg_color_team) {\
        panel_bg_color = '1 0 0' * panel_bg_color_team;\
 } else {\
index 6643387f8896069d615ecb4a15624b2c665aaa23..3059916c61ba4445c9b0da907b187d36a817adc4 100644 (file)
@@ -436,13 +436,15 @@ void GenericCommand_restartnotifs(float request)
                        print(sprintf(
                                strcat(
                                        "Restart_Notifications(): Restarting %d notifications... ",
-                                       "Counts: MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d\n"
+                                       "Counts: MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d\n"
                                ),
                                (
+                                       NOTIF_ANNCE_COUNT +
                                        NOTIF_INFO_COUNT +
                                        NOTIF_CENTER_COUNT +
                                        NOTIF_MULTI_COUNT
-                               ), 
+                               ),
+                               NOTIF_ANNCE_COUNT,
                                NOTIF_INFO_COUNT,
                                NOTIF_CENTER_COUNT,
                                NOTIF_MULTI_COUNT
index c25fb059f6ebc2d52b017541eeb39e084ab4166b..ffec62095b9b9466ffcf5db66a75251f254a18f5 100644 (file)
@@ -36,14 +36,13 @@ const float TE_CSQC_NEXGUNBEAMPARTICLE = 104;
 const float TE_CSQC_LIGHTNINGARC = 105;
 const float TE_CSQC_TEAMNAGGER = 106;
 const float TE_CSQC_PINGPLREPORT = 107;
-const float TE_CSQC_ANNOUNCE = 108;
-const float TE_CSQC_TARGET_MUSIC = 109;
-const float TE_CSQC_WEAPONCOMPLAIN = 110;
-const float TE_CSQC_NEX_SCOPE = 111;
-const float TE_CSQC_MINELAYER_MAXMINES = 112;
-const float TE_CSQC_HAGAR_MAXROCKETS = 113;
-const float TE_CSQC_VEHICLESETUP = 114;
-const float TE_CSQC_SVNOTICE = 115;
+const float TE_CSQC_TARGET_MUSIC = 108;
+const float TE_CSQC_WEAPONCOMPLAIN = 109;
+const float TE_CSQC_NEX_SCOPE = 110;
+const float TE_CSQC_MINELAYER_MAXMINES = 111;
+const float TE_CSQC_HAGAR_MAXROCKETS = 112;
+const float TE_CSQC_VEHICLESETUP = 113;
+const float TE_CSQC_SVNOTICE = 114;
 
 const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
 const float RACE_NET_CHECKPOINT_CLEAR = 1;
index f7ced420579acb32837ea61f04511d39ddac86f5..b4dbda25f2bc2b2617c37342f460e2e2715e6a8f 100644 (file)
@@ -313,8 +313,6 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
                                        MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF;
                                else if(v == "team_CTF_blueflag")
                                        MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF;
-                               else if(v == "runematch_spawn_point")
-                                       MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RUNEMATCH;
                                else if(v == "target_assault_roundend")
                                        MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_ASSAULT;
                                else if(v == "onslaught_generator")
@@ -364,7 +362,6 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
        else
        {
                MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_DEATHMATCH;      // DM always works
-               MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RUNEMATCH;       // Rune always works
                MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_LMS;             // LMS always works
                MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_KEEPAWAY;                // Keepaway always works
 
@@ -418,7 +415,6 @@ string _MapInfo_GetDefault(float t)
                case MAPINFO_TYPE_TEAM_DEATHMATCH: return "50 20 2 0";
                case MAPINFO_TYPE_DOMINATION:      return "200 20 0";
                case MAPINFO_TYPE_CTF:             return "300 20 10 0";
-               case MAPINFO_TYPE_RUNEMATCH:       return "200 20 0";
                case MAPINFO_TYPE_LMS:             return "9 20 0";
                case MAPINFO_TYPE_ARENA:           return "10 20 0";
                case MAPINFO_TYPE_CA:              return "10 20 0";
index bd67f67a825104abcd3108d8096d501fa8a27762..10a35ee470a7e3cfbdfc70792dcf4b628977a3da 100644 (file)
@@ -42,9 +42,6 @@ REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 lea
 REGISTER_GAMETYPE(_("Arena"),arena,g_arena,ARENA,"timelimit=20 pointlimit=10 leadlimit=0")
 #define g_arena IS_GAMETYPE(ARENA)
 
-REGISTER_GAMETYPE(_("Runematch"),rune,g_runematch,RUNEMATCH,"timelimit=20 pointlimit=200 leadlimit=0")
-#define g_runematch IS_GAMETYPE(RUNEMATCH)
-
 REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0")
 #define g_race IS_GAMETYPE(RACE)
 
index 2c25d97ddc30cfb1f219f0c02505ca739e207ee3..a0f19746a1e7abc2dd4e1e1a006ea28b59ee4fed 100644 (file)
@@ -7,6 +7,7 @@ string Get_Notif_TypeName(float net_type)
 {
        switch(net_type)
        {
+               case MSG_ANNCE: return "MSG_ANNCE";
                case MSG_INFO: return "MSG_INFO";
                case MSG_CENTER: return "MSG_CENTER";
                case MSG_CENTER_CPID: return "MSG_CENTER_CPID";
@@ -20,6 +21,7 @@ entity Get_Notif_Ent(float net_type, float net_name)
 {
        switch(net_type)
        {
+               case MSG_ANNCE: return msg_annce_notifs[net_name - 1];
                case MSG_INFO: return msg_info_notifs[net_name - 1];
                case MSG_CENTER: return msg_center_notifs[net_name - 1];
                case MSG_MULTI: return msg_multi_notifs[net_name - 1];
@@ -37,6 +39,7 @@ string Notification_CheckArgs_TypeName(float net_type, float net_name)
                { checkargs = sprintf("Improper name: %d!", net_name); } break; }
        switch(net_type)
        {
+               CHECKARG_TYPENAME(ANNCE)
                CHECKARG_TYPENAME(INFO)
                CHECKARG_TYPENAME(CENTER)
                CHECKARG_TYPENAME(MULTI)
@@ -104,6 +107,7 @@ string Notification_CheckArgs(
 void Destroy_Notification_Entity(entity notif)
 {
        if(notif.nent_name != "") { strunzone(notif.nent_name); }
+       if(notif.nent_snd != "") { strunzone(notif.nent_snd); }
        if(notif.nent_args != "") { strunzone(notif.nent_args); }
        if(notif.nent_hudargs != "") { strunzone(notif.nent_hudargs); }
        if(notif.nent_icon != "") { strunzone(notif.nent_icon); }
@@ -125,12 +129,15 @@ void Destroy_All_Notifications(void)
                        Destroy_Notification_Entity(notif); \
                }
 
-       // kill all networked notifications
+       // kill all networked notifications and centerprints
        #ifdef SVQC
        Kill_Notification(NOTIF_ALL, world, 0, 0);
+       #else
+       reset_centerprint_messages();
        #endif
 
        // kill all real notification entities
+       DESTROY_LOOP(MSG_ANNCE, NOTIF_ANNCE_COUNT)
        DESTROY_LOOP(MSG_INFO, NOTIF_INFO_COUNT)
        DESTROY_LOOP(MSG_CENTER, NOTIF_CENTER_COUNT)
        DESTROY_LOOP(MSG_MULTI, NOTIF_MULTI_COUNT)
@@ -337,8 +344,13 @@ void Create_Notification_Entity(
        float typeid,
        float nameid,
        string namestring,
+       float anncename,
        float infoname,
        float centername,
+       float channel,
+       string snd,
+       float vol,
+       float position,
        float strnum,
        float flnum,
        string args,
@@ -358,6 +370,13 @@ void Create_Notification_Entity(
        string typestring = "";
        switch(typeid)
        {
+               case MSG_ANNCE:
+               {
+                       typestring = "MSG_ANNCE";
+                       msg_annce_notifs[nameid - 1] = notif;
+                       notif.classname = "msg_annce_notification";
+                       break;
+               }
                case MSG_INFO:
                {
                        typestring = "MSG_INFO";
@@ -407,7 +426,7 @@ void Create_Notification_Entity(
        if(msg_is_multi)
        {
                // Set MSG_MULTI string/float counts
-               if((infoname == NO_MSG) && (centername == NO_MSG))
+               if((anncename == NO_MSG) && (infoname == NO_MSG) && (centername == NO_MSG))
                {
                        print(sprintf(
                                strcat(
@@ -421,6 +440,9 @@ void Create_Notification_Entity(
                }
                else
                {
+                       // announcements don't actually need any arguments, so lets not even count them.
+                       if(anncename != NO_MSG) { notif.nent_msgannce = msg_annce_notifs[anncename - 1]; }
+                       
                        float infoname_stringcount = 0, infoname_floatcount = 0;
                        float centername_stringcount = 0, centername_floatcount = 0;
                        
@@ -443,6 +465,41 @@ void Create_Notification_Entity(
                        notif.nent_floatcount = max(infoname_floatcount, centername_floatcount);
                }
        }
+       else if(typeid == MSG_ANNCE)
+       {
+               // Set MSG_ANNCE information and handle precaching
+               #ifdef CSQC
+               if not(GENTLE && (var_cvar == 1))
+               {
+                       if(snd != "")
+                       {
+                               if(notif.nent_enabled)
+                               {
+                                       precache_sound(sprintf("announcer/%s/%s.wav", autocvar_cl_announcer, snd));
+                                       notif.nent_channel = channel;
+                                       notif.nent_snd = strzone(snd);
+                                       notif.nent_vol = vol;
+                                       notif.nent_position = position;
+                               }
+                       }
+                       else
+                       {
+                               print(sprintf(
+                                       strcat(
+                                               "^1NOTIFICATION WITH NO SOUND: ",
+                                               "^7net_type = %s, net_name = %s.\n"
+                                       ),
+                                       typestring,
+                                       namestring
+                               ));
+                               notif_error = TRUE;
+                       }
+               }
+               else { notif.nent_enabled = FALSE; }
+               #else
+               notif.nent_enabled = FALSE;
+               #endif
+       }
        else
        {
                // Set MSG_INFO and MSG_CENTER string/float counts
@@ -651,6 +708,14 @@ void Dump_Notifications(float fh, float alsoprint)
        // This is not necessary, and does not matter if they vary between config versions,
        // it is just a semi-helpful tool for those who want to manually change their user settings.
 
+       NOTIF_WRITE(sprintf("\n// MSG_ANNCE notifications (count = %d):\n", NOTIF_ANNCE_COUNT));
+       for(i = 1; i <= NOTIF_ANNCE_COUNT; ++i)
+       {
+               e = Get_Notif_Ent(MSG_ANNCE, i);
+               if not(e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
+               NOTIF_WRITE_ENTITY(e.nent_name, e.nent_default, "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)");
+       }
+
        NOTIF_WRITE(sprintf("\n// MSG_INFO notifications (count = %d):\n", NOTIF_INFO_COUNT));
        for(i = 1; i <= NOTIF_INFO_COUNT; ++i)
        {
@@ -700,13 +765,15 @@ void Dump_Notifications(float fh, float alsoprint)
        NOTIF_WRITE(sprintf(
                strcat(
                        "\n// Notification counts (total = %d): ",
-                       "MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d\n"
+                       "MSG_ANNCE = %d, MSG_INFO = %d, MSG_CENTER = %d, MSG_MULTI = %d\n"
                ),
                (
+                       NOTIF_ANNCE_COUNT +
                        NOTIF_INFO_COUNT +
                        NOTIF_CENTER_COUNT +
                        NOTIF_MULTI_COUNT
-               ), 
+               ),
+               NOTIF_ANNCE_COUNT,
                NOTIF_INFO_COUNT,
                NOTIF_CENTER_COUNT,
                NOTIF_MULTI_COUNT
@@ -776,6 +843,62 @@ string Local_Notification_sprintf(
 }
 
 #ifdef CSQC
+void Local_Notification_sound(
+       float soundchannel, string soundfile,
+       float soundvolume, float soundposition)
+{
+       if((soundfile != prev_soundfile) || (time >= (prev_soundtime + autocvar_cl_announcer_antispam)))
+       {
+               #ifdef NOTIFICATIONS_DEBUG
+               dprint(sprintf(
+                       "Local_Notification_sound(world, %f, '%s', %f, %f);\n",
+                       soundchannel,
+                       sprintf(
+                               "announcer/%s/%s.wav",
+                               autocvar_cl_announcer,
+                               soundfile
+                       ),
+                       soundvolume,
+                       soundposition
+               ));
+               #endif
+               
+               sound(
+                       world,
+                       soundchannel,
+                       sprintf(
+                               "announcer/%s/%s.wav",
+                               autocvar_cl_announcer,
+                               soundfile
+                       ),
+                       soundvolume,
+                       soundposition
+               );
+               
+               if(prev_soundfile) { strunzone(prev_soundfile); }
+               prev_soundfile = strzone(soundfile);
+               prev_soundtime = time;
+       }
+       else
+       {
+               #ifdef NOTIFICATIONS_DEBUG
+               dprint(sprintf(
+                       "Local_Notification_sound(world, %f, '%s', %f, %f) ^1BLOCKED BY ANTISPAM:^7 prevsnd: '%s', time/prevtime: %f, limit: %f\n",
+                       soundchannel,
+                       sprintf(
+                               "announcer/%s/%s.wav",
+                               autocvar_cl_announcer,
+                               soundfile
+                       ),
+                       soundvolume,
+                       soundposition,
+                       prev_soundfile,
+                       (time - prev_soundtime),
+                       autocvar_cl_announcer_antispam
+               ));
+               #endif
+       }
+}
 void Local_Notification_HUD_Notify_Push(
        string icon, string hudargs,
        string s1, string s2, string s3, string s4)
@@ -860,18 +983,17 @@ void Local_Notification(float net_type, float net_name, ...count)
 
        entity notif = Get_Notif_Ent(net_type, net_name);
        if not(notif) { backtrace("Local_Notification: Could not find notification entity!\n"); return; }
-
-       #ifdef NOTIFICATIONS_DEBUG
        if not(notif.nent_enabled)
        {
+               #ifdef NOTIFICATIONS_DEBUG
                dprint(sprintf(
                        "Local_Notification(%s, %s): Entity was disabled...\n",
                        Get_Notif_TypeName(net_type),
                        notif.nent_name
                ));
+               #endif
                return;
        }
-       #endif
        
        if((notif.nent_stringcount + notif.nent_floatcount) > count)
        {
@@ -921,6 +1043,21 @@ void Local_Notification(float net_type, float net_name, ...count)
        
        switch(net_type)
        {
+               case MSG_ANNCE:
+               {
+                       #ifdef CSQC
+                       Local_Notification_sound(
+                               notif.nent_channel,
+                               notif.nent_snd,
+                               notif.nent_vol,
+                               notif.nent_position
+                       );
+                       #else
+                       backtrace("MSG_ANNCE on server?... Please notify Samual immediately!\n");
+                       #endif
+                       break;
+               }
+               
                case MSG_INFO:
                {
                        print(
@@ -972,6 +1109,16 @@ void Local_Notification(float net_type, float net_name, ...count)
                                        f1, f2, f3, f4);
                        }
                        #ifdef CSQC
+                       if(notif.nent_msgannce)
+                       if(notif.nent_msgannce.nent_enabled)
+                       {
+                               Local_Notification_WOVA(
+                                       MSG_ANNCE,
+                                       notif.nent_msgannce.nent_id, 
+                                       0, 0, 
+                                       "", "", "", "",
+                                       0, 0, 0, 0);
+                       }
                        if(notif.nent_msgcenter)
                        if(notif.nent_msgcenter.nent_enabled)
                        {
@@ -1207,7 +1354,7 @@ void Kill_Notification(
                "Kill_Notification(%d, '%s', %s, %d);\n",
                broadcast,
                client.netname,
-               Get_Notif_TypeName(net_type),
+               (net_type ? Get_Notif_TypeName(net_type) : "0"),
                net_name
        ));
        #endif
@@ -1372,7 +1519,7 @@ void Send_Notification(
 
        Net_LinkEntity(net_notif, FALSE, 0, Net_Write_Notification);
 
-       if(server_is_dedicated && (broadcast == NOTIF_ALL || broadcast == NOTIF_ALL_EXCEPT) && (net_type != MSG_CENTER))
+       if(server_is_dedicated && (broadcast == NOTIF_ALL || broadcast == NOTIF_ALL_EXCEPT) && (net_type != MSG_ANNCE) && (net_type != MSG_CENTER))
        {
                Local_Notification_WOVA(
                        net_type, net_name,
index 719e5b0bddad2878d691d618d4cfce56a3a71e35..67b5f243e7fc31c0bd930dd610999925f273385d 100644 (file)
@@ -4,10 +4,11 @@
 // ================================================
 
 // main types/groups of notifications
-#define MSG_INFO 1 // "Global" information messages (sent to console, and notify panel if it has an icon)
-#define MSG_CENTER 2 // "Personal" centerprint messages
-#define MSG_CENTER_CPID 3 // Kill centerprint message
-#define MSG_MULTI 4 // Subcall MSG_INFO and/or MSG_CENTER notifications
+#define MSG_ANNCE 1 // "Global" AND "personal" announcer messages
+#define MSG_INFO 2 // "Global" information messages 
+#define MSG_CENTER 3 // "Personal" centerprint messages
+#define MSG_CENTER_CPID 4 // Kill centerprint message
+#define MSG_MULTI 5 // Subcall MSG_INFO and/or MSG_CENTER notifications
 
 #define NO_MSG -12345 
 
@@ -44,8 +45,13 @@ void Create_Notification_Entity(
        float typeid,
        float nameid,
        string namestring,
+       float anncename,
        float infoname,
        float centername,
+       float channel,
+       string snd,
+       float vol,
+       float position,
        float strnum,
        float flnum,
        string args,
@@ -69,6 +75,8 @@ void Local_Notification_WOVA(
 
 #ifdef CSQC // CLIENT ONLY
 void Read_Notification(float is_new);
+string prev_soundfile;
+float prev_soundtime;
 #endif
 
 #ifdef SVQC // SERVER ONLY
@@ -102,8 +110,19 @@ void Send_Notification_WOVA(
 // ====================================
 /*
  List of all notifications (including identifiers and display information)
- Possible Tokens: default, name, infoname, centername, strnum, flnum, args, hudargs, icon, cpid, durcnt, normal, gentle
+ Possible Tokens:
+    default, name, channel, sound, volume, position,
+    anncename, infoname, centername, strnum, flnum, args,
+    hudargs, icon, cpid, durcnt, normal, gentle
  Format Specifications:
+    MSG_ANNCE:
+      default: FLOAT: Default setting for whether the notification is enabled or not
+         ^-> 0 = disabled, 1 = enabled if gentle is disabled, 2 = always enabled
+      name: VAR: Name of notification
+      channel: FLOAT: Sound channel to broadcast on to
+      sound: STRING: Filename for the announcement sound
+      volume: FLOAT: Volume setting for the announcement sound
+      position: FLOAT: Attenuation/positioning value
     MSG_INFO:
       default: FLOAT: Default setting for whether the notification is enabled or not
          ^-> 0 = disabled, 1 = enabled, 2 = also print to chat box
@@ -130,6 +149,7 @@ void Send_Notification_WOVA(
       default: FLOAT: Default setting for whether the notification is enabled or not
          ^-> 0 = disabled, 1 = enabled
       name: VAR: Name of chaining notification
+      anncename: VAR: Name of announcer notification for reference
       infoname: VAR: Name of info notification for reference
       centername: VAR: Name of centerprint notification for reference
 
@@ -170,14 +190,55 @@ void Send_Notification_WOVA(
       If you send a notification with mismatching arguments, Send_Notification() will error.
 */
 
+#define MSG_ANNCE_NOTIFICATIONS \
+       MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AIRSHOT,       CH_INFO, "airshot",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AMAZING,       CH_INFO, "amazing",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_AWESOME,       CH_INFO, "awesome",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_BOTLIKE,       CH_INFO, "botlike",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_ACHIEVEMENT_ELECTROBITCH,  CH_INFO, "electrobitch",      VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_IMPRESSIVE,    CH_INFO, "impressive",        VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_ACHIEVEMENT_YODA,          CH_INFO, "yoda",              VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_BEGIN,                     CH_INFO, "begin",             VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_03,             CH_INFO, "03kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_05,             CH_INFO, "05kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_10,             CH_INFO, "10kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_15,             CH_INFO, "15kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_20,             CH_INFO, "20kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_25,             CH_INFO, "25kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_30,             CH_INFO, "30kills",           VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_LASTSECOND,      CH_INFO, "lastsecond",        VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_NARROWLY,        CH_INFO, "narrowly",          VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_TERMINATED,      CH_INFO, "terminated",        VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(0, ANNCE_MULTIFRAG,                 CH_INFO, "multifrag",         VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_1,                     CH_INFO, "1",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_2,                     CH_INFO, "2",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_3,                     CH_INFO, "3",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_4,                     CH_INFO, "4",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_5,                     CH_INFO, "5",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_6,                     CH_INFO, "6",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_7,                     CH_INFO, "7",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_8,                     CH_INFO, "8",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_9,                     CH_INFO, "9",                 VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_NUM_10,                    CH_INFO, "10",                VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_PREPARE,                   CH_INFO, "prepareforbattle",  VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_REMAINING_FRAG_1,          CH_INFO, "1fragleft",         VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_REMAINING_FRAG_2,          CH_INFO, "2fragsleft",        VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_REMAINING_FRAG_3,          CH_INFO, "3fragsleft",        VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_REMAINING_MIN_1,           CH_INFO, "1minuteremains",    VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_REMAINING_MIN_5,           CH_INFO, "5minutesremain",    VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_TIMEOUT,                   CH_INFO, "timeoutcalled",     VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_VOTE_ACCEPT,               CH_INFO, "voteaccept",        VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_VOTE_CALL,                 CH_INFO, "votecall",          VOL_BASEVOICE, ATTN_NONE) \
+       MSG_ANNCE_NOTIF(2, ANNCE_VOTE_FAIL,                 CH_INFO, "votefail",          VOL_BASEVOICE, ATTN_NONE)
+
 #define MULTITEAM_INFO(default,prefix,teams,strnum,flnum,args,hudargs,icon,normal,gentle) \
-       MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
-       MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \
+       MSG_INFO_NOTIF(default, prefix##RED, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_1)), TCR(normal, COL_TEAM_1, strtoupper(STATIC_NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(STATIC_NAME_TEAM_1))) \
+       MSG_INFO_NOTIF(default, prefix##BLUE, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_2)), TCR(normal, COL_TEAM_2, strtoupper(STATIC_NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(STATIC_NAME_TEAM_2))) \
        #if teams >= 3 \
-               MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \
+               MSG_INFO_NOTIF(default, prefix##YELLOW, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_3)), TCR(normal, COL_TEAM_3, strtoupper(STATIC_NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(STATIC_NAME_TEAM_3))) \
        #endif \
        #if teams >= 4 \
-               MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) \
+               MSG_INFO_NOTIF(default, prefix##PINK, strnum, flnum, args, hudargs, sprintf(icon, strtolower(STATIC_NAME_TEAM_4)), TCR(normal, COL_TEAM_4, strtoupper(STATIC_NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(STATIC_NAME_TEAM_4))) \
        #endif
 #define MSG_INFO_NOTIFICATIONS \
        MULTITEAM_INFO(1, INFO_CTF_CAPTURE_, 2,                1, 0, "s1", "s1",                        "notify_%s_captured",   _("^BG%s^BG captured the ^TC^TT^BG flag\n"), "") \
@@ -256,7 +317,7 @@ void Send_Notification_WOVA(
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_DEATH,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 got caught in the blast of a Racer explosion%s%s\n"), "") \
        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\n"), "") \
        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\n"), "") \
-       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\n"), "") \
+       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\n"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K1 was frozen by ^BG%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K3 was revived by ^BG%s\n"), "") \
        MULTITEAM_INFO(1, INFO_FREEZETAG_ROUND_WIN_, 4,        0, 0, "", "",                            "",                     _("^TC^TT^BG team wins the round, all other teams were frozen\n"), "") \
@@ -288,8 +349,8 @@ void Send_Notification_WOVA(
        MSG_INFO_NOTIF(1, INFO_QUIT_KICK_SPECTATING,           0, 0, "", "",                            "",                     _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment.\n"), "") \
        MSG_INFO_NOTIF(1, INFO_QUIT_SPECTATE,                  1, 0, "s1", "",                          "",                     _("^BG%s^F3 is now spectating\n"), "") \
        MSG_INFO_NOTIF(1, INFO_RACE_ABANDONED,                 1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has abandoned the race\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED,               1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED,             1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s\n"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_RANKED,               1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break their %s%s^BG place record of %s%s %s\n"), "") \
+       MSG_INFO_NOTIF(1, INFO_RACE_FAIL_UNRANKED,             1, 3, "s1 race_col f1ord race_col f3race_time race_diff", "s1",        "race_newfail",          _("^BG%s^BG couldn't break the %s%s^BG place record of %s%s %s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_RACE_FINISHED,                  1, 0, "s1", "",                                                        "",                      _("^BG%s^BG has finished the race\n"), "") \
        MSG_INFO_NOTIF(1, INFO_RACE_NEW_BROKEN,                2, 3, "s1 s2 race_col f1ord race_col f2race_time race_diff", "s1 s2",  "race_newrankyellow",    _("^BG%s^BG broke %s^BG's %s%s^BG place record with %s%s %s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_RACE_NEW_IMPROVED,              1, 3, "s1 race_col f1ord race_col f2race_time race_diff", "s1",        "race_newtime",          _("^BG%s^BG improved their %s%s^BG place record with %s%s %s\n"), "") \
@@ -297,7 +358,7 @@ void Send_Notification_WOVA(
        MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET,                   1, 2, "s1 race_col f1ord race_col f2race_time", "s1",                  "race_newrecordserver",  _("^BG%s^BG set the %s%s^BG place record with %s%s\n"), "") \
        MULTITEAM_INFO(1, INFO_SCORES_, 4,                     0, 0, "", "",                            "",                     _("^TC^TT ^BGteam scores!\n"), "") \
        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!\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             0, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up a Superweapon\n"), "") \
+       MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up a Superweapon\n"), "") \
        MSG_INFO_NOTIF(2, INFO_VERSION_BETA,                   2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s\n"), "") \
        MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                    2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s\n"), "") \
        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!\n"), "") \
@@ -336,7 +397,6 @@ void Send_Notification_WOVA(
        MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER,                  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 was sniped with a Rifle by ^BG%s^K1%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 died in ^BG%s^K1's Rifle bullet hail%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle bullet hail%s%s\n"), "") \
-       MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_HEADSHOT,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_headshot",        _("^BG%s%s^K1 was shot in the head with a Rifle by ^BG%s^K1%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_RIFLE_MURDER_PIERCING,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrifle",            _("^BG%s%s^K1 failed to hide from ^BG%s^K1's Rifle%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 ate ^BG%s^K1's rocket%s%s\n"), "") \
        MSG_INFO_NOTIF(1, INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponrocketlauncher",   _("^BG%s%s^K1 got too close ^BG%s^K1's rocket%s%s\n"), "") \
@@ -353,13 +413,13 @@ void Send_Notification_WOVA(
        MSG_INFO_NOTIF(1, INFO_WEAPON_UZI_MURDER_SPRAY,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "weaponuzi",              _("^BG%s%s^K1 was riddled full of holes by ^BG%s^K1's Machine Gun%s%s\n"), "") 
 
 #define MULTITEAM_CENTER(default,prefix,teams,strnum,flnum,args,cpid,durcnt,normal,gentle) \
-       MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(NAME_TEAM_1))) \
-       MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(NAME_TEAM_2))) \
+       MSG_CENTER_NOTIF(default, prefix##RED, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_1, strtoupper(STATIC_NAME_TEAM_1)), TCR(gentle, COL_TEAM_1, strtoupper(STATIC_NAME_TEAM_1))) \
+       MSG_CENTER_NOTIF(default, prefix##BLUE, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_2, strtoupper(STATIC_NAME_TEAM_2)), TCR(gentle, COL_TEAM_2, strtoupper(STATIC_NAME_TEAM_2))) \
        #if teams >= 3 \
-               MSG_CENTER_NOTIF(default, prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(NAME_TEAM_3))) \
+               MSG_CENTER_NOTIF(default, prefix##YELLOW, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_3, strtoupper(STATIC_NAME_TEAM_3)), TCR(gentle, COL_TEAM_3, strtoupper(STATIC_NAME_TEAM_3))) \
        #endif \
        #if teams >= 4 \
-               MSG_CENTER_NOTIF(default, prefix##PINK, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(NAME_TEAM_4))) \
+               MSG_CENTER_NOTIF(default, prefix##PINK, strnum, flnum, args, cpid, durcnt, TCR(normal, COL_TEAM_4, strtoupper(STATIC_NAME_TEAM_4)), TCR(gentle, COL_TEAM_4, strtoupper(STATIC_NAME_TEAM_4))) \
        #endif
 #define MSG_CENTER_NOTIFICATIONS \
        MSG_CENTER_NOTIF(1, CENTER_ARENA_BEGIN,                 0, 0, "",             CPID_ARENA,          "2 0", _("^F4Begin!"), "") \
@@ -479,124 +539,126 @@ void Send_Notification_WOVA(
        MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING,              0, 1, "",              CPID_TIMEOUT,          "1 f1", _("^F4Timeout ends in ^COUNT"), "")
 
 #define MSG_MULTI_NOTIFICATIONS \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_CHEAT,                   INFO_DEATH_MURDER_CHEAT,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_DROWN,                   INFO_DEATH_MURDER_DROWN,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_FALL,                    INFO_DEATH_MURDER_FALL,                    NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_FIRE,                    INFO_DEATH_MURDER_FIRE,                    NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA,                    INFO_DEATH_MURDER_LAVA,                    NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_SHOOTING_STAR,           INFO_DEATH_MURDER_SHOOTING_STAR,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_SLIME,                   INFO_DEATH_MURDER_SLIME,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_SWAMP,                   INFO_DEATH_MURDER_SWAMP,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_TELEFRAG,                INFO_DEATH_MURDER_TELEFRAG,                NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_TOUCHEXPLODE,            INFO_DEATH_MURDER_TOUCHEXPLODE,            NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_DEATH,           INFO_DEATH_MURDER_VH_BUMB_DEATH,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_GUN,             INFO_DEATH_MURDER_VH_BUMB_GUN,             NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_CRUSH,                INFO_DEATH_MURDER_VH_CRUSH,                NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_BOMB,            INFO_DEATH_MURDER_VH_RAPT_BOMB,            NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_CANNON,          INFO_DEATH_MURDER_VH_RAPT_CANNON,          NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_DEATH,           INFO_DEATH_MURDER_VH_RAPT_DEATH,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_DEATH,           INFO_DEATH_MURDER_VH_SPID_DEATH,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_MINIGUN,         INFO_DEATH_MURDER_VH_SPID_MINIGUN,         NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_ROCKET,          INFO_DEATH_MURDER_VH_SPID_ROCKET,          NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH,           INFO_DEATH_MURDER_VH_WAKI_DEATH,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN,             INFO_DEATH_MURDER_VH_WAKI_GUN,             NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET,          INFO_DEATH_MURDER_VH_WAKI_ROCKET,          NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_MURDER_VOID,                    INFO_DEATH_MURDER_VOID,                    NO_MSG) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE,            INFO_DEATH_SELF_AUTOTEAMCHANGE,            CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_BETRAYAL,                  INFO_DEATH_SELF_BETRAYAL,                  CENTER_DEATH_SELF_BETRAYAL) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_CAMP,                      INFO_DEATH_SELF_CAMP,                      CENTER_DEATH_SELF_CAMP) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_CHEAT,                     INFO_DEATH_SELF_CHEAT,                     CENTER_DEATH_SELF_CHEAT) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_CUSTOM,                    INFO_DEATH_SELF_GENERIC,                   CENTER_DEATH_SELF_CUSTOM) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_DROWN,                     INFO_DEATH_SELF_DROWN,                     CENTER_DEATH_SELF_DROWN) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_FALL,                      INFO_DEATH_SELF_FALL,                      CENTER_DEATH_SELF_FALL) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_FIRE,                      INFO_DEATH_SELF_FIRE,                      CENTER_DEATH_SELF_FIRE) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_GENERIC,                   INFO_DEATH_SELF_GENERIC,                   CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_LAVA,                      INFO_DEATH_SELF_LAVA,                      CENTER_DEATH_SELF_LAVA) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_NOAMMO,                    INFO_DEATH_SELF_NOAMMO,                    CENTER_DEATH_SELF_NOAMMO) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_ROT,                       INFO_DEATH_SELF_ROT,                       CENTER_DEATH_SELF_ROT) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_SHOOTING_STAR,             INFO_DEATH_SELF_SHOOTING_STAR,             CENTER_DEATH_SELF_SHOOTING_STAR) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_SLIME,                     INFO_DEATH_SELF_SLIME,                     CENTER_DEATH_SELF_SLIME) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_SUICIDE,                   INFO_DEATH_SELF_SUICIDE,                   CENTER_DEATH_SELF_SUICIDE) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_SWAMP,                     INFO_DEATH_SELF_SWAMP,                     CENTER_DEATH_SELF_SWAMP) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TEAMCHANGE,                INFO_DEATH_SELF_TEAMCHANGE,                CENTER_DEATH_SELF_TEAMCHANGE) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TOUCHEXPLODE,              INFO_DEATH_SELF_TOUCHEXPLODE,              CENTER_DEATH_SELF_TOUCHEXPLODE) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET,                    INFO_DEATH_SELF_TURRET,                    CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_EWHEEL,             INFO_DEATH_SELF_TURRET_EWHEEL,             CENTER_DEATH_SELF_TURRET_EWHEEL) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_FLAC,               INFO_DEATH_SELF_TURRET_FLAC,               CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HELLION,            INFO_DEATH_SELF_TURRET_HELLION,            CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HK,                 INFO_DEATH_SELF_TURRET_HK,                 CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MACHINEGUN,         INFO_DEATH_SELF_TURRET_MACHINEGUN,         CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MLRS,               INFO_DEATH_SELF_TURRET_MLRS,               CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PHASER,             INFO_DEATH_SELF_TURRET_PHASER,             CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PLASMA,             INFO_DEATH_SELF_TURRET_PLASMA,             CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_TESLA,              INFO_DEATH_SELF_TURRET_TESLA,              CENTER_DEATH_SELF_TURRET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_GUN,           INFO_DEATH_SELF_TURRET_WALK_GUN,           CENTER_DEATH_SELF_TURRET_WALK) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_MEELE,         INFO_DEATH_SELF_TURRET_WALK_MEELE,         CENTER_DEATH_SELF_TURRET_WALK) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_ROCKET,        INFO_DEATH_SELF_TURRET_WALK_ROCKET,        CENTER_DEATH_SELF_TURRET_WALK) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_BUMB_DEATH,             INFO_DEATH_SELF_VH_BUMB_DEATH,             CENTER_DEATH_SELF_VH_BUMB_DEATH) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_CRUSH,                  INFO_DEATH_SELF_VH_CRUSH,                  CENTER_DEATH_SELF_VH_CRUSH) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_BOMB,              INFO_DEATH_SELF_VH_RAPT_BOMB,              CENTER_DEATH_SELF_VH_RAPT_BOMB) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_DEATH,             INFO_DEATH_SELF_VH_RAPT_DEATH,             CENTER_DEATH_SELF_VH_RAPT_DEATH) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_DEATH,             INFO_DEATH_SELF_VH_SPID_DEATH,             CENTER_DEATH_SELF_VH_SPID_DEATH) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_ROCKET,            INFO_DEATH_SELF_VH_SPID_ROCKET,            CENTER_DEATH_SELF_VH_SPID_ROCKET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_DEATH,             INFO_DEATH_SELF_VH_WAKI_DEATH,             CENTER_DEATH_SELF_VH_WAKI_DEATH) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_ROCKET,            INFO_DEATH_SELF_VH_WAKI_ROCKET,            CENTER_DEATH_SELF_VH_WAKI_ROCKET) \
-       MSG_MULTI_NOTIF(1, DEATH_SELF_VOID,                      INFO_DEATH_SELF_VOID,                      CENTER_DEATH_SELF_VOID) \
-       MSG_MULTI_NOTIF(1, ITEM_WEAPON_DONTHAVE,                 INFO_ITEM_WEAPON_DONTHAVE,                 CENTER_ITEM_WEAPON_DONTHAVE) \
-       MSG_MULTI_NOTIF(1, ITEM_WEAPON_DROP,                     INFO_ITEM_WEAPON_DROP,                     CENTER_ITEM_WEAPON_DROP) \
-       MSG_MULTI_NOTIF(1, ITEM_WEAPON_GOT,                      INFO_ITEM_WEAPON_GOT,                      CENTER_ITEM_WEAPON_GOT) \
-       MSG_MULTI_NOTIF(1, ITEM_WEAPON_NOAMMO,                   INFO_ITEM_WEAPON_NOAMMO,                   CENTER_ITEM_WEAPON_NOAMMO) \
-       MSG_MULTI_NOTIF(1, ITEM_WEAPON_PRIMORSEC,                INFO_ITEM_WEAPON_PRIMORSEC,                CENTER_ITEM_WEAPON_PRIMORSEC) \
-       MSG_MULTI_NOTIF(1, ITEM_WEAPON_UNAVAILABLE,              INFO_ITEM_WEAPON_UNAVAILABLE,              CENTER_ITEM_WEAPON_UNAVAILABLE) \
-       MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_MURDER,              INFO_WEAPON_ACCORDEON_MURDER,              NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_SUICIDE,             INFO_WEAPON_ACCORDEON_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_MURDER,                INFO_WEAPON_CRYLINK_MURDER,                NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_SUICIDE,               INFO_WEAPON_CRYLINK_SUICIDE,               CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_BOLT,           INFO_WEAPON_ELECTRO_MURDER_BOLT,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_COMBO,          INFO_WEAPON_ELECTRO_MURDER_COMBO,          NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_ORBS,           INFO_WEAPON_ELECTRO_MURDER_ORBS,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_BOLT,          INFO_WEAPON_ELECTRO_SUICIDE_BOLT,          CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_ORBS,          INFO_WEAPON_ELECTRO_SUICIDE_ORBS,          CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_BLAST,         INFO_WEAPON_FIREBALL_MURDER_BLAST,         NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_FIREMINE,      INFO_WEAPON_FIREBALL_MURDER_FIREMINE,      NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_BLAST,        INFO_WEAPON_FIREBALL_SUICIDE_BLAST,        CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_FIREMINE,     INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,     CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_BURST,            INFO_WEAPON_HAGAR_MURDER_BURST,            NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_SPRAY,            INFO_WEAPON_HAGAR_MURDER_SPRAY,            NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_HAGAR_SUICIDE,                 INFO_WEAPON_HAGAR_SUICIDE,                 CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_HLAC_MURDER,                   INFO_WEAPON_HLAC_MURDER,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_HLAC_SUICIDE,                  INFO_WEAPON_HLAC_SUICIDE,                  CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_HOOK_MURDER,                   INFO_WEAPON_HOOK_MURDER,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_MURDER,            INFO_WEAPON_KLEINBOTTLE_MURDER,            NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_SUICIDE,           INFO_WEAPON_KLEINBOTTLE_SUICIDE,           CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_LASER_MURDER,                  INFO_WEAPON_LASER_MURDER,                  NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_LASER_SUICIDE,                 INFO_WEAPON_LASER_SUICIDE,                 CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_MURDER,              INFO_WEAPON_MINELAYER_MURDER,              NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_SUICIDE,             INFO_WEAPON_MINELAYER_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_MINSTANEX_MURDER,              INFO_WEAPON_MINSTANEX_MURDER,              NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_BOUNCE,          INFO_WEAPON_MORTAR_MURDER_BOUNCE,          NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_EXPLODE,         INFO_WEAPON_MORTAR_MURDER_EXPLODE,         NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_BOUNCE,         INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,         CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_EXPLODE,        INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,        CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_NEX_MURDER,                    INFO_WEAPON_NEX_MURDER,                    NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER,                  INFO_WEAPON_RIFLE_MURDER,                  NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL,             INFO_WEAPON_RIFLE_MURDER_HAIL,             NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL_PIERCING,    INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HEADSHOT,         INFO_WEAPON_RIFLE_MURDER_HEADSHOT,         NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_PIERCING,         INFO_WEAPON_RIFLE_MURDER_PIERCING,         NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_SUICIDE,        INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,        CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_SPRAY,           INFO_WEAPON_SEEKER_MURDER_SPRAY,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_TAG,             INFO_WEAPON_SEEKER_MURDER_TAG,             NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_SEEKER_SUICIDE,                INFO_WEAPON_SEEKER_SUICIDE,                CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER,                INFO_WEAPON_SHOTGUN_MURDER,                NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER_SLAP,           INFO_WEAPON_SHOTGUN_MURDER_SLAP,           NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_THINKING_WITH_PORTALS,         INFO_WEAPON_THINKING_WITH_PORTALS,         CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_TUBA_MURDER,                   INFO_WEAPON_TUBA_MURDER,                   NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_TUBA_SUICIDE,                  INFO_WEAPON_TUBA_SUICIDE,                  CENTER_DEATH_SELF_GENERIC) \
-       MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SNIPE,              INFO_WEAPON_UZI_MURDER_SNIPE,              NO_MSG) \
-       MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SPRAY,              INFO_WEAPON_UZI_MURDER_SPRAY,              NO_MSG)
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_CHEAT,                   NO_MSG,        INFO_DEATH_MURDER_CHEAT,                   NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_DROWN,                   NO_MSG,        INFO_DEATH_MURDER_DROWN,                   NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_FALL,                    NO_MSG,        INFO_DEATH_MURDER_FALL,                    NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_FIRE,                    NO_MSG,        INFO_DEATH_MURDER_FIRE,                    NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA,                    NO_MSG,        INFO_DEATH_MURDER_LAVA,                    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_TELEFRAG,                NO_MSG,        INFO_DEATH_MURDER_TELEFRAG,                NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_TOUCHEXPLODE,            NO_MSG,        INFO_DEATH_MURDER_TOUCHEXPLODE,            NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_DEATH,           NO_MSG,        INFO_DEATH_MURDER_VH_BUMB_DEATH,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_BUMB_GUN,             NO_MSG,        INFO_DEATH_MURDER_VH_BUMB_GUN,             NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_CRUSH,                NO_MSG,        INFO_DEATH_MURDER_VH_CRUSH,                NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_BOMB,            NO_MSG,        INFO_DEATH_MURDER_VH_RAPT_BOMB,            NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_CANNON,          NO_MSG,        INFO_DEATH_MURDER_VH_RAPT_CANNON,          NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_RAPT_DEATH,           NO_MSG,        INFO_DEATH_MURDER_VH_RAPT_DEATH,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_DEATH,           NO_MSG,        INFO_DEATH_MURDER_VH_SPID_DEATH,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_MINIGUN,         NO_MSG,        INFO_DEATH_MURDER_VH_SPID_MINIGUN,         NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_SPID_ROCKET,          NO_MSG,        INFO_DEATH_MURDER_VH_SPID_ROCKET,          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_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_CAMP,                      NO_MSG,        INFO_DEATH_SELF_CAMP,                      CENTER_DEATH_SELF_CAMP) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_CHEAT,                     NO_MSG,        INFO_DEATH_SELF_CHEAT,                     CENTER_DEATH_SELF_CHEAT) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_CUSTOM,                    NO_MSG,        INFO_DEATH_SELF_GENERIC,                   CENTER_DEATH_SELF_CUSTOM) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_DROWN,                     NO_MSG,        INFO_DEATH_SELF_DROWN,                     CENTER_DEATH_SELF_DROWN) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_FALL,                      NO_MSG,        INFO_DEATH_SELF_FALL,                      CENTER_DEATH_SELF_FALL) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_FIRE,                      NO_MSG,        INFO_DEATH_SELF_FIRE,                      CENTER_DEATH_SELF_FIRE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_GENERIC,                   NO_MSG,        INFO_DEATH_SELF_GENERIC,                   CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_LAVA,                      NO_MSG,        INFO_DEATH_SELF_LAVA,                      CENTER_DEATH_SELF_LAVA) \
+       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_SLIME,                     NO_MSG,        INFO_DEATH_SELF_SLIME,                     CENTER_DEATH_SELF_SLIME) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_SUICIDE,                   NO_MSG,        INFO_DEATH_SELF_SUICIDE,                   CENTER_DEATH_SELF_SUICIDE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_SWAMP,                     NO_MSG,        INFO_DEATH_SELF_SWAMP,                     CENTER_DEATH_SELF_SWAMP) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TEAMCHANGE,                NO_MSG,        INFO_DEATH_SELF_TEAMCHANGE,                CENTER_DEATH_SELF_TEAMCHANGE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TOUCHEXPLODE,              NO_MSG,        INFO_DEATH_SELF_TOUCHEXPLODE,              CENTER_DEATH_SELF_TOUCHEXPLODE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET,                    NO_MSG,        INFO_DEATH_SELF_TURRET,                    CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_EWHEEL,             NO_MSG,        INFO_DEATH_SELF_TURRET_EWHEEL,             CENTER_DEATH_SELF_TURRET_EWHEEL) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_FLAC,               NO_MSG,        INFO_DEATH_SELF_TURRET_FLAC,               CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HELLION,            NO_MSG,        INFO_DEATH_SELF_TURRET_HELLION,            CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_HK,                 NO_MSG,        INFO_DEATH_SELF_TURRET_HK,                 CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MACHINEGUN,         NO_MSG,        INFO_DEATH_SELF_TURRET_MACHINEGUN,         CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_MLRS,               NO_MSG,        INFO_DEATH_SELF_TURRET_MLRS,               CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PHASER,             NO_MSG,        INFO_DEATH_SELF_TURRET_PHASER,             CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_PLASMA,             NO_MSG,        INFO_DEATH_SELF_TURRET_PLASMA,             CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_TESLA,              NO_MSG,        INFO_DEATH_SELF_TURRET_TESLA,              CENTER_DEATH_SELF_TURRET) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_GUN,           NO_MSG,        INFO_DEATH_SELF_TURRET_WALK_GUN,           CENTER_DEATH_SELF_TURRET_WALK) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_MEELE,         NO_MSG,        INFO_DEATH_SELF_TURRET_WALK_MEELE,         CENTER_DEATH_SELF_TURRET_WALK) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_TURRET_WALK_ROCKET,        NO_MSG,        INFO_DEATH_SELF_TURRET_WALK_ROCKET,        CENTER_DEATH_SELF_TURRET_WALK) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_BUMB_DEATH,             NO_MSG,        INFO_DEATH_SELF_VH_BUMB_DEATH,             CENTER_DEATH_SELF_VH_BUMB_DEATH) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_CRUSH,                  NO_MSG,        INFO_DEATH_SELF_VH_CRUSH,                  CENTER_DEATH_SELF_VH_CRUSH) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_BOMB,              NO_MSG,        INFO_DEATH_SELF_VH_RAPT_BOMB,              CENTER_DEATH_SELF_VH_RAPT_BOMB) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_RAPT_DEATH,             NO_MSG,        INFO_DEATH_SELF_VH_RAPT_DEATH,             CENTER_DEATH_SELF_VH_RAPT_DEATH) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_DEATH,             NO_MSG,        INFO_DEATH_SELF_VH_SPID_DEATH,             CENTER_DEATH_SELF_VH_SPID_DEATH) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_VH_SPID_ROCKET,            NO_MSG,        INFO_DEATH_SELF_VH_SPID_ROCKET,            CENTER_DEATH_SELF_VH_SPID_ROCKET) \
+       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_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) \
+       MSG_MULTI_NOTIF(1, ITEM_WEAPON_NOAMMO,                   NO_MSG,        INFO_ITEM_WEAPON_NOAMMO,                   CENTER_ITEM_WEAPON_NOAMMO) \
+       MSG_MULTI_NOTIF(1, ITEM_WEAPON_PRIMORSEC,                NO_MSG,        INFO_ITEM_WEAPON_PRIMORSEC,                CENTER_ITEM_WEAPON_PRIMORSEC) \
+       MSG_MULTI_NOTIF(1, ITEM_WEAPON_UNAVAILABLE,              NO_MSG,        INFO_ITEM_WEAPON_UNAVAILABLE,              CENTER_ITEM_WEAPON_UNAVAILABLE) \
+       MSG_MULTI_NOTIF(1, MULTI_ARENA_BEGIN,                    ANNCE_BEGIN,   NO_MSG,                                    CENTER_ARENA_BEGIN) \
+       MSG_MULTI_NOTIF(1, MULTI_COUNTDOWN_BEGIN,                ANNCE_BEGIN,   NO_MSG,                                    CENTER_COUNTDOWN_BEGIN) \
+       MSG_MULTI_NOTIF(1, MULTI_MINSTA_FINDAMMO,                ANNCE_NUM_10,  NO_MSG,                                    CENTER_MINSTA_FINDAMMO_FIRST) \
+       MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_MURDER,              NO_MSG,        INFO_WEAPON_ACCORDEON_MURDER,              NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ACCORDEON_SUICIDE,             NO_MSG,        INFO_WEAPON_ACCORDEON_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_MURDER,                NO_MSG,        INFO_WEAPON_CRYLINK_MURDER,                NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_CRYLINK_SUICIDE,               NO_MSG,        INFO_WEAPON_CRYLINK_SUICIDE,               CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_BOLT,           NO_MSG,        INFO_WEAPON_ELECTRO_MURDER_BOLT,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_COMBO,          NO_MSG,        INFO_WEAPON_ELECTRO_MURDER_COMBO,          NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_MURDER_ORBS,           NO_MSG,        INFO_WEAPON_ELECTRO_MURDER_ORBS,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_BOLT,          NO_MSG,        INFO_WEAPON_ELECTRO_SUICIDE_BOLT,          CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_ELECTRO_SUICIDE_ORBS,          NO_MSG,        INFO_WEAPON_ELECTRO_SUICIDE_ORBS,          CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_BLAST,         NO_MSG,        INFO_WEAPON_FIREBALL_MURDER_BLAST,         NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_MURDER_FIREMINE,      NO_MSG,        INFO_WEAPON_FIREBALL_MURDER_FIREMINE,      NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_BLAST,        NO_MSG,        INFO_WEAPON_FIREBALL_SUICIDE_BLAST,        CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_FIREBALL_SUICIDE_FIREMINE,     NO_MSG,        INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE,     CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_BURST,            NO_MSG,        INFO_WEAPON_HAGAR_MURDER_BURST,            NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_HAGAR_MURDER_SPRAY,            NO_MSG,        INFO_WEAPON_HAGAR_MURDER_SPRAY,            NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_HAGAR_SUICIDE,                 NO_MSG,        INFO_WEAPON_HAGAR_SUICIDE,                 CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_HLAC_MURDER,                   NO_MSG,        INFO_WEAPON_HLAC_MURDER,                   NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_HLAC_SUICIDE,                  NO_MSG,        INFO_WEAPON_HLAC_SUICIDE,                  CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_HOOK_MURDER,                   NO_MSG,        INFO_WEAPON_HOOK_MURDER,                   NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_MURDER,            NO_MSG,        INFO_WEAPON_KLEINBOTTLE_MURDER,            NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_KLEINBOTTLE_SUICIDE,           NO_MSG,        INFO_WEAPON_KLEINBOTTLE_SUICIDE,           CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_LASER_MURDER,                  NO_MSG,        INFO_WEAPON_LASER_MURDER,                  NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_LASER_SUICIDE,                 NO_MSG,        INFO_WEAPON_LASER_SUICIDE,                 CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_MURDER,              NO_MSG,        INFO_WEAPON_MINELAYER_MURDER,              NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_MINELAYER_SUICIDE,             NO_MSG,        INFO_WEAPON_MINELAYER_SUICIDE,             CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_MINSTANEX_MURDER,              NO_MSG,        INFO_WEAPON_MINSTANEX_MURDER,              NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_BOUNCE,          NO_MSG,        INFO_WEAPON_MORTAR_MURDER_BOUNCE,          NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_MURDER_EXPLODE,         NO_MSG,        INFO_WEAPON_MORTAR_MURDER_EXPLODE,         NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_BOUNCE,         NO_MSG,        INFO_WEAPON_MORTAR_SUICIDE_BOUNCE,         CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_MORTAR_SUICIDE_EXPLODE,        NO_MSG,        INFO_WEAPON_MORTAR_SUICIDE_EXPLODE,        CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_NEX_MURDER,                    NO_MSG,        INFO_WEAPON_NEX_MURDER,                    NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER,                  NO_MSG,        INFO_WEAPON_RIFLE_MURDER,                  NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL,             NO_MSG,        INFO_WEAPON_RIFLE_MURDER_HAIL,             NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_HAIL_PIERCING,    NO_MSG,        INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING,    NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_RIFLE_MURDER_PIERCING,         NO_MSG,        INFO_WEAPON_RIFLE_MURDER_PIERCING,         NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  NO_MSG,        INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT,  NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  NO_MSG,        INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH,  NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_ROCKETLAUNCHER_SUICIDE,        NO_MSG,        INFO_WEAPON_ROCKETLAUNCHER_SUICIDE,        CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_SPRAY,           NO_MSG,        INFO_WEAPON_SEEKER_MURDER_SPRAY,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_SEEKER_MURDER_TAG,             NO_MSG,        INFO_WEAPON_SEEKER_MURDER_TAG,             NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_SEEKER_SUICIDE,                NO_MSG,        INFO_WEAPON_SEEKER_SUICIDE,                CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER,                NO_MSG,        INFO_WEAPON_SHOTGUN_MURDER,                NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_SHOTGUN_MURDER_SLAP,           NO_MSG,        INFO_WEAPON_SHOTGUN_MURDER_SLAP,           NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_THINKING_WITH_PORTALS,         NO_MSG,        INFO_WEAPON_THINKING_WITH_PORTALS,         CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_TUBA_MURDER,                   NO_MSG,        INFO_WEAPON_TUBA_MURDER,                   NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_TUBA_SUICIDE,                  NO_MSG,        INFO_WEAPON_TUBA_SUICIDE,                  CENTER_DEATH_SELF_GENERIC) \
+       MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SNIPE,              NO_MSG,        INFO_WEAPON_UZI_MURDER_SNIPE,              NO_MSG) \
+       MSG_MULTI_NOTIF(1, WEAPON_UZI_MURDER_SPRAY,              NO_MSG,        INFO_WEAPON_UZI_MURDER_SPRAY,              NO_MSG)
 
 
 // ===========================
@@ -721,6 +783,7 @@ string arg_slot[NOTIF_MAX_ARGS];
     ARG_CASE(ARG_CS,        "f1time",        process_time(2, f1)) \
     ARG_CASE(ARG_CS_SV,     "f1race_time",   mmssss(f1)) \
     ARG_CASE(ARG_CS_SV,     "f2race_time",   mmssss(f2)) \
+    ARG_CASE(ARG_CS_SV,     "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,        "kh_teams",      notif_arg_kh_teams(f1, f2, f3, f4)) \
@@ -947,11 +1010,13 @@ float notif_error;
 float notif_global_error;
 
 // notification entities
+entity msg_annce_notifs[NOTIF_MAX];
 entity msg_info_notifs[NOTIF_MAX];
 entity msg_center_notifs[NOTIF_MAX];
 entity msg_multi_notifs[NOTIF_MAX];
 
 // notification counts
+float NOTIF_ANNCE_COUNT;
 float NOTIF_INFO_COUNT;
 float NOTIF_CENTER_COUNT;
 float NOTIF_MULTI_COUNT;
@@ -962,8 +1027,13 @@ float NOTIF_CPID_COUNT;
 .string nent_name;
 .float nent_id;
 .float nent_enabled;
+.entity nent_msgannce;
 .entity nent_msginfo;
 .entity nent_msgcenter;
+.float nent_channel;
+.string nent_snd;
+.float nent_vol;
+.float nent_position;
 .float nent_stringcount;
 .float nent_floatcount; 
 .string nent_args;
@@ -981,6 +1051,40 @@ float NOTIF_CPID_COUNT;
 .string nent_strings[4];
 .float nent_floats[4];
 
+#define MSG_ANNCE_NOTIF(default,name,channel,sound,volume,position) \
+       NOTIF_ADD_AUTOCVAR(name, default) \
+       float name; \
+       void RegisterNotification_##name() \
+       { \
+               SET_FIELD_COUNT(name, NOTIF_FIRST, NOTIF_ANNCE_COUNT) \
+               CHECK_MAX_COUNT(name, NOTIF_MAX, NOTIF_ANNCE_COUNT, "notifications") \
+               Create_Notification_Entity( \
+                       default,                       /* var_default */ \
+                       autocvar_notification_##name,  /* var_cvar */ \
+                       MSG_ANNCE,                     /* typeid */ \
+                       name,                          /* nameid */ \
+                       strtoupper(#name),             /* namestring */ \
+                       NO_MSG,                        /* anncename */ \
+                       NO_MSG,                        /* infoname */ \
+                       NO_MSG,                        /* centername */ \
+                       channel,                       /* channel */ \
+                       sound,                         /* snd */ \
+                       volume,                        /* vol */ \
+                       position,                      /* position */ \
+                       NO_MSG,                        /* strnum */ \
+                       NO_MSG,                        /* flnum */ \
+                       "",                            /* args */ \
+                       "",                            /* hudargs */ \
+                       "",                            /* icon */ \
+                       NO_MSG,                        /* cpid */ \
+                       "",                            /* durcnt */ \
+                       "",                            /* normal */ \
+                       "",                            /* gentle */ \
+                       FALSE,                         /* msg_is_info */ \
+                       FALSE);                        /* msg_is_multi */ \
+       } \
+       ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
+
 #define MSG_INFO_NOTIF(default,name,strnum,flnum,args,hudargs,icon,normal,gentle) \
        NOTIF_ADD_AUTOCVAR(name, default) \
        float name; \
@@ -994,8 +1098,13 @@ float NOTIF_CPID_COUNT;
                        MSG_INFO,                      /* typeid */ \
                        name,                          /* nameid */ \
                        strtoupper(#name),             /* namestring */ \
+                       NO_MSG,                        /* anncename */ \
                        NO_MSG,                        /* infoname */ \
                        NO_MSG,                        /* centername */ \
+                       NO_MSG,                        /* channel */ \
+                       "",                            /* snd */ \
+                       NO_MSG,                        /* vol */ \
+                       NO_MSG,                        /* position */ \
                        strnum,                        /* strnum */ \
                        flnum,                         /* flnum */ \
                        args,                          /* args */ \
@@ -1025,8 +1134,13 @@ float NOTIF_CPID_COUNT;
                        MSG_CENTER,                    /* typeid */ \
                        name,                          /* nameid */ \
                        strtoupper(#name),             /* namestring */ \
+                       NO_MSG,                        /* anncename */ \
                        NO_MSG,                        /* infoname */ \
                        NO_MSG,                        /* centername */ \
+                       NO_MSG,                        /* channel */ \
+                       "",                            /* snd */ \
+                       NO_MSG,                        /* vol */ \
+                       NO_MSG,                        /* position */ \
                        strnum,                        /* strnum */ \
                        flnum,                         /* flnum */ \
                        args,                          /* args */ \
@@ -1041,7 +1155,7 @@ float NOTIF_CPID_COUNT;
        } \
        ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotification_##name)
 
-#define MSG_MULTI_NOTIF(default,name,infoname,centername) \
+#define MSG_MULTI_NOTIF(default,name,anncename,infoname,centername) \
        NOTIF_ADD_AUTOCVAR(name, default) \
        float name; \
        void RegisterNotification_##name() \
@@ -1054,8 +1168,13 @@ float NOTIF_CPID_COUNT;
                        MSG_MULTI,                     /* typeid */ \
                        name,                          /* nameid */ \
                        strtoupper(#name),             /* namestring */ \
+                       anncename,                     /* anncename */ \
                        infoname,                      /* infoname */ \
                        centername,                    /* centername */ \
+                       NO_MSG,                        /* channel */ \
+                       "",                            /* snd */ \
+                       NO_MSG,                        /* vol */ \
+                       NO_MSG,                        /* position */ \
                        NO_MSG,                        /* strnum */ \
                        NO_MSG,                        /* flnum */ \
                        "",                            /* args */ \
@@ -1112,10 +1231,12 @@ void RegisterNotifications_Done()
 
 // NOW we actually activate the declarations
 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_First)
+MSG_ANNCE_NOTIFICATIONS
 MSG_INFO_NOTIFICATIONS
 MSG_CENTER_NOTIFICATIONS
 MSG_MULTI_NOTIFICATIONS
 ACCUMULATE_FUNCTION(RegisterNotifications, RegisterNotifications_Done)
+#undef MSG_ANNCE_NOTIF
 #undef MSG_INFO_NOTIF
 #undef MSG_CENTER_NOTIF
 #undef MSG_MULTI_NOTIF
index c9bed09a626da42d29209871b51886a00e65bbf1..e77b7643cbdc80dd86c53d42e2a59e6b825654af 100644 (file)
@@ -30,6 +30,12 @@ const string NAME_TEAM_4 = _("Pink");
 const string NAME_TEAM = _("Team");
 const string NAME_NEUTRAL = _("Neutral");
 
+// used for replacement in filenames or such where the name CANNOT be allowed to be translated
+const string STATIC_NAME_TEAM_1 = "Red";
+const string STATIC_NAME_TEAM_2 = "Blue";
+const string STATIC_NAME_TEAM_3 = "Yellow";
+const string STATIC_NAME_TEAM_4 = "Pink";
+
 #define APP_TEAM_NUM_2(num,prefix) ((num == NUM_TEAM_1) ? prefix##RED : prefix##BLUE)
 #define APP_TEAM_NUM_4(num,prefix) ((num == NUM_TEAM_1) ? prefix##RED : ((num == NUM_TEAM_2) ? prefix##BLUE : ((num == NUM_TEAM_3) ? prefix##YELLOW : prefix##PINK)))
 #define APP_TEAM_ENT_2(ent,prefix) ((ent.team == NUM_TEAM_1) ? prefix##RED : prefix##BLUE)
index dffce2f2bb0e206c3a73b296b7136f82daecb18f..1c2c1cc9f266fdb2fdc16ab627e95fd46ca9be18 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef NOCOMPAT
 //# define WORKAROUND_XON010
 //# define COMPAT_XON010_CHANNELS
-# define COMPAT_XON050_ENGINE
+//# define COMPAT_XON050_ENGINE
 # define COMPAT_NO_MOD_IS_XONOTIC
 # define COMPAT_XON060_DONTCRASH_CHECKPVS
 #endif
index 9db09a24345d118bb3a7620204fdd954191360bc..7fa2f576a64649cce85982cf908b5b4b0ae2a229 100644 (file)
@@ -2586,3 +2586,23 @@ void dedicated_print(string input) // print(), but only print if the server is n
        if(server_is_dedicated) { print(input); }
 }
 #endif
+
+#ifndef MENUQC
+float Announcer_PickNumber(float num)
+{
+       switch(num)
+       {
+               case 10: num = ANNCE_NUM_10; break;
+               case 9:  num = ANNCE_NUM_9;  break;
+               case 8:  num = ANNCE_NUM_8;  break;
+               case 7:  num = ANNCE_NUM_7;  break;
+               case 6:  num = ANNCE_NUM_6;  break;
+               case 5:  num = ANNCE_NUM_5;  break;
+               case 4:  num = ANNCE_NUM_4;  break;
+               case 3:  num = ANNCE_NUM_3;  break;
+               case 2:  num = ANNCE_NUM_2;  break;
+               case 1:  num = ANNCE_NUM_1;  break;
+       }
+       return num;
+}
+#endif
index bd603b74c25905b90edd304a116d12e3d0019576..df910e353927a2593f56a7d5f245d0d29702f0ed 100644 (file)
@@ -430,3 +430,7 @@ void dedicated_print(string input);
 #define PROGNAME "CSQC"
 #endif
 #endif
+
+#ifndef MENUQC
+float Announcer_PickNumber(float num);
+#endif
index ddf9ff686adc7b4413086cab0093d08fc6aa0a7a..2dc73a8d22675d78d36d789408b907d6b40f2d75 100644 (file)
@@ -687,7 +687,7 @@ void m_draw()
                if(Menu_Active)
                if(!cvar("menu_video_played"))
                {
-                       localcmd("cd loop $menu_cdtrack; play sound/announcer/default/welcome.ogg\n");
+                       localcmd("cd loop $menu_cdtrack; play sound/announcer/default/welcome.wav\n");
                        menuLogoAlpha = -0.8; // no idea why, but when I start this at zero, it jumps instead of fading FIXME
                }
                // ALWAYS set this cvar; if we start but menu is not active, this means we want no background music!
index a5340169319d1b47b15df0c01bbc0bb09e99c143..3fc6f31fe322e47bd208a0bdc1384754498defa7 100644 (file)
@@ -153,7 +153,6 @@ void XonoticServerCreateTab_gameTypeChangeNotify(entity me)
                case MAPINFO_TYPE_CTF:        GameType_ConfigureSliders(e, l, l2, _("Capture limit:"),   1,   20, 1, "capturelimit_override");     break;
                case MAPINFO_TYPE_DOMINATION: GameType_ConfigureSliders(e, l, l2, _("Point limit:"),    50,  500, 10, "g_domination_point_limit"); break;
                case MAPINFO_TYPE_KEYHUNT:    GameType_ConfigureSliders(e, l, l2, _("Point limit:"),   200, 1500, 50, "g_keyhunt_point_limit");    break;
-               case MAPINFO_TYPE_RUNEMATCH:  GameType_ConfigureSliders(e, l, l2, _("Point limit:"),    50,  500, 10, "g_runematch_point_limit");  break;
                case MAPINFO_TYPE_LMS:        GameType_ConfigureSliders(e, l, l2, _("Lives:"),           3,   50,  1, "g_lms_lives_override");     break;
                case MAPINFO_TYPE_RACE:       GameType_ConfigureSliders(e, l, l2, _("Laps:"),            1,   25,  1, "g_race_laps_limit");        break;
                case MAPINFO_TYPE_NEXBALL:    GameType_ConfigureSliders(e, l, l2, _("Goals:"),           1,   50,  1, "g_nexball_goallimit");      break;
index e80bf30e4e410b183ca23dc487b6f15afd1ae5b1..b4ca21385d3d744652d9e68ce7acec9a5e22be17 100644 (file)
@@ -609,7 +609,6 @@ float updateCompression()
        GAMETYPE(MAPINFO_TYPE_ONSLAUGHT) \
        GAMETYPE(MAPINFO_TYPE_RACE) \
        GAMETYPE(MAPINFO_TYPE_CTS) \
-       GAMETYPE(MAPINFO_TYPE_RUNEMATCH) \
        GAMETYPE(MAPINFO_TYPE_TEAM_DEATHMATCH) \
        /* nothing */
 
index 7b2d715835c0ebda093becabd1f00326b9a37e68..34b81bb62a1bb0d6c2b077ddc4e3d602c863c094 100644 (file)
@@ -22,7 +22,7 @@ float red_players, blue_players, yellow_players, pink_players;
 float total_players;
 
 /**
- * Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map.
+ * Resets the state of all clients, items, flags, keys, weapons, waypoints, ... of the map.
  * Sets the 'warmup' global variable.
  */
 void reset_map(float dorespawn)
@@ -237,13 +237,13 @@ void Arena_Warmup()
                                warmup = time + autocvar_g_ca_warmup;
                        } else {
                                if(f == 5)
-                                       Announce("prepareforbattle");
+                                       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_PREPARE);
                                else if(f == 3)
-                                       Announce("3");
+                                       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_NUM_3);
                                else if(f == 2)
-                                       Announce("2");
+                                       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_NUM_2);
                                else if(f == 1)
-                                       Announce("1");
+                                       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_NUM_1);
 
                                Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ARENA_ROUNDSTART, f);
                        }
@@ -266,8 +266,7 @@ void Arena_Warmup()
                        else
                                reset_map(TRUE);
                } else {
-                       Announce("begin");
-                       Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ARENA_BEGIN); 
+                       Send_Notification(NOTIF_ALL, world, MSG_MULTI, MULTI_ARENA_BEGIN);
                }
 
                if(g_arena) {
diff --git a/qcsrc/server/attic/runematch.qc b/qcsrc/server/attic/runematch.qc
new file mode 100644 (file)
index 0000000..ba8f648
--- /dev/null
@@ -0,0 +1,604 @@
+float rune_numspawns;
+
+float  RUNE_FIRST      = 1;
+float  RUNE_STRENGTH   = 1;
+float  RUNE_DEFENSE    = 2;
+float  RUNE_REGEN      = 4;
+float  RUNE_SPEED      = 8;
+float  RUNE_VAMPIRE    = 16;
+float  RUNE_LAST       = 16;
+
+float  CURSE_FIRST     = 8192;
+float  CURSE_WEAK      = 8192;
+float  CURSE_VULNER    = 16384;
+float  CURSE_VENOM     = 32768;
+float  CURSE_SLOW      = 65536;
+float  CURSE_EMPATHY   = 131072;
+float  CURSE_LAST      = 131072;
+
+float RUNE_COUNT = 5;
+
+/* rune ideas:
+
+       Doom/Death
+       Rune: When you damage enemies, you have a slight chance of instant-killing them (porportional to damage dealt / their health)
+       Curse: When you are damaged, you have a chance of being instant-killed
+
+       Vengence/Slothful
+       Rune: The lower your health below 100, the more damage you deal (does not decrease your damage if you're above 100)
+       Curse: The higher your health (up to 100), the less damage you deal (at 100 hp deal 1/5th damage)
+
+*/
+
+/*QUAKED spawnfunc_runematch_spawn_point (1 0 0) (-16 -16 -24) (16 16 24)
+spawn point for runes in runematch
+*/
+
+void spawnfunc_runematch_spawn_point()
+{
+       if(!g_runematch || !autocvar_g_runematch_fixedspawns)
+       {
+               remove(self);
+               return;
+       }
+
+       setsize(self, '0 0 -35', '0 0 0');
+       droptofloor();
+       ++rune_numspawns;
+}
+
+// only used if using rune spawns at all
+entity rune_find_spawnpoint()
+{
+       entity e;
+
+       if(rune_numspawns < RUNE_COUNT)
+               return world;
+
+       RandomSelection_Init();
+
+       for(e = world; (e = find(e, classname, "runematch_spawn_point")); )
+               if(e.owner == world)
+                       RandomSelection_Add(e, 0, string_null, e.cnt, 0);
+
+       return RandomSelection_chosen_ent;
+}
+
+float rune_spawn_somewhere(entity e)
+{
+       entity spot;
+       spot = rune_find_spawnpoint();
+       if(spot)
+       {
+               spot.owner = e;
+               setorigin(e, spot.origin);
+
+               e.owner = spot;
+               spot.owner = e;
+
+               return TRUE;
+       }
+       else
+       {
+               if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
+               {
+                       // great
+                       makevectors(self.angles),
+                       self.velocity = v_forward * 250;
+                       self.angles = '0 0 0';
+                       return TRUE;
+               }
+               else
+               {
+                       // sorry, can't spawn, better luck next frame
+                       return FALSE;
+               }
+       }
+}
+
+void rune_unmark_spot(entity e)
+{
+       if(e.owner.classname == "runematch_spawn_point")
+       {
+               e.owner.owner = world;
+               e.owner = world;
+       }
+}
+
+string RuneName(float r)
+{
+       if(r == RUNE_STRENGTH)
+               return "^1Strength^7";
+       if(r == RUNE_DEFENSE)
+               return "^4Defense^7";
+       if(r == RUNE_REGEN)
+               return "^2Vitality^7";
+       if(r == RUNE_SPEED)
+               return "^3Speed^7";
+       if(r == RUNE_VAMPIRE)
+               return "^6Vampire^7";
+
+       if(r == CURSE_WEAK)
+               return "^1Weakness^7";
+       if(r == CURSE_VULNER)
+               return "^4Vulnerability^7";
+       if(r == CURSE_VENOM)
+               return "^2Venom^7";
+       if(r == CURSE_SLOW)
+               return "^3Slow^7";
+       if(r == CURSE_EMPATHY)
+               return "^6Empathy^7";
+       return strcat("^8[unnamed", ftos(r), "]^7");
+}
+
+vector RuneColormod(float r)
+{
+       vector _color = '255 0 255';
+
+       if(r == RUNE_STRENGTH)
+               _color = '255 0 0';
+       if(r == RUNE_DEFENSE)
+               _color = '0 0 255';//'0 102 255';//
+       if(r == RUNE_REGEN)
+               _color = '0 204 0';//'0 255 0';
+       if(r == RUNE_SPEED)
+               _color = 0.35*'185 185 0';//255 230 0';//'255 255 0';
+       if(r == RUNE_VAMPIRE)
+               _color = '64 0 128';//'108 0 217';//'128 0 255';//'179 0 204';//
+
+       if(r == CURSE_WEAK)
+               _color = '255 0 0';
+       if(r == CURSE_VULNER)
+               _color = '0 0 255';//'0 102 255';//
+       if(r == CURSE_VENOM)
+               _color = '0 204 0';//'0 255 0';
+       if(r == CURSE_SLOW)
+               _color = 0.5*'185 185 0';//'255 255 0';
+       if(r == CURSE_EMPATHY)
+               _color = '179 0 204';//'128 0 255';
+
+       return _color * (1 / 255) * autocvar_g_runematch_rune_color_strength;
+}
+
+void rune_respawn();
+
+void RuneCarriedThink()
+{
+       float rcount, rnum;
+       vector ang = '0 0 0';
+       entity rune;
+
+       if(self.owner.classname != "player" || time < game_starttime)
+       {
+               rune_respawn();
+               return;
+       }
+
+       self.nextthink = time + 0.1;
+
+       // count runes my owner holds
+       rcount = 0;
+       rune = find(world, classname, "rune");
+       rnum = -1;
+       while(rune)
+       {
+               if(rune.owner == self.owner)
+                       rcount = rcount + 1;
+               if(rune == self)
+                       rnum = rcount;
+               rune = find(rune, classname, "rune");
+       }
+
+       ang_y = rnum*(360 / rcount) + mod(time, 360)*45;//180;
+
+       makevectors(ang);
+
+       setorigin(self, v_forward*32);
+}
+
+void rune_touch()
+{
+       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+       {
+               self.think = rune_respawn;
+               self.nextthink = time;
+               return;
+       }
+
+       if(other.classname != "player" || other.health < 1)
+               return;
+       if(self.wait > time)
+               return; // "notouch" time isn't finished
+
+       // detach from the spawn point you're on
+       rune_unmark_spot(self);
+
+       self.owner = other;
+       self.enemy.owner = other;
+       setattachment(self, other, "");
+
+       other.runes = other.runes | self.runes | self.enemy.runes;
+
+       //self.think = func_null;
+       //self.nextthink = 0;
+       self.think = RuneCarriedThink;
+       self.nextthink = time;
+       self.touch = func_null;
+
+       self.solid = SOLID_NOT;
+       setorigin(self, self.origin);
+
+       //sprint(other, strcat("^3You have picked up ",
+       //      RuneName(self.runes & (RUNE_LAST*2-1)), " and "));
+       //sprint(other, strcat(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"));
+
+       bprint("^3", other.netname, "^7 has picked up ",
+               RuneName(self.runes & (RUNE_LAST*2-1)), "^7 and ");
+       bprint(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n");
+}
+
+void rune_respawn()
+{
+       rune_unmark_spot(self);
+       if(rune_spawn_somewhere(self))
+       {
+               self.solid = SOLID_TRIGGER;
+               self.touch = rune_touch;
+               self.think = rune_respawn;
+               self.nextthink = time + autocvar_g_runematch_shuffletime;//30 + random()*5; // fixme: cvar
+       }
+       else
+       {
+               // try again later
+               self.think = rune_respawn;
+               self.nextthink = time;
+       }
+}
+
+entity FindRune(entity own, string clname, float r)
+{
+       entity rune;
+       float _count, c;
+
+       c = _count = 0;
+       rune = world;
+
+       do
+       {
+               rune = find(rune, classname, clname);
+               if(!rune)
+                       rune = find(rune, classname, clname);
+               if(!rune)
+                       break;
+               if(rune.owner == own)
+               {
+                       _count = _count + 1;
+                       if(_count >= r)
+                               return rune;
+                       if(r <= 1)
+                               return rune;
+               }
+               c = c + 1;
+       }while(c < 30);
+       return world;
+}
+
+
+void DropRune(entity pl, entity e)
+{
+       //entity pl;
+
+       //pl = e.owner;
+       // detach from player
+       setattachment(e, world, "");
+       e.owner = world;
+       e.enemy.owner = world;
+       // don't instantly touch player again
+       e.wait = time + 1; // "notouch" time
+       e.movetype = MOVETYPE_TOSS;
+       e.solid = SOLID_TRIGGER;
+       // reposition itself if not picked up soon
+       e.think = rune_respawn;
+       e.nextthink = time + autocvar_g_runematch_respawntime;//15 + random()*5; // fixme: cvar
+       e.touch = rune_touch;
+
+       pl.runes = pl.runes - (pl.runes & (e.runes | e.enemy.runes));
+
+       // toss from player
+       setorigin(e, pl.origin + '0 0 10');
+       e.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
+
+
+       bprint("^3", pl.netname, "^7 has lost ",
+               RuneName(e.runes & (RUNE_LAST*2-1)), "^7 and ");
+       bprint(RuneName(e.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n");
+}
+
+float RuneMatchesCurse(float r, float c)
+{
+       float cr;
+       if(r & RUNE_STRENGTH)
+               cr = CURSE_WEAK;
+       else if(r & RUNE_DEFENSE)
+               cr = CURSE_VULNER;
+       else if(r & RUNE_REGEN)
+               cr = CURSE_VENOM;
+       else if(r & RUNE_SPEED)
+               cr = CURSE_SLOW;
+       else if(r & RUNE_VAMPIRE)
+               cr = CURSE_EMPATHY;
+       else return FALSE; // fixme: error?
+
+       if(c & cr)
+               return TRUE;
+       return FALSE;
+}
+
+// player died, drop runes
+// each rune should pair up with a random curse and then be tossed from the player
+void DropAllRunes(entity pl)
+{
+       entity rune, curse;
+       float rcount, ccount, r, c, rand, prevent_same, numtodrop, tries;
+
+       entity curse1, rune1, curse2, rune2;
+
+       rcount = ccount = r = c = 0;
+       rune = find(world, classname, "rune");
+       while(rune)
+       {
+               if(rune.owner == pl)
+                       rcount = rcount + 1;
+               rune = find(rune, classname, "rune");
+       }
+       curse = find(world, classname, "curse");
+       while(curse)
+       {
+               if(curse.owner == pl)
+                       ccount = ccount + 1;
+               curse = find(curse, classname, "curse");
+       }
+
+       numtodrop = autocvar_g_runematch_drop_runes_max;
+       prevent_same = !autocvar_g_runematch_allow_same;
+
+       do
+       {
+               rune = find(rune, classname, "rune");
+               if(!rune)
+                       break;
+               if(rune.owner != pl)
+                       continue;
+
+
+               // find a random curse
+               tries = 15;
+               if(ccount > 1 && prevent_same)
+               {
+                       // avoid pairing runes and curses that match each other
+                       do{
+                               rand = floor(random()*ccount) + 1;
+                               curse = FindRune(pl, "curse", rand);
+                               tries = tries - 1;
+                       }while(RuneMatchesCurse(rune.runes, curse.runes) && tries > 0);
+                       if(tries <= 0)
+                       {
+                               bprint("warning: couldn't prevent same rune\n");
+                       }
+               }
+               else
+               {
+                               rand = floor(random()*ccount) + 1;
+                               curse = FindRune(pl, "curse", rand);
+               }
+
+               if(!curse)
+                       error("Couldn't fine curse to bind rune to\n");
+
+               // pair rune and curse
+
+               rune1 = rune;
+               curse1 = curse;
+               rune2 = curse1.enemy;
+               curse2 = rune1.enemy;
+
+               if(rune1 != rune2) // not already attached to each other
+               {
+                       rune1.enemy = curse1;
+                       curse1.enemy = rune1;
+                       setattachment(curse1, rune1, "");
+                       rune2.enemy = curse2;
+                       curse2.enemy = rune2;
+                       setattachment(curse2, rune2, "");
+                       //DropRune(pl, rune2);
+                       //ccount = ccount - 1;
+                       //rcount = rcount - 1;
+               }
+               DropRune(pl, rune1);
+
+               if(numtodrop <=0)
+               {
+                       rune1.think = rune_respawn;
+                       rune1.nextthink = time;
+               }
+
+               numtodrop = numtodrop - 1;
+
+               ccount = ccount - 1;
+               rcount = rcount - 1;
+
+       }while(rune);
+}
+
+void rune_reset()
+{
+       if(self.owner)
+               if(self.owner.classname != "runematch_spawn_point")
+                       DropAllRunes(self.owner);
+       rune_respawn();
+}
+
+void spawn_runes()
+{
+       float rn, cs, runes_used, curses_used, prevent_same, numrunes;
+       entity e;
+
+       if(self)
+               remove(self);
+
+       // fixme: instead of placing them all now, why not
+       // simply create them all and let them call rune_respawn() as their think?
+
+       runes_used  = 0;
+       curses_used = 0;
+
+       prevent_same = !autocvar_g_runematch_allow_same;
+       numrunes = RUNE_COUNT;
+
+       while(numrunes > 0)
+       {
+               RandomSelection_Init();
+               for(rn = RUNE_FIRST; rn <= RUNE_LAST; rn *= 2)
+                       if not(runes_used & rn)
+                               RandomSelection_Add(world, rn, string_null, 1, 1);
+               rn = RandomSelection_chosen_float;
+
+               RandomSelection_Init();
+               for(cs = CURSE_FIRST; cs <= CURSE_LAST; cs *= 2)
+                       if not(curses_used & cs)
+                               if not(prevent_same && cs == RuneMatchesCurse(rn, cs))
+                                       RandomSelection_Add(world, cs, string_null, 1, 1);
+               cs = RandomSelection_chosen_float;
+
+               if(!rn || !cs)
+                       error("No rune/curse left");
+
+               runes_used |= rn;
+               curses_used |= cs;
+
+               e = spawn();
+               e.runes = rn;
+               e.classname = "rune";
+               e.touch = rune_touch;
+               e.think = rune_respawn;
+               e.nextthink = time;
+               e.movetype = MOVETYPE_TOSS;
+               e.solid = SOLID_TRIGGER;
+               e.flags = FL_ITEM;
+               e.reset = rune_reset;
+               setmodel(e, "models/runematch/rune.mdl"); // precision set below
+               setsize(e, '0 0 -35', '0 0 0');
+
+               e.enemy = spawn();
+               e.enemy.enemy = e;
+               e.enemy.classname = "curse";
+               e.enemy.runes = cs;
+               //e.enemy.avelocity = '300 500 200';
+               setmodel(e.enemy, "models/runematch/curse.mdl"); // precision set below
+               setorigin(e, '0 0 0');
+               setattachment(e.enemy, e, "");
+
+               e.colormod = RuneColormod(rn);
+               e.enemy.colormod = RuneColormod(cs);
+
+               e.alpha = e.enemy.alpha = autocvar_g_runematch_rune_alpha;//0.78;
+               e.effects = e.enemy.effects = autocvar_g_runematch_rune_effects | EF_LOWPRECISION;//EF_ADDITIVE;// | EF_FULLBRIGHT;
+
+               //e.glow_size = e.enemy.glow_size = cvar("g_runematch_rune_glow_size");
+               //e.glow_color = e.enemy.glow_color = cvar("g_runematch_rune_glow_color");
+
+               //rn = RUNE_FIRST;
+               //cs = CURSE_FIRST;
+
+               numrunes = numrunes - 1;
+       }
+}
+
+void runematch_init()
+{
+       if(!g_runematch)
+               return;
+
+       entity e;
+       e = spawn();
+       e.think = spawn_runes;
+       e.nextthink = time + 0.1;
+}
+
+
+float runematch_point_time;
+
+// give points to players who are holding runes
+void RuneMatchGivePoints()
+{
+       entity rune;
+
+       if(!g_runematch || !autocvar_g_runematch_pointamt)
+               return;
+
+       if(gameover)
+               return;
+
+       if(runematch_point_time > time)
+               return;
+
+       runematch_point_time = time + autocvar_g_runematch_pointrate;
+
+       rune = world;
+       do
+       {
+               rune = find(rune, classname, "rune");
+               if(!rune)
+                       return;
+
+               if(rune.owner.classname == "player")
+               {
+                       UpdateFrags(rune.owner, autocvar_g_runematch_pointamt);
+               }
+       }while(rune);
+}
+
+float RunematchHandleFrags(entity attacker, entity targ, float f)
+{
+       entity head;
+       float arunes, trunes, newfrags;
+
+       if(f <= 0)
+               return f;
+       if(attacker == targ)
+               return f;
+
+       arunes = trunes = 0;
+
+       head = find(world, classname, "rune");
+       while(head)
+       {
+               if(head.owner == attacker)
+               {
+                       arunes = arunes + 1;
+               }
+               else if(head.owner == targ)
+               {
+                       trunes = trunes + 1;
+               }
+
+               head = find(head, classname, "rune");
+       }
+
+       if(!arunes && !trunes)
+               return f - 1 + autocvar_g_runematch_frags_norune; // don't give points to players when no runes are involved.
+
+       newfrags = 0;
+       if(arunes)
+       {       // got a kill while holding runes
+               newfrags = newfrags + autocvar_g_runematch_frags_killedby_runeholder;//5;
+       }
+       if(trunes)
+       {       // killed an enemy holding runes
+               newfrags = newfrags + autocvar_g_runematch_frags_killed_runeholder;//5;
+       }
+       if(newfrags)
+               f = f - 1 + newfrags;
+
+       return f;
+}
index 1ea2615eadc2e846e807fd074b13fc6954e32e61..1febc23d26801842d3f916d02357612009789d63 100644 (file)
@@ -178,16 +178,6 @@ float autocvar_g_balance_crylink_secondary_spread;
 float autocvar_g_balance_crylink_secondary_spreadtype;
 float autocvar_g_balance_crylink_reload_ammo;
 float autocvar_g_balance_crylink_reload_time;
-float autocvar_g_balance_curse_empathy_minhealth;
-float autocvar_g_balance_curse_empathy_takedamage;
-float autocvar_g_balance_curse_slow_atkrate;
-float autocvar_g_balance_curse_slow_highspeed;
-float autocvar_g_balance_curse_venom_hpmod;
-float autocvar_g_balance_curse_venom_limitmod;
-float autocvar_g_balance_curse_venom_rotrate;
-float autocvar_g_balance_curse_vulner_takedamage;
-float autocvar_g_balance_curse_weak_damage;
-float autocvar_g_balance_curse_weak_force;
 float autocvar_g_balance_damagepush_speedfactor;
 float autocvar_g_balance_electro_combo_comboradius;
 float autocvar_g_balance_electro_combo_damage;
@@ -593,26 +583,6 @@ float autocvar_g_balance_rocketlauncher_speedaccel;
 float autocvar_g_balance_rocketlauncher_speedstart;
 float autocvar_g_balance_rocketlauncher_reload_ammo;
 float autocvar_g_balance_rocketlauncher_reload_time;
-float autocvar_g_balance_rune_defense_combo_takedamage;
-float autocvar_g_balance_rune_defense_takedamage;
-float autocvar_g_balance_rune_regen_combo_hpmod;
-float autocvar_g_balance_rune_regen_combo_limitmod;
-float autocvar_g_balance_rune_regen_combo_regenrate;
-float autocvar_g_balance_rune_regen_combo_rotrate;
-float autocvar_g_balance_rune_regen_hpmod;
-float autocvar_g_balance_rune_regen_limitmod;
-float autocvar_g_balance_rune_regen_regenrate;
-float autocvar_g_balance_rune_speed_atkrate;
-float autocvar_g_balance_rune_speed_combo_atkrate;
-float autocvar_g_balance_rune_speed_combo_highspeed;
-float autocvar_g_balance_rune_speed_highspeed;
-float autocvar_g_balance_rune_strength_combo_damage;
-float autocvar_g_balance_rune_strength_combo_force;
-float autocvar_g_balance_rune_strength_damage;
-float autocvar_g_balance_rune_strength_force;
-float autocvar_g_balance_rune_vampire_absorb;
-float autocvar_g_balance_rune_vampire_combo_absorb;
-float autocvar_g_balance_rune_vampire_maxhealth;
 float autocvar_g_balance_seeker_type;
 float autocvar_g_balance_seeker_flac_ammo;
 float autocvar_g_balance_seeker_flac_animtime;
@@ -986,21 +956,6 @@ float autocvar_g_respawn_ghosts;
 float autocvar_g_respawn_ghosts_maxtime;
 float autocvar_g_respawn_ghosts_speed;
 float autocvar_g_respawn_waves;
-float autocvar_g_runematch_allow_same;
-float autocvar_g_runematch_drop_runes_max;
-float autocvar_g_runematch_fixedspawns;
-float autocvar_g_runematch_frags_killed_runeholder;
-float autocvar_g_runematch_frags_killedby_runeholder;
-float autocvar_g_runematch_frags_norune;
-float autocvar_g_runematch_point_leadlimit;
-#define autocvar_g_runematch_point_limit cvar("g_runematch_point_limit")
-float autocvar_g_runematch_pointamt;
-float autocvar_g_runematch_pointrate;
-float autocvar_g_runematch_respawntime;
-float autocvar_g_runematch_rune_alpha;
-float autocvar_g_runematch_rune_color_strength;
-float autocvar_g_runematch_rune_effects;
-float autocvar_g_runematch_shuffletime;
 float autocvar_g_running_guns;
 float autocvar_g_shootfromcenter;
 float autocvar_g_shootfromclient;
index 0ef81002416112d5ec02049983080c9a0af0a427..b61fbfa913bb7e6612fc4f60f91d1081601aae95 100644 (file)
@@ -6,22 +6,6 @@ void send_CSQC_teamnagger() {
        WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
 }
 
-void Announce(string snd) {
-       WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
-       WriteByte(MSG_BROADCAST, TE_CSQC_ANNOUNCE);
-       WriteString(MSG_BROADCAST, snd);
-}
-
-void AnnounceTo(entity e, string snd) {
-       if (clienttype(e) == CLIENTTYPE_REAL)
-       {
-               msg_entity = e;
-               WriteByte(MSG_ONE, SVC_TEMPENTITY);
-               WriteByte(MSG_ONE, TE_CSQC_ANNOUNCE);
-               WriteString(MSG_ONE, snd);
-       }
-}
-
 float ClientData_Send(entity to, float sf)
 {
        if(to != self.owner)
@@ -401,7 +385,6 @@ void PutObserverInServer (void)
                WriteEntity(MSG_ONE, self);
        }
 
-       DropAllRunes(self);
        MUTATOR_CALLHOOK(MakePlayerObserver);
 
        minstagib_stop_countdown(self);
@@ -474,7 +457,6 @@ void PutObserverInServer (void)
        self.think = func_null;
        self.nextthink = 0;
        self.hook_time = 0;
-       self.runes = 0;
        self.deadflag = DEAD_NO;
        self.angles = spot.angles;
        self.angles_z = 0;
@@ -807,8 +789,6 @@ void PutClientInServer (void)
 
                self.metertime = 0;
 
-               self.runes = 0;
-
                self.deadflag = DEAD_NO;
 
                self.angles = spot.angles;
@@ -1151,7 +1131,7 @@ void KillIndicator_Think()
                if(clienttype(self.owner) == CLIENTTYPE_REAL)
                {
                        if(self.cnt <= 10)
-                               AnnounceTo(self.owner, strcat(ftos(self.cnt), ""));
+                               { Send_Notification(NOTIF_ONE, self.owner, MSG_ANNCE, Announcer_PickNumber(self.cnt)); }
                }
                self.nextthink = time + 1;
                self.cnt -= 1;
@@ -1640,7 +1620,6 @@ void ClientDisconnect (void)
                
        Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_DISCONNECT, self.netname);
 
-       DropAllRunes(self);
        MUTATOR_CALLHOOK(ClientDisconnect);
 
        Portal_ClearAll(self);
@@ -2014,32 +1993,6 @@ void player_regen (void)
 
        max_mod = regen_mod = rot_mod = limit_mod = 1;
 
-       if (self.runes & RUNE_REGEN)
-       {
-               if (self.runes & CURSE_VENOM) // do we have both rune/curse?
-               {
-                       regen_mod = autocvar_g_balance_rune_regen_combo_regenrate;
-                       max_mod = autocvar_g_balance_rune_regen_combo_hpmod;
-                       limit_mod = autocvar_g_balance_rune_regen_combo_limitmod;
-               }
-               else
-               {
-                       regen_mod = autocvar_g_balance_rune_regen_regenrate;
-                       max_mod = autocvar_g_balance_rune_regen_hpmod;
-                       limit_mod = autocvar_g_balance_rune_regen_limitmod;
-               }
-       }
-       else if (self.runes & CURSE_VENOM)
-       {
-               max_mod = autocvar_g_balance_curse_venom_hpmod;
-               if (self.runes & RUNE_REGEN) // do we have both rune/curse?
-                       rot_mod = autocvar_g_balance_rune_regen_combo_rotrate;
-               else
-                       rot_mod = autocvar_g_balance_curse_venom_rotrate;
-               limit_mod = autocvar_g_balance_curse_venom_limitmod;
-               //if (!self.runes & RUNE_REGEN)
-               //      rot_mod = autocvar_g_balance_curse_venom_rotrate;
-       }
        maxh = maxh * max_mod;
        //maxa = maxa * max_mod;
        //maxf = maxf * max_mod;
@@ -2319,7 +2272,7 @@ void ShowRespawnCountdown()
                {
                        self.respawn_countdown = number - 1;
                        if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds
-                               AnnounceTo(self, strcat(ftos(number), ""));
+                               Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(number)); 
                }
        }
 }
@@ -2995,7 +2948,7 @@ void PlayerPostThink (void)
                        else if(timeleft <= 10)
                        {
                                if(timeleft != self.idlekick_lasttimeleft)
-                                       AnnounceTo(self, ftos(timeleft));
+                                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(timeleft));
                                self.idlekick_lasttimeleft = timeleft;
                        }
                }
index 50401604ef905313d521380d6995b0cf202d6bec..6ddf7b69ed806e75bf81c1cea5de0307176a03b6 100644 (file)
@@ -712,20 +712,6 @@ void SV_PlayerPhysics()
                else if(g_keepaway)
                        maxspd_mod *= autocvar_g_keepaway_ballcarrier_highspeed;
 
-       if(g_runematch)
-       {
-               if(self.runes & RUNE_SPEED)
-               {
-                       if(self.runes & CURSE_SLOW)
-                               maxspd_mod *= autocvar_g_balance_rune_speed_combo_highspeed;
-                       else
-                               maxspd_mod *= autocvar_g_balance_rune_speed_highspeed;
-               }
-               else if(self.runes & CURSE_SLOW)
-               {
-                       maxspd_mod *= autocvar_g_balance_curse_slow_highspeed;
-               }
-       }
        maxspd_mod *= autocvar_g_movement_highspeed;
 
        // fix physics stats for g_movement_highspeed
index cb44da03fe794cada0243885dd44b53f0a974860..944db7e5b8b07dd7588c90679c5ad0ba1b872a12 100644 (file)
@@ -590,7 +590,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                // print an obituary message
                Obituary (attacker, inflictor, self, deathtype);
                race_PreDie();
-               DropAllRunes(self);
 
         // increment frag counter for used weapon type
         float w;
@@ -619,7 +618,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                if(clienttype(self) == CLIENTTYPE_REAL)
                {
-                       stuffcmd(self, "-zoom\n");
                        self.fixangle = TRUE;
                        //msg_entity = self;
                        //WriteByte (MSG_ONE, SVC_SETANGLE);
index c559c150db4a28adb8b41aca39b737f775277d85..afabe1820284522acf4d4dc0211d610d277de559 100644 (file)
@@ -14,21 +14,6 @@ float W_WeaponRateFactor()
        float t;
        t = 1.0 / g_weaponratefactor;
 
-       if(g_runematch)
-       {
-               if(self.runes & RUNE_SPEED)
-               {
-                       if(self.runes & CURSE_SLOW)
-                               t = t * autocvar_g_balance_rune_speed_combo_atkrate;
-                       else
-                               t = t * autocvar_g_balance_rune_speed_atkrate;
-               }
-               else if(self.runes & CURSE_SLOW)
-               {
-                       t = t * autocvar_g_balance_curse_slow_atkrate;
-               }
-       }
-
        return t;
 }
 
index e95cf4c6585ba07ec0aa45008bdaf747bb728f8f..132a0af70e31be2fbc97bbc79006ae5b5c1f263c 100644 (file)
@@ -182,7 +182,7 @@ void timeout_handler_think()
                                Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_TIMEOUT_ENDING, timeout_time);
 
                                if(timeout_time == autocvar_sv_timeout_resumetime) // play a warning sound when only <sv_timeout_resumetime> seconds are left
-                                       Announce("prepareforbattle");
+                                       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_PREPARE);
 
                                self.nextthink = time + TIMEOUT_SLOWMO_VALUE; // think again in one second
                                timeout_time -= 1; // decrease the time counter
@@ -575,7 +575,7 @@ void CommonCommand_timeout(float request, entity caller) // DEAR GOD THIS COMMAN
                                        timeout_handler.think = timeout_handler_think;
                                        timeout_handler.nextthink = time; // always let the entity think asap
 
-                                       Announce("timeoutcalled");
+                                       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_TIMEOUT);
                                }
                        }
                        else { print_to(caller, "^1Timeouts are not allowed to be called, enable them with sv_timeout 1.\n"); }
index 329fb9d4ef98c1a4d8d4ee0c30b8b15e9625f701..199e3265a8f75672ea0fe9ce53ffea1ddfb8853a 100644 (file)
@@ -148,21 +148,21 @@ void VoteAccept()
        if(vote_caller) { vote_caller.vote_waittime = 0; } // people like your votes, you don't need to wait to vote again
 
        VoteReset();
-       Announce("voteaccept");
+       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_ACCEPT);
 }
 
 void VoteReject() 
 {
        bprint("\{1}^2* ^3", GetCallerName(vote_caller), "^2's vote for ", vote_called_display, "^2 was rejected\n");
        VoteReset();
-       Announce("votefail");
+       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_FAIL);
 }
 
 void VoteTimeout() 
 {
        bprint("\{1}^2* ^3", GetCallerName(vote_caller), "^2's vote for ", vote_called_display, "^2 timed out\n");
        VoteReset();
-       Announce("votefail");
+       Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_FAIL);
 }
 
 void VoteSpam(float notvoters, float mincount, string result)
@@ -348,10 +348,11 @@ void ReadyRestart_force()
        game_starttime = time;
        if(!g_ca && !g_arena) { game_starttime += RESTART_COUNTDOWN; }
 
-       // clear alivetime
+       // clear player attributes
        FOR_EACH_CLIENT(tmp_player)
        {
                tmp_player.alivetime = 0;
+               tmp_player.killcount = 0;
                PlayerStats_Event(tmp_player, PLAYERSTATS_ALIVETIME, -PlayerStats_Event(tmp_player, PLAYERSTATS_ALIVETIME, 0));
        }
 
@@ -725,7 +726,7 @@ void VoteCommand_call(float request, entity caller, float argc, string vote_comm
                                }
                                
                                FOR_EACH_REALCLIENT(tmp_player) { ++tmp_playercount; }
-                               if(tmp_playercount > 1) { Announce("votecall"); } // don't announce a "vote now" sound if player is alone
+                               if(tmp_playercount > 1) { Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_VOTE_CALL); } // don't announce a "vote now" sound if player is alone
                                
                                bprint("\{1}^2* ^3", GetCallerName(vote_caller), "^2 calls a vote for ", vote_called_display, "\n");
                                if(autocvar_sv_eventlog) { GameLogEcho(strcat(":vote:vcall:", ftos(vote_caller.playerid), ":", vote_called_display)); }
index 7f7e3b4578c14192ac400d9a457b229acc64449b..a7cd80136676b4ad3a9362776c6065c8c7d6dfaf 100644 (file)
@@ -215,9 +215,6 @@ float intermission_running;
 float intermission_exittime;
 float alreadychangedlevel;
 
-
-.float runes;
-
 // Keys player is holding
 .float itemkeys;
 // message delay for func_door locked by keys and key locks
@@ -284,9 +281,6 @@ float default_weapon_alpha;
 .float cvar_cl_allow_uidtracking;
 .string stored_netname;
 
-void Announce(string snd);
-void AnnounceTo(entity e, string snd);
-
 .float version_nagtime;
 
 #define NUM_JUMPPADSUSED 3
@@ -297,9 +291,6 @@ string gamemode_name;
 
 float startitem_failed;
 
-void DropAllRunes(entity pl);
-
-
 typedef .float floatfield;
 floatfield Item_CounterField(float it);
 
index e86b148bcb0b170851e4ac934ba1917d6a3353c3..3b7251261dc54ea3fbee04ee792908e6bc1b13a3 100644 (file)
@@ -186,11 +186,7 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype)
        else
        {
                self = oldself;
-               if(g_runematch)
-               {
-                       f = RunematchHandleFrags(attacker, targ, f);
-               }
-               else if(g_lms)
+               if(g_lms)
                {
                        // remove a life
                        float tl;
@@ -235,8 +231,6 @@ string AppendItemcodes(string s, entity player)
                s = strcat(s, "T");
        if(player.kh_next)
                s = strcat(s, "K");
-       if(player.runes)
-               s = strcat(s, "|", ftos(player.runes));
        return s;
 }
 
@@ -446,7 +440,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
                        
                        Send_Notification(NOTIF_ONE, attacker, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAG, targ.netname);
                        Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_DEATH_TEAMKILL_FRAGGED, attacker.netname);
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, targ.killcount);
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(targ.team, INFO_DEATH_TEAMKILL_), targ.netname, attacker.netname, deathlocation, targ.killcount);
 
                        // In this case, the death message will ALWAYS be "foo was betrayed by bar"
                        // No need for specific death/weapon messages...
@@ -462,7 +456,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
                        #define SPREE_ITEM(counta,countb,center,normal,gentle) \
                                case counta: \
                                { \
-                                       AnnounceTo(attacker, strcat(#countb, "kills")); \
+                                       Send_Notification(NOTIF_ONE, attacker, MSG_ANNCE, ANNCE_KILLSTREAK_##countb); \
                                        PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##counta, 1); \
                                        break; \
                                }
@@ -563,7 +557,7 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
 
                if(PlayerScore_Add(targ, SP_SCORE, 0) == -5)
                {
-                       AnnounceTo(targ, "botlike");
+                       Send_Notification(NOTIF_ONE, targ, MSG_ANNCE, ANNCE_ACHIEVEMENT_BOTLIKE);
                        PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
                }
        }
@@ -797,40 +791,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                                damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
                }
 
-               if(g_runematch)
-               {
-                       // apply strength rune
-                       if (attacker.runes & RUNE_STRENGTH)
-                       {
-                               if(attacker.runes & CURSE_WEAK) // have both curse & rune
-                               {
-                                       damage = damage * autocvar_g_balance_rune_strength_combo_damage;
-                                       force = force * autocvar_g_balance_rune_strength_combo_force;
-                               }
-                               else
-                               {
-                                       damage = damage * autocvar_g_balance_rune_strength_damage;
-                                       force = force * autocvar_g_balance_rune_strength_force;
-                               }
-                       }
-                       else if (attacker.runes & CURSE_WEAK)
-                       {
-                               damage = damage * autocvar_g_balance_curse_weak_damage;
-                               force = force * autocvar_g_balance_curse_weak_force;
-                       }
-
-                       // apply defense rune
-                       if (targ.runes & RUNE_DEFENSE)
-                       {
-                               if (targ.runes & CURSE_VULNER) // have both curse & rune
-                                       damage = damage * autocvar_g_balance_rune_defense_combo_takedamage;
-                               else
-                                       damage = damage * autocvar_g_balance_rune_defense_takedamage;
-                       }
-                       else if (targ.runes & CURSE_VULNER)
-                               damage = damage * autocvar_g_balance_curse_vulner_takedamage;
-               }
-
                // count the damage
                if(attacker)
                if(!targ.deadflag)
@@ -922,42 +882,6 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                self.event_damage (inflictor, attacker, damage, deathtype, hitloc, force);
        self = oldself;
 
-       if(targ.classname == "player" && attacker.classname == "player" && attacker != targ && attacker.health > 2)
-       {
-               if(g_runematch)
-               {
-                       if (attacker.runes & RUNE_VAMPIRE)
-                       {
-                       // apply vampire rune
-                               if (attacker.runes & CURSE_EMPATHY) // have the curse too
-                               {
-                                       //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb;
-                                       attacker.health = bound(
-                                               autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 40
-                                               attacker.health + damage * autocvar_g_balance_rune_vampire_combo_absorb,
-                                               autocvar_g_balance_rune_vampire_maxhealth);     // LA: was 1000, now 500
-                               }
-                               else
-                               {
-                                       //attacker.health = attacker.health + damage * autocvar_g_balance_rune_vampire_absorb;
-                                       attacker.health = bound(
-                                               attacker.health,        // LA: was 3, but changed so that you can't lose health
-                                                                                       // empathy won't let you gain health in the same way...
-                                               attacker.health + damage * autocvar_g_balance_rune_vampire_absorb,
-                                               autocvar_g_balance_rune_vampire_maxhealth);     // LA: was 1000, now 500
-                                       }
-                       }
-                       // apply empathy curse
-                       else if (attacker.runes & CURSE_EMPATHY)
-                       {
-                               attacker.health = bound(
-                                       autocvar_g_balance_curse_empathy_minhealth, // LA: was 3, now 20
-                                       attacker.health + damage * autocvar_g_balance_curse_empathy_takedamage,
-                                       attacker.health);
-                       }
-               }
-       }
-
        // apply mirror damage if any
        if(mirrordamage > 0 || mirrorforce > 0)
        {
index 293c78f001f0f3a2df0c050d91102db2b53a4289..12c75ae9e57199fb5499b0a910c5ecda94d3ed42 100644 (file)
@@ -476,17 +476,6 @@ void trigger_hurt_touch()
                        Damage(other, self, self, self.dmg, DEATH_HURTTRIGGER, other.origin, '0 0 0');
                }
        }
-       else
-       {
-               if (!other.owner)
-               {
-                       if (other.classname == "rune")                  // reset runes
-                       {
-                               EXACTTRIGGER_TOUCH;
-                               other.nextthink = min(other.nextthink, time + 1);
-                       }
-               }
-       }
 
        return;
 }
index 894ffd6158b7b347a5ed283d6f334ee3aef57988..25cd566587e051965be60b23d6a586b0366fff63 100644 (file)
@@ -271,7 +271,6 @@ void cvar_changes_init()
                BADCVAR("g_onslaught");
                BADCVAR("g_race");
                BADCVAR("g_race_qualifying_timelimit");
-               BADCVAR("g_runematch");
                BADCVAR("g_tdm");
                BADCVAR("g_tdm_teams");
                BADCVAR("leadlimit");
@@ -315,7 +314,6 @@ void cvar_changes_init()
                BADCVAR("g_keyhunt_point_leadlimit");
                BADPREFIX("g_mod_");
                BADCVAR("g_nexball_goalleadlimit");
-               BADCVAR("g_runematch_point_leadlimit");
                BADCVAR("leadlimit_and_fraglimit");
                BADCVAR("leadlimit_override");
                BADCVAR("pausable");
@@ -381,7 +379,6 @@ void cvar_changes_init()
                BADCVAR("g_mirrordamage");
                BADCVAR("g_nexball_goallimit");
                BADCVAR("g_powerups");
-               BADCVAR("g_runematch_point_limit");
                BADCVAR("g_start_delay");
                BADCVAR("g_warmup");
                BADCVAR("g_weapon_stay"); BADPRESUFFIX("g_", "_weapon_stay");
@@ -1964,11 +1961,11 @@ float WinningCondition_Scores(float limit, float leadlimit)
 
                        if (limit)
                        if (leaderfrags == limit - 1)
-                               Announce("1fragleft");
+                               Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_1);
                        else if (leaderfrags == limit - 2)
-                               Announce("2fragsleft");
+                               Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_2);
                        else if (leaderfrags == limit - 3)
-                               Announce("3fragsleft");
+                               Send_Notification(NOTIF_ALL, world, MSG_ANNCE, ANNCE_REMAINING_FRAG_3);
                }
        }
 
index 2b73841808bed3223c1eef10bef5c06dd384138c..17a26821d9a997005184152cf57c5304dcd2eaf4 100644 (file)
@@ -1081,7 +1081,7 @@ void readlevelcvars(void)
        g_warmup_allguns = cvar("g_warmup_allguns");
        g_warmup_allow_timeout = cvar("g_warmup_allow_timeout");
 
-       if ((g_race && g_race_qualifying == 2) || g_runematch || g_arena || g_assault || cvar("g_campaign"))
+       if ((g_race && g_race_qualifying == 2) || g_arena || g_assault || cvar("g_campaign"))
                inWarmupStage = 0; // these modes cannot work together, sorry
 
        g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
@@ -1414,11 +1414,6 @@ void precache()
 {
     // gamemode related things
     precache_model ("models/misc/chatbubble.spr");
-    if (g_runematch)
-    {
-        precache_model ("models/runematch/curse.mdl");
-        precache_model ("models/runematch/rune.mdl");
-    }
 
 #ifdef TTURRETS_ENABLED
     if (autocvar_g_turrets)
index d90d564b501447acb3e3ef1def71530be1a521ee..35b2e652349a3f95ac238df57e083082537c62ab 100644 (file)
@@ -142,7 +142,7 @@ MUTATOR_HOOKABLE(PlayerDamage_SplitHealthArmor);
                float damage_save;
                
 MUTATOR_HOOKABLE(PlayerDamage_Calculate);
-       // called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier or runematch runes
+       // called to adjust damage and force values which are applied to the player, used for e.g. strength damage/force multiplier
        // i'm not sure if I should change this around slightly (Naming of the entities, and also how they're done in g_damage).
        // INPUT:
                entity frag_attacker;
index 6ee3e87b3c193e52354dd4e9e40301a8b6a756fc..89ad13c5380775439b1a186e05ff93c81dba8141 100644 (file)
@@ -184,7 +184,7 @@ MUTATOR_HOOKFUNCTION(nt_SetWeaponreplace)
 MUTATOR_HOOKFUNCTION(nt_FilterItem)
 {
        if(nt_IsNewToy(self.weapon))
-               self.item_pickupsound = "weapons/weaponpickup_new_toys.ogg";
+               self.item_pickupsound = "weapons/weaponpickup_new_toys.wav";
        return 0;
 }
 
@@ -200,7 +200,7 @@ MUTATOR_DEFINITION(mutator_new_toys)
                if(time > 1) // game loads at time 1
                        error("This cannot be added at runtime\n");
 
-               precache_sound("weapons/weaponpickup_new_toys.ogg");
+               precache_sound("weapons/weaponpickup_new_toys.wav");
 
                // mark the guns as ok to use by e.g. impulse 99
                float i;
index 391e317423dffd4dd37e628effe9a988b452267f..cf5d82f87ae4ecf141afd7d80dbbb31af2a07e43 100644 (file)
@@ -26,7 +26,7 @@ void sandbox_ObjectFunction_Touch()
        intensity -= autocvar_g_sandbox_object_material_velocity_min; // start from minimum velocity, not actual velocity
        intensity = bound(0, intensity * autocvar_g_sandbox_object_material_velocity_factor, 1);
 
-       sound(self, CH_TRIGGER, strcat("object/impact_", self.material, "_", ftos(ceil(random() * 5)) , ".ogg"), VOL_BASE * intensity, ATTN_NORM);
+       sound(self, CH_TRIGGER, strcat("object/impact_", self.material, "_", ftos(ceil(random() * 5)) , ".wav"), VOL_BASE * intensity, ATTN_NORM);
        pointparticles(particleeffectnum(strcat("impact_", self.material)), self.origin, '0 0 0', ceil(intensity * 10)); // allow a count from 1 to 10
 }
 
@@ -403,7 +403,7 @@ void sandbox_Database_Load()
                        {
                                // since objects are being loaded for the first time, precache material sounds for each
                                for (i = 1; i <= 5; i++) // 5 sounds in total
-                                       precache_sound(strcat("object/impact_", e.material, "_", ftos(i), ".ogg"));
+                                       precache_sound(strcat("object/impact_", e.material, "_", ftos(i), ".wav"));
                        }
                }
                if(autocvar_g_sandbox_info > 0)
@@ -675,7 +675,7 @@ MUTATOR_HOOKFUNCTION(sandbox_PlayerCommand)
                                                        if(argv(3))
                                                        {
                                                                for (i = 1; i <= 5; i++) // precache material sounds, 5 in total
-                                                                       precache_sound(strcat("object/impact_", argv(3), "_", ftos(i), ".ogg"));
+                                                                       precache_sound(strcat("object/impact_", argv(3), "_", ftos(i), ".wav"));
                                                                e.material = strzone(argv(3));
                                                        }
                                                        else
index 3e83c972eece82f015fafae1804b1e6db6a0ddda..f0b9c5b21861a8095913ca6fc3066a53590c4411 100644 (file)
@@ -172,7 +172,7 @@ float Portal_TeleportPlayer(entity teleporter, entity player)
        {
                // telefrag within 1 second of portal creation = amazing
                if(time < teleporter.teleport_time + 1)
-                       AnnounceTo(player, "amazing");
+                       Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_ACHIEVEMENT_AMAZING);
        }
 
        if not(teleporter.enemy)
index a00fd32c5e6f0e47a4865434dadee0ce79556034..f33be85b9b4c3816451ef7de35efe6492e91800a 100644 (file)
@@ -101,7 +101,7 @@ g_subs.qc
 
 g_tetris.qc
 
-runematch.qc
+//runematch.qc
 arena.qc
 
 g_violence.qc
diff --git a/qcsrc/server/runematch.qc b/qcsrc/server/runematch.qc
deleted file mode 100644 (file)
index ba8f648..0000000
+++ /dev/null
@@ -1,604 +0,0 @@
-float rune_numspawns;
-
-float  RUNE_FIRST      = 1;
-float  RUNE_STRENGTH   = 1;
-float  RUNE_DEFENSE    = 2;
-float  RUNE_REGEN      = 4;
-float  RUNE_SPEED      = 8;
-float  RUNE_VAMPIRE    = 16;
-float  RUNE_LAST       = 16;
-
-float  CURSE_FIRST     = 8192;
-float  CURSE_WEAK      = 8192;
-float  CURSE_VULNER    = 16384;
-float  CURSE_VENOM     = 32768;
-float  CURSE_SLOW      = 65536;
-float  CURSE_EMPATHY   = 131072;
-float  CURSE_LAST      = 131072;
-
-float RUNE_COUNT = 5;
-
-/* rune ideas:
-
-       Doom/Death
-       Rune: When you damage enemies, you have a slight chance of instant-killing them (porportional to damage dealt / their health)
-       Curse: When you are damaged, you have a chance of being instant-killed
-
-       Vengence/Slothful
-       Rune: The lower your health below 100, the more damage you deal (does not decrease your damage if you're above 100)
-       Curse: The higher your health (up to 100), the less damage you deal (at 100 hp deal 1/5th damage)
-
-*/
-
-/*QUAKED spawnfunc_runematch_spawn_point (1 0 0) (-16 -16 -24) (16 16 24)
-spawn point for runes in runematch
-*/
-
-void spawnfunc_runematch_spawn_point()
-{
-       if(!g_runematch || !autocvar_g_runematch_fixedspawns)
-       {
-               remove(self);
-               return;
-       }
-
-       setsize(self, '0 0 -35', '0 0 0');
-       droptofloor();
-       ++rune_numspawns;
-}
-
-// only used if using rune spawns at all
-entity rune_find_spawnpoint()
-{
-       entity e;
-
-       if(rune_numspawns < RUNE_COUNT)
-               return world;
-
-       RandomSelection_Init();
-
-       for(e = world; (e = find(e, classname, "runematch_spawn_point")); )
-               if(e.owner == world)
-                       RandomSelection_Add(e, 0, string_null, e.cnt, 0);
-
-       return RandomSelection_chosen_ent;
-}
-
-float rune_spawn_somewhere(entity e)
-{
-       entity spot;
-       spot = rune_find_spawnpoint();
-       if(spot)
-       {
-               spot.owner = e;
-               setorigin(e, spot.origin);
-
-               e.owner = spot;
-               spot.owner = e;
-
-               return TRUE;
-       }
-       else
-       {
-               if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
-               {
-                       // great
-                       makevectors(self.angles),
-                       self.velocity = v_forward * 250;
-                       self.angles = '0 0 0';
-                       return TRUE;
-               }
-               else
-               {
-                       // sorry, can't spawn, better luck next frame
-                       return FALSE;
-               }
-       }
-}
-
-void rune_unmark_spot(entity e)
-{
-       if(e.owner.classname == "runematch_spawn_point")
-       {
-               e.owner.owner = world;
-               e.owner = world;
-       }
-}
-
-string RuneName(float r)
-{
-       if(r == RUNE_STRENGTH)
-               return "^1Strength^7";
-       if(r == RUNE_DEFENSE)
-               return "^4Defense^7";
-       if(r == RUNE_REGEN)
-               return "^2Vitality^7";
-       if(r == RUNE_SPEED)
-               return "^3Speed^7";
-       if(r == RUNE_VAMPIRE)
-               return "^6Vampire^7";
-
-       if(r == CURSE_WEAK)
-               return "^1Weakness^7";
-       if(r == CURSE_VULNER)
-               return "^4Vulnerability^7";
-       if(r == CURSE_VENOM)
-               return "^2Venom^7";
-       if(r == CURSE_SLOW)
-               return "^3Slow^7";
-       if(r == CURSE_EMPATHY)
-               return "^6Empathy^7";
-       return strcat("^8[unnamed", ftos(r), "]^7");
-}
-
-vector RuneColormod(float r)
-{
-       vector _color = '255 0 255';
-
-       if(r == RUNE_STRENGTH)
-               _color = '255 0 0';
-       if(r == RUNE_DEFENSE)
-               _color = '0 0 255';//'0 102 255';//
-       if(r == RUNE_REGEN)
-               _color = '0 204 0';//'0 255 0';
-       if(r == RUNE_SPEED)
-               _color = 0.35*'185 185 0';//255 230 0';//'255 255 0';
-       if(r == RUNE_VAMPIRE)
-               _color = '64 0 128';//'108 0 217';//'128 0 255';//'179 0 204';//
-
-       if(r == CURSE_WEAK)
-               _color = '255 0 0';
-       if(r == CURSE_VULNER)
-               _color = '0 0 255';//'0 102 255';//
-       if(r == CURSE_VENOM)
-               _color = '0 204 0';//'0 255 0';
-       if(r == CURSE_SLOW)
-               _color = 0.5*'185 185 0';//'255 255 0';
-       if(r == CURSE_EMPATHY)
-               _color = '179 0 204';//'128 0 255';
-
-       return _color * (1 / 255) * autocvar_g_runematch_rune_color_strength;
-}
-
-void rune_respawn();
-
-void RuneCarriedThink()
-{
-       float rcount, rnum;
-       vector ang = '0 0 0';
-       entity rune;
-
-       if(self.owner.classname != "player" || time < game_starttime)
-       {
-               rune_respawn();
-               return;
-       }
-
-       self.nextthink = time + 0.1;
-
-       // count runes my owner holds
-       rcount = 0;
-       rune = find(world, classname, "rune");
-       rnum = -1;
-       while(rune)
-       {
-               if(rune.owner == self.owner)
-                       rcount = rcount + 1;
-               if(rune == self)
-                       rnum = rcount;
-               rune = find(rune, classname, "rune");
-       }
-
-       ang_y = rnum*(360 / rcount) + mod(time, 360)*45;//180;
-
-       makevectors(ang);
-
-       setorigin(self, v_forward*32);
-}
-
-void rune_touch()
-{
-       if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-       {
-               self.think = rune_respawn;
-               self.nextthink = time;
-               return;
-       }
-
-       if(other.classname != "player" || other.health < 1)
-               return;
-       if(self.wait > time)
-               return; // "notouch" time isn't finished
-
-       // detach from the spawn point you're on
-       rune_unmark_spot(self);
-
-       self.owner = other;
-       self.enemy.owner = other;
-       setattachment(self, other, "");
-
-       other.runes = other.runes | self.runes | self.enemy.runes;
-
-       //self.think = func_null;
-       //self.nextthink = 0;
-       self.think = RuneCarriedThink;
-       self.nextthink = time;
-       self.touch = func_null;
-
-       self.solid = SOLID_NOT;
-       setorigin(self, self.origin);
-
-       //sprint(other, strcat("^3You have picked up ",
-       //      RuneName(self.runes & (RUNE_LAST*2-1)), " and "));
-       //sprint(other, strcat(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n"));
-
-       bprint("^3", other.netname, "^7 has picked up ",
-               RuneName(self.runes & (RUNE_LAST*2-1)), "^7 and ");
-       bprint(RuneName(self.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n");
-}
-
-void rune_respawn()
-{
-       rune_unmark_spot(self);
-       if(rune_spawn_somewhere(self))
-       {
-               self.solid = SOLID_TRIGGER;
-               self.touch = rune_touch;
-               self.think = rune_respawn;
-               self.nextthink = time + autocvar_g_runematch_shuffletime;//30 + random()*5; // fixme: cvar
-       }
-       else
-       {
-               // try again later
-               self.think = rune_respawn;
-               self.nextthink = time;
-       }
-}
-
-entity FindRune(entity own, string clname, float r)
-{
-       entity rune;
-       float _count, c;
-
-       c = _count = 0;
-       rune = world;
-
-       do
-       {
-               rune = find(rune, classname, clname);
-               if(!rune)
-                       rune = find(rune, classname, clname);
-               if(!rune)
-                       break;
-               if(rune.owner == own)
-               {
-                       _count = _count + 1;
-                       if(_count >= r)
-                               return rune;
-                       if(r <= 1)
-                               return rune;
-               }
-               c = c + 1;
-       }while(c < 30);
-       return world;
-}
-
-
-void DropRune(entity pl, entity e)
-{
-       //entity pl;
-
-       //pl = e.owner;
-       // detach from player
-       setattachment(e, world, "");
-       e.owner = world;
-       e.enemy.owner = world;
-       // don't instantly touch player again
-       e.wait = time + 1; // "notouch" time
-       e.movetype = MOVETYPE_TOSS;
-       e.solid = SOLID_TRIGGER;
-       // reposition itself if not picked up soon
-       e.think = rune_respawn;
-       e.nextthink = time + autocvar_g_runematch_respawntime;//15 + random()*5; // fixme: cvar
-       e.touch = rune_touch;
-
-       pl.runes = pl.runes - (pl.runes & (e.runes | e.enemy.runes));
-
-       // toss from player
-       setorigin(e, pl.origin + '0 0 10');
-       e.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
-
-
-       bprint("^3", pl.netname, "^7 has lost ",
-               RuneName(e.runes & (RUNE_LAST*2-1)), "^7 and ");
-       bprint(RuneName(e.enemy.runes & (CURSE_WEAK | CURSE_VULNER | CURSE_VENOM | CURSE_SLOW | CURSE_EMPATHY)), "\n");
-}
-
-float RuneMatchesCurse(float r, float c)
-{
-       float cr;
-       if(r & RUNE_STRENGTH)
-               cr = CURSE_WEAK;
-       else if(r & RUNE_DEFENSE)
-               cr = CURSE_VULNER;
-       else if(r & RUNE_REGEN)
-               cr = CURSE_VENOM;
-       else if(r & RUNE_SPEED)
-               cr = CURSE_SLOW;
-       else if(r & RUNE_VAMPIRE)
-               cr = CURSE_EMPATHY;
-       else return FALSE; // fixme: error?
-
-       if(c & cr)
-               return TRUE;
-       return FALSE;
-}
-
-// player died, drop runes
-// each rune should pair up with a random curse and then be tossed from the player
-void DropAllRunes(entity pl)
-{
-       entity rune, curse;
-       float rcount, ccount, r, c, rand, prevent_same, numtodrop, tries;
-
-       entity curse1, rune1, curse2, rune2;
-
-       rcount = ccount = r = c = 0;
-       rune = find(world, classname, "rune");
-       while(rune)
-       {
-               if(rune.owner == pl)
-                       rcount = rcount + 1;
-               rune = find(rune, classname, "rune");
-       }
-       curse = find(world, classname, "curse");
-       while(curse)
-       {
-               if(curse.owner == pl)
-                       ccount = ccount + 1;
-               curse = find(curse, classname, "curse");
-       }
-
-       numtodrop = autocvar_g_runematch_drop_runes_max;
-       prevent_same = !autocvar_g_runematch_allow_same;
-
-       do
-       {
-               rune = find(rune, classname, "rune");
-               if(!rune)
-                       break;
-               if(rune.owner != pl)
-                       continue;
-
-
-               // find a random curse
-               tries = 15;
-               if(ccount > 1 && prevent_same)
-               {
-                       // avoid pairing runes and curses that match each other
-                       do{
-                               rand = floor(random()*ccount) + 1;
-                               curse = FindRune(pl, "curse", rand);
-                               tries = tries - 1;
-                       }while(RuneMatchesCurse(rune.runes, curse.runes) && tries > 0);
-                       if(tries <= 0)
-                       {
-                               bprint("warning: couldn't prevent same rune\n");
-                       }
-               }
-               else
-               {
-                               rand = floor(random()*ccount) + 1;
-                               curse = FindRune(pl, "curse", rand);
-               }
-
-               if(!curse)
-                       error("Couldn't fine curse to bind rune to\n");
-
-               // pair rune and curse
-
-               rune1 = rune;
-               curse1 = curse;
-               rune2 = curse1.enemy;
-               curse2 = rune1.enemy;
-
-               if(rune1 != rune2) // not already attached to each other
-               {
-                       rune1.enemy = curse1;
-                       curse1.enemy = rune1;
-                       setattachment(curse1, rune1, "");
-                       rune2.enemy = curse2;
-                       curse2.enemy = rune2;
-                       setattachment(curse2, rune2, "");
-                       //DropRune(pl, rune2);
-                       //ccount = ccount - 1;
-                       //rcount = rcount - 1;
-               }
-               DropRune(pl, rune1);
-
-               if(numtodrop <=0)
-               {
-                       rune1.think = rune_respawn;
-                       rune1.nextthink = time;
-               }
-
-               numtodrop = numtodrop - 1;
-
-               ccount = ccount - 1;
-               rcount = rcount - 1;
-
-       }while(rune);
-}
-
-void rune_reset()
-{
-       if(self.owner)
-               if(self.owner.classname != "runematch_spawn_point")
-                       DropAllRunes(self.owner);
-       rune_respawn();
-}
-
-void spawn_runes()
-{
-       float rn, cs, runes_used, curses_used, prevent_same, numrunes;
-       entity e;
-
-       if(self)
-               remove(self);
-
-       // fixme: instead of placing them all now, why not
-       // simply create them all and let them call rune_respawn() as their think?
-
-       runes_used  = 0;
-       curses_used = 0;
-
-       prevent_same = !autocvar_g_runematch_allow_same;
-       numrunes = RUNE_COUNT;
-
-       while(numrunes > 0)
-       {
-               RandomSelection_Init();
-               for(rn = RUNE_FIRST; rn <= RUNE_LAST; rn *= 2)
-                       if not(runes_used & rn)
-                               RandomSelection_Add(world, rn, string_null, 1, 1);
-               rn = RandomSelection_chosen_float;
-
-               RandomSelection_Init();
-               for(cs = CURSE_FIRST; cs <= CURSE_LAST; cs *= 2)
-                       if not(curses_used & cs)
-                               if not(prevent_same && cs == RuneMatchesCurse(rn, cs))
-                                       RandomSelection_Add(world, cs, string_null, 1, 1);
-               cs = RandomSelection_chosen_float;
-
-               if(!rn || !cs)
-                       error("No rune/curse left");
-
-               runes_used |= rn;
-               curses_used |= cs;
-
-               e = spawn();
-               e.runes = rn;
-               e.classname = "rune";
-               e.touch = rune_touch;
-               e.think = rune_respawn;
-               e.nextthink = time;
-               e.movetype = MOVETYPE_TOSS;
-               e.solid = SOLID_TRIGGER;
-               e.flags = FL_ITEM;
-               e.reset = rune_reset;
-               setmodel(e, "models/runematch/rune.mdl"); // precision set below
-               setsize(e, '0 0 -35', '0 0 0');
-
-               e.enemy = spawn();
-               e.enemy.enemy = e;
-               e.enemy.classname = "curse";
-               e.enemy.runes = cs;
-               //e.enemy.avelocity = '300 500 200';
-               setmodel(e.enemy, "models/runematch/curse.mdl"); // precision set below
-               setorigin(e, '0 0 0');
-               setattachment(e.enemy, e, "");
-
-               e.colormod = RuneColormod(rn);
-               e.enemy.colormod = RuneColormod(cs);
-
-               e.alpha = e.enemy.alpha = autocvar_g_runematch_rune_alpha;//0.78;
-               e.effects = e.enemy.effects = autocvar_g_runematch_rune_effects | EF_LOWPRECISION;//EF_ADDITIVE;// | EF_FULLBRIGHT;
-
-               //e.glow_size = e.enemy.glow_size = cvar("g_runematch_rune_glow_size");
-               //e.glow_color = e.enemy.glow_color = cvar("g_runematch_rune_glow_color");
-
-               //rn = RUNE_FIRST;
-               //cs = CURSE_FIRST;
-
-               numrunes = numrunes - 1;
-       }
-}
-
-void runematch_init()
-{
-       if(!g_runematch)
-               return;
-
-       entity e;
-       e = spawn();
-       e.think = spawn_runes;
-       e.nextthink = time + 0.1;
-}
-
-
-float runematch_point_time;
-
-// give points to players who are holding runes
-void RuneMatchGivePoints()
-{
-       entity rune;
-
-       if(!g_runematch || !autocvar_g_runematch_pointamt)
-               return;
-
-       if(gameover)
-               return;
-
-       if(runematch_point_time > time)
-               return;
-
-       runematch_point_time = time + autocvar_g_runematch_pointrate;
-
-       rune = world;
-       do
-       {
-               rune = find(rune, classname, "rune");
-               if(!rune)
-                       return;
-
-               if(rune.owner.classname == "player")
-               {
-                       UpdateFrags(rune.owner, autocvar_g_runematch_pointamt);
-               }
-       }while(rune);
-}
-
-float RunematchHandleFrags(entity attacker, entity targ, float f)
-{
-       entity head;
-       float arunes, trunes, newfrags;
-
-       if(f <= 0)
-               return f;
-       if(attacker == targ)
-               return f;
-
-       arunes = trunes = 0;
-
-       head = find(world, classname, "rune");
-       while(head)
-       {
-               if(head.owner == attacker)
-               {
-                       arunes = arunes + 1;
-               }
-               else if(head.owner == targ)
-               {
-                       trunes = trunes + 1;
-               }
-
-               head = find(head, classname, "rune");
-       }
-
-       if(!arunes && !trunes)
-               return f - 1 + autocvar_g_runematch_frags_norune; // don't give points to players when no runes are involved.
-
-       newfrags = 0;
-       if(arunes)
-       {       // got a kill while holding runes
-               newfrags = newfrags + autocvar_g_runematch_frags_killedby_runeholder;//5;
-       }
-       if(trunes)
-       {       // killed an enemy holding runes
-               newfrags = newfrags + autocvar_g_runematch_frags_killed_runeholder;//5;
-       }
-       if(newfrags)
-               f = f - 1 + newfrags;
-
-       return f;
-}
index eb305e72203d48462e505a7a9261622660a5f2f1..e8d5590238b877b79fdb53a74d1dc44f2f1c03a0 100644 (file)
@@ -393,15 +393,15 @@ void WinningConditionHelper()
        // so to match pure, match for :P0:
        // to match full, match for :S0:
 
+       fullstatus = autocvar_g_full_getstatus_responses;
+
        s = GetGametype();
        s = strcat(s, ":", autocvar_g_xonoticversion);
        s = strcat(s, ":P", ftos(cvar_purechanges_count));
        s = strcat(s, ":S", ftos(nJoinAllowed(world)));
        s = strcat(s, ":F", ftos(serverflags));
        s = strcat(s, ":M", modname);
-       s = strcat(s, "::", GetPlayerScoreString(world, 1)); // make this 1 once we can, note: this doesn't contain any :<letter>
-
-       fullstatus = autocvar_g_full_getstatus_responses;
+       s = strcat(s, "::", GetPlayerScoreString(world, (fullstatus ? 1 : 2)));
 
        if(teamscores_entities_count)
        {
@@ -622,7 +622,7 @@ string GetTeamScoreString(float tm, float shortString)
        if(tm == 0)
        {
                // label
-               for(i = 0; i < MAX_SCORE; ++i)
+               for(i = 0; i < MAX_TEAMSCORE; ++i)
                        if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_PRIMARY)
                        {
                                f = teamscores_flags[i];
@@ -630,7 +630,7 @@ string GetTeamScoreString(float tm, float shortString)
                                out = strcat(out, GetScoreLogLabel(l, f), ",");
                        }
                if(shortString < 2)
-               for(i = 0; i < MAX_SCORE; ++i)
+               for(i = 0; i < MAX_TEAMSCORE; ++i)
                        if(teamscores_flags[i] & SFL_SORT_PRIO_MASK == SFL_SORT_PRIO_SECONDARY)
                        {
                                f = teamscores_flags[i];
@@ -638,7 +638,7 @@ string GetTeamScoreString(float tm, float shortString)
                                out = strcat(out, GetScoreLogLabel(l, f), ",");
                        }
                if(shortString < 1)
-               for(i = 0; i < MAX_SCORE; ++i)
+               for(i = 0; i < MAX_TEAMSCORE; ++i)
                        if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_PRIMARY)
                        if(teamscores_flags[i] & SFL_SORT_PRIO_MASK != SFL_SORT_PRIO_SECONDARY)
                        {
index c91c1ac1895ecae9d49667175258f3b91b9f9486..d80b777a6f129197428f16146e36af1b32fc186a 100644 (file)
@@ -153,7 +153,6 @@ Called before each frame by the server
 float game_delay;
 float game_delay_last;
 
-void RuneMatchGivePoints();
 float RedirectionThink();
 entity SelectSpawnPoint (float anypoint);
 void StartFrame (void)
@@ -238,7 +237,6 @@ void StartFrame (void)
        CreatureFrame ();
        CheckRules_World ();
 
-       RuneMatchGivePoints();
        bot_serverframe();
 
        FOR_EACH_PLAYER(self)
index 2ff925ca53d9fbf2ac2c05c103b85e4a0402e263..392c05ce14f3e9b9ac0671b662e510adf34393fd 100644 (file)
@@ -630,9 +630,9 @@ float Item_GiveTo(entity item, entity player)
                        if (clienttype(player) == CLIENTTYPE_REAL)
                        {
                                if(player.health <= 5)
-                                       AnnounceTo(player, "lastsecond");
+                                       Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_MINSTAGIB_LASTSECOND);
                                else if(player.health < 50)
-                                       AnnounceTo(player, "narrowly");
+                                       Send_Notification(NOTIF_ONE, player, MSG_ANNCE, ANNCE_MINSTAGIB_NARROWLY);
                        }
                        // sound not available
                        // else if(item.items == IT_CELLS)
index 5a5042b3d48a63dc1a273feff50b33e767a7de8f..0b6f7fc4cd9488357ccb0b0110adf3adf87a18ec 100644 (file)
@@ -37,6 +37,8 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
 
        grav = autocvar_sv_gravity;
+       if(other.gravity)
+               grav *= other.gravity;
 
        zdist = torg_z - org_z;
        sdist = vlen(torg - org - zdist * '0 0 1');
index a96726c5643f175174783c563ec77751deb70190..6608fc9a317e38e1e73686179016a354ecdabe45 100644 (file)
@@ -13,7 +13,6 @@ void TeamchangeFrags(entity e)
        PlayerScore_Clear(e);
 }
 
-void runematch_init();
 void tdm_init();
 void entcs_init();
 
@@ -107,14 +106,6 @@ void InitGameplayMode()
                have_team_spawns = -1; // request team spawns
        }
 
-       if(g_runematch)
-       {
-               // ActivateTeamplay();
-               fraglimit_override = autocvar_g_runematch_point_limit;
-               leadlimit_override = autocvar_g_runematch_point_leadlimit;
-               runematch_init();
-       }
-
        if(g_lms)
        {
                fraglimit_override = autocvar_g_lms_lives_override;
index aacca522ec9a1d63c05ac5a042da69ab7e2614fc..f4a60e545a12163a9d14b894d8804106a5f63ead 100644 (file)
@@ -25,6 +25,44 @@ void turret_plasma_dual_postthink()
         self.tur_head.frame = 0;
 }
 
+void turret_plasma_minsta_attack (void)
+{
+       float flying;
+       flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
+        
+       FireRailgunBullet (self.tur_shotorg, self.tur_shotorg + self.tur_shotdir_updated * MAX_SHOT_DISTANCE, 10000000000,
+                                          800, 0, 0, 0, 0, DEATH_TURRET_PLASMA);
+
+
+       pointparticles(particleeffectnum("nex_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+       // teamcolor / hit beam effect
+       vector v;
+       v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+       if(teamplay)
+       {
+           switch(self.team)
+           {
+            case NUM_TEAM_1:   // Red
+                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3RED"), self.tur_shotorg, v);
+                break;
+            case NUM_TEAM_2:   // Blue
+                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3BLUE"), self.tur_shotorg, v);
+                break;
+            case NUM_TEAM_3:   // Yellow
+                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3YELLOW"), self.tur_shotorg, v);
+                break;
+            case NUM_TEAM_4:   // Pink
+                    WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3PINK"), self.tur_shotorg, v);
+                break;
+           }
+       }
+       else
+        WarpZone_TrailParticles(world, particleeffectnum("TE_TEI_G3"), self.tur_shotorg, v);
+    if (self.tur_head.frame == 0)
+        self.tur_head.frame = 1;
+}
+
 void turret_plasma_attack()
 { 
     entity missile = turret_projectile("weapons/hagar_fire.wav", 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);    
@@ -64,7 +102,10 @@ void turret_plasma_std_init()
     self.firecheck_flags |= TFL_FIRECHECK_AFF;
 
     // Our fireing routine
-    self.turret_firefunc  = turret_plasma_attack;
+    if(g_minstagib)
+        self.turret_firefunc  = turret_plasma_minsta_attack;
+    else
+        self.turret_firefunc  = turret_plasma_attack;
 
     // Custom per turret frame stuff. usualy animation.
     self.turret_postthink = turret_plasma_postthink;
index e68a417e00de6855f4bbfce117ce244b4de3a5f1..2e0c1e8f02bbcd466773894e43e3da4df52104f5 100644 (file)
@@ -166,6 +166,7 @@ void FireRailgunBullet (vector start, vector end, float bdamage, float bforce, f
 .float dmg_force;
 .float dmg_radius;
 .float dmg_total;
+//.float last_yoda;
 void W_BallisticBullet_Hit (void)
 {
        float f, q, g;
@@ -186,8 +187,11 @@ void W_BallisticBullet_Hit (void)
                g = accuracy_isgooddamage(self.realowner, other);
                Damage(other, self, self.realowner, self.dmg * f, self.projectiledeathtype, self.origin, self.dmg_force * normalize(self.velocity) * f);
 
-               if(yoda)
-                       AnnounceTo(self.realowner, "awesome");
+               /*if(yoda && (time > (self.last_yoda + 5)))
+               {
+                       Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
+                       self.last_yoda = time; 
+               }*/
 
                // calculate hits for ballistic weapons
                if(g)
index 20aac867e91ae0f3b856be81fecc325b96f14180..972642343b38c068317eeb1ec5b1cae944e6fdfb 100644 (file)
@@ -33,7 +33,7 @@ void W_Plasma_Explode (void)
                        if(IsDifferentTeam(self.realowner, other))
                                if(other.deadflag == DEAD_NO)
                                        if(IsFlying(other))
-                                               AnnounceTo(self.realowner, "electrobitch");
+                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_ELECTROBITCH);
 
        self.event_damage = func_null;
        self.takedamage = DAMAGE_NO;
index b463a4e71ab0c18823678c8bd9d992060698dbe0..cdcf841e018956e11b48ddd61afe7903f76e1fca 100644 (file)
@@ -12,7 +12,7 @@ void W_Grenade_Explode (void)
                        if(IsDifferentTeam(self.realowner, other))
                                if(other.deadflag == DEAD_NO)
                                        if(IsFlying(other))
-                                               AnnounceTo(self.realowner, "airshot");
+                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        self.event_damage = func_null;
        self.takedamage = DAMAGE_NO;
@@ -32,7 +32,7 @@ void W_Grenade_Explode2 (void)
                        if(IsDifferentTeam(self.realowner, other))
                                if(other.deadflag == DEAD_NO)
                                        if(IsFlying(other))
-                                               AnnounceTo(self.realowner, "airshot");
+                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        self.event_damage = func_null;
        self.takedamage = DAMAGE_NO;
index 6d3c331739917267ff28ff3035581d5f1631aec2..40c60e827e3adc024457f462577d6a2b68b32ac0 100644 (file)
@@ -66,7 +66,7 @@ void W_Mine_Explode ()
                        if(IsDifferentTeam(self.realowner, other))
                                if(other.deadflag == DEAD_NO)
                                        if(IsFlying(other))
-                                               AnnounceTo(self.realowner, "airshot");
+                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        self.event_damage = func_null;
        self.takedamage = DAMAGE_NO;
index c464af93a27c07e05ad5493efe0cfcd4b3cb60f8..b34d66bf677184220955ef3b6b69304c1130ab3d 100644 (file)
@@ -19,15 +19,15 @@ void W_MinstaNex_Attack (void)
        if(g_minstagib)
        {
                if(yoda)
-                       AnnounceTo(self, "yoda");
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
        }
        else
        {
                if(yoda && flying)
-                       AnnounceTo(self, "yoda");
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA);
                if(damage_goodhits && self.minstanex_lasthit)
                {
-                       AnnounceTo(self, "impressive");
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_IMPRESSIVE);
                        damage_goodhits = 0; // only every second time
                }
        }
@@ -93,7 +93,7 @@ void minstagib_ammocheck(void)
        if (time < self.minstagib_nextthink)
                return;
 
-       if (self.deadflag || gameover)
+       if (self.deadflag || gameover || (self.flags & FL_GODMODE))
                minstagib_stop_countdown(self);
        else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
        {
@@ -106,60 +106,58 @@ void minstagib_ammocheck(void)
                if (self.health == 5)
                {
                        Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
-                       AnnounceTo(self, "terminated");
+                       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');
-                       AnnounceTo(self, "1");
+                       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');
-                       AnnounceTo(self, "2");
+                       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');
-                       AnnounceTo(self, "3");
+                       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');
-                       AnnounceTo(self, "4");
+                       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');
-                       AnnounceTo(self, "5");
+                       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');
-                       AnnounceTo(self, "6");
+                       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');
-                       AnnounceTo(self, "7");
+                       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');
-                       AnnounceTo(self, "8");
+                       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');
-                       AnnounceTo(self, "9");
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_9);
                }
                else if (self.health == 100)
                {
-                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO_FIRST);
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_MULTI, MULTI_MINSTA_FINDAMMO);
                        Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       if not(self.flags & FL_GODMODE)
-                               AnnounceTo(self, "10");
                }
        }
        self.minstagib_nextthink = time + 1;
index 9d66f407ef8bbb401c2fd4c77f0c1fd2ae52cf42..23dcce96d81a73fa8e2e3ab2e51cd56dbb2189cf 100644 (file)
@@ -66,7 +66,7 @@ void W_Nex_Attack (float issecondary)
        FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, mydmg, myforce, mymindist, mymaxdist, myhalflife, myforcehalflife, WEP_NEX);
 
        if(yoda && flying)
-               AnnounceTo(self, "yoda");
+               Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_ACHIEVEMENT_YODA); 
 
        //beam and muzzle flash done on client
        SendCSQCNexBeamParticle(charge);
index 202dd68bdfaac166918253cf0863c88b3287c338..250fc0d3bea089ff22db74c3633f54244e38f8b4 100644 (file)
@@ -23,7 +23,7 @@ void W_Rocket_Explode ()
                        if(IsDifferentTeam(self.realowner, other))
                                if(other.deadflag == DEAD_NO)
                                        if(IsFlying(other))
-                                               AnnounceTo(self.realowner, "airshot");
+                                               Send_Notification(NOTIF_ONE, self.realowner, MSG_ANNCE, ANNCE_ACHIEVEMENT_AIRSHOT);
 
        self.event_damage = func_null;
        self.takedamage = DAMAGE_NO;