]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/physics
authorMario <zacjardine@y7mail.com>
Sun, 7 Dec 2014 02:39:31 +0000 (13:39 +1100)
committerMario <zacjardine@y7mail.com>
Sun, 7 Dec 2014 02:39:31 +0000 (13:39 +1100)
Conflicts:
qcsrc/common/constants.qh
qcsrc/server/autocvars.qh
qcsrc/server/cl_physics.qc

317 files changed:
.gitignore
_hud_descriptions.cfg
common.ast.po
common.be.po
common.bg.po
common.ca.po
common.cs.po
common.de.po
common.el.po
common.es.po
common.fi.po
common.fr.po
common.hu.po
common.it.po
common.mk.po
common.nl.po
common.pl.po
common.pot
common.pt.po
common.ro.po
common.ru.po
common.sr.po
common.sv.po
common.uk.po
common.zh_CN.po
common.zh_TW.po
defaultXonotic.cfg
effects-high.cfg
effects-low.cfg
effects-med.cfg
effects-normal.cfg
effects-omg.cfg
effects-ultimate.cfg
effects-ultra.cfg
gamemodes.cfg
gfx/hud/default/nade_bg.tga [new file with mode: 0644]
gfx/hud/default/nade_nbg.tga [new file with mode: 0644]
gfx/hud/default/notify_nade.tga [new file with mode: 0644]
gfx/hud/default/notify_nade_heal.tga [new file with mode: 0644]
gfx/hud/default/notify_nade_ice.tga [new file with mode: 0644]
gfx/hud/default/notify_nade_napalm.tga [new file with mode: 0644]
gfx/menu/luminos/color.tga [deleted file]
gfx/menu/luminos/colorbutton_c.tga
gfx/menu/luminos/colorbutton_f.tga
gfx/menu/luminos/colorbutton_n.tga [changed mode: 0755->0644]
gfx/menu/luminos/skinvalues.txt
gfx/menu/wickedx/color.tga [deleted file]
gfx/menu/wickedx/colorbutton_c.tga
gfx/menu/wickedx/colorbutton_f.tga
gfx/menu/wickedx/colorbutton_n.tga [changed mode: 0755->0644]
gfx/menu/wickedx/skinvalues.txt
gfx/menu/xaw/color.tga [deleted file]
gfx/menu/xaw/colorbutton_c.tga
gfx/menu/xaw/colorbutton_f.tga
gfx/menu/xaw/colorbutton_n.tga
gfx/menu/xaw/skinvalues.txt
hook-firing_swap.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
keybinds.txt
keybinds.txt.de
keybinds.txt.es
keybinds.txt.fr
keybinds.txt.hu
keybinds.txt.it
keybinds.txt.ru
keybinds.txt.uk
models/domination/dom_axe.tga [new file with mode: 0644]
models/domination/dom_axe_glow.tga [new file with mode: 0644]
models/domination/dom_bolt.tga [new file with mode: 0644]
models/domination/dom_bolt_glow.tga [new file with mode: 0644]
models/player/erebus.iqm_0.txt
models/player/gak.iqm_0.txt
models/player/gakarmored.iqm_0.txt
models/player/gakmasked.iqm_0.txt
models/player/ignis.iqm_0.txt
models/player/ignishalfmasked.iqm_0.txt
models/player/ignismasked.iqm_0.txt
models/player/megaerebus.iqm_0.txt
models/player/nyx.iqm_0.txt
models/player/pyria.iqm_0.txt
models/player/seraphina.iqm_0.txt
models/player/seraphinamasked.iqm_0.txt
models/player/umbra.iqm_0.txt
models/weapons/g_arc_simple.iqm [new file with mode: 0644]
models/weapons/g_arc_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_arc_simple.tga [new file with mode: 0644]
models/weapons/g_campingrifle_simple.iqm [new file with mode: 0644]
models/weapons/g_campingrifle_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_campingrifle_simple.tga [new file with mode: 0644]
models/weapons/g_crylink_simple.tga
models/weapons/g_electro_simple.tga
models/weapons/g_fireball_simple.iqm [new file with mode: 0644]
models/weapons/g_fireball_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_fireball_simple.tga [new file with mode: 0644]
models/weapons/g_gl_simple.tga
models/weapons/g_hagar_simple.tga
models/weapons/g_hlac_simple.iqm [new file with mode: 0644]
models/weapons/g_hlac_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_hlac_simple.tga [new file with mode: 0644]
models/weapons/g_hookgun_simple.iqm [new file with mode: 0644]
models/weapons/g_hookgun_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_hookgun_simple.tga [new file with mode: 0644]
models/weapons/g_laser_simple.iqm [new file with mode: 0644]
models/weapons/g_laser_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_laser_simple.tga [new file with mode: 0644]
models/weapons/g_minelayer_simple.iqm [new file with mode: 0644]
models/weapons/g_minelayer_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_minelayer_simple.tga [new file with mode: 0644]
models/weapons/g_minstanex_simple.iqm [new file with mode: 0644]
models/weapons/g_minstanex_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_minstanex_simple.tga [new file with mode: 0644]
models/weapons/g_nex_simple.tga
models/weapons/g_porto_simple.iqm [new file with mode: 0644]
models/weapons/g_porto_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_porto_simple.tga [new file with mode: 0644]
models/weapons/g_rl_simple.tga
models/weapons/g_seeker_simple.iqm [new file with mode: 0644]
models/weapons/g_seeker_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_seeker_simple.tga [new file with mode: 0644]
models/weapons/g_shotgun_simple.tga
models/weapons/g_tuba_simple.iqm [new file with mode: 0644]
models/weapons/g_tuba_simple.iqm_0.skin [new file with mode: 0644]
models/weapons/g_tuba_simple.tga [new file with mode: 0644]
models/weapons/g_uzi_simple.tga
models/weapons/make-sprites.sh [new file with mode: 0755]
mutators.cfg
notifications.cfg
qcsrc/Makefile
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/autocvars.qh
qcsrc/client/csqc_constants.qc
qcsrc/client/hud.qc
qcsrc/client/hud.qh
qcsrc/client/hud_config.qc
qcsrc/client/main.qh
qcsrc/client/mapvoting.qc
qcsrc/client/movetypes.qc
qcsrc/client/progs.src
qcsrc/client/projectile.qc
qcsrc/client/scoreboard.qc
qcsrc/client/shownames.qc
qcsrc/client/tuba.qc
qcsrc/client/waypointsprites.qc
qcsrc/common/buffs.qc [new file with mode: 0644]
qcsrc/common/buffs.qh [new file with mode: 0644]
qcsrc/common/constants.qh
qcsrc/common/deathtypes.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/nades.qc [new file with mode: 0644]
qcsrc/common/nades.qh [new file with mode: 0644]
qcsrc/common/notifications.qc
qcsrc/common/notifications.qh
qcsrc/common/stats.qh [new file with mode: 0644]
qcsrc/common/util-pre.qh
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/menu/classes.c
qcsrc/menu/item/container.c
qcsrc/menu/item/label.c
qcsrc/menu/item/modalcontroller.c
qcsrc/menu/menu.qc
qcsrc/menu/skin-customizables.inc
qcsrc/menu/xonotic/colorbutton.c
qcsrc/menu/xonotic/demolist.c
qcsrc/menu/xonotic/dialog_hudpanel_buffs.c [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_multiplayer_create.c
qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c
qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c
qcsrc/menu/xonotic/dialog_settings_effects.c
qcsrc/menu/xonotic/gametypelist.c
qcsrc/menu/xonotic/languagelist.c
qcsrc/menu/xonotic/mainwindow.c
qcsrc/menu/xonotic/maplist.c
qcsrc/menu/xonotic/playerlist.c
qcsrc/menu/xonotic/playermodel.c
qcsrc/menu/xonotic/serverlist.c
qcsrc/menu/xonotic/skinlist.c
qcsrc/menu/xonotic/slider.c
qcsrc/menu/xonotic/slider_particles.c [new file with mode: 0644]
qcsrc/menu/xonotic/weaponslist.c
qcsrc/server/anticheat.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/aim.qc
qcsrc/server/bot/bot.qc
qcsrc/server/bot/havocbot/roles.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/cl_weaponsystem.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/getreplies.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/csqcprojectile.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/mapvoting.qc [new file with mode: 0644]
qcsrc/server/mapvoting.qh [new file with mode: 0644]
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/base.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/gamemode_ca.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_cts.qc [new file with mode: 0644]
qcsrc/server/mutators/gamemode_cts.qh [new file with mode: 0644]
qcsrc/server/mutators/gamemode_domination.qc
qcsrc/server/mutators/gamemode_domination.qh
qcsrc/server/mutators/gamemode_freezetag.qc
qcsrc/server/mutators/gamemode_invasion.qc
qcsrc/server/mutators/gamemode_keepaway.qc
qcsrc/server/mutators/gamemode_keyhunt.qc
qcsrc/server/mutators/gamemode_nexball.qc
qcsrc/server/mutators/gamemode_race.qc [new file with mode: 0644]
qcsrc/server/mutators/gamemode_race.qh [new file with mode: 0644]
qcsrc/server/mutators/gamemode_tdm.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator_buffs.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator_buffs.qh [new file with mode: 0644]
qcsrc/server/mutators/mutator_campcheck.qc
qcsrc/server/mutators/mutator_dodging.qc
qcsrc/server/mutators/mutator_instagib.qc [new file with mode: 0644]
qcsrc/server/mutators/mutator_minstagib.qc [deleted file]
qcsrc/server/mutators/mutator_nades.qc
qcsrc/server/mutators/mutator_nades.qh
qcsrc/server/mutators/mutator_spawn_near_teammate.qc
qcsrc/server/mutators/mutator_touchexplode.qc
qcsrc/server/mutators/mutators.qc [new file with mode: 0644]
qcsrc/server/mutators/mutators.qh
qcsrc/server/mutators/mutators_include.qc [new file with mode: 0644]
qcsrc/server/mutators/mutators_include.qh [new file with mode: 0644]
qcsrc/server/progs.src
qcsrc/server/race.qc
qcsrc/server/race.qh
qcsrc/server/scores.qc
qcsrc/server/scores_rules.qc
qcsrc/server/spawnpoints.qh
qcsrc/server/sv_main.qc
qcsrc/server/t_items.qc
qcsrc/server/t_plats.qc
qcsrc/server/t_quake3.qc
qcsrc/server/target_music.qc
qcsrc/server/teamplay.qc
qcsrc/server/tturrets/units/unit_plasma.qc
qcsrc/server/vehicles/vehicles.qc
qcsrc/server/w_electro.qc
qcsrc/server/w_minelayer.qc
qcsrc/server/w_minstanex.qc
scripts/simpleitems.shader
sound/tutorial/1-welcome.ogg [deleted file]
sound/tutorial/10-at_corp_switch.ogg [deleted file]
sound/tutorial/11-behind_glass.ogg [deleted file]
sound/tutorial/12-crylink.ogg [deleted file]
sound/tutorial/13-no_imitations.ogg [deleted file]
sound/tutorial/14-room_with_switch.ogg [deleted file]
sound/tutorial/15-x_marks_the_spot.ogg [deleted file]
sound/tutorial/16-shoot_with_electro.ogg [deleted file]
sound/tutorial/17-deeper.ogg [deleted file]
sound/tutorial/18-fire_then_fire.ogg [deleted file]
sound/tutorial/19-activates_the_buried_switch.ogg [deleted file]
sound/tutorial/2-jumppad.ogg [deleted file]
sound/tutorial/20-at_corp_says_you_are_smart.ogg [deleted file]
sound/tutorial/21-rocket_launcher.ogg [deleted file]
sound/tutorial/22-as_a_special_feature.ogg [deleted file]
sound/tutorial/23-hold_the_fire_button.ogg [deleted file]
sound/tutorial/24-guide_the_rocket.ogg [deleted file]
sound/tutorial/25-omg_laser.ogg [deleted file]
sound/tutorial/26-the_red_platform.ogg [deleted file]
sound/tutorial/27-wga.ogg [deleted file]
sound/tutorial/28-grappling_hook.ogg [deleted file]
sound/tutorial/29-hooker.ogg [deleted file]
sound/tutorial/3-death.ogg [deleted file]
sound/tutorial/30-destination_of_the_hook.ogg [deleted file]
sound/tutorial/31-pogo_stick.ogg [deleted file]
sound/tutorial/32-way_to_go_champ.ogg [deleted file]
sound/tutorial/33-cr-vi.ogg [deleted file]
sound/tutorial/34-pierce_walls.ogg [deleted file]
sound/tutorial/35-shoot_your_instructor.ogg [deleted file]
sound/tutorial/36-hit_me.ogg [deleted file]
sound/tutorial/36-just_shoot_it.ogg [deleted file]
sound/tutorial/37-I_am_waiting.ogg [deleted file]
sound/tutorial/38-impatient.ogg [deleted file]
sound/tutorial/39-srs_trouble.ogg [deleted file]
sound/tutorial/4-big_jump.ogg [deleted file]
sound/tutorial/5-to_the_left_to_the_left.ogg [deleted file]
sound/tutorial/6-air_friction.ogg [deleted file]
sound/tutorial/7-rocket_at_you.ogg [deleted file]
sound/tutorial/8-shoot-switch.ogg [deleted file]
sound/tutorial/9-unbreakable.ogg [deleted file]
sound/tutorial/frag_on.ogg [deleted file]
sound/tutorial/misc-at_corp_rap.ogg [deleted file]
sound/tutorial/misc-detonate.ogg [deleted file]
sound/tutorial/misc-did_yoda_show_you_that.ogg [deleted file]
sound/tutorial/misc-door.ogg [deleted file]
sound/tutorial/misc-emergency_tele.ogg [deleted file]
sound/tutorial/misc-excellent.ogg [deleted file]
sound/tutorial/misc-good_work.ogg [deleted file]
sound/tutorial/misc-nice.ogg [deleted file]
sound/tutorial/misc-very_impressive.ogg [deleted file]
tooltips.db
tooltips.db.de
tooltips.db.es
tooltips.db.fr
tooltips.db.hu
tooltips.db.it
tooltips.db.ru
tooltips.db.uk
weapons.cfg
xonotic-credits.txt

index 111ff910955c548eff9626df6d03e7f9892890e7..6b5cef68e6ae6881cd0fc23abc2340230d73614e 100644 (file)
@@ -6,4 +6,6 @@ qcsrc/menu/fteqcc.log
 qcsrc/server/fteqcc.log
 weapons.qc.tmp
 *.lno
-qcsrc/qccversion.*
+qcsrc/qccversion*
+qcsrc/server/precache-for-csqc.inc
+.DS_Store
index 5f21867d353600ab2aa32dbad1c137f6d3a8ccae..270bd2bd9294693bcbf787666f7b3b2d341e2141 100644 (file)
@@ -128,6 +128,7 @@ seta hud_panel_notify_flip "" "order the list top to bottom instead of bottom to
 seta hud_panel_notify_fontsize "" "multiplier for the font size used for player names in the panel"
 seta hud_panel_notify_fadetime "" "fade out time"
 seta hud_panel_notify_time "" "time that a new entry stays until it fades out"
+seta hud_panel_notify_icon_aspect "" "aspect ratio of total drawing area per icon"
 
 seta hud_panel_timer "" "enable/disable this panel"
 seta hud_panel_timer_pos "" "position of this base of the panel"
@@ -296,3 +297,13 @@ seta hud_panel_centerprint_fade_subsequent_passtwo "" "division factor for the s
 seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "" "minimum factor that the second pass can fade to"
 seta hud_panel_centerprint_fade_subsequent_minfontsize "" "minimum factor for the font size from the subsequent fading effects"
 seta hud_panel_centerprint_fade_minfontsize "" "minimum factor for the font size from the fading in/out effects"
+
+seta hud_panel_buffs "" "enable/disable this panel"
+seta hud_panel_buffs_pos "" "position of this panel"
+seta hud_panel_buffs_size "" "size of this panel"
+seta hud_panel_buffs_bg "" "if set to something else than \"\" = override default background"
+seta hud_panel_buffs_bg_color "" "if set to something else than \"\" = override default panel background color"
+seta hud_panel_buffs_bg_color_team "" "override panel color with team color in team based games"
+seta hud_panel_buffs_bg_alpha "" "if set to something else than \"\" = override default panel background alpha"
+seta hud_panel_buffs_bg_border "" "if set to something else than \"\" = override default size of border around the background"
+seta hud_panel_buffs_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
index 89e4680d301a3183718c37d98d3214d120a710f0..bc99aa60a3603a05263bab7e195ac267726d446d 100644 (file)
@@ -4196,7 +4196,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4248,7 +4248,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6128,7 +6128,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index afe2a535c7e46608877ac249a46e2289a6b63f73..7f97286bf30eb19c17cbe52460690c45bea429e5 100644 (file)
@@ -4212,8 +4212,8 @@ msgid "Full item placement"
 msgstr "Са зброяй"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Толькі MinstaGib"
+msgid "InstaGib only"
+msgstr "Толькі InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4264,8 +4264,8 @@ msgstr "Ухіленне"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6147,7 +6147,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 34978b5fb2fed5058b573585efe1c988bb4c5648..d363d0d4da59bdcdd006274ad0bf736866ce4caf 100644 (file)
@@ -4196,7 +4196,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4248,7 +4248,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6128,7 +6128,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index b47984f4493aa84959ca791360f5378039142df2..6297eaebd96e8dab6064898ef467b7286ca60d58 100644 (file)
@@ -4196,7 +4196,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4248,7 +4248,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6128,7 +6128,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 639a44085568c121c43656718aed0014fea5abaf..f153765e6046d269b7c833d068c6d6e50b07c7f2 100644 (file)
@@ -4196,7 +4196,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4248,7 +4248,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6128,7 +6128,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index b51d4170e98ead256944ee64f596cf60da700fc0..cb5a224fb0561be759a20652a104fd3ca7ba38a7 100644 (file)
@@ -4332,8 +4332,8 @@ msgid "Full item placement"
 msgstr "Mit allen Items"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Nur MinstaGib"
+msgid "InstaGib only"
+msgstr "Nur InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4384,8 +4384,8 @@ msgstr "Ausweichen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6268,8 +6268,8 @@ msgid "SLCAT^Overkill Mode"
 msgstr "SLCAT^Overkill Modus"
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "SLCAT^MinstaGib Modus"
+msgid "SLCAT^InstaGib Mode"
+msgstr "SLCAT^InstaGib Modus"
 
 #: qcsrc/menu/xonotic/serverlist.c:156
 msgid "SLCAT^Defrag Mode"
index 6b830eab9312c95fb4f0fb427a2546e2d4f97f95..212df32acd993872c216c319a3beae8f4afe36a1 100644 (file)
@@ -4202,7 +4202,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4254,7 +4254,7 @@ msgstr "Υπεκφυγή"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6134,7 +6134,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index a3953b4a718a349cfb0d7b934a3224bb8b16cae1..ac4675db8918568466a1977eef5f10604188cf81 100644 (file)
@@ -4248,8 +4248,8 @@ msgid "Full item placement"
 msgstr "Con objetos"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Sólo MinstaGib"
+msgid "InstaGib only"
+msgstr "Sólo InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4300,8 +4300,8 @@ msgstr "Esquivar"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6185,7 +6185,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 17fb34727deceeeb931a487c704b1dc28d00273b..70797fa56e31541380901bf92e9b5e9a7d35a351 100644 (file)
@@ -4202,8 +4202,8 @@ msgid "Full item placement"
 msgstr "Esineiden täysi sijoittaminen"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Vain MinstaGib"
+msgid "InstaGib only"
+msgstr "Vain InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4254,8 +4254,8 @@ msgstr "Väistely"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6139,7 +6139,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index a8909ffab136879ba8fb58c29ce38e2efd0dbe3a..58ebba378825d4571d4b1a70dab36f49ca93ff1d 100644 (file)
@@ -4362,8 +4362,8 @@ msgid "Full item placement"
 msgstr "Placement complet des objets"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "MinstaGib uniquement"
+msgid "InstaGib only"
+msgstr "InstaGib uniquement"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4414,8 +4414,8 @@ msgstr "Esquives"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6300,8 +6300,8 @@ msgid "SLCAT^Overkill Mode"
 msgstr "Mode Overkill"
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "Mode MinstaGib"
+msgid "SLCAT^InstaGib Mode"
+msgstr "Mode InstaGib"
 
 #: qcsrc/menu/xonotic/serverlist.c:156
 msgid "SLCAT^Defrag Mode"
index 14ab01f958711a028a4d3e14e1bc96c17b298219..7ec54de9c195583c59c0742eb7a5f45a70db479f 100644 (file)
@@ -4244,8 +4244,8 @@ msgid "Full item placement"
 msgstr "Minden tárgy elhelyezése"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Csak MinstaGib"
+msgid "InstaGib only"
+msgstr "Csak InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4296,8 +4296,8 @@ msgstr "Félreugrás"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6180,7 +6180,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index eba61119ad466c9fa0d6564c44e9f989ff625259..307211b42ab7cfe19d59bab4565b5a4f6a8de611 100644 (file)
@@ -4358,8 +4358,8 @@ msgid "Full item placement"
 msgstr "Posizionamento oggetti completo"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Solo MinstaGib"
+msgid "InstaGib only"
+msgstr "Solo InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4410,8 +4410,8 @@ msgstr "Schivamento"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6293,8 +6293,8 @@ msgid "SLCAT^Overkill Mode"
 msgstr "Modo Overkill"
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "Modo Minstagib"
+msgid "SLCAT^InstaGib Mode"
+msgstr "Modo InstaGib"
 
 #: qcsrc/menu/xonotic/serverlist.c:156
 msgid "SLCAT^Defrag Mode"
index 75c6ecde79af737251e036724efe57de9a81d7fc..982a31699d67c70b92f28cea9724e5f48f216773 100644 (file)
@@ -4196,7 +4196,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4248,7 +4248,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6128,7 +6128,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 1ebad855bdcd272c29580db615f1fae2c6299cee..050613e742675ff767e378a08e93e56ecd871d84 100644 (file)
@@ -4241,8 +4241,8 @@ msgid "Full item placement"
 msgstr "Volledige item distributie"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Alleen MinstaGib"
+msgid "InstaGib only"
+msgstr "Alleen InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4293,8 +4293,8 @@ msgstr "Ontwijken"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6177,7 +6177,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 17e9eac9857f70952601d33d88fbab0d9baeaeea..21372925c5ed1cb38c627eacd904a438a6f0d14b 100644 (file)
@@ -4198,7 +4198,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4250,7 +4250,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6130,7 +6130,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index e2c6d70ac4698c5077bc449eb194bb7b9a0b0279..426fb1f322da4bcbfb543d6c87a4722eb2c61b1a 100644 (file)
@@ -4195,7 +4195,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4247,7 +4247,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6127,7 +6127,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 94d564e464d2300d7eff070be466d604313cbecc..6e3bbdbf19b3d6fa04be27d8bd5c7608f40f83ef 100644 (file)
@@ -4202,8 +4202,8 @@ msgid "Full item placement"
 msgstr "Colocação total dos items"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Apenas MinstaGib"
+msgid "InstaGib only"
+msgstr "Apenas InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4254,8 +4254,8 @@ msgstr "Desvio"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6138,7 +6138,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 3611887733625dcb5756d6dea1438980c276065d..b87bc637848276e82627460db68b535befd8c9e4 100644 (file)
@@ -4206,8 +4206,8 @@ msgid "Full item placement"
 msgstr "Plasare obiecte"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Numai MinstaGib"
+msgid "InstaGib only"
+msgstr "Numai InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4258,8 +4258,8 @@ msgstr "Satiruta laterala"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6142,7 +6142,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 171d2db281f1e19a6d514150a65586c10f2219fd..dfb8e7672eb0ff9b790e93fbc93de64275be816f 100644 (file)
@@ -4304,8 +4304,8 @@ msgid "Full item placement"
 msgstr "С оружием"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Только MinstaGib"
+msgid "InstaGib only"
+msgstr "Только InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4356,8 +4356,8 @@ msgstr "Уклонение"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6240,8 +6240,8 @@ msgid "SLCAT^Overkill Mode"
 msgstr "Режим Overkill"
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
-msgstr "Режим MinstaGib"
+msgid "SLCAT^InstaGib Mode"
+msgstr "Режим InstaGib"
 
 #: qcsrc/menu/xonotic/serverlist.c:156
 msgid "SLCAT^Defrag Mode"
index 1e9faed0c2565d518d3c6380ac8b55f1ffd428a9..9a022e15ef3f48c387d1bd3eee43389ac2848df3 100644 (file)
@@ -4213,7 +4213,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4265,7 +4265,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6145,7 +6145,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 677f55f77dbad2ac6f3aa6172c9be9b89511a2e0..1e45ea85a0e97655f076699b6567502f06e4abf3 100644 (file)
@@ -4204,8 +4204,8 @@ msgid "Full item placement"
 msgstr "Fullständing sakplacering"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Endast MinstaGib"
+msgid "InstaGib only"
+msgstr "Endast InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4256,8 +4256,8 @@ msgstr "Undvika"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6136,7 +6136,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index db7e4dfed8fdd2123a8b581272623e8562a5e3b5..1b26d19a90333a05ebfafff1ec47a70dbf421c23 100644 (file)
@@ -4261,8 +4261,8 @@ msgid "Full item placement"
 msgstr "Вся зброя"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
-msgstr "Тільки MinstaGib"
+msgid "InstaGib only"
+msgstr "Тільки InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
 msgid "Title:"
@@ -4313,8 +4313,8 @@ msgstr "Ухилення"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
-msgstr "MinstaGib"
+msgid "InstaGib"
+msgstr "InstaGib"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:208
@@ -6197,7 +6197,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index dd2ecb619e2ff5e62592b01a0726f50d229080b8..63a5a61db7067f911dcfdeaf18cf4aba918ed2c6 100644 (file)
@@ -4198,7 +4198,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4250,7 +4250,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6130,7 +6130,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 079411cc6226d5b212cc1a0d61e460507cd6bf0b..befc34c493084d620ca5aaadeb86f3fe584091fd 100644 (file)
@@ -4196,7 +4196,7 @@ msgid "Full item placement"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:49
-msgid "MinstaGib only"
+msgid "InstaGib only"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.c:81
@@ -4248,7 +4248,7 @@ msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:70
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:254
-msgid "MinstaGib"
+msgid "InstaGib"
 msgstr ""
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.c:72
@@ -6128,7 +6128,7 @@ msgid "SLCAT^Overkill Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:155
-msgid "SLCAT^MinstaGib Mode"
+msgid "SLCAT^InstaGib Mode"
 msgstr ""
 
 #: qcsrc/menu/xonotic/serverlist.c:156
index 09cc6119ce3bc16e4a85b417da350cd65bf5ee4f..71c8c9cc1d0badfc53f8271e1ed1550514b3778b 100644 (file)
@@ -220,8 +220,11 @@ set sv_ready_restart 0 "if set to 1 allow a map to be restarted once all players
 set sv_ready_restart_after_countdown 0 "if set to 1 the players and map items are reset after the countdown ended, otherwise they're reset already at the beginning of the countdown"
 set sv_ready_restart_repeatable 0      "allows the players to restart the game as often as needed"
 
-seta cl_hitsound 1 "play a hit notifier sound when you have hit an enemy"
+seta cl_hitsound 1 "play a hit notifier sound when you have hit an enemy, 1: same pitch 2: increase pitch with more damage 3: decrease pitch with more damage"
 set cl_hitsound_antispam_time 0.05 "don't play the hitsound more often than this"
+seta cl_hitsound_min_pitch 0.75 "minimum pitch of hit sound"
+seta cl_hitsound_max_pitch 1.5 "maximum pitch of hit sound"
+seta cl_hitsound_nom_damage 25 "damage amount at which hitsound bases pitch off"
 
 seta cl_eventchase_death 1 "camera goes into 3rd person mode when the player is dead"
 seta cl_eventchase_nexball 1 "camera goes into 3rd person mode when in nexball game-mode"
@@ -468,7 +471,7 @@ set g_botclip_collisions 1 "0 = disable collision testing against botclips, migh
 set g_grappling_hook 0 "let players spawn with the grappling hook which allows them to pull themselves up"
 
 set g_spawn_alloweffects 1 "allow clients to enable spawn point and event effects such as particles and sounds, see cl_spawn_ cvars for more info"
-set g_spawn_furthest 1 "this amount of the spawns shall be far away from any players"
+set g_spawn_furthest 0.5 "this amount of the spawns shall be far away from any players"
 set g_spawn_useallspawns 0 "use all spawns, e.g. also team spawns in non-teamplay, and all spawns, even enemy spawns, in teamplay"
 // respawn delay
 set g_respawn_delay_small 2 "small game number of seconds you have to wait before you can respawn again"
@@ -544,12 +547,12 @@ r_mipsprites 1
 r_mipskins 1
 r_shadow_realtime_world_lightmaps 1
 cl_decals_fadetime 5
-cl_decals_time 2
+cl_decals_time 1
 seta cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
 seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
 seta cl_particlegibs 0 "simpler gibs"
 seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
-seta cl_gibs_lifetime 5 "average lifetime of gibs"
+seta cl_gibs_lifetime 2.5 "average lifetime of gibs"
 seta cl_gibs_velocity_scale 1 "gib throw velocity force scale"
 seta cl_gibs_velocity_random 1 "gib throw velocity randomness scale"
 seta cl_gibs_velocity_up 1 "extra z velocity for gibs"
@@ -561,7 +564,7 @@ seta cl_casings_shell_time 30 "shell casing lifetime"
 seta cl_casings_bronze_time 10 "bullet casings lifetime"
 seta cl_casings_ticrate 0.1 "ticrate for casings"
 seta cl_casings_sloppy 1 "sloppy casings, may temporarily penetrate walls"
-seta cl_projectiles_sloppy 0 "sloppy projectiles, may temporarily penetrate walls"
+seta cl_projectiles_sloppy 1 "sloppy projectiles, may temporarily penetrate walls"
 cl_stainmaps 0
 cl_particles_smoke 1
 vid_gl20 1
@@ -813,6 +816,12 @@ seta g_maplist_votable_nodetail 1  "nodetail only shows total count instead of al
 seta g_maplist_votable_abstain 0       "when 1, you can abstain from your vote"
 seta g_maplist_votable_screenshot_dir "maps levelshots"        "where to look for map screenshots"
 
+set sv_vote_gametype 0 "show a vote screen for gametypes before map vote screen"
+set sv_vote_gametype_keeptwotime 10 "show only 2 options for this amount of time during gametype vote screen"
+set sv_vote_gametype_options "dm ctf ca lms tdm ft"
+set sv_vote_gametype_timeout 20
+set sv_vote_gametype_default_current 1 "Keep the current gametype if no one votes"
+
 set g_chat_flood_spl 3 "normal chat: seconds between lines to not count as flooding"
 set g_chat_flood_lmax 2        "normal chat: maximum number of lines per chat message at once"
 set g_chat_flood_burst 2       "normal chat: allow bursts of so many chat lines"
@@ -1008,7 +1017,7 @@ seta menu_slist_categories_CAT_SERVERS_override "CAT_NORMAL"
 seta menu_slist_categories_CAT_XPM_override "CAT_NORMAL"
 seta menu_slist_categories_CAT_MODIFIED_override ""
 seta menu_slist_categories_CAT_OVERKILL_override ""
-seta menu_slist_categories_CAT_MINSTAGIB_override ""
+seta menu_slist_categories_CAT_INSTAGIB_override ""
 seta menu_slist_categories_CAT_DEFRAG_override ""
 
 seta menu_weaponarena ""
@@ -1056,7 +1065,7 @@ set con_completion_gotomap        map
 set con_completion_vmap                map
 set con_completion_vnextmap    map
 set con_completion_vdomap      map
-set con_completion_playermodel models/player/*.iqm
+set con_completion_playermodel "models/player/*.iqm"
 
 // helper
 // these non-saved engine cvars shall be saved
@@ -1258,7 +1267,7 @@ set bot_sound_monopoly 0 "when enabled, only bots can make any noise"
 
 set cl_loddistance1 1024
 set cl_loddistance2 3072
-seta cl_playerdetailreduction 1        "the higher, the less detailed player models are displayed (LOD)"
+seta cl_playerdetailreduction 4        "the higher, the less detailed player models are displayed (LOD)"
 seta cl_modeldetailreduction 1 "the higher, the less detailed certain map models are displayed (LOD)"
 
 set g_mapinfo_settemp_acl "+*" "ACL for mapinfo setting cvars"
@@ -1436,6 +1445,7 @@ r_shadow_glossintensity 1
 r_fakelight 1
 
 r_water_hideplayer 1 // hide your own feet/player model in refraction views, this way you don't see half of your body under water
+r_water_refractdistort 0.019
 
 // strength sound settings
 set sv_strengthsound_antispam_time 0.1 "minimum distance of strength sounds"
index 979c8b17405a727ca64d57e04c21915ea75deb55..a514ce5cb67d9f2eb563ff8d4220d3a510ee61f7 100644 (file)
@@ -1,10 +1,11 @@
 cl_decals 1
 cl_decals_models 0
-cl_decals_time 4
-cl_particles_quality 1
+cl_decals_fadetime 4
+cl_particles 1
+cl_particles_quality 1.0
 cl_damageeffect 1
 cl_spawn_point_particles 1
-cl_playerdetailreduction 0.5
+cl_playerdetailreduction 4.0
 gl_flashblend 0
 gl_picmip -1
 mod_q3bsp_nolightmaps 0
@@ -15,7 +16,7 @@ hud_postprocessing_maxbluralpha 0.5
 hud_powerup 0
 r_depthfirst 2
 r_drawdecals_drawdistance 500
-r_drawparticles_drawdistance 2000
+r_drawparticles_drawdistance 1500
 r_glsl_deluxemapping 1
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0
index 8d6e72a4d0b043a45531383ebe07b99b8828ec92..b7e9a98a3a7a78fa396023d1f3fe615cd4cb4c4a 100644 (file)
@@ -1,10 +1,11 @@
 cl_decals 1
 cl_decals_models 0
-cl_decals_time 2
+cl_decals_fadetime 2
+cl_particles 1
 cl_particles_quality 0.4
 cl_damageeffect 0
 cl_spawn_point_particles 0
-cl_playerdetailreduction 2
+cl_playerdetailreduction 4
 gl_flashblend 1
 gl_picmip 1
 mod_q3bsp_nolightmaps 1
index 1611943c64323588e9e53b057346194149423c82..66eed5aa5d55dc897c6cd748848cd5ed82cb3efe 100644 (file)
@@ -1,10 +1,11 @@
 cl_decals 1
 cl_decals_models 0
-cl_decals_time 2
-cl_particles_quality 1
+cl_decals_fadetime 2
+cl_particles 1
+cl_particles_quality 0.8
 cl_damageeffect 0
 cl_spawn_point_particles 0
-cl_playerdetailreduction 1
+cl_playerdetailreduction 4
 gl_flashblend 0
 gl_picmip 0
 mod_q3bsp_nolightmaps 0
@@ -15,7 +16,7 @@ hud_postprocessing_maxbluralpha 0
 hud_powerup 0
 r_depthfirst 0
 r_drawdecals_drawdistance 300
-r_drawparticles_drawdistance 1000
+r_drawparticles_drawdistance 750
 r_glsl_deluxemapping 0
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0
index 064af655007dabaf85825570d73287d843eb917a..63dcd134a066f0c4255c4ad380f085249e177d0a 100644 (file)
@@ -1,10 +1,11 @@
 cl_decals 1
 cl_decals_models 0
-cl_decals_time 2
-cl_particles_quality 1
+cl_decals_fadetime 2
+cl_particles 1
+cl_particles_quality 1.0
 cl_damageeffect 1
 cl_spawn_point_particles 1
-cl_playerdetailreduction 1
+cl_playerdetailreduction 4
 gl_flashblend 0
 gl_picmip 0
 mod_q3bsp_nolightmaps 0
index 9ede9c7d7236cbd8cb66ddf25d6dcc8900db39d4..9018ee2c94375ba8740fa35f3357f55ff1d3cf15 100644 (file)
@@ -1,6 +1,7 @@
 cl_decals 0
 cl_decals_models 0
-cl_decals_time 2
+cl_decals_fadetime 2
+cl_particles 1
 cl_particles_quality 0.4
 cl_damageeffect 0
 cl_spawn_point_particles 0
index 92539b9b76fb8e278a43375a685ccea517b0e2c6..0cf3a899cbcebf5fa385a66ffd3fc07f326ca3c0 100644 (file)
@@ -1,7 +1,8 @@
 cl_decals 1
 cl_decals_models 1
-cl_decals_time 10
-cl_particles_quality 1
+cl_decals_fadetime 10
+cl_particles 1
+cl_particles_quality 1.0
 cl_damageeffect 2
 cl_spawn_point_particles 1
 cl_playerdetailreduction 0
@@ -15,7 +16,7 @@ hud_postprocessing_maxbluralpha 0.5
 hud_powerup 0.5
 r_depthfirst 2
 r_drawdecals_drawdistance 500
-r_drawparticles_drawdistance 2000
+r_drawparticles_drawdistance 3000
 r_glsl_deluxemapping 1
 r_glsl_offsetmapping 1
 r_glsl_offsetmapping_reliefmapping 1
index 63cfc63ea9fedb7e82b692ab83477eb36c413484..5909f3b83dc956b18141d4c0111b251c60080813 100644 (file)
@@ -1,8 +1,9 @@
 cl_decals 1
 cl_decals_models 0
-cl_decals_time 10
-cl_particles_quality 1
-cl_damageeffect 1
+cl_decals_fadetime 10
+cl_particles 1
+cl_particles_quality 1.0
+cl_damageeffect 2
 cl_spawn_point_particles 1
 cl_playerdetailreduction 0
 gl_flashblend 0
index dfc240536e655cc16867fbee950cb57046e0c681..c31f7f9013a9d4e4e0fc26262175878985d71ecd 100644 (file)
@@ -62,6 +62,28 @@ alias sv_hook_gamerestart
 alias sv_hook_gameend
 
 
+// =====================
+//  gametype vote hooks
+// =====================
+// these are called when the mode is switched via gametype vote screen, earlier than gamestart hooks (useful for enabling per-gamemode mutators)
+alias sv_vote_gametype_hook_all 
+alias sv_vote_gametype_hook_as
+alias sv_vote_gametype_hook_ca
+alias sv_vote_gametype_hook_ctf
+alias sv_vote_gametype_hook_cts
+alias sv_vote_gametype_hook_dm
+alias sv_vote_gametype_hook_dom
+alias sv_vote_gametype_hook_ft
+alias sv_vote_gametype_hook_inv
+alias sv_vote_gametype_hook_ka
+alias sv_vote_gametype_hook_kh
+alias sv_vote_gametype_hook_lms
+alias sv_vote_gametype_hook_nb
+alias sv_vote_gametype_hook_ons
+alias sv_vote_gametype_hook_rc
+alias sv_vote_gametype_hook_tdm
+
+
 // ===========
 //  leadlimit
 // ===========
@@ -203,10 +225,10 @@ set g_assault 0 "Assault: attack the enemy base as fast as you can, then defend
 // ============
 //  clan arena
 // ============
-set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round."
-set g_ca_point_limit 10 "point limit 10 is standard for clan arena"
-set g_ca_point_leadlimit 0
-set g_ca_spectate_enemies 0 "Allow spectating enemy player by dead player during clan arena games."
+set g_ca 0 "Clan Arena: Played in rounds, once you're dead you're out! The team with survivors wins the round"
+seta g_ca_point_limit -1 "Clan Arena point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+seta g_ca_point_leadlimit -1 "Clan Arena point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+set g_ca_spectate_enemies 0 "Allow spectating enemy player by dead player during clan arena games"
 set g_ca_warmup 10 "how long the players will have time to run around the map before the round starts"
 set g_ca_damage2score_multiplier 0.01
 set g_ca_round_timelimit 180 "round time limit in seconds"
@@ -300,6 +322,8 @@ set g_dm 1 "Deathmatch: killing any other player is one frag, player with most f
 set g_tdm_teams 2 "how many teams are in team deathmatch (set by mapinfo)"
 set g_tdm_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
 seta g_tdm_teams_override 0    "how many teams are in team deathmatch"
+set g_tdm_point_limit -1 "TDM point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
+set g_tdm_point_leadlimit -1 "TDM point lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
 
 
 // ============
@@ -314,6 +338,10 @@ set g_domination_point_fullbright  0 "domination point fullbright"
 set g_domination_point_rate            0 "override: how often to give those points"
 set g_domination_point_capturetime     0.1 "how long it takes to capture a point (given no interference)"
 set g_domination_point_glow            0 "domination point glow (warning, slow)"
+set g_domination_roundbased 0 "enable round-based domination (capture all control points to win the round)"
+set g_domination_roundbased_point_limit 5 "capture limit in round-based domination mode"
+set g_domination_round_timelimit 120
+set g_domination_warmup 5
 //set g_domination_balance_team_points 1 "# of points received is based on team sizes"
 
 
@@ -327,9 +355,12 @@ seta g_freezetag_point_leadlimit -1        "Freeze Tag point lead limit overriding the
 set g_freezetag_revive_speed 0.4 "Speed for reviving a frozen teammate"
 set g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets lost when out of range"
 set g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
+set g_freezetag_revive_nade 1 "Enable reviving from own nade explosion"
+set g_freezetag_revive_nade_health 40 "Amount of health player has if they revived from their own nade explosion"
 set g_freezetag_revive_falldamage 0 "Enable reviving from this amount of fall damage"
 set g_freezetag_revive_falldamage_health 40 "Amount of health player has if they revived from falling"
 set g_freezetag_round_timelimit 180 "round time limit in seconds"
+set g_freezetag_frozen_damage_trigger 1 "if 1, frozen players falling into the void will die instead of teleporting to spawn"
 set g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen player with"
 set g_freezetag_frozen_maxtime 60 "frozen players will be automatically unfrozen after this time in seconds"
 seta g_freezetag_teams_override 0
diff --git a/gfx/hud/default/nade_bg.tga b/gfx/hud/default/nade_bg.tga
new file mode 100644 (file)
index 0000000..ffe0e0f
Binary files /dev/null and b/gfx/hud/default/nade_bg.tga differ
diff --git a/gfx/hud/default/nade_nbg.tga b/gfx/hud/default/nade_nbg.tga
new file mode 100644 (file)
index 0000000..1868374
Binary files /dev/null and b/gfx/hud/default/nade_nbg.tga differ
diff --git a/gfx/hud/default/notify_nade.tga b/gfx/hud/default/notify_nade.tga
new file mode 100644 (file)
index 0000000..78dd0e2
Binary files /dev/null and b/gfx/hud/default/notify_nade.tga differ
diff --git a/gfx/hud/default/notify_nade_heal.tga b/gfx/hud/default/notify_nade_heal.tga
new file mode 100644 (file)
index 0000000..17e2408
Binary files /dev/null and b/gfx/hud/default/notify_nade_heal.tga differ
diff --git a/gfx/hud/default/notify_nade_ice.tga b/gfx/hud/default/notify_nade_ice.tga
new file mode 100644 (file)
index 0000000..f752808
Binary files /dev/null and b/gfx/hud/default/notify_nade_ice.tga differ
diff --git a/gfx/hud/default/notify_nade_napalm.tga b/gfx/hud/default/notify_nade_napalm.tga
new file mode 100644 (file)
index 0000000..bb84101
Binary files /dev/null and b/gfx/hud/default/notify_nade_napalm.tga differ
diff --git a/gfx/menu/luminos/color.tga b/gfx/menu/luminos/color.tga
deleted file mode 100644 (file)
index 3ce25a5..0000000
Binary files a/gfx/menu/luminos/color.tga and /dev/null differ
index 586f9b47ef07ed2f7d4660df0fa22edd15521b7d..5f1fc2bcd79eeb072bd996daa9104290e65fd9d6 100644 (file)
Binary files a/gfx/menu/luminos/colorbutton_c.tga and b/gfx/menu/luminos/colorbutton_c.tga differ
index 57d7d933cc38bb28c6fe88521c8dce43723feb01..0ca0d9b6b8a26e0d440611fbdd965835febfc2a4 100644 (file)
Binary files a/gfx/menu/luminos/colorbutton_f.tga and b/gfx/menu/luminos/colorbutton_f.tga differ
old mode 100755 (executable)
new mode 100644 (file)
index 110faa1..26e6da5
Binary files a/gfx/menu/luminos/colorbutton_n.tga and b/gfx/menu/luminos/colorbutton_n.tga differ
index 5e311c9090adaef842639e5a1d0dc5165e559423..025475ab746ad5962d9c004f1ac84e6373fe4841 100755 (executable)
@@ -46,6 +46,7 @@ ALPHA_BACKGROUND_INGAME         1
 ALPHA_DISABLED                  0.2
 ALPHA_BEHIND                    0.5
 ALPHA_TEXT                      0.7
+COLOR_TEXT                      '1 1 1'
 
 // mouse
 //   uses "cursor" images
@@ -67,6 +68,7 @@ MARGIN_TOOLTIP                  '8 8 0'
 BORDER_TOOLTIP                  '16 16 0'
 FONTSIZE_TOOLTIP                12
 ALPHA_TOOLTIP                   0.7
+COLOR_TOOLTIP                   '1 1 1'
 WIDTH_TOOLTIP                   0.3
 AVOID_TOOLTIP                   '8 8 0'
 
@@ -133,6 +135,8 @@ COLOR_SERVERLIST_HIGHPING       '1 0 0'
 ALPHA_SERVERLIST_HIGHPING       0.4
 ALPHA_SERVERLIST_FAVORITE       0.8
 COLOR_SERVERLIST_FAVORITE       '1 1 1'
+ALPHA_SERVERLIST_CATEGORY       0.7
+COLOR_SERVERLIST_CATEGORY       '1 1 1'
 
 // item: skin list
 COLOR_SKINLIST_TITLE            '1 1 1'
@@ -204,7 +208,6 @@ ALPHA_KEYGRABBER_KEYS           0.7
 
 // item: player color button
 //   uses "colorbutton" images
-//   uses "color" images
 
 // item: player name editor
 //   uses "charmap" images
diff --git a/gfx/menu/wickedx/color.tga b/gfx/menu/wickedx/color.tga
deleted file mode 100755 (executable)
index 5189ab4..0000000
Binary files a/gfx/menu/wickedx/color.tga and /dev/null differ
index 1c294f77f51a50a5a8085373e9e03d1144277f33..5f1fc2bcd79eeb072bd996daa9104290e65fd9d6 100644 (file)
Binary files a/gfx/menu/wickedx/colorbutton_c.tga and b/gfx/menu/wickedx/colorbutton_c.tga differ
index 0031c35e35c2c1f6a544c9bbca69ee53a685fba9..0ca0d9b6b8a26e0d440611fbdd965835febfc2a4 100644 (file)
Binary files a/gfx/menu/wickedx/colorbutton_f.tga and b/gfx/menu/wickedx/colorbutton_f.tga differ
old mode 100755 (executable)
new mode 100644 (file)
index 7fec859..26e6da5
Binary files a/gfx/menu/wickedx/colorbutton_n.tga and b/gfx/menu/wickedx/colorbutton_n.tga differ
index 15605128588e79c4e3c73c4f647a3e518837ea50..c5062d91a17be5c381a151a25d3deb861100d02c 100755 (executable)
@@ -46,6 +46,7 @@ ALPHA_BACKGROUND_INGAME         1
 ALPHA_DISABLED                  0.2
 ALPHA_BEHIND                    0.5
 ALPHA_TEXT                      0.7
+COLOR_TEXT                      '1 1 1'
 
 // mouse
 //   uses "cursor" images
@@ -67,6 +68,7 @@ MARGIN_TOOLTIP                  '8 8 0'
 BORDER_TOOLTIP                  '16 16 0'
 FONTSIZE_TOOLTIP                12
 ALPHA_TOOLTIP                   0.7
+COLOR_TOOLTIP                   '1 1 1'
 WIDTH_TOOLTIP                   0.3
 AVOID_TOOLTIP                   '8 8 0'
 
@@ -133,6 +135,8 @@ COLOR_SERVERLIST_HIGHPING       '1 0 0'
 ALPHA_SERVERLIST_HIGHPING       0.4
 ALPHA_SERVERLIST_FAVORITE       0.8
 COLOR_SERVERLIST_FAVORITE       '1 1 1'
+ALPHA_SERVERLIST_CATEGORY       0.7
+COLOR_SERVERLIST_CATEGORY       '1 1 1'
 
 // item: skin list
 COLOR_SKINLIST_TITLE            '1 1 1'
@@ -204,7 +208,6 @@ ALPHA_KEYGRABBER_KEYS           0.7
 
 // item: player color button
 //   uses "colorbutton" images
-//   uses "color" images
 
 // item: player name editor
 //   uses "charmap" images
diff --git a/gfx/menu/xaw/color.tga b/gfx/menu/xaw/color.tga
deleted file mode 100644 (file)
index c7d2fbd..0000000
Binary files a/gfx/menu/xaw/color.tga and /dev/null differ
index e3b92d15fe263e45b95914cc5e0fde4e74e5f3d0..c12daf484aef4ba62aa4ada30741788a257ddcb2 100644 (file)
Binary files a/gfx/menu/xaw/colorbutton_c.tga and b/gfx/menu/xaw/colorbutton_c.tga differ
index 31912d79536c50d53d4fa64fb7d08db2b4b72b80..1c737dc9d785535dfdd4ebfe6ac11a60b00eb19e 100644 (file)
Binary files a/gfx/menu/xaw/colorbutton_f.tga and b/gfx/menu/xaw/colorbutton_f.tga differ
index 5d678a6cd88fba822c3a0967ca3ae7e093ff1a8e..537f0254e17adb0065458b0384c5f7c1d87e33b2 100644 (file)
Binary files a/gfx/menu/xaw/colorbutton_n.tga and b/gfx/menu/xaw/colorbutton_n.tga differ
index 3bd555f031ed32255e35cec19596893bfc5597dc..2dc86f698f19f531bfcf7aa99798fcc8d051f8b5 100644 (file)
@@ -14,6 +14,7 @@ MARGIN_TOOLTIP                  '5 5 0'
 BORDER_TOOLTIP                  '1 1 0'
 FONTSIZE_TOOLTIP                12
 ALPHA_TOOLTIP                   0.7
+COLOR_TOOLTIP                   '1 1 1'
 WIDTH_TOOLTIP                   0.3
 AVOID_TOOLTIP                   '8 8 0'
 
@@ -61,6 +62,7 @@ ALPHA_BACKGROUND_INGAME         0
 ALPHA_DISABLED                  0.2
 ALPHA_BEHIND                    1
 ALPHA_TEXT                      0.7
+COLOR_TEXT                      '1 1 1'
 
 // item: button
 //   uses "button" images
@@ -163,7 +165,6 @@ ALPHAS_MAINMENU                 '1 1 1'
 
 // item: player color button
 //   uses "colorbutton" images
-//   uses "color" images
 
 // item: player model
 COLOR_MODELTITLE                '1 1 1'
@@ -197,6 +198,8 @@ COLOR_SERVERLIST_HIGHPING       '1 0 0'
 ALPHA_SERVERLIST_HIGHPING       0.2
 ALPHA_SERVERLIST_FAVORITE       0.8
 COLOR_SERVERLIST_FAVORITE       '1 1 1'
+ALPHA_SERVERLIST_CATEGORY       0.7
+COLOR_SERVERLIST_CATEGORY       '1 1 1'
 
 // item: server info
 COLOR_SERVERINFO_NAME           '1 1 1'
index 4ed1381201a350b10cc7a0442120af1687d892eb..919d2ead2c70caaaf702f06314fe44b66732dd0c 100644 (file)
@@ -9,18 +9,18 @@
 // after exec'ing them all from your autoexec.cfg
 
 // Set the cvars for each gun
-seta cl_swapattacks_laser 0
+seta cl_swapattacks_blaster 0
 seta cl_swapattacks_shotgun 0
-seta cl_swapattacks_uzi 0
-seta cl_swapattacks_grenadelauncher 0
+seta cl_swapattacks_machinegun 0
+seta cl_swapattacks_mortar 0
 seta cl_swapattacks_minelayer 0
 seta cl_swapattacks_electro 0
 seta cl_swapattacks_crylink 0
-seta cl_swapattacks_nex 0
+seta cl_swapattacks_vortex 0
 seta cl_swapattacks_hagar 0
-seta cl_swapattacks_rocketlauncher 0
+seta cl_swapattacks_devastator 0
 seta cl_swapattacks_porto 0
-seta cl_swapattacks_minstanex 0
+seta cl_swapattacks_vaporizer 0
 seta cl_swapattacks_hook 0
 seta cl_swapattacks_hlac 0
 seta cl_swapattacks_tuba 0
@@ -28,6 +28,14 @@ seta cl_swapattacks_rifle 0
 seta cl_swapattacks_fireball 0
 seta cl_swapattacks_seeker 0
 
+// Backwards compatibility with 0.7.0
+alias cl_swapattacks_laser $cl_swapattacks_blaster
+alias cl_swapattacks_rocketlauncher $cl_swapattacks_devastator
+alias cl_swapattacks_uzi $cl_swapattacks_machinegun
+alias cl_swapattacks_grenadelauncher $cl_swapattacks_mortar
+alias cl_swapattacks_minstanex $cl_swapattacks_vaporizer
+alias cl_swapattacks_nex $cl_swapattacks_vortex
+
 // This part of the code is necessary to keep us firing when we switch weapons while holding a fire button pressed
 // Also updates the keys before firing, so we don't have to switch to another weapon and back to apply the changes
 set fire_last 0
@@ -48,7 +56,7 @@ alias firing_decision_1 "alias +checkattack +attack2; alias -checkattack -attack
 alias firing_swap_apply "firing_decision_${$1}"
 alias firing_swap "firing_swap_apply cl_swapattacks_$1; set firing_lastweapon cl_swapattacks_$1; firing_switch"
 
-// Not correct, but prevents firing from braking after executing the script until switching weapons
+// Not correct, but prevents firing from breaking after executing the script until switching weapons
 alias +fire +attack
 alias -fire -attack
 alias +fire2 +attack2
index f2b4fa4bd8504dca76aae7b705b2d948614518c0..f3bc914e6a48be696bd9e3b8879eb90d9ab0254f 100644 (file)
@@ -126,6 +126,7 @@ seta hud_panel_notify_flip "0"
 seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer 1
 seta hud_panel_timer_pos "0.800000 0.040000"
@@ -295,4 +296,14 @@ seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "0.5"
 seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
 seta hud_panel_centerprint_fade_minfontsize "0"
 
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
 menu_sync
index c401132ac3d2fe00f44ca3d1c3da806f85ea6a5b..050689b38caf95d525f07e83f378649fc49dafff 100644 (file)
@@ -126,6 +126,7 @@ seta hud_panel_notify_flip "1"
 seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer 1
 seta hud_panel_timer_pos "0.435000 0"
@@ -295,4 +296,14 @@ seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "0.5"
 seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
 seta hud_panel_centerprint_fade_minfontsize "0"
 
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
 menu_sync
index 518492ed4a7998973481221c835453a6f4d71bab..8fb6cbe93da88fd67f099c634126551449435fdf 100644 (file)
@@ -126,6 +126,7 @@ seta hud_panel_notify_flip "1"
 seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer 1
 seta hud_panel_timer_pos "0.435000 0"
@@ -295,4 +296,14 @@ seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "0.5"
 seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
 seta hud_panel_centerprint_fade_minfontsize "0"
 
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
 menu_sync
index 0a5f05955ef8d1a24b1fd5dbcbc95db0e8de84bf..9d71e2e2872cc4f4d6e0624a2d2b5e74064fa5cf 100644 (file)
@@ -126,6 +126,7 @@ seta hud_panel_notify_flip "0"
 seta hud_panel_notify_fontsize "0.8"
 seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer 1
 seta hud_panel_timer_pos "0.870000 0"
@@ -295,4 +296,14 @@ seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "0.5"
 seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
 seta hud_panel_centerprint_fade_minfontsize "0"
 
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
 menu_sync
index acf3ad921e84dd874a96f9b8bd6ca8d4253679ee..9e4678293d627419612564b5d12d91a4365d56fc 100644 (file)
@@ -126,6 +126,7 @@ seta hud_panel_notify_flip "0"
 seta hud_panel_notify_fontsize "1"
 seta hud_panel_notify_time "10"
 seta hud_panel_notify_fadetime "3"
+seta hud_panel_notify_icon_aspect "2"
 
 seta hud_panel_timer 1
 seta hud_panel_timer_pos "0.850000 0"
@@ -295,4 +296,14 @@ seta hud_panel_centerprint_fade_subsequent_passtwo_minalpha "0.5"
 seta hud_panel_centerprint_fade_subsequent_minfontsize "0.75"
 seta hud_panel_centerprint_fade_minfontsize "0"
 
+seta hud_panel_buffs 1
+seta hud_panel_buffs_pos "0.450000 0.855000"
+seta hud_panel_buffs_size "0.050000 0.070000"
+seta hud_panel_buffs_bg "0"
+seta hud_panel_buffs_bg_color ""
+seta hud_panel_buffs_bg_color_team ""
+seta hud_panel_buffs_bg_alpha ""
+seta hud_panel_buffs_bg_border ""
+seta hud_panel_buffs_bg_padding ""
+
 menu_sync
index 22f021434183f8611ae0307dc1b2314874ef6292..95d24acdbd67f30279c8f2f18aa94134dd2838a4 100644 (file)
@@ -58,6 +58,7 @@
 "dropweapon"                            "drop weapon"
 "+use"                                  "drop key / drop flag"
 "+button8"                              "drag object"
+"toggle chase_active"                   "3rd person view"
 ""                                      ""
 ""                                      "User defined"
 "+userbind 1"                           "$userbind1"
index 2aac70080a7e53e8e051ad6d7b2f470a2a631e7b..85d34b95723301db8d66a21e5b65341d33ca2ef4 100644 (file)
 "messagemode2"                          "Nachricht ans Team"
 "team_auto"                             "Team automatisch wählen"
 "menu_showteamselect"                   "Team auswählen"
-"menu_showsandboxtools"                 "Sandbox-Menu"
+"menu_showsandboxtools"                 "Sandkasten menu"
 "spec"                                  "Zuschauen"
 "dropweapon"                            "Waffe wegwerfen"
 "+use"                                  "Schlüssel oder Flagge wegwerfen"
 "+button8"                              "Objekt ziehen"
+"toggle chase_active"                   "Schultercamera"
 ""                                      ""
 ""                                      "Benutzerdefiniert"
 "+userbind 1"                           "$userbind1"
index 55c82cd3f7405b9efb36a84c495402231125d33b..0c3b8364c203f1e130de8c9d092b96f311ad17fa 100644 (file)
@@ -58,6 +58,7 @@
 "dropweapon"                            "soltar arma"
 "+use"                                  "soltar llave / soltar bandera"
 "+button8"                              "drag object (FIXME)"
+"toggle chase_active"                   "3rd person view (FIXME)"
 ""                                      ""
 ""                                      "Definido por el usuario"
 "+userbind 1"                           "$userbind1"
index 4693e38686428f1a52a98f336d286383d5d1a88d..17ac95409331156a0b3d4973815b055379a2d10b 100644 (file)
 "weaplast"                              "dernière utilisée"
 "weapbest"                              "meilleure arme"
 "reload"                                "recharger"
-"weapon_group_1"                        "laser"
-"weapon_group_2"                        "shotgun"
-"weapon_group_3"                        "machine gun / rifle"
-"weapon_group_4"                        "mortar"
-"weapon_group_5"                        "electro"
-"weapon_group_6"                        "crylink / hlac"
-"weapon_group_7"                        "nex / minstanex"
-"weapon_group_8"                        "hagar"
-"weapon_group_9"                        "rocket launcher / fireball"
-"weapon_group_0"                        "porto / hook"
+"weapon_group_1"                        "Laser"
+"weapon_group_2"                        "Fusil"
+"weapon_group_3"                        "Mitrailleuse"
+"weapon_group_4"                        "Mortier / Poseur de Mines"
+"weapon_group_5"                        "Electro"
+"weapon_group_6"                        "Crylink / HLAC"
+"weapon_group_7"                        "Nex / Fusil de précision"
+"weapon_group_8"                        "Hagar / Seeker"
+"weapon_group_9"                        "Lance-roquettes / Fireball"
+"weapon_group_0"                        "Port-O-Launch / Grappin"
 ""                                      ""
 ""                                      "Vue"
-"+zoom"                                 "zoom clic enfoncé"
+"+zoom"                                 "zoom"
 "togglezoom"                            "zoom 2 clics"
-"+showscores"                           "montrer les scores (enfoncé)"
+"+showscores"                           "afficher les scores"
 "screenshot"                            "capture d'écran"
-"+hud_panel_radar_maximized"            "maximize radar (FIXME)"
+"+hud_panel_radar_maximized"            "agrandir le radar"
 ""                                      ""
-""                                      "Communiquer"
-"messagemode"                           "chat public"
-"messagemode2"                          "chat d'équipe"
-"+con_chat_maximize"                    "historique du chat (enfoncé)"
+""                                      "Communication"
+"messagemode"                           "tchat public"
+"messagemode2"                          "tchat d'équipe"
+"+con_chat_maximize"                    "historique du tchat"
 "vyes"                                  "voter OUI"
 "vno"                                   "voter NON"
-"ready"                                 "prêt (en mode échauffement)"
+"ready"                                 "prêt"
 ""                                      ""
-""                                      "Joueur"
+""                                      "Client"
 "+show_info"                            "information serveur"
 "toggleconsole"                         "ouvrir la console"
 "disconnect"                            "se déconnecter"
 "menu_showquitdialog"                   "quitter"
 ""                                      ""
 ""                                      "Équipe"
-"messagemode2"                          "chat d'équipe"
+"messagemode2"                          "tchat d'équipe"
 "team_auto"                             "auto-joindre une équipe"
-"menu_showteamselect"                   "séléction d'équipe"
-"menu_showsandboxtools"                 "sandbox menu (FIXME)"
+"menu_showteamselect"                   "sélection d'équipe"
+"menu_showsandboxtools"                 "menu bac à sable"
 "spec"                                  "mode spectateur"
 "dropweapon"                            "lâcher l'arme"
-"+use"                                  "lâcher la clé / lâcher le drapeau"
-"+button8"                              "drag object (FIXME)"
+"+use"                                  "lâcher la clef / drapeau"
+"+button8"                              "traîner l'objet"
+"toggle chase_active"                   "vue à la 3ème personne"
 ""                                      ""
-""                                      "Utilisateur"
+""                                      "Raccourcis personnalisés"
 "+userbind 1"                           "$userbind1"
 "+userbind 2"                           "$userbind2"
 "+userbind 3"                           "$userbind3"
index 74d96470be0b5161ace4cf64ad9b47e6234ddb74..c4e418d120fef0551819ecc39dfe180a79b1c2ff 100644 (file)
@@ -58,6 +58,7 @@
 "dropweapon"                            "fegyver eldobás"
 "+use"                                  "zászló eldobás, kiszállás"
 "+button8"                              "drag object"
+"toggle chase_active"                   "3rd person view (FIXME)"
 ""                                      ""
 ""                                      "Felhasználói hozzárendelések"
 "+userbind 1"                           "$userbind1"
index 87d7840295d1bd6db9f04778c6e8e390152ab58e..e46ef92440616e732199569bf175ba717b8042d6 100644 (file)
@@ -58,6 +58,7 @@
 "dropweapon"                            "abbandona arma"
 "+use"                                  "abbandona chiave / bandiera"
 "+button8"                              "trascina oggetto"
+"toggle chase_active"                   "3rd person view (FIXME)"
 ""                                      ""
 ""                                      "Definiti dall'utente"
 "+userbind 1"                           "$userbind1"
index 4d4221a205d648285049e6e6fd39ef97ff321071..3431c25f67e721fec122dfea5a8b5e37167b430d 100644 (file)
@@ -58,6 +58,7 @@
 "dropweapon"                            "бросить оружие"
 "+use"                                  "бросить ключ или флаг"
 "+button8"                              "drag object"
+"toggle chase_active"                   "3rd person view (FIXME)"
 ""                                      ""
 ""                                      "Определенно пользователем"
 "+userbind 1"                           "$userbind1"
index 02b4e579b24b0e95741eb86ffd2e2596433515eb..eae9049c1dddfe833b867b90d042eda509ae4c47 100644 (file)
@@ -58,6 +58,7 @@
 "dropweapon"                            "викинути зброю"
 "+use"                                  "викинути ключ / прапор"
 "+button8"                              "drag object"
+"toggle chase_active"                   "3rd person view (FIXME)"
 ""                                      ""
 ""                                      "Визначені користувачем"
 "+userbind 1"                           "$userbind1"
diff --git a/models/domination/dom_axe.tga b/models/domination/dom_axe.tga
new file mode 100644 (file)
index 0000000..d6e94cf
Binary files /dev/null and b/models/domination/dom_axe.tga differ
diff --git a/models/domination/dom_axe_glow.tga b/models/domination/dom_axe_glow.tga
new file mode 100644 (file)
index 0000000..d6e94cf
Binary files /dev/null and b/models/domination/dom_axe_glow.tga differ
diff --git a/models/domination/dom_bolt.tga b/models/domination/dom_bolt.tga
new file mode 100644 (file)
index 0000000..d5d36ee
Binary files /dev/null and b/models/domination/dom_bolt.tga differ
diff --git a/models/domination/dom_bolt_glow.tga b/models/domination/dom_bolt_glow.tga
new file mode 100644 (file)
index 0000000..d5d36ee
Binary files /dev/null and b/models/domination/dom_bolt_glow.tga differ
index 3b8198a6d30b4f308a84f7f4aa6df8b061b0fe70..103276d0be776e382b738f48d2b264912eea07f0 100644 (file)
@@ -3,6 +3,7 @@ species human
 sex Male
 weight 105
 age 26
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
@@ -10,5 +11,3 @@ bone_aim2 0.2 upperarm_L
 bone_aim3 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index 2f864a686e7887ae788d7718d742a3df7b4528e8..27b579027f93063f207b8fbf849e538a7ea4dff3 100644 (file)
@@ -3,11 +3,10 @@ species alien
 sex Male
 weight 85
 age 16
+description Lightweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Lightweight Xonotic Solider
index d561d64800c737dbd56f117de3fcee61d8a7db69..46977b885488e8214865814686a7293dca180f15 100644 (file)
@@ -3,11 +3,10 @@ species alien
 sex Male
 weight 90
 age 20
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index 10aeee8e16808386ba2318d3e446d07cee30e92b..44843b7058baf5ccd13a0e37c88694b99620f9a1 100644 (file)
@@ -3,11 +3,10 @@ species alien
 sex Male
 weight 87
 age 18
+description Mediumweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Mediumweight Xonotic Solider
index 6744e652a56af85d517bfb2ef39a77a7b0dabb28..981562cfcf28bbcb5784ed3a4a3c9f31c5eaf794 100644 (file)
@@ -3,6 +3,7 @@ species human
 sex Male
 weight 88
 age 31
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
@@ -10,5 +11,3 @@ bone_aim2 0.2 upperarm_L
 bone_aim3 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index c956630f33bb961f2f237497e9700c3f4ac7fbaf..01c99adf0b7dacce11a5f34b67f52b6c5fb23b12 100644 (file)
@@ -3,6 +3,7 @@ species human
 sex Male
 weight 90
 age 31
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
@@ -10,5 +11,3 @@ bone_aim2 0.2 upperarm_L
 bone_aim3 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index e89ead1dab4bdaa4d725868d4180b4c44971aab7..2610d2b92db356797a22a0b52605efc304c05f41 100644 (file)
@@ -3,6 +3,7 @@ species human
 sex Male
 weight 92
 age 31
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
@@ -10,5 +11,3 @@ bone_aim2 0.2 upperarm_L
 bone_aim3 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index c2d811779c83544114b45874844d3698edbb0898..f75a15fb8ef55b3cf7b06abeaec7ba451ae9ab9f 100644 (file)
@@ -3,6 +3,7 @@ species human
 sex Male
 weight 210
 age 26
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
@@ -10,5 +11,3 @@ bone_aim2 0.2 upperarm_L
 bone_aim3 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index 50f41f35e5dbe3344d6d2a9645903e9fd8cf6c9e..ba14c232a63c85f3cf6071d35ce218884dadf33f 100644 (file)
@@ -3,11 +3,10 @@ species human
 sex Female
 weight 100
 age 24
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Soldier
index 489571a91a51998e0519c863be828442d82283cb..e8a6c90446eb9192a7c7ce5ae58e5c622896ae22 100644 (file)
@@ -3,11 +3,10 @@ species human
 sex Female
 weight 57
 age 53
+description Necro Warrior
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Necro Warrior
index fc5a62b248af63bbd1884718cff76a5e94d66db7..f7b07b0e67cca74072b7d92eadf8b525348c628c 100644 (file)
@@ -3,11 +3,10 @@ species human
 sex Female
 weight 89
 age 31
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index 2a48e8d4e552144d7a9a65ee4ddb3f21dc2f9d69..c997d01f36488d7771766fe38956f883b8bcc9bc 100644 (file)
@@ -3,11 +3,10 @@ species human
 sex Female
 weight 90
 age 31
+description Heavyweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Heavyweight Xonotic Solider
index c5933c1ab601576e6929efbac9ed42a70cbc72ee..25ce2d07c6698f856bd2a79c891645df8ccae3a9 100644 (file)
@@ -3,11 +3,10 @@ species human
 sex Female
 weight 61
 age 25
+description Lightweight Xonotic Soldier
 bone_upperbody spine2
 bone_aim0 0.25 spine2
 bone_aim1 0.4 spine4
 bone_aim2 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
-
-Lightweight Xonotic Solider
diff --git a/models/weapons/g_arc_simple.iqm b/models/weapons/g_arc_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_arc_simple.iqm differ
diff --git a/models/weapons/g_arc_simple.iqm_0.skin b/models/weapons/g_arc_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..df43c61
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_arc_simple
\ No newline at end of file
diff --git a/models/weapons/g_arc_simple.tga b/models/weapons/g_arc_simple.tga
new file mode 100644 (file)
index 0000000..2e94008
Binary files /dev/null and b/models/weapons/g_arc_simple.tga differ
diff --git a/models/weapons/g_campingrifle_simple.iqm b/models/weapons/g_campingrifle_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_campingrifle_simple.iqm differ
diff --git a/models/weapons/g_campingrifle_simple.iqm_0.skin b/models/weapons/g_campingrifle_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..6b2726f
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_campingrifle_simple
\ No newline at end of file
diff --git a/models/weapons/g_campingrifle_simple.tga b/models/weapons/g_campingrifle_simple.tga
new file mode 100644 (file)
index 0000000..2a9c449
Binary files /dev/null and b/models/weapons/g_campingrifle_simple.tga differ
index f4054b7beca99c12d8bce595362efa95b4a05a5d..0bbdbc7bfa892c8a2ad2aa53facb44f06d4e3949 100644 (file)
Binary files a/models/weapons/g_crylink_simple.tga and b/models/weapons/g_crylink_simple.tga differ
index b523c722e32a60c0df4d60f82c1d5c13bfddce07..02c67de755bd6d3b443b798697ac8f4d68605ed7 100644 (file)
Binary files a/models/weapons/g_electro_simple.tga and b/models/weapons/g_electro_simple.tga differ
diff --git a/models/weapons/g_fireball_simple.iqm b/models/weapons/g_fireball_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_fireball_simple.iqm differ
diff --git a/models/weapons/g_fireball_simple.iqm_0.skin b/models/weapons/g_fireball_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..cceb6a6
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_fireball_simple
\ No newline at end of file
diff --git a/models/weapons/g_fireball_simple.tga b/models/weapons/g_fireball_simple.tga
new file mode 100644 (file)
index 0000000..2632b76
Binary files /dev/null and b/models/weapons/g_fireball_simple.tga differ
index e138aa42e71c1776426d63f632882f9fcf46c168..114c6f25f5431c8a2649161b2e1d220c1570075d 100644 (file)
Binary files a/models/weapons/g_gl_simple.tga and b/models/weapons/g_gl_simple.tga differ
index 4c82e4beee45ac267cf24ecfb47b70274e4183df..fb99dea73952998b8e23e578b6c1d554ffb3e9e4 100644 (file)
Binary files a/models/weapons/g_hagar_simple.tga and b/models/weapons/g_hagar_simple.tga differ
diff --git a/models/weapons/g_hlac_simple.iqm b/models/weapons/g_hlac_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_hlac_simple.iqm differ
diff --git a/models/weapons/g_hlac_simple.iqm_0.skin b/models/weapons/g_hlac_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..020dcc1
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_hlac_simple
\ No newline at end of file
diff --git a/models/weapons/g_hlac_simple.tga b/models/weapons/g_hlac_simple.tga
new file mode 100644 (file)
index 0000000..6d2302c
Binary files /dev/null and b/models/weapons/g_hlac_simple.tga differ
diff --git a/models/weapons/g_hookgun_simple.iqm b/models/weapons/g_hookgun_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_hookgun_simple.iqm differ
diff --git a/models/weapons/g_hookgun_simple.iqm_0.skin b/models/weapons/g_hookgun_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..2c8bd5f
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_hookgun_simple
\ No newline at end of file
diff --git a/models/weapons/g_hookgun_simple.tga b/models/weapons/g_hookgun_simple.tga
new file mode 100644 (file)
index 0000000..be44b81
Binary files /dev/null and b/models/weapons/g_hookgun_simple.tga differ
diff --git a/models/weapons/g_laser_simple.iqm b/models/weapons/g_laser_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_laser_simple.iqm differ
diff --git a/models/weapons/g_laser_simple.iqm_0.skin b/models/weapons/g_laser_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..02e24bc
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_laser_simple
\ No newline at end of file
diff --git a/models/weapons/g_laser_simple.tga b/models/weapons/g_laser_simple.tga
new file mode 100644 (file)
index 0000000..66223a3
Binary files /dev/null and b/models/weapons/g_laser_simple.tga differ
diff --git a/models/weapons/g_minelayer_simple.iqm b/models/weapons/g_minelayer_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_minelayer_simple.iqm differ
diff --git a/models/weapons/g_minelayer_simple.iqm_0.skin b/models/weapons/g_minelayer_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..f9d4b61
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_minelayer_simple
\ No newline at end of file
diff --git a/models/weapons/g_minelayer_simple.tga b/models/weapons/g_minelayer_simple.tga
new file mode 100644 (file)
index 0000000..dfba264
Binary files /dev/null and b/models/weapons/g_minelayer_simple.tga differ
diff --git a/models/weapons/g_minstanex_simple.iqm b/models/weapons/g_minstanex_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_minstanex_simple.iqm differ
diff --git a/models/weapons/g_minstanex_simple.iqm_0.skin b/models/weapons/g_minstanex_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..3a255b4
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_minstanex_simple
\ No newline at end of file
diff --git a/models/weapons/g_minstanex_simple.tga b/models/weapons/g_minstanex_simple.tga
new file mode 100644 (file)
index 0000000..68bf311
Binary files /dev/null and b/models/weapons/g_minstanex_simple.tga differ
index 27c984f8a19a03899373e464c8941f9003709e4f..a254e962d8489f251301b43a9e00ecd22b632b40 100644 (file)
Binary files a/models/weapons/g_nex_simple.tga and b/models/weapons/g_nex_simple.tga differ
diff --git a/models/weapons/g_porto_simple.iqm b/models/weapons/g_porto_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_porto_simple.iqm differ
diff --git a/models/weapons/g_porto_simple.iqm_0.skin b/models/weapons/g_porto_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..944e14a
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_porto_simple
\ No newline at end of file
diff --git a/models/weapons/g_porto_simple.tga b/models/weapons/g_porto_simple.tga
new file mode 100644 (file)
index 0000000..aa6f6cd
Binary files /dev/null and b/models/weapons/g_porto_simple.tga differ
index d65fa8788b4030e21160c61fb0ef91dd971a0745..2ac19c8f53a2a9d5763fbc87a1699fb69f9a90e3 100644 (file)
Binary files a/models/weapons/g_rl_simple.tga and b/models/weapons/g_rl_simple.tga differ
diff --git a/models/weapons/g_seeker_simple.iqm b/models/weapons/g_seeker_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_seeker_simple.iqm differ
diff --git a/models/weapons/g_seeker_simple.iqm_0.skin b/models/weapons/g_seeker_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..5123515
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_seeker_simple
\ No newline at end of file
diff --git a/models/weapons/g_seeker_simple.tga b/models/weapons/g_seeker_simple.tga
new file mode 100644 (file)
index 0000000..322ee53
Binary files /dev/null and b/models/weapons/g_seeker_simple.tga differ
index 37da2f8629232c453e012071ff6bd1b27b76b78e..3c120c89ae6625827d3eb4e5fe2a8a25cea83888 100644 (file)
Binary files a/models/weapons/g_shotgun_simple.tga and b/models/weapons/g_shotgun_simple.tga differ
diff --git a/models/weapons/g_tuba_simple.iqm b/models/weapons/g_tuba_simple.iqm
new file mode 100644 (file)
index 0000000..a5cc3e6
Binary files /dev/null and b/models/weapons/g_tuba_simple.iqm differ
diff --git a/models/weapons/g_tuba_simple.iqm_0.skin b/models/weapons/g_tuba_simple.iqm_0.skin
new file mode 100644 (file)
index 0000000..3fd8bd8
--- /dev/null
@@ -0,0 +1 @@
+Plane,g_tuba_simple
\ No newline at end of file
diff --git a/models/weapons/g_tuba_simple.tga b/models/weapons/g_tuba_simple.tga
new file mode 100644 (file)
index 0000000..8af65e0
Binary files /dev/null and b/models/weapons/g_tuba_simple.tga differ
index d9b5df404a54bc6ec61a93aa41acd13c037ec319..55d68cd930f2e2dfb60bba49ade7772181dd12b6 100644 (file)
Binary files a/models/weapons/g_uzi_simple.tga and b/models/weapons/g_uzi_simple.tga differ
diff --git a/models/weapons/make-sprites.sh b/models/weapons/make-sprites.sh
new file mode 100755 (executable)
index 0000000..50f3fc6
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/bash
+
+baseline=20
+
+sprite()
+{
+       name=$1
+       text=$(echo $2) # Handle newlines
+       color=$3
+
+       echo $name
+
+       # Text
+       exec {FD}< <(convert \
+       -size 185x120 \
+       -background transparent \
+       -fill "#$color" \
+       -font BigNoodleTitling \
+       -interline-spacing -15 \
+       -gravity south \
+       label:"$text" \
+       -trim \
+       png:-)
+       itext=$FD
+
+       # Rectangles
+
+       # Thick
+       xa1=34
+       xa2=$((xa1+185-1))
+       ya1=174
+       ya2=$((ya1+37-1))
+
+       # Thin
+       xb1=34
+       xb2=$((xb1+185-1))
+       yb1=224
+       yb2=$((yb1+15-1))
+
+       exec {FD}< <(convert \
+       -size 256x256 \
+       -background transparent \
+       -fill "#$color" \
+       xc:none \
+       -draw "rectangle $xa1,$ya1 $xa2,$ya2" \
+       -draw "rectangle $xb1,$yb1 $xb2,$yb2" \
+       png:-)
+       irects=$FD
+
+       # Join
+
+       composite \
+       -gravity south \
+       -geometry -2+$((82+$baseline)) \
+       -compress RLE \
+       png:fd:$itext png:fd:$irects g_${name}_simple.tga
+}
+
+# grep '* color' ../../qcsrc/common/weapons/w_*.qc | awk '{ print $1 "  \t" $4 " " $5 " " $6 }'
+# def h(r,g,b): return '#{:02x}{:02x}{:02x}'.format(int(round(r*255)),int(round(g*255)),int(round(b*255)))
+sprite arc                     "Arc"                           ffffff # White
+sprite laser           "Blaster"                       ff8080 # Vivid Tangerine
+sprite crylink         "Crylink"                       ff80ff # Blush Pink
+sprite rl                      "Devastator"            ffff00 # Yellow
+sprite electro         "Electro"                       0080ff # Azure Radiance
+sprite fireball                "Fireball"                      ff8000 # Flush Orange
+sprite hagar           "Hagar"                         ffff80 # Dolly
+sprite hlac                    "HLAC"                          00ff00 # Green
+sprite hookgun         "Grappling\nHook"       008000 # Japanese Laurel
+sprite uzi                     "Machine\nGun"          ffff00 # Yellow
+sprite minelayer       "Mine\nLayer"           bfff00 # Lime
+sprite gl                      "Mortar"                        ff0000 # Red
+sprite porto           "Port-O-Launch"         808080 # Gray
+sprite campingrifle    "Rifle"                         80ff00 # Chartreuse
+sprite seeker          "T.A.G.\nSeeker"        80ff00 # Chartreuse
+#sprite shockwave      "Shockwave"                     804000 # Cinnamon
+sprite shotgun         "Shotgun"                       804000 # Cinnamon
+sprite tuba                    "Tuba"                          00ff00 # Green
+sprite minstanex       "Vaporizer"                     80ffff # Anakiwa
+sprite nex                     "Vortex"                        80ffff # Anakiwa
index c762ef9dec047aaa26cebd9320da67e40aad6aef..63a4356b82e1a686cee946135e3d3e8b61849837 100644 (file)
@@ -23,14 +23,14 @@ set sv_dodging_frozen 0 "allow dodging while frozen"
 
 
 // ===========
-//  minstagib
+//  instagib
 // ===========
-set g_minstagib 0 "enable minstagib"
-set g_minstagib_extralives 1 "how many extra lives you will get per powerup"
-set g_minstagib_ammo_start 10 "starting ammo"
-set g_minstagib_ammo_drop 5 "how much ammo you'll get for weapons or cells"
-set g_minstagib_invis_alpha 0.15
-set g_minstagib_speed_highspeed 1.5 "speed-multiplier that applies while you carry the invincibility powerup"
+set g_instagib 0 "enable instagib"
+set g_instagib_extralives 1 "how many extra lives you will get per powerup"
+set g_instagib_ammo_start 10 "starting ammo"
+set g_instagib_ammo_drop 5 "how much ammo you'll get for weapons or cells"
+set g_instagib_invis_alpha 0.15
+set g_instagib_speed_highspeed 1.5 "speed-multiplier that applies while you carry the invincibility powerup"
 
 
 // =========
@@ -138,10 +138,11 @@ set g_random_gravity_negative 1000 "negative gravity multiplier"
 
 
 // =======
-//  nades
+//  Nades
 // =======
 set g_nades 0 "enable off-hand grenades"
 set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire"
+set g_nades_client_select 0 "allow client side selection of nade type"
 set g_nades_nade_lifetime 3.5
 set g_nades_nade_minforce 400
 set g_nades_nade_maxforce 2000
@@ -152,6 +153,73 @@ set g_nades_nade_edgedamage 90
 set g_nades_nade_radius 300
 set g_nades_nade_force 650
 set g_nades_nade_newton_style 0
+set g_nades_nade_type 1 "Type of the off-hand grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade"
+
+seta cl_nade_timer 1 "show a visual timer for nades, 1 = only circle, 2 = circle with text"
+seta cl_nade_type 3
+seta cl_pokenade_type "zombie"
+
+// ------------
+//  Nade bonus
+// ------------
+//
+// How the nade bonus system works:
+// Each player has a score counter that is increased by some actions (eg: capping, fragging...)
+// Once this counter reaches its maximum, the player will receive a bonus grenade and the score counter resets
+// If the player dies all the bonus nades will be lost and the score counter resets
+// If g_nades_bonus_score_time is not zero, this score will increase or decrease over time
+//
+set g_nades_bonus 0 "Enable bonus grenades"
+set g_nades_bonus_client_select 0 "Allow client side selection of bonus nade type"
+set g_nades_bonus_type 2 "Type of the bonus grenade. 1:normal 2:napalm 3:ice 4:translocate 5:spawn 6:heal 7:pokenade"
+set g_nades_bonus_onstrength 1 "Always give bonus grenades to players that have the strength powerup"
+set g_nades_bonus_max 3 "Maximum number of bonus grenades"
+// Bonus score
+set g_nades_bonus_score_max   120 "Score value that will give a bonus nade"
+set g_nades_bonus_score_minor   5 "Score given for minor actions (pickups, regular frags etc.)"
+set g_nades_bonus_score_low    20 "Score given for frags and unfreezes"
+set g_nades_bonus_score_medium 30 "Score given for flag returns and flag carrier kills"
+set g_nades_bonus_score_high   60 "Score given for flag captures"
+set g_nades_bonus_score_spree  40 "Score given every spree of this many frags"
+set g_nades_bonus_score_time   -1 "Bonus nade score given per second (negative to have the score decay)"
+set g_nades_bonus_score_time_flagcarrier 2 "Bonus nade score given per second as flag carrier (negative to have the score decay)"
+
+// Napalm (2)
+set g_nades_napalm_blast 1 "Whether the napalm grenades also give damage with the usual grenade explosion"
+set g_nades_napalm_burntime 0.5 "Time that the fire from napalm will stick to the player"
+set g_nades_napalm_selfdamage 1 "Whether the player that tossed the nade can be harmed by its fire"
+// Napalm fireballs
+set g_nades_napalm_ball_count 6 "Number of fireballs emitted during the explosion"
+set g_nades_napalm_ball_spread 500 "Maximum force which the fireballs will have on explosion"
+set g_nades_napalm_ball_damageforcescale 4
+set g_nades_napalm_ball_damage 40
+set g_nades_napalm_ball_lifetime 7
+set g_nades_napalm_ball_radius 100 "Distance from the fireball within which you may get burned"
+// Napalm Fire fountain
+set g_nades_napalm_fountain_lifetime 3 "Time period during which extra fire mines are ejected"
+set g_nades_napalm_fountain_delay 0.5 "Delay between emissions by the fountain"
+set g_nades_napalm_fountain_damage 50 "Damage caused by the center of the fountain"
+set g_nades_napalm_fountain_edgedamage 20 "Damage caused by the edge of the fountain"
+set g_nades_napalm_fountain_radius 130
+
+// Ice (3)
+set g_nades_ice_freeze_time 3 "How long the ice field will last"
+set g_nades_ice_health      0 "How much health the player will have after being unfrozen"
+set g_nades_ice_explode     0 "Whether the ice nade should explode again once the ice field dissipated"
+set g_nades_ice_teamcheck   0 "Don't freeze teammates"
+
+// Spawn (5)
+set g_nades_spawn_count 3 "Number of times player will spawn at their spawn nade explosion location"
+
+// Heal (6)
+set g_nades_heal_time 5 "How long the heling field will last"
+set g_nades_heal_rate 30 "Health given per second"
+set g_nades_heal_friend 1 "Multiplier of health given to team mates"
+set g_nades_heal_foe   -2 "Multiplier of health given to enemies"
+
+// Pokenade (7)
+set g_nades_pokenade_monster_lifetime 150 "How long pokenade monster will survive"
+set g_nades_pokenade_monster_type "zombie" "Monster to spawn"
 
 
 // ============
@@ -162,3 +230,50 @@ set g_campcheck_interval 10
 set g_campcheck_damage 100
 set g_campcheck_distance 1800
 
+
+// =======
+//  buffs
+// =======
+set cl_buffs_autoreplace 1 "automatically drop current buff when picking up another"
+set g_buffs 0 "enable buffs (requires buff items or powerups)"
+set g_buffs_waypoint_distance 1024 "maximum distance at which buff waypoint can be seen from item"
+set g_buffs_randomize 1 "randomize buff type when player drops buff"
+set g_buffs_random_lifetime 30 "re-spawn the buff again if it hasn't been touched after this time in seconds"
+set g_buffs_random_location 0 "randomize buff location on start and when reset"
+set g_buffs_random_location_attempts 10 "number of random locations a single buff will attempt to respawn at before giving up"
+set g_buffs_spawn_count 5 "how many buffs to spawn on the map if none exist already"
+set g_buffs_replace_powerups 1 "replace powerups on the map with random buffs"
+set g_buffs_cooldown_activate 5 "cooldown period when buff is first activated"
+set g_buffs_cooldown_respawn 3 "cooldown period when buff is reloading"
+set g_buffs_ammo 1 "ammo buff: infinite ammunition"
+set g_buffs_resistance 1 "resistance buff: greatly reduces damage taken"
+set g_buffs_resistance_blockpercent 0.7 "damage reduction multiplier, higher values mean less damage"
+set g_buffs_medic 1 "medic buff: increased regeneration speed, extra health, chance to survive a fatal attack"
+set g_buffs_medic_survive_chance 0.6 "multiplier chance of player surviving a fatal hit"
+set g_buffs_medic_survive_health 5 "amount of health player survives with after taking a fatal hit"
+set g_buffs_medic_rot 0.7 "health rot rate multiplier"
+set g_buffs_medic_max 1.5 "stable health medic limit multiplier"
+set g_buffs_medic_regen 1.7 "health medic rate multiplier"
+set g_buffs_vengeance 1 "vengeance buff: attackers also take damage"
+set g_buffs_vengeance_damage_multiplier 0.6 "amount of damage dealt the attacker takes when hitting a target with vengeance"
+set g_buffs_bash 1 "bash buff: increased knockback force and immunity to knockback"
+set g_buffs_bash_force 2 "bash force multiplier"
+set g_buffs_bash_force_self 1.2 "bash self force multiplier"
+set g_buffs_disability 1 "disability buff: attacks to players and monsters deal slowness (decreased movement/attack speed) for a few seconds"
+set g_buffs_disability_time 3 "time in seconds for target disability"
+set g_buffs_disability_speed 0.5 "player speed multiplier while disabled"
+set g_buffs_disability_rate 1.7 "player weapon rate multiplier while disabled"
+set g_buffs_speed 1 "speed buff: increased movement/attack/health regeneration speed, carrier takes slightly more damage"
+set g_buffs_speed_speed 1.7 "player speed multiplier while holding speed buff"
+set g_buffs_speed_rate 0.8 "player weapon rate multiplier while holding speed buff"
+set g_buffs_speed_damage_take 1.2 "damage taken multiplier while holding speed buff"
+set g_buffs_speed_regen 1.2 "regeneration speed multiplier while holding speed buff"
+set g_buffs_vampire 1 "vampire buff: attacks to players and monsters heal the carrier"
+set g_buffs_vampire_damage_steal 0.6 "damage stolen multiplier while holding vampire buff"
+set g_buffs_jump 1 "jump buff: greatly increased jump height"
+set g_buffs_jump_height 600 "jump height while holding jump buff"
+set g_buffs_flight 1 "flight buff: greatly decreased gravity"
+set g_buffs_flight_gravity 0.3 "player gravity multiplier while holding flight buff"
+set g_buffs_invisible 1 "invisible buff: carrier becomes invisible"
+set g_buffs_invisible_alpha 0.4 "player invisibility multiplier while holding invisible buff"
+
index f0650653d8b22f0a75d8381d088dd7b1a3e25d62..e9299f42fbbde54cfd5bcee1399e069f7c245e4e 100644 (file)
 // ********************************************** //
 
 // MSG_ANNCE notifications (count = 89):
-seta notification_ANNCE_ACHIEVEMENT_AIRSHOT "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_AMAZING "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_AWESOME "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_BOTLIKE "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_ELECTROBITCH "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_IMPRESSIVE "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_ACHIEVEMENT_YODA "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_BEGIN "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_03 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_05 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_10 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_15 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_20 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_25 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_KILLSTREAK_30 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MINSTAGIB_LASTSECOND "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MINSTAGIB_NARROWLY "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MINSTAGIB_TERMINATED "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_MULTIFRAG "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_2 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_3 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_4 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_5 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_6 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_7 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_8 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_9 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_10 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_2 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_3 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_4 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_5 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_GAMESTART_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_1 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_2 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_3 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_IDLE_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_1 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_2 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_3 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_KILL_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_1 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_2 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_3 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_RESPAWN_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_2 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_3 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_4 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_5 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_6 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_7 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_8 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_9 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_NUM_ROUNDSTART_10 "0" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_PREPARE "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_FRAG_1 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_FRAG_2 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_FRAG_3 "1" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_MIN_1 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_REMAINING_MIN_5 "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_TIMEOUT "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_VOTE_ACCEPT "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_VOTE_CALL "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
-seta notification_ANNCE_VOTE_FAIL "2" "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
+seta notification_ANNCE_ACHIEVEMENT_AIRSHOT "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_AMAZING "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_AWESOME "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_BOTLIKE "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_ELECTROBITCH "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_IMPRESSIVE "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_ACHIEVEMENT_YODA "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_BEGIN "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_03 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_05 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_10 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_15 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_20 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_25 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_KILLSTREAK_30 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MINSTAGIB_LASTSECOND "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MINSTAGIB_NARROWLY "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MINSTAGIB_TERMINATED "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_MULTIFRAG "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_4 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_5 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_6 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_7 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_8 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_9 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_10 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_4 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_5 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_GAMESTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_IDLE_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_KILL_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_1 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_2 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_3 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_RESPAWN_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_2 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_3 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_4 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_5 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_6 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_7 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_8 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_9 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_NUM_ROUNDSTART_10 "0" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_PREPARE "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_FRAG_1 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_FRAG_2 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_FRAG_3 "1" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_MIN_1 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_REMAINING_MIN_5 "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_TIMEOUT "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_VOTE_ACCEPT "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_VOTE_CALL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
+seta notification_ANNCE_VOTE_FAIL "2" "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
 
-// MSG_INFO notifications (count = 214):
-seta notification_INFO_CTF_CAPTURE_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_BROKEN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_BROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_TIME_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_TIME_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_UNBROKEN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_CAPTURE_UNBROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DAMAGED_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DAMAGED_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DROPPED_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_DROPPED_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_LOST_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_LOST_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_PICKUP_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_PICKUP_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_RETURN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_CTF_RETURN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_CHEAT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_DROWN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_FALL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_FIRE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_LAVA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_NADE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_SLIME "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_SWAMP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_TELEFRAG "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_BUMB_GUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_RAPT_CANNON "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_SPID_MINIGUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_WAKI_GUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_MURDER_VOID "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_AUTOTEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_BETRAYAL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_CAMP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_CHEAT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_CUSTOM "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_DROWN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_FALL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_FIRE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_GENERIC "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_LAVA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_NADE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_NOAMMO "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_ROT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SLIME "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_SWAMP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_EWHEEL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_FLAC "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_HELLION "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_HK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_MACHINEGUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_MLRS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_PHASER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_PLASMA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_TESLA "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_WALK_GUN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_WALK_MEELE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_TURRET_WALK_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_SELF_VOID "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_DEATH_TEAMKILL_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_FREEZE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_REVIVED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_REVIVED_FALL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_AUTO_REVIVED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TEAM_WIN_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_PLAYER_WIN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_TIED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ROUND_OVER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_FREEZETAG_SELF "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_GODMODE_OFF "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_DONTHAVE "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_DROP "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_GOT "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_NOAMMO "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_PRIMORSEC "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_ITEM_WEAPON_UNAVAILABLE "0" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_BLUE "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_YELLOW "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_CONNECT_TEAM_PINK "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_JOIN_PLAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEEPAWAY_DROPPED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEEPAWAY_PICKUP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_CAPTURE_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_DROP_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_LOST_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_KEYHUNT_PICKUP_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_LMS_FORFEIT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_LMS_NOLIVES "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_INVISIBILITY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_SHIELD "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_SPEED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_POWERUP_STRENGTH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_DISCONNECT "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_KICK_IDLING "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_KICK_SPECTATING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_QUIT_SPECTATE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_ABANDONED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_FAIL_RANKED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_FAIL_UNRANKED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_FINISHED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_BROKEN "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_IMPROVED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_MISSING_UID "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_RACE_NEW_SET "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_RED "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_BLUE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_YELLOW "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SCORES_PINK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SPECTATE_WARNING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_SUPERWEAPON_PICKUP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_VERSION_BETA "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_VERSION_OLD "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_VERSION_OUTDATED "2" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WATERMARK "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ACCORDEON_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ACCORDEON_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_CRYLINK_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_CRYLINK_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_MURDER_BOLT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_MURDER_COMBO "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_MURDER_ORBS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_SUICIDE_BOLT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ELECTRO_SUICIDE_ORBS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_MURDER_BLAST "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_MURDER_FIREMINE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_SUICIDE_BLAST "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HAGAR_MURDER_BURST "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HAGAR_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HAGAR_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HLAC_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HLAC_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_HOOK_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_KLEINBOTTLE_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_KLEINBOTTLE_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_LASER_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_LASER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MINELAYER_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MINELAYER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MINSTANEX_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_MURDER_BOUNCE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_MURDER_EXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_NEX_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_RIFLE_MURDER_PIERCING "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SEEKER_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SEEKER_MURDER_TAG "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SEEKER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SHOTGUN_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_SHOTGUN_MURDER_SLAP "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_THINKING_WITH_PORTALS "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_TUBA_MURDER "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_UZI_MURDER_SNIPE "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
-seta notification_INFO_WEAPON_UZI_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+// MSG_INFO notifications (count = 244):
+seta notification_INFO_CHAT_NOSPECTATORS "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_BROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_BROKEN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_TIME_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_TIME_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_UNBROKEN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_CAPTURE_UNBROKEN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_ABORTRUN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DAMAGED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DAMAGED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DROPPED_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_DROPPED_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_NEEDKILL_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_SPEEDRUN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_FLAGRETURN_TIMEOUT_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_LOST_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_MONSTER_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_CTF_RETURN_MONSTER_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_CHEAT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_DROWN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_FIRE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_LAVA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_MONSTER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_ICE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_ICE_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_SHOOTING_STAR "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_SLIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_SWAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_TELEFRAG "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_TOUCHEXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_BUMB_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_BUMB_GUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_CRUSH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_RAPT_BOMB "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_RAPT_CANNON "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_RAPT_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_SPID_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_SPID_MINIGUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_SPID_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_WAKI_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_WAKI_GUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VH_WAKI_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VENGEANCE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_MURDER_VOID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_AUTOTEAMCHANGE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_BETRAYAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_CAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_CHEAT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_CUSTOM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_DROWN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_FIRE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_GENERIC "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_LAVA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_MAGE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SHAMBLER_CLAW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SHAMBLER_SMASH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SHAMBLER_ZAP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_SPIDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_WYVERN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_ZOMBIE_JUMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_MON_ZOMBIE_MELEE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_ICE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_NOAMMO "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_ROT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SHOOTING_STAR "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SLIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_SWAMP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TEAMCHANGE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TOUCHEXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_EWHEEL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_FLAC "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_HELLION "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_HK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_MACHINEGUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_MLRS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_PHASER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_PLASMA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_TESLA "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_WALK_GUN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_WALK_MEELE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_TURRET_WALK_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_BUMB_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_CRUSH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_RAPT_BOMB "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_RAPT_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_SPID_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_SPID_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_WAKI_DEATH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VH_WAKI_ROCKET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_SELF_VOID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DEATH_TEAMKILL_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_DOMINATION_CAPTURE_TIME "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_FREEZE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_REVIVED_FALL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_REVIVED_NADE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_PLAYER_WIN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_TIED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ROUND_OVER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_FREEZETAG_SELF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_GODMODE_OFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF_LOST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF_DROP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_BUFF_GOT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_DONTHAVE "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_DROP "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_GOT "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_NOAMMO "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_PRIMORSEC "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_ITEM_WEAPON_UNAVAILABLE "0" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_RED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_BLUE "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_YELLOW "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_CONNECT_TEAM_PINK "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_JOIN_PLAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEEPAWAY_DROPPED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEEPAWAY_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_CAPTURE_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_DROP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_LOST_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_KEYHUNT_PICKUP_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_LMS_FORFEIT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_LMS_NOLIVES "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_MONSTERS_DISABLED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_INVISIBILITY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_SHIELD "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_SPEED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_POWERUP_STRENGTH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_DISCONNECT "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_KICK_IDLING "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_KICK_SPECTATING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_QUIT_SPECTATE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_ABANDONED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_FAIL_RANKED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_FAIL_UNRANKED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_FINISHED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_BROKEN "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_IMPROVED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_MISSING_UID "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_RACE_NEW_SET "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_RED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_BLUE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_YELLOW "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SCORES_PINK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SPECTATE_WARNING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_SUPERWEAPON_PICKUP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_TEAMCHANGE_LARGERTEAM "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_TEAMCHANGE_NOTALLOWED "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_VERSION_BETA "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_VERSION_OLD "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_VERSION_OUTDATED "2" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WATERMARK "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ACCORDEON_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ACCORDEON_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_CRYLINK_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_CRYLINK_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_MURDER_BOLT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_MURDER_COMBO "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_MURDER_ORBS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_SUICIDE_BOLT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ELECTRO_SUICIDE_ORBS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_MURDER_BLAST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_MURDER_FIREMINE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_SUICIDE_BLAST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HAGAR_MURDER_BURST "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HAGAR_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HAGAR_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HLAC_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HLAC_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_HOOK_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_KLEINBOTTLE_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_KLEINBOTTLE_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_LASER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_LASER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MINELAYER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MINELAYER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MINSTANEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_MURDER_BOUNCE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_MURDER_EXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_NEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_RIFLE_MURDER_PIERCING "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SEEKER_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SEEKER_MURDER_TAG "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SEEKER_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SHOTGUN_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_SHOTGUN_MURDER_SLAP "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_THINKING_WITH_PORTALS "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_TUBA_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_UZI_MURDER_SNIPE "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
+seta notification_INFO_WEAPON_UZI_MURDER_SPRAY "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 
-// MSG_CENTER notifications (count = 146):
-seta notification_CENTER_ASSAULT_ATTACKING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ASSAULT_DEFENDING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_BEGIN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_GAMESTART "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_ROUNDSTART "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_COUNTDOWN_ROUNDSTOP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TIED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_OVER "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CAMPCHECK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURESHIELD_FREE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURESHIELD_SHIELDED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURE_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_CAPTURE_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_FLAG_THROW_PUNISH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_OTHER_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_OTHER_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_RECEIVED_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_RECEIVED_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_REQUESTED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_REQUESTING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_SENT_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PASS_SENT_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_ENEMY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_ENEMY_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_TEAM "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_RETURN_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_RETURN_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_STALEMATE_CARRIER "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_CTF_STALEMATE_OTHER "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAGGED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAGGED_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_FRAG_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NADE_THROW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_AUTOTEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_BETRAYAL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_CAMP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_CHEAT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_CUSTOM "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_DROWN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_FALL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_FIRE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_GENERIC "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_LAVA "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_NADE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_NOAMMO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_ROT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SLIME "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SUICIDE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_SWAMP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TURRET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TURRET_EWHEEL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_TURRET_WALK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_SELF_VOID "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_TEAMKILL_FRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DEATH_TEAMKILL_FRAGGED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_DISCONNECT_IDLING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_EXTRALIVES "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_FREEZE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_FROZEN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_REVIVE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_REVIVE_FALL "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_REVIVED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_AUTO_REVIVED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ROUND_PLAYER_WIN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_SELF "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_FREEZETAG_SPAWN_LATE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_DONTHAVE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_DROP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_GOT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_NOAMMO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_PRIMORSEC "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_ITEM_WEAPON_UNAVAILABLE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_JOIN_NOSPAWNS "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_JOIN_PREVENT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEEPAWAY_DROPPED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEEPAWAY_PICKUP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEEPAWAY_WARN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_HELP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_INTERFERE_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_MEET "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_ROUNDSTART "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_SCAN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_START_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_KEYHUNT_WAIT "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MISSING_TEAMS "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MISSING_PLAYERS "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_FINDAMMO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_FINDAMMO_FIRST "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_LIVES_REMAINING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MINSTA_SECONDARY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_MOTD "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NIX_COUNTDOWN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NIX_NEWWEAPON "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_NADE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_OVERTIME_FRAG "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_OVERTIME_TIME "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_INVISIBILITY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_SHIELD "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_SPEED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERDOWN_STRENGTH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_INVISIBILITY "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_SHIELD "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_SPEED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_POWERUP_STRENGTH "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_RACE_FINISHLAP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_SUPERWEAPON_BROKEN "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_SUPERWEAPON_LOST "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_SUPERWEAPON_PICKUP "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_RED "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_BLUE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_YELLOW "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_PINK "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_AUTO "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_SPECTATE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TIMEOUT_BEGINNING "1" "Notification control cvar: 0 = off, 1 = centerprint"
-seta notification_CENTER_TIMEOUT_ENDING "1" "Notification control cvar: 0 = off, 1 = centerprint"
+// MSG_CENTER notifications (count = 161):
+seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_GAMESTART "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_ROUNDSTART "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_COUNTDOWN_ROUNDSTOP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TIED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_OVER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURESHIELD_FREE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURESHIELD_SHIELDED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURE_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_CAPTURE_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_FLAG_THROW_PUNISH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_OTHER_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_OTHER_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_RECEIVED_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_RECEIVED_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_REQUESTED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_REQUESTING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_SENT_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PASS_SENT_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_ENEMY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_ENEMY_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_TEAM "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_PICKUP_TEAM_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_RETURN_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_RETURN_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_STALEMATE_CARRIER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_CTF_STALEMATE_OTHER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAGGED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAGGED_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_FRAG_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NADE_THROW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NADE_BONUS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_AUTOTEAMCHANGE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_BETRAYAL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_CAMP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_CHEAT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_CUSTOM "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_DROWN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_FALL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_FIRE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_GENERIC "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_LAVA "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_MONSTER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE_NAPALM "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE_ICE_FREEZE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NADE_HEAL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_NOAMMO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_ROT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SHOOTING_STAR "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SLIME "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SUICIDE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_SWAMP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TEAMCHANGE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TOUCHEXPLODE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TURRET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TURRET_EWHEEL "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_TURRET_WALK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_BUMB_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_CRUSH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_RAPT_BOMB "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_RAPT_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_SPID_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_SPID_ROCKET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_WAKI_DEATH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VH_WAKI_ROCKET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_SELF_VOID "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_TEAMKILL_FRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DEATH_TEAMKILL_FRAGGED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DISCONNECT_IDLING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DOOR_LOCKED_NEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DOOR_LOCKED_ALSONEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_DOOR_UNLOCKED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_EXTRALIVES "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_FREEZE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_FROZEN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_REVIVE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_REVIVE_SELF "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_REVIVED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_AUTO_REVIVED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_TEAM_WIN_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ROUND_PLAYER_WIN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_SELF "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_FREEZETAG_SPAWN_LATE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_INVASION_SUPERMONSTER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_BUFF_DROP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_BUFF_GOT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_DONTHAVE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_DROP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_GOT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_NOAMMO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_PRIMORSEC "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ITEM_WEAPON_UNAVAILABLE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_JOIN_NOSPAWNS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_JOIN_PREVENT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_DROPPED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_PICKUP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_PICKUP_SELF "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEEPAWAY_WARN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_HELP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_INTERFERE_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_MEET "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_ROUNDSTART "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_SCAN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_START_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_KEYHUNT_WAIT "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MISSING_TEAMS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MISSING_PLAYERS "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_FINDAMMO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_FINDAMMO_FIRST "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_LIVES_REMAINING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MINSTA_SECONDARY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_MOTD "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NIX_COUNTDOWN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NIX_NEWWEAPON "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_NADE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_OVERTIME_FRAG "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_OVERTIME_TIME "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_INVISIBILITY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_SHIELD "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_SPEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERDOWN_STRENGTH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_INVISIBILITY "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_SHIELD "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_SPEED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_POWERUP_STRENGTH "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_RACE_FINISHLAP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SEQUENCE_COMPLETED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SEQUENCE_COUNTER "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SEQUENCE_COUNTER_FEWMORE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SUPERWEAPON_BROKEN "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SUPERWEAPON_LOST "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_SUPERWEAPON_PICKUP "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_RED "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_BLUE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_YELLOW "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_PINK "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_AUTO "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_SPECTATE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TIMEOUT_BEGINNING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_TIMEOUT_ENDING "1" "0 = off, 1 = centerprint"
 
-// MSG_MULTI notifications (count = 121):
-seta notification_DEATH_MURDER_CHEAT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_DROWN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_FALL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_FIRE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_LAVA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_NADE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_SLIME "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_SWAMP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_TELEFRAG "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_BUMB_GUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_RAPT_CANNON "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_SPID_MINIGUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_WAKI_GUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_MURDER_VOID "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_AUTOTEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_BETRAYAL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_CAMP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_CHEAT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_CUSTOM "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_DROWN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_FALL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_FIRE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_GENERIC "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_LAVA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_NADE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_NOAMMO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_ROT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SHOOTING_STAR "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SLIME "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_SWAMP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TEAMCHANGE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TOUCHEXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_EWHEEL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_FLAC "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_HELLION "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_HK "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_MACHINEGUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_MLRS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_PHASER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_PLASMA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_TESLA "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_WALK_GUN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_WALK_MEELE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_TURRET_WALK_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_BUMB_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_CRUSH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_RAPT_BOMB "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_RAPT_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_SPID_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_SPID_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_WAKI_DEATH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VH_WAKI_ROCKET "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_DEATH_SELF_VOID "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_DONTHAVE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_DROP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_GOT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_NOAMMO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_PRIMORSEC "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_ITEM_WEAPON_UNAVAILABLE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_MULTI_COUNTDOWN_BEGIN "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_MULTI_MINSTA_FINDAMMO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ACCORDEON_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ACCORDEON_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_CRYLINK_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_CRYLINK_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_MURDER_BOLT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_MURDER_COMBO "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_MURDER_ORBS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_SUICIDE_BOLT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ELECTRO_SUICIDE_ORBS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_MURDER_BLAST "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_MURDER_FIREMINE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_SUICIDE_BLAST "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HAGAR_MURDER_BURST "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HAGAR_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HAGAR_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HLAC_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HLAC_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_HOOK_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_KLEINBOTTLE_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_KLEINBOTTLE_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_LASER_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_LASER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MINELAYER_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MINELAYER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MINSTANEX_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_MURDER_BOUNCE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_MURDER_EXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_NEX_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER_HAIL "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_RIFLE_MURDER_PIERCING "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SEEKER_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SEEKER_MURDER_TAG "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SEEKER_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SHOTGUN_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_SHOTGUN_MURDER_SLAP "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_THINKING_WITH_PORTALS "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_TUBA_MURDER "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_TUBA_SUICIDE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_UZI_MURDER_SNIPE "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
-seta notification_WEAPON_UZI_MURDER_SPRAY "1" "Notification control cvar: 0 = off, 1 = trigger subcalls"
+// MSG_MULTI notifications (count = 141):
+seta notification_DEATH_MURDER_CHEAT "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_DROWN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_FALL "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_FIRE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_LAVA "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_MONSTER "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_NAPALM "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_ICE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_ICE_FREEZE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_NADE_HEAL "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_SHOOTING_STAR "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_SLIME "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_SWAMP "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_TELEFRAG "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_TOUCHEXPLODE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_BUMB_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_BUMB_GUN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_CRUSH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_RAPT_BOMB "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_RAPT_CANNON "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_RAPT_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_SPID_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_SPID_MINIGUN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_SPID_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_WAKI_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_WAKI_GUN "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VH_WAKI_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VENGEANCE "1" "Enable this multiple notification"
+seta notification_DEATH_MURDER_VOID "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_AUTOTEAMCHANGE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_BETRAYAL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_CAMP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_CHEAT "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_CUSTOM "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_DROWN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_FALL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_FIRE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_GENERIC "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_LAVA "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_MAGE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SHAMBLER_CLAW "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SHAMBLER_SMASH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SHAMBLER_ZAP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_SPIDER "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_WYVERN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_ZOMBIE_JUMP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_MON_ZOMBIE_MELEE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_NAPALM "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_ICE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_ICE_FREEZE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NADE_HEAL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_NOAMMO "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_ROT "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SHOOTING_STAR "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SLIME "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SUICIDE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_SWAMP "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TEAMCHANGE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TOUCHEXPLODE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_EWHEEL "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_FLAC "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_HELLION "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_HK "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_MACHINEGUN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_MLRS "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_PHASER "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_PLASMA "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_TESLA "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_WALK_GUN "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_WALK_MEELE "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_TURRET_WALK_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_BUMB_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_CRUSH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_RAPT_BOMB "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_RAPT_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_SPID_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_SPID_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_WAKI_DEATH "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VH_WAKI_ROCKET "1" "Enable this multiple notification"
+seta notification_DEATH_SELF_VOID "1" "Enable this multiple notification"
+seta notification_ITEM_BUFF_DROP "1" "Enable this multiple notification"
+seta notification_ITEM_BUFF_GOT "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_DONTHAVE "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_DROP "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_GOT "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_NOAMMO "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_PRIMORSEC "1" "Enable this multiple notification"
+seta notification_ITEM_WEAPON_UNAVAILABLE "1" "Enable this multiple notification"
+seta notification_MULTI_COUNTDOWN_BEGIN "1" "Enable this multiple notification"
+seta notification_MULTI_MINSTA_FINDAMMO "1" "Enable this multiple notification"
+seta notification_WEAPON_ACCORDEON_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_ACCORDEON_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_CRYLINK_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_CRYLINK_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_MURDER_BOLT "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_MURDER_COMBO "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_MURDER_ORBS "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_SUICIDE_BOLT "1" "Enable this multiple notification"
+seta notification_WEAPON_ELECTRO_SUICIDE_ORBS "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_MURDER_BLAST "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_MURDER_FIREMINE "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_SUICIDE_BLAST "1" "Enable this multiple notification"
+seta notification_WEAPON_FIREBALL_SUICIDE_FIREMINE "1" "Enable this multiple notification"
+seta notification_WEAPON_HAGAR_MURDER_BURST "1" "Enable this multiple notification"
+seta notification_WEAPON_HAGAR_MURDER_SPRAY "1" "Enable this multiple notification"
+seta notification_WEAPON_HAGAR_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_HLAC_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_HLAC_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_HOOK_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_KLEINBOTTLE_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_KLEINBOTTLE_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_LASER_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_LASER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_MINELAYER_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_MINELAYER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_MINSTANEX_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_MURDER_BOUNCE "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_MURDER_EXPLODE "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_SUICIDE_BOUNCE "1" "Enable this multiple notification"
+seta notification_WEAPON_MORTAR_SUICIDE_EXPLODE "1" "Enable this multiple notification"
+seta notification_WEAPON_NEX_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER_HAIL "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER_HAIL_PIERCING "1" "Enable this multiple notification"
+seta notification_WEAPON_RIFLE_MURDER_PIERCING "1" "Enable this multiple notification"
+seta notification_WEAPON_ROCKETLAUNCHER_MURDER_DIRECT "1" "Enable this multiple notification"
+seta notification_WEAPON_ROCKETLAUNCHER_MURDER_SPLASH "1" "Enable this multiple notification"
+seta notification_WEAPON_ROCKETLAUNCHER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_SEEKER_MURDER_SPRAY "1" "Enable this multiple notification"
+seta notification_WEAPON_SEEKER_MURDER_TAG "1" "Enable this multiple notification"
+seta notification_WEAPON_SEEKER_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_SHOTGUN_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_SHOTGUN_MURDER_SLAP "1" "Enable this multiple notification"
+seta notification_WEAPON_THINKING_WITH_PORTALS "1" "Enable this multiple notification"
+seta notification_WEAPON_TUBA_MURDER "1" "Enable this multiple notification"
+seta notification_WEAPON_TUBA_SUICIDE "1" "Enable this multiple notification"
+seta notification_WEAPON_UZI_MURDER_SNIPE "1" "Enable this multiple notification"
+seta notification_WEAPON_UZI_MURDER_SPRAY "1" "Enable this multiple notification"
 
 // MSG_CHOICE notifications (count = 12):
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_TIME_RED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_TIME_RED_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_PICKUP_TEAM "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_PICKUP_TEAM_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_CTF_PICKUP_ENEMY "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_CTF_PICKUP_ENEMY_ALLOWED "2" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_FRAG "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_FRAG_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_FRAGGED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_FRAGGED_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_TYPEFRAG "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_TYPEFRAG_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
-seta notification_CHOICE_TYPEFRAGGED "1" "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall"
-seta notification_CHOICE_TYPEFRAGGED_ALLOWED "1" "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_BROKEN_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_TIME_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_TIME_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_TIME_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_RED_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_CAPTURE_UNBROKEN_BLUE_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_PICKUP_TEAM "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_PICKUP_TEAM_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_CTF_PICKUP_ENEMY "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_CTF_PICKUP_ENEMY_ALLOWED "2" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_FRAG "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_FRAG_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_FRAGGED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_FRAGGED_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_TYPEFRAG "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_TYPEFRAG_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
+seta notification_CHOICE_TYPEFRAGGED "1" "Choice for this notification 0 = off, 1 = default message, 2 = verbose message"
+seta notification_CHOICE_TYPEFRAGGED_ALLOWED "1" "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
 
 // HARD CODED notification variables:
-seta notification_allow_chatboxprint "1" "Allow notifications to be printed to chat box by setting notification cvar to 2 (You can also set this cvar to 2 to force ALL notifications to be printed to the chatbox)"
+seta notification_allow_chatboxprint "1" "Allow INFO notifications to be printed to chat box0 = do not allow, 1 = allow only if allowed by individual notification_INFO* cvars, 2 = force all INFO notifications to be printed to the chatbox"
 seta notification_debug "0" "Print extra debug information on all notification function calls (Requires -DNOTIFICATIONS_DEBUG flag to be enabled on QCSRC compilation)... 0 = disabled, 1 = dprint, 2 = print"
 seta notification_errors_are_fatal "1" "If a notification fails upon initialization, cause a Host_Error to stop the program"
 seta notification_item_centerprinttime "1.5" "How long to show item information centerprint messages (like 'You got the Electro' or such)"
@@ -632,4 +697,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 = 582): MSG_ANNCE = 89, MSG_INFO = 214, MSG_CENTER = 146, MSG_MULTI = 121, MSG_CHOICE = 12
+// Notification counts (total = 647): MSG_ANNCE = 89, MSG_INFO = 244, MSG_CENTER = 161, MSG_MULTI = 141, MSG_CHOICE = 12
index e271ad99050377127a47fc83baa710df3da6a627..edac7388c10b06cedfa04d9a13038fcb32a08d79 100644 (file)
@@ -3,7 +3,7 @@ PERL ?= perl
 QCCFLAGS_WATERMARK ?= -DWATERMARK='"$(shell git describe)"'
 QCC ?= gmqcc
 
-QCCVERSIONFILE := qccversion.$(shell $(QCC) --version > qccversion.txt && git hash-object qccversion.txt)
+QCCVERSIONFILE := qccversion.$(shell (cd server && $(QCC) --version) > qccversion.txt && git hash-object qccversion.txt)
 
 # We eventually need to get rid of these.
 QCCFLAGS_WTFS ?= \
index 4ea750ce5dbc5c465713037d84ada9ad97b579c0..2a97056a43d21b7568ea143c620e911b6e7d41c5 100644 (file)
@@ -87,12 +87,17 @@ void CSQC_Init(void)
        registercvar("hud_usecsqc", "1");
        registercvar("scoreboard_columns", "default");
 
+       registercvar("cl_nade_type", "3");
+       registercvar("cl_pokenade_type", "zombie");
+
        gametype = 0;
 
        // hud_fields uses strunzone on the titles!
        for(i = 0; i < MAX_HUD_FIELDS; ++i)
                hud_title[i] = strzone("(null)");
 
+       Cmd_HUD_SetFields(0);
+
        postinit = false;
 
        calledhooks = 0;
@@ -109,6 +114,7 @@ void CSQC_Init(void)
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
        CALL_ACCUMULATED_FUNCTION(RegisterHUD_Panels);
+       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
 
        WaypointSprite_Load();
 
@@ -312,8 +318,6 @@ void Porto_Init();
 void TrueAim_Init();
 void PostInit(void)
 {
-       localcmd(strcat("\nscoreboard_columns_set ", autocvar_scoreboard_columns, ";\n"));
-
        entity playerchecker;
        playerchecker = spawn();
        playerchecker.think = Playerchecker_Think;
@@ -602,6 +606,27 @@ void Ent_Nagger()
        warmup_stage = (nags & 16);
 }
 
+void Ent_EliminatedPlayers()
+{
+       float sf, i, j, b, f;
+
+       sf = ReadByte();
+       if(sf & 1)
+       {
+               for(j = 0; j < maxclients; ++j)
+                       if(playerslots[j])
+                               playerslots[j].eliminated = 1;
+               for(i = 1; i <= maxclients; i += 8)
+               {
+                       f = ReadByte();
+                       for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+                               if (!(f & b))
+                                       if(playerslots[j])
+                                               playerslots[j].eliminated = 0;
+               }
+       }
+}
+
 void Ent_RandomSeed()
 {
        float s;
@@ -800,6 +825,7 @@ void CSQC_Ent_Update(float bIsNewEntity)
                case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
                case ENT_CLIENT_LASER: Ent_Laser(); break;
                case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
+               case ENT_CLIENT_ELIMINATEDPLAYERS: Ent_EliminatedPlayers(); break;
                case ENT_CLIENT_WAYPOINT: Ent_WaypointSprite(); break;
                case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
                case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
@@ -830,6 +856,7 @@ void CSQC_Ent_Update(float bIsNewEntity)
                case ENT_CLIENT_SPAWNPOINT: Ent_ReadSpawnPoint(bIsNewEntity); break;
                case ENT_CLIENT_SPAWNEVENT: Ent_ReadSpawnEvent(bIsNewEntity); break;
                case ENT_CLIENT_NOTIFICATION: Read_Notification(bIsNewEntity); break;
+               case ENT_CLIENT_HEALING_ORB: ent_healer(); break;
 
                default:
                        //error(strcat(_("unknown entity type in CSQC_Ent_Update: %d\n"), self.enttype));
@@ -937,11 +964,15 @@ void Ent_ScoresInfo()
        HUD_ModIcons_SetFunc();
        for(i = 0; i < MAX_SCORE; ++i)
        {
+               if(scores_label[i])
+                       strunzone(scores_label[i]);
                scores_label[i] = strzone(ReadString());
                scores_flags[i] = ReadByte();
        }
        for(i = 0; i < MAX_TEAMSCORE; ++i)
        {
+               if(teamscores_label[i])
+                       strunzone(teamscores_label[i]);
                teamscores_label[i] = strzone(ReadString());
                teamscores_flags[i] = ReadByte();
        }
index 2a41ba13c673c601f9134052a5f4cba68425a5ee..166ea07f0903e287d9785c21fe3a443d0087f03e 100644 (file)
@@ -374,9 +374,11 @@ entity nightvision_noise, nightvision_noise2;
 
 #define MAX_TIME_DIFF 5
 float pickup_crosshair_time, pickup_crosshair_size;
-float hit_time, typehit_time;
-float nextsound_hit_time, nextsound_typehit_time;
-float hitindication_crosshair_time, hitindication_crosshair_size;
+float hitsound_time_prev;
+float spectatee_status_prev; // for preventing hitsound when switching spectatee
+float damage_dealt_total, damage_dealt_total_prev;
+float typehit_time, typehit_time_prev;
+float hitindication_crosshair_size;
 float use_nex_chargepool;
 
 float myhealth, myhealth_prev;
@@ -1136,34 +1138,105 @@ void CSQC_UpdateView(float w, float h)
 
        scoreboard_active = HUD_WouldDrawScoreboard();
 
-       hit_time = getstatf(STAT_HIT_TIME);
-       if(hit_time > nextsound_hit_time && autocvar_cl_hitsound)
+       // varying sound pitch
+       damage_dealt_total = getstati(STAT_DAMAGE_DEALT_TOTAL);
+       
+       // detect overflow on server side
+       if (damage_dealt_total < damage_dealt_total_prev)
        {
-               if(time - hit_time < MAX_TIME_DIFF) // don't play the sound if it's too old.
-                       sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE);
+               dprint("resetting dmg total: ", ftos(damage_dealt_total), " prev: ", ftos(damage_dealt_total_prev), "\n");
+               damage_dealt_total_prev = 0;
+       }
+
+       // prevent hitsound when switching spectatee
+       if (spectatee_status != spectatee_status_prev)
+       {
+               damage_dealt_total_prev = damage_dealt_total;
+       }
+       spectatee_status_prev = spectatee_status;
+
+       // amount of damage since last hit sound
+       float unaccounted_damage = damage_dealt_total - damage_dealt_total_prev;
+       
 
-               nextsound_hit_time = time + autocvar_cl_hitsound_antispam_time;
+       if (autocvar_cl_hitsound == 1)
+       {
+               if ( time - hitsound_time_prev > autocvar_cl_hitsound_antispam_time )
+               if ( damage_dealt_total > 0 )
+               {
+                       sound(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTEN_NONE);
+                       hitsound_time_prev = time;
+               }
+       }
+       else if (unaccounted_damage > 0 && autocvar_cl_hitsound > 0 && time - hitsound_time_prev > autocvar_cl_hitsound_antispam_time)
+       {
+               // customizable gradient function that crosses (0,a), (c,1) and asymptotically approaches b
+               float a, b, c, x;
+               a = autocvar_cl_hitsound_max_pitch;
+               b = autocvar_cl_hitsound_min_pitch;
+               c = autocvar_cl_hitsound_nom_damage;
+               x = unaccounted_damage;
+               float pitch_shift = (b*x*(a-1) + a*c*(1-b)) / (x*(a-1) + c*(1-b));
+               
+               // if sound variation is disabled, set pitch_shift to 1
+               if (autocvar_cl_hitsound == 1)
+               {
+                       pitch_shift = 1;
+               }
+               
+               // if pitch shift is reversed, mirror in (max-min)/2 + min
+               if (autocvar_cl_hitsound == 3)
+               {
+                       float mirror_value = (a-b)/2 + b;
+                       pitch_shift = mirror_value + (mirror_value - pitch_shift);
+               }
+               
+               dprint("dmg total (dmg): ", ftos(damage_dealt_total), " (+", ftos(unaccounted_damage), "), pitch shift: ", ftos(pitch_shift), "\n");
+               
+               // todo: avoid very long and very short sounds from wave stretching using different sound files? seems unnecessary
+               // todo: normalize sound pressure levels? seems unnecessary
+               
+               // scale to fit function interface
+               float param_pitch_shift = pitch_shift * 100;
+               
+               // play sound
+               sound7(world, CH_INFO, "misc/hit.wav", VOL_BASE, ATTN_NONE, param_pitch_shift, 0);
+               
+               // track damage accounted for
+               damage_dealt_total_prev = damage_dealt_total;
+
+               // remember when this sound was played to prevent sound spam
+               hitsound_time_prev = time;
+       }
+       else if (autocvar_cl_hitsound == 0)
+       {
+               // forget the damage to prevent hitsound when enabling it
+               damage_dealt_total_prev = damage_dealt_total;
        }
+       
        typehit_time = getstatf(STAT_TYPEHIT_TIME);
-       if(typehit_time > nextsound_typehit_time)
+       if(typehit_time - typehit_time_prev > autocvar_cl_hitsound_antispam_time)
        {
-               if(time - typehit_time < MAX_TIME_DIFF) // don't play the sound if it's too old.
-                       sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTEN_NONE);
-
-               nextsound_typehit_time = time + autocvar_cl_hitsound_antispam_time;
+               sound(world, CH_INFO, "misc/typehit.wav", VOL_BASE, ATTN_NONE);
+               typehit_time_prev = typehit_time;
        }
 
        //else
        {
-               if(gametype == MAPINFO_TYPE_FREEZETAG)
+               if(getstati(STAT_FROZEN))
+                       drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((getstatf(STAT_REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * getstatf(STAT_REVIVE_PROGRESS)) + ('0 1 1' * getstatf(STAT_REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+               else if (getstatf(STAT_HEALING_ORB)>time)
+                       drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, Nade_Color(NADE_TYPE_HEAL), autocvar_hud_colorflash_alpha*getstatf(STAT_HEALING_ORB_ALPHA), DRAWFLAG_ADDITIVE);
+               if(!intermission)
+               if(getstatf(STAT_NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
                {
-                       if(getstati(STAT_FROZEN))
-                               drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-                       if(getstatf(STAT_REVIVE_PROGRESS))
-                       {
-                               DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
-                               drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
-                       }
+                       DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * getstatf(STAT_NADE_TIMER)) - ('0 1 1' * getstatf(STAT_NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+                       drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+               }
+               else if(getstatf(STAT_REVIVE_PROGRESS))
+               {
+                       DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+                       drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
                }
 
                if(autocvar_r_letterbox == 0)
@@ -1345,16 +1418,14 @@ void CSQC_UpdateView(float w, float h)
                                wcross_scale += sin(pickup_crosshair_size) * autocvar_crosshair_pickup;
                        }
 
+                       // todo: make crosshair hit indication dependent on damage dealt
                        if(autocvar_crosshair_hitindication)
                        {
                                vector hitindication_color = ((autocvar_crosshair_color_special == 1) ? stov(autocvar_crosshair_hitindication_per_weapon_color) : stov(autocvar_crosshair_hitindication_color));
 
-                               if(hitindication_crosshair_time < hit_time)
+                               if(unaccounted_damage)
                                {
-                                       if(time - hit_time < MAX_TIME_DIFF) // don't trigger the animation if it's too old
-                                               hitindication_crosshair_size = 1;
-
-                                       hitindication_crosshair_time = hit_time;
+                                       hitindication_crosshair_size = 1;
                                }
 
                                if(hitindication_crosshair_size > 0)
index 67a03259382feba3d5e14adf53087c834eac6491..55fbebd7f30cf738fff06d0710ce0901eb2db025 100644 (file)
@@ -268,6 +268,7 @@ float autocvar_hud_panel_notify_fadetime;
 float autocvar_hud_panel_notify_flip;
 float autocvar_hud_panel_notify_fontsize;
 float autocvar_hud_panel_notify_time;
+float autocvar_hud_panel_notify_icon_aspect;
 float autocvar_hud_panel_physics;
 float autocvar_hud_panel_physics_acceleration_progressbar_mode;
 float autocvar_hud_panel_physics_acceleration_progressbar_scale;
@@ -290,6 +291,8 @@ float autocvar_hud_panel_powerups_baralign;
 float autocvar_hud_panel_powerups_flip;
 float autocvar_hud_panel_powerups_iconalign;
 float autocvar_hud_panel_powerups_progressbar;
+float autocvar_hud_panel_buffs;
+//float autocvar_hud_panel_buffs_iconalign;
 string autocvar_hud_panel_powerups_progressbar_shield;
 string autocvar_hud_panel_powerups_progressbar_strength;
 string autocvar_hud_panel_powerups_progressbar_superweapons;
@@ -408,6 +411,9 @@ float autocvar_vid_conwidth;
 float autocvar_vid_pixelheight;
 float autocvar_viewsize;
 float autocvar_cl_hitsound;
+var float autocvar_cl_hitsound_min_pitch = 0.75; // minimal difference in minsta
+var float autocvar_cl_hitsound_max_pitch = 1.5;
+var float autocvar_cl_hitsound_nom_damage = 25;
 float autocvar_cl_hitsound_antispam_time;
 var float autocvar_cl_eventchase_death = 1;
 var float autocvar_cl_eventchase_nexball = 1;
@@ -440,3 +446,4 @@ string autocvar__cl_playermodel;
 float autocvar_cl_deathglow;
 float autocvar_developer_csqcentities;
 float autocvar_g_jetpack_attenuation;
+float autocvar_cl_nade_timer;
index 3889603aa8867679a4ba23cc4cf6d69150664f6e..4d966476f3eb91d7ac835c62994ac296f1d005ad 100644 (file)
@@ -41,29 +41,6 @@ const float          VF_CL_VIEWANGLES_X                              = 34;   //(float)
 const float            VF_CL_VIEWANGLES_Y                              = 35;   //(float)
 const float            VF_CL_VIEWANGLES_Z                              = 36;   //(float)
 
-// Server Autosent Stat Constants
-const float            STAT_HEALTH                                             = 0;
-const float            STAT_WEAPONMODEL                                = 2;
-const float            STAT_AMMO                                               = 3;
-const float            STAT_ARMOR                                              = 4;
-const float            STAT_WEAPONFRAME                                = 5;
-const float            STAT_SHELLS                                             = 6;
-const float            STAT_NAILS                                              = 7;
-const float            STAT_ROCKETS                                    = 8;
-const float            STAT_CELLS                                              = 9;
-const float            STAT_ACTIVEWEAPON                               = 10;
-const float            STAT_TOTALSECRETS                               = 11;
-const float            STAT_TOTALMONSTERS                              = 12;
-const float            STAT_SECRETS                                    = 13;
-const float            STAT_MONSTERS                                   = 14;
-const float            STAT_ITEMS                                              = 15;
-const float            STAT_VIEWHEIGHT                                 = 16;
-const float            STAT_MOVEVARS_TICRATE           = 240;
-const float            STAT_MOVEVARS_TIMESCALE         = 241;
-const float            STAT_FRAGLIMIT                                  = 235;
-const float            STAT_TIMELIMIT                                  = 236;
-const float     STAT_MOVEVARS_GRAVITY           = 242;
-
 // Quake-style Point Contents
 const float            CONTENT_EMPTY                                   = -1;
 const float            CONTENT_SOLID                                   = -2;
index bb5eb4a68f534081953aa7d860c69602659d7fa3..ab61eb3c3eb4c071c549467e1b9b556deefadc76 100644 (file)
@@ -886,6 +886,54 @@ string GetAmmoPicture(float i)
        }
 }
 
+void DrawNadeScoreBar(vector myPos, vector mySize, vector color)
+{
+       
+       HUD_Panel_DrawProgressBar(
+               myPos + eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x, 
+               mySize - eX * autocvar_hud_panel_ammo_progressbar_xoffset * mySize_x, 
+               autocvar_hud_panel_ammo_progressbar_name, 
+               getstatf(STAT_NADE_BONUS_SCORE), 0, 0, color, 
+               autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+
+}
+
+void DrawAmmoNades(vector myPos, vector mySize, float draw_expanding, float expand_time)
+{
+       float theAlpha = 1, a, b;
+       vector nade_color, picpos, numpos;
+       
+       nade_color = Nade_Color(getstati(STAT_NADE_BONUS_TYPE));
+       
+       a = getstatf(STAT_NADE_BONUS);
+       b = getstatf(STAT_NADE_BONUS_SCORE);
+       
+       if(autocvar_hud_panel_ammo_iconalign)
+       {
+               numpos = myPos;
+               picpos = myPos + eX * 2 * mySize_y;
+       }
+       else
+       {
+               numpos = myPos + eX * mySize_y;
+               picpos = myPos;
+       }
+
+       DrawNadeScoreBar(myPos, mySize, nade_color);
+
+       if(b > 0 || a > 0)
+       {
+               if(autocvar_hud_panel_ammo_text)
+                       drawstring_aspect(numpos, ftos(a), eX * (2/3) * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+               
+               if(draw_expanding)
+                       drawpic_aspect_skin_expanding(picpos, "nade_nbg", '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL, expand_time);
+                       
+               drawpic_aspect_skin(picpos, "nade_bg" , '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+               drawpic_aspect_skin(picpos, "nade_nbg" , '1 1 0' * mySize_y, nade_color, panel_fg_alpha * theAlpha, DRAWFLAG_NORMAL);
+       }
+}
+
 void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_selected, float infinite_ammo)
 {
        float a;
@@ -942,6 +990,9 @@ void DrawAmmoItem(vector myPos, vector mySize, float itemcode, float currently_s
                drawpic_aspect_skin(picpos, GetAmmoPicture(itemcode), '1 1 0' * mySize_y, '0 0 0', panel_fg_alpha * theAlpha * 0.5, DRAWFLAG_NORMAL);
 }
 
+float nade_prevstatus;
+float nade_prevframe;
+float nade_statuschange_time;
 void HUD_Ammo(void)
 {
        if(hud != HUD_NORMAL) return;
@@ -966,21 +1017,39 @@ void HUD_Ammo(void)
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
-       const float AMMO_COUNT = 4;
        float rows = 0, columns, row, column;
+       float nade_cnt = getstatf(STAT_NADE_BONUS), nade_score = getstatf(STAT_NADE_BONUS_SCORE);
+       float draw_nades = (nade_cnt > 0 || nade_score > 0), nade_statuschange_elapsedtime;
+       float total_ammo_count;
+
        vector ammo_size;
+       float AMMO_COUNT = 4;
        if (autocvar_hud_panel_ammo_onlycurrent)
-               ammo_size = mySize;
+               total_ammo_count = 1;
        else
+               total_ammo_count = AMMO_COUNT - 1; // fuel
+
+       if(draw_nades)
        {
-               rows = mySize_y/mySize_x;
-               rows = bound(1, floor((sqrt(4 * (3/1) * rows * AMMO_COUNT + rows * rows) + rows + 0.5) / 2), AMMO_COUNT);
-               //                               ^^^ ammo item aspect goes here
+               ++total_ammo_count;
+               if (nade_cnt != nade_prevframe)
+               {
+                       nade_statuschange_time = time;
+                       nade_prevstatus = nade_prevframe;
+                       nade_prevframe = nade_cnt;
+               }
+       }
+       else
+               nade_prevstatus = nade_prevframe = nade_statuschange_time = 0;
 
-               columns = ceil(AMMO_COUNT/rows);
+       rows = mySize_y/mySize_x;
+       rows = bound(1, floor((sqrt(4 * (3/1) * rows * (total_ammo_count) + rows * rows) + rows + 0.5) / 2), (total_ammo_count));
+       //                               ^^^ ammo item aspect goes here
 
-               ammo_size = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
-       }
+       columns = ceil((total_ammo_count)/rows);
+
+       ammo_size = eX * mySize_x*(1/columns) + eY * mySize_y*(1/rows);
+       
 
        local vector offset = '0 0 0'; // fteqcc sucks
        float newSize;
@@ -1001,6 +1070,9 @@ void HUD_Ammo(void)
 
        float i, stat_items, currently_selected, infinite_ammo;
        infinite_ammo = FALSE;
+
+       row = column = 0;
+
        if (autocvar_hud_panel_ammo_onlycurrent)
        {
                if(autocvar__hud_configure)
@@ -1021,13 +1093,19 @@ void HUD_Ammo(void)
                                }
                        }
                }
+
+               ++row;
+               if(row >= rows)
+               {
+                       row = 0;
+                       column = column + 1;
+               }
        }
        else
        {
                stat_items = getstati(STAT_ITEMS, 0, 24);
                if (stat_items & IT_UNLIMITED_WEAPON_AMMO)
                        infinite_ammo = TRUE;
-               row = column = 0;
                for (i = 0; i < AMMO_COUNT; ++i) {
                        currently_selected = stat_items & GetAmmoItemCode(i);
                        DrawAmmoItem(pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y), ammo_size, i, currently_selected, infinite_ammo);
@@ -1040,6 +1118,15 @@ void HUD_Ammo(void)
                }
        }
 
+       if (draw_nades)
+       {
+               nade_statuschange_elapsedtime = time - nade_statuschange_time;
+
+               float f = bound(0, nade_statuschange_elapsedtime*2, 1);
+
+               DrawAmmoNades(pos + eX * column * (ammo_size_x + offset_x) + eY * row * (ammo_size_y + offset_y), ammo_size, nade_prevstatus < nade_cnt && nade_cnt != 0 && f < 1, f);
+       }
+
        draw_endBoldFont();
 }
 
@@ -1601,148 +1688,154 @@ void HUD_HealthArmor(void)
 
 void HUD_Notify_Push(string icon, string attacker, string victim)
 {
-       if(icon != "")
-       {
-               --kn_index;
-               if (kn_index == -1) { kn_index = KN_MAX_ENTRIES-1; }
-               notify_times[kn_index] = time;
+       if (icon == "")
+               return;
+
+       ++notify_count;
+       --notify_index;
+
+       if (notify_index == -1)
+               notify_index = NOTIFY_MAX_ENTRIES-1;
+
+       // Free old strings
+       if (notify_attackers[notify_index])
+               strunzone(notify_attackers[notify_index]);
 
-               // icon
-               if(notify_icon[kn_index]) { strunzone(notify_icon[kn_index]); }
-               notify_icon[kn_index] = strzone(icon);
+       if (notify_victims[notify_index])
+               strunzone(notify_victims[notify_index]);
 
-               // attacker
-               if(notify_attackers[kn_index]) { strunzone(notify_attackers[kn_index]); }
-               notify_attackers[kn_index] = strzone(attacker);
+       if (notify_icons[notify_index])
+               strunzone(notify_icons[notify_index]);
 
-               // victim
-               if(notify_victims[kn_index]) { strunzone(notify_victims[kn_index]); }
-               notify_victims[kn_index] = strzone(victim);
+       // Allocate new strings
+       if (victim != "")
+       {
+               notify_attackers[notify_index] = strzone(attacker);
+               notify_victims[notify_index] = strzone(victim);
+       }
+       else
+       {
+               // In case of a notification without a victim, the attacker
+               // is displayed on the victim's side. Instead of special
+               // treatment later on, we can simply switch them here.
+               notify_attackers[notify_index] = string_null;
+               notify_victims[notify_index] = strzone(attacker);
        }
+
+       notify_icons[notify_index] = strzone(icon);
+       notify_times[notify_index] = time;
 }
 
 void HUD_Notify(void)
 {
-       if(!autocvar__hud_configure)
-       {
-               if(!autocvar_hud_panel_notify) return;
-       }
+       if (!autocvar__hud_configure)
+               if (!autocvar_hud_panel_notify)
+                       return;
 
        HUD_Panel_UpdateCvars();
-       vector pos, mySize;
-       pos = panel_pos;
-       mySize = panel_size;
-
        HUD_Panel_DrawBg(1);
-       if(panel_bg_padding)
+
+       if (!autocvar__hud_configure)
+               if (notify_count == 0)
+                       return;
+
+       vector pos, size;
+       pos  = panel_pos;
+       size = panel_size;
+
+       if (panel_bg_padding)
        {
-               pos += '1 1 0' * panel_bg_padding;
-               mySize -= '2 2 0' * panel_bg_padding;
+               pos  += '1 1 0' * panel_bg_padding;
+               size -= '2 2 0' * panel_bg_padding;
        }
 
-       float entries, height;
-       entries = bound(1, floor(KN_MAX_ENTRIES * mySize_y/mySize_x), KN_MAX_ENTRIES);
-       height = mySize_y/entries;
+       float fade_start = max(0, autocvar_hud_panel_notify_time);
+       float fade_time = max(0, autocvar_hud_panel_notify_fadetime);
+       float icon_aspect = max(1, autocvar_hud_panel_notify_icon_aspect);
 
-       vector fontsize;
-       float fontheight = height * autocvar_hud_panel_notify_fontsize;
-       fontsize = '0.5 0.5 0' * fontheight;
+       float entry_count = bound(1, floor(NOTIFY_MAX_ENTRIES * size_y / size_x), NOTIFY_MAX_ENTRIES);
+       float entry_height = size_y / entry_count;
 
-       float a;
-       float when;
-       when = autocvar_hud_panel_notify_time;
-       float fadetime;
-       fadetime = autocvar_hud_panel_notify_fadetime;
+       float panel_width_half = size_x * 0.5;
+       float icon_width_half = entry_height * icon_aspect / 2;
+       float name_maxwidth = panel_width_half - icon_width_half - size_x * NOTIFY_ICON_MARGIN;
 
-       vector pos_attacker, pos_victim, pos_icon;
-       float width_attacker;
+       vector font_size = '0.5 0.5 0' * entry_height * autocvar_hud_panel_notify_fontsize;
+       vector icon_size = (eX * icon_aspect + eY) * entry_height;
+       vector icon_left = eX * (panel_width_half - icon_width_half);
+       vector attacker_right = eX * name_maxwidth;
+       vector victim_left = eX * (size_x - name_maxwidth);
+
+       vector attacker_pos, victim_pos, icon_pos;
        string attacker, victim, icon;
+       float i, j, count, step, limit, alpha;
 
-       float i, j, step, limit;
-       if(autocvar_hud_panel_notify_flip) //order items from the top down
+       if (autocvar_hud_panel_notify_flip)
        {
+               // Order items from the top down
                i = 0;
                step = +1;
-               limit = entries;
+               limit = entry_count;
        }
-       else //order items from the bottom up
+       else
        {
-               i = entries - 1;
+               // Order items from the bottom up
+               i = entry_count - 1;
                step = -1;
                limit = -1;
        }
 
-       for(j = kn_index;  i != limit;  i += step, ++j)
+       for (j = notify_index, count = 0; i != limit; i += step, ++j, ++count)
        {
                if(autocvar__hud_configure)
                {
-                       if (step == +1)
-                               a = i;
-                       else // inverse order
-                               a = entries - 1 - i;
-                       attacker = textShortenToWidth(sprintf(_("Player %d"), a+1), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-                       victim = textShortenToWidth(sprintf(_("Player %d"), a+2), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-                       icon = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
-                       a = bound(0, (when - a) / 4, 1);
-                       goto hud_config_notifyprint;
+                       attacker = sprintf(_("Player %d"), count + 1);
+                       victim = sprintf(_("Player %d"), count + 2);
+                       icon = strcat("weapon", get_weaponinfo(min(WEP_FIRST + count * 2, WEP_LAST)).netname);
+                       alpha = bound(0, 1.2 - count / entry_count, 1);
                }
                else
                {
-                       if (j == KN_MAX_ENTRIES)
+                       if (j == NOTIFY_MAX_ENTRIES)
                                j = 0;
 
-                       if(notify_times[j] + when > time)
-                               a = 1;
-                       else if(fadetime)
+                       if (notify_times[j] + fade_start > time)
+                               alpha = 1;
+                       else if (fade_time != 0)
                        {
-                               a = bound(0, (notify_times[j] + when + fadetime - time) / fadetime, 1);
-                               if(!a)
-                               {
+                               alpha = bound(0, (notify_times[j] + fade_start + fade_time - time) / fade_time, 1);
+                               if (alpha == 0)
                                        break;
-                               }
                        }
                        else
-                       {
                                break;
-                       }
 
                        attacker = notify_attackers[j];
                        victim = notify_victims[j];
-                       icon = notify_icon[j];
+                       icon = notify_icons[j];
                }
 
-               //type = notify_deathtype[j];
-               //w = DEATH_WEAPONOF(type);
-
-               if(icon != "")
+               if (icon != "" && victim != "")
                {
-                       if((attacker != "") && (victim == ""))
-                       {
-                               // Y [used by] X
-                               attacker = textShortenToWidth(attacker, 0.73 * mySize_x - height, fontsize, stringwidth_colors);
-                               pos_attacker = pos + eX * (0.27 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
-                               pos_icon = pos + eX * 0.25 * mySize_x - eX * height + eY * i * height;
+                       vector name_top = eY * (i * entry_height + 0.5 * (entry_height - font_size_y));
 
-                               drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
-                               drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
-                       }
-                       else if((attacker != "") && (victim != ""))
+                       icon_pos = pos + icon_left + eY * i * entry_height;
+                       drawpic_aspect_skin(icon_pos, icon, icon_size, '1 1 1', panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
+
+                       victim = textShortenToWidth(victim, name_maxwidth, font_size, stringwidth_colors);
+                       victim_pos = pos + victim_left + name_top;
+                       drawcolorcodedstring(victim_pos, victim, font_size, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
+
+                       if (attacker != "")
                        {
-                               // X [did action to] Y
-                               attacker = textShortenToWidth(attacker, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-                               victim = textShortenToWidth(victim, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
-:hud_config_notifyprint
-                               width_attacker = stringwidth(attacker, TRUE, fontsize);
-                               pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
-                               pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
-                               pos_icon = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
-
-                               drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
-                               drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
-                               drawcolorcodedstring(pos_victim, victim, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
+                               attacker = textShortenToWidth(attacker, name_maxwidth, font_size, stringwidth_colors);
+                               attacker_pos = pos + attacker_right - eX * stringwidth(attacker, TRUE, font_size) + name_top;
+                               drawcolorcodedstring(attacker_pos, attacker, font_size, panel_fg_alpha * alpha, DRAWFLAG_NORMAL);
                        }
                }
        }
+
+       notify_count = count;
 }
 
 // Timer (#5)
@@ -4366,6 +4459,66 @@ void HUD_CenterPrint (void)
        }
 }
 
+// Buffs (#18)
+//
+void HUD_Buffs(void)
+{
+       float buffs = getstati(STAT_BUFFS, 0, 24);
+       if(!autocvar__hud_configure)
+       {
+               if(!autocvar_hud_panel_buffs) return;
+               if(spectatee_status == -1) return;
+               if(getstati(STAT_HEALTH) <= 0) return;
+               if(!buffs) return;
+       }
+       else
+       {
+               buffs = Buff_Type_first.items; // force first buff
+       }
+       
+       float b = 0; // counter to tell other functions that we have buffs
+       entity e;
+       string s = "";
+       for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
+       {
+               ++b;
+               string o = strcat(rgb_to_hexcolor(Buff_Color(e.items)), Buff_PrettyName(e.items));
+               if(s == "")
+                       s = o;
+               else
+                       s = strcat(s, " ", o);
+       }
+
+       HUD_Panel_UpdateCvars();
+
+       draw_beginBoldFont();
+
+       vector pos, mySize;
+       pos = panel_pos;
+       mySize = panel_size;
+
+       HUD_Panel_DrawBg(bound(0, b, 1));
+       if(panel_bg_padding)
+       {
+               pos += '1 1 0' * panel_bg_padding;
+               mySize -= '2 2 0' * panel_bg_padding;
+       }
+
+       //float panel_ar = mySize_x/mySize_y;
+       //float is_vertical = (panel_ar < 1);
+       //float buff_iconalign = autocvar_hud_panel_buffs_iconalign;
+       vector buff_offset = '0 0 0';
+       
+       for(e = Buff_Type_first; e; e = e.enemy) if(buffs & e.items)
+       {
+               //DrawNumIcon(pos + buff_offset, mySize, shield, "shield", is_vertical, buff_iconalign, '1 1 1', 1);
+               drawcolorcodedstring_aspect(pos + buff_offset, s, mySize, panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
+       }
+
+       draw_endBoldFont();
+}
+
+
 /*
 ==================
 Main HUD system
index 5c062c5facb3400224105766e1628651f83c8c50..55d4bd0db8c9fdd71265993fea3dd372549c83c9 100644 (file)
@@ -114,7 +114,8 @@ float current_player;
        HUD_PANEL(ENGINEINFO   , HUD_EngineInfo   , engineinfo) \
        HUD_PANEL(INFOMESSAGES , HUD_InfoMessages , infomessages) \
        HUD_PANEL(PHYSICS      , HUD_Physics      , physics) \
-       HUD_PANEL(CENTERPRINT  , HUD_CenterPrint  , centerprint)
+       HUD_PANEL(CENTERPRINT  , HUD_CenterPrint  , centerprint) \
+       HUD_PANEL(BUFFS        , HUD_Buffs        , buffs) 
 
 #define HUD_PANEL(NAME,draw_func,name) \
        float HUD_PANEL_##NAME; \
@@ -337,14 +338,16 @@ panel_bg_border_str = cvar_string(strcat("hud_panel_", panel.panel_name, "_bg_bo
 HUD_Panel_GetBorder() \
 } ENDS_WITH_CURLY_BRACE
 
+#define NOTIFY_MAX_ENTRIES 10
+#define NOTIFY_ICON_MARGIN 0.02
 
-#define KN_MAX_ENTRIES 10
+float notify_index;
+float notify_count;
+float notify_times[NOTIFY_MAX_ENTRIES];
+string notify_attackers[NOTIFY_MAX_ENTRIES];
+string notify_victims[NOTIFY_MAX_ENTRIES];
+string notify_icons[NOTIFY_MAX_ENTRIES];
 
-float kn_index;
-float notify_times[KN_MAX_ENTRIES];
-string notify_icon[KN_MAX_ENTRIES];
-string notify_attackers[KN_MAX_ENTRIES];
-string notify_victims[KN_MAX_ENTRIES];
 void HUD_Notify_Push(string icon, string attacker, string victim);
 
 var void HUD_ModIcons_GameType(vector pos, vector size);
index 98dbdefd1872ee2637a7d04ef383f4b244d48e70..8ecc326b1e788441547b2fd7ec2081ffbd7bbd60 100644 (file)
@@ -119,6 +119,7 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_PanelCvar_q("_fontsize");
                                        HUD_Write_PanelCvar_q("_time");
                                        HUD_Write_PanelCvar_q("_fadetime");
+                                       HUD_Write_PanelCvar_q("_icon_aspect");
                                        break;
                                case HUD_PANEL_TIMER:
                                        HUD_Write_PanelCvar_q("_increment");
index 815c20a33ed1788eb16129b136bfe18372f3fe87..5bf3e5bc61fc47e2b5d8fce0e20cce11e0d5024d 100644 (file)
@@ -86,6 +86,7 @@ entity teamslots[17];    // 17 teams (including "spectator team")
 .float gotscores;
 .entity owner;
 .float ready;
+.float eliminated;
 
 .void(void) draw;
 .void(void) draw2d;
index 8caeb01d524064f51c3191440555c0cd814ce0e3..a354bacf28d9ecbec0b259bb5055f2989c889a98 100644 (file)
@@ -6,17 +6,26 @@ string mv_pics[MAPVOTE_COUNT];
 string mv_pk3[MAPVOTE_COUNT];
 float mv_preview[MAPVOTE_COUNT];
 float mv_votes[MAPVOTE_COUNT];
+float mv_avail[MAPVOTE_COUNT];
+float mv_avail_start[MAPVOTE_COUNT];
 entity mv_pk3list;
 float mv_abstain;
 float mv_ownvote;
 float mv_detail;
 float mv_timeout;
-float mv_maps_mask;
 float mv_top2_time;
 float mv_top2_alpha;
 
 vector mv_mousepos;
 float mv_selection;
+float mv_columns;
+float mv_mouse_selection;
+float mv_selection_keyboard;
+
+float gametypevote;
+string mapvote_chosenmap;
+vector gtv_text_size;
+vector gtv_text_size_small;
 
 string MapVote_FormatMapItem(float id, string map, float count, float maxwidth, vector fontsize)
 {
@@ -26,7 +35,7 @@ string MapVote_FormatMapItem(float id, string map, float count, float maxwidth,
        {
                if(count == 1)
                        post = _(" (1 vote)");
-               else if(count >= 0)
+               else if(count >= 0 && mv_avail[id] == GTV_AVAILABLE)
                        post = sprintf(_(" (%d votes)"), count);
                else
                        post = "";
@@ -38,9 +47,14 @@ string MapVote_FormatMapItem(float id, string map, float count, float maxwidth,
        return strcat(pre, map, post);
 }
 
-vector MapVote_RGB(float id, float count)
+string GameTypeVote_DescriptionByID(float id)
+{
+       return MapInfo_Type_Description(MapInfo_Type_FromString(mv_maps[id]));
+}
+
+vector MapVote_RGB(float id)
 {
-       if(count < 0)
+       if(mv_avail[id] != GTV_AVAILABLE)
                return '1 1 1';
        if(id == mv_ownvote)
                return '0 1 0';
@@ -50,6 +64,100 @@ vector MapVote_RGB(float id, float count)
                return '1 1 1';
 }
 
+void GameTypeVote_DrawGameTypeItem(vector pos, float maxh, float tsize, string gtype, string pic, float count, float id)
+{
+       float alpha;
+       float desc_padding = gtv_text_size_x * 3;
+       float rect_margin = hud_fontsize_y / 2;
+       vector rect_pos = pos - '0.5 0.5 0' * rect_margin;
+       vector rect_size = '1 1 0';
+       rect_size_x = tsize + rect_margin;
+       rect_size_y = maxh + rect_margin;
+       vector rgb = MapVote_RGB(id);
+       vector offset = pos;
+       float nlines = 0;
+       
+       if(mv_avail_start[id] != GTV_AVAILABLE)
+               alpha = 0.2;
+       else if ( mv_avail[id] != GTV_AVAILABLE && mv_top2_alpha)
+               alpha = mv_top2_alpha;
+       else
+               alpha = 1;
+       
+       if(id == mv_selection && mv_avail[id] == GTV_AVAILABLE)
+       {
+               drawfill(rect_pos, rect_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
+       }
+       if(id == mv_ownvote)
+       {
+               drawfill(rect_pos, rect_size, rgb, 0.1*alpha, DRAWFLAG_NORMAL);
+               drawborderlines(autocvar_scoreboard_border_thickness, rect_pos, rect_size, rgb, alpha, DRAWFLAG_NORMAL);
+       }
+       
+       entity title;
+       title = spawn();
+       title.message = MapVote_FormatMapItem(id, MapInfo_Type_ToText(MapInfo_Type_FromString(gtype)), 
+                                                                                 count, tsize, gtv_text_size);
+       title.origin = pos-offset;
+       
+       pos_y += gtv_text_size_small_y;
+       pos_y += gtv_text_size_y/2;
+       
+       maxh -= gtv_text_size_y;
+       
+       entity picent = spawn();
+       picent.origin = pos-offset;
+       picent.maxs = '1 1 0 ' * min(maxh, desc_padding) * 0.8;
+       
+       pos_x += desc_padding;
+       tsize -= desc_padding;
+       
+       string thelabel = GameTypeVote_DescriptionByID(id), ts;
+       entity last = title;
+       entity next = world;
+       if( thelabel != "") 
+       {
+               float i,n = tokenizebyseparator(thelabel, "\n");
+               for(i = 0; i < n && maxh > (nlines+1)*gtv_text_size_small_y; ++i)
+               {
+                       getWrappedLine_remaining = argv(i);
+                       while(getWrappedLine_remaining && maxh > (nlines+1)*gtv_text_size_small_y)
+                       {
+                               ts = getWrappedLine(tsize, gtv_text_size_small, stringwidth_colors);
+                               if (ts != "")
+                               {
+                                       next = spawn();
+                                       next.message = ts;
+                                       next.origin = pos-offset;
+                                       last.chain = next;
+                                       last = next;
+                                       pos_y += gtv_text_size_small_y;
+                                       nlines++;
+                               }
+                       }
+               }
+       }
+       
+       maxh -= max(nlines*gtv_text_size_small_y,picent.maxs_y);
+       if ( maxh > 0 )
+               offset_y += maxh/2;
+       drawstring(title.origin+offset, title.message, gtv_text_size, rgb, alpha, DRAWFLAG_NORMAL); 
+       
+       if(pic != "")
+               drawpic(picent.origin+offset, pic, picent.maxs, '1 1 1', alpha, DRAWFLAG_NORMAL);
+       
+       for ( last = title.chain; last ; )
+       {
+               drawstring(last.origin+offset, last.message, gtv_text_size_small, '1 1 1', alpha, DRAWFLAG_NORMAL);
+               next = last;
+               last = last.chain;
+               remove(next);
+       }
+       
+       remove(picent);
+       remove(title);
+}
+
 void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float count, float id)
 {
        vector img_size = '0 0 0';
@@ -59,7 +167,7 @@ void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, strin
 
        isize -= hud_fontsize_y; // respect the text when calculating the image size
 
-       rgb = MapVote_RGB(id, count);
+       rgb = MapVote_RGB(id);
 
        img_size_y = isize;
        img_size_x = isize / 0.75; // 4:3 x can be stretched easily, height is defined in isize
@@ -71,7 +179,7 @@ void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, strin
        text_size = stringwidth(label, false, hud_fontsize);
 
        float theAlpha;
-       if (count < 0 && mv_top2_alpha)
+       if (mv_avail[id] != GTV_AVAILABLE && mv_top2_alpha)
                theAlpha = mv_top2_alpha;
        else
                theAlpha = 1;
@@ -101,7 +209,7 @@ void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, strin
        else
                drawborderlines(autocvar_scoreboard_border_thickness, pos, img_size, '0 0 0', theAlpha, DRAWFLAG_NORMAL);
 
-       if(id == mv_selection && count >= 0)
+       if(id == mv_selection && mv_avail[id] == GTV_AVAILABLE)
                drawfill(pos, img_size, '1 1 1', 0.1, DRAWFLAG_NORMAL);
 }
 
@@ -111,7 +219,7 @@ void MapVote_DrawAbstain(vector pos, float isize, float tsize, float count, floa
        float text_size;
        string label;
 
-       rgb = MapVote_RGB(id, count);
+       rgb = MapVote_RGB(id);
 
        pos_y = pos_y + hud_fontsize_y;
 
@@ -135,10 +243,10 @@ vector MapVote_GridVec(vector gridspec, float i, float m)
 
 float MapVote_Selection(vector topleft, vector cellsize, float rows, float columns)
 {
-       float cell;
+
        float c, r;
 
-       cell = -1;
+       mv_mouse_selection = -1;
 
        for (r = 0; r < rows; ++r)
                for (c = 0; c < columns; ++c)
@@ -148,18 +256,21 @@ float MapVote_Selection(vector topleft, vector cellsize, float rows, float colum
                                mv_mousepos_y >= topleft_y + cellsize_y *  r &&
                                mv_mousepos_y <= topleft_y + cellsize_y * (r + 1))
                        {
-                               cell = r * columns + c;
+                               mv_mouse_selection = r * columns + c;
                                break;
                        }
                }
 
-       if (cell >= mv_num_maps)
-               cell = -1;
+       if (mv_mouse_selection >= mv_num_maps)
+               mv_mouse_selection = -1;
 
-       if (mv_abstain && cell < 0)
-               return mv_num_maps;
+       if (mv_abstain && mv_mouse_selection < 0)
+               mv_mouse_selection = mv_num_maps;
 
-       return cell;
+       if ( mv_selection_keyboard )
+               return mv_selection;
+       
+       return mv_mouse_selection;
 }
 
 void MapVote_Draw()
@@ -169,7 +280,7 @@ void MapVote_Draw()
        vector pos;
        float isize;
        float center;
-       float columns, rows;
+       float rows;
        float tsize;
        vector dist = '0 0 0';
 
@@ -178,10 +289,14 @@ void MapVote_Draw()
 
        if (!autocvar_hud_cursormode)
        {
-               mv_mousepos = mv_mousepos + getmousepos();
+               vector mpos = mv_mousepos + getmousepos();
+               mpos_x = bound(0, mpos_x, vid_conwidth);
+               mpos_y = bound(0, mpos_y, vid_conheight);
+               
+               if ( mpos_x != mv_mousepos_x || mpos_y != mv_mousepos_y )
+                       mv_selection_keyboard = 0;
+               mv_mousepos = mpos;
 
-               mv_mousepos_x = bound(0, mv_mousepos_x, vid_conwidth);
-               mv_mousepos_y = bound(0, mv_mousepos_y, vid_conheight);
        }
 
        center = (vid_conwidth - 1)/2;
@@ -200,11 +315,18 @@ void MapVote_Draw()
        pos_z = 0;
 
        draw_beginBoldFont();
-       map = _("Vote for a map");
+       map = ((gametypevote) ? _("Decide the gametype") : _("Vote for a map"));
        pos_x = center - stringwidth(map, false, '12 0 0');
        drawstring(pos, map, '24 24 0', '1 1 1', 1, DRAWFLAG_NORMAL);
        pos_y += 26;
 
+       if( mapvote_chosenmap != "" )
+       {
+               pos_x = center - stringwidth(mapvote_chosenmap, false, hud_fontsize*1.5/2);
+               drawstring(pos, mapvote_chosenmap, hud_fontsize*1.5, '1 1 1', 1, DRAWFLAG_NORMAL);
+               pos_y += hud_fontsize_y*2;
+       }
+
        i = ceil(max(0, mv_timeout - time));
        map = sprintf(_("%d seconds left"), i);
        pos_x = center - stringwidth(map, false, '8 0 0');
@@ -218,36 +340,56 @@ void MapVote_Draw()
        if(mv_abstain)
                mv_num_maps -= 1;
 
-       if(mv_num_maps > 3)
-       {
-               columns = 3;
-       } else {
-               columns = mv_num_maps;
-       }
-       rows = ceil(mv_num_maps / columns);
+       rows = ceil(mv_num_maps / mv_columns);
 
-       dist_x = (xmax - xmin) / columns;
+       dist_x = (xmax - xmin) / mv_columns;
        dist_y = (ymax - pos_y) / rows;
-       tsize = dist_x - 10;
-       isize = min(dist_y - 10, 0.75 * tsize);
 
-       mv_selection = MapVote_Selection(pos, dist, rows, columns);
+       if ( gametypevote )
+       {
+               tsize = dist_x - hud_fontsize_y;
+               isize = dist_y;
+               float maxheight = (ymax - pos_y) / 3;
+               if ( isize > maxheight )
+               {
+                       pos_x += (isize - maxheight)/2;
+                       isize = maxheight;
+               }
+               else
+                       dist_y += hud_fontsize_y;
+               pos_x = ( vid_conwidth - dist_x * mv_columns ) / 2;
+       }
+       else
+       {
+               tsize = dist_x - 10;
+               isize = min(dist_y - 10, 0.75 * tsize);
+       }
+
+       mv_selection = MapVote_Selection(pos, dist, rows, mv_columns);
 
-       pos_x += (xmax - xmin) / (2 * columns);
+       if ( !gametypevote )
+               pos_x += dist_x / 2;
        pos_y += (dist_y - isize) / 2;
        ymax -= isize;
 
        if (mv_top2_time)
                mv_top2_alpha = max(0.2, 1 - (time - mv_top2_time)*(time - mv_top2_time));
 
+       void (vector, float, float, string, string, float, float) DrawItem;
+
+       if(gametypevote)
+               DrawItem = GameTypeVote_DrawGameTypeItem;
+       else
+               DrawItem = MapVote_DrawMapItem;
+
        for(i = 0; i < mv_num_maps; ++i)
        {
                tmp = mv_votes[i]; // FTEQCC bug: too many array accesses in the function call screw it up
                map = mv_maps[i];
                if(mv_preview[i])
-                       MapVote_DrawMapItem(pos + MapVote_GridVec(dist, i, columns), isize, tsize, map, mv_pics[i], tmp, i);
+                       DrawItem(pos + MapVote_GridVec(dist, i, mv_columns), isize, tsize, map, mv_pics[i], tmp, i);
                else
-                       MapVote_DrawMapItem(pos + MapVote_GridVec(dist, i, columns), isize, tsize, map, "", tmp, i);
+                       DrawItem(pos + MapVote_GridVec(dist, i, mv_columns), isize, tsize, map, "", tmp, i);
        }
 
        if(mv_abstain)
@@ -329,12 +471,35 @@ void MapVote_CheckPic(string pic, string pk3, float id)
        MapVote_CheckPK3(pic, pk3, id);
 }
 
+void MapVote_ReadMask()
+{
+       float i;
+       if ( mv_num_maps < 24 )
+       {
+               float mask, power;
+               if(mv_num_maps < 8)
+                       mask = ReadByte();
+               else if(mv_num_maps < 16)
+                       mask = ReadShort();
+               else
+                       mask = ReadLong();
+               
+               for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+                       mv_avail[i] = (mask & power) ? GTV_AVAILABLE : GTV_FORBIDDEN;
+       }
+       else
+       {
+               for(i = 0; i < mv_num_maps; ++i )
+                       mv_avail[i] = ReadByte();
+       }
+}
+
 #define NUM_SSDIRS 4
 string ssdirs[NUM_SSDIRS];
 float n_ssdirs;
 void MapVote_Init()
 {
-       float i, j, power;
+       float i, j;
        string map, pk3, s;
 
        precache_sound ("misc/invshot.wav");
@@ -343,6 +508,7 @@ void MapVote_Init()
        if(autocvar_hud_cursormode) { setcursormode(1); }
        else { mv_mousepos = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; }
        mv_selection = -1;
+       mv_selection_keyboard = 0;
 
        for(n_ssdirs = 0; ; ++n_ssdirs)
        {
@@ -363,39 +529,72 @@ void MapVote_Init()
        mv_ownvote = -1;
        mv_timeout = ReadCoord();
 
-       if(mv_num_maps <= 8)
-               mv_maps_mask = ReadByte();
-       else
-               mv_maps_mask = ReadShort();
+       gametypevote = ReadByte();
+       
+       float mv_real_num_maps = mv_num_maps - mv_abstain;
+
+       if(gametypevote)
+       {
+               mapvote_chosenmap = strzone(ReadString());
+               if ( gametypevote == 2 )
+                       gametypevote = 0;
+
+               gtv_text_size = hud_fontsize*1.4;
+               gtv_text_size_small = hud_fontsize*1.1;
+               
+               if (mv_real_num_maps > 8 )
+                       mv_columns = 3;
+               else
+                       mv_columns = min(2, mv_real_num_maps);
+    }
+    else
+       {
+               if (mv_real_num_maps > 16)
+                       mv_columns = 5;
+               else if (mv_real_num_maps > 9)
+                       mv_columns = 4;
+               else if(mv_real_num_maps > 3)
+                       mv_columns = 3;
+               else
+                       mv_columns = mv_real_num_maps;
+       }
+
+       MapVote_ReadMask();
+       for(i = 0; i < mv_num_maps; ++i )
+               mv_avail_start[i] = mv_avail[i];
 
        // Assume mv_pk3list is world, there should only be 1 mapvote per round
        mv_pk3list = world; // I'm still paranoid!
 
-       for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+       for(i = 0; i < mv_num_maps; ++i)
        {
                mv_votes[i] = 0;
 
-               if(mv_maps_mask & power)
-               {
-                       map = strzone(ReadString());
-                       pk3 = strzone(ReadString());
-                       j = bound(0, ReadByte(), n_ssdirs - 1);
-
-                       mv_maps[i] = map;
-                       mv_pk3[i] = pk3;
-                       map = strzone(strcat(ssdirs[j], "/", map));
-                       mv_pics[i] = map;
+               map = strzone(ReadString());
+               pk3 = strzone(ReadString());
+               j = bound(0, ReadByte(), n_ssdirs - 1);
 
-                       mv_preview[i] = false;
+               mv_maps[i] = map;
+               mv_pk3[i] = pk3;
+               mv_avail[i] = ReadByte();
 
-                       MapVote_CheckPic(map, pk3, i);
+               if(gametypevote)
+               {
+                       //map = strzone(strcat("gfx/menu/default/gametype_", map));
+                       //map = strzone(sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, map));
+                       string mv_picpath = sprintf("gfx/menu/%s/gametype_%s", autocvar_menu_skin, map);
+                       if(precache_pic(mv_picpath) == "")
+                               mv_picpath = strcat("gfx/menu/default/gametype_", map);
+                       map = strzone(mv_picpath);
+                       mv_pics[i] = map;
+                       mv_preview[i] = PreviewExists(map);
                }
                else
                {
-                       mv_maps[i] = strzone("if-you-see-this-the-code-is-broken");
-                       mv_pk3[i] = strzone("if-you-see-this-the-code-is-broken");
-                       mv_pics[i] = strzone("if-you-see-this-the-code-is-broken");
+                       map = strzone(strcat(ssdirs[j], "/", map));
+                       mv_pics[i] = map;
                        mv_preview[i] = false;
+                       MapVote_CheckPic(map, pk3, i);
                }
        }
 
@@ -404,6 +603,68 @@ void MapVote_Init()
        n_ssdirs = 0;
 }
 
+void MapVote_SendChoice(float index)
+{
+       localcmd(strcat("\nimpulse ", ftos(index+1), "\n"));
+}
+
+float MapVote_MoveLeft(float pos)
+{
+       float imp;
+       if ( pos < 0 ) 
+               imp = mv_num_maps - 1;
+       else
+               imp = pos < 1 ? mv_num_maps - 1 : pos - 1;
+       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+               imp = MapVote_MoveLeft(imp);
+       return imp;
+}
+float MapVote_MoveRight(float pos)
+{
+       float imp;
+       if ( pos < 0 ) 
+               imp = 0;
+       else
+               imp = pos >= mv_num_maps - 1 ? 0 : pos + 1;
+       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+               imp = MapVote_MoveRight(imp);
+       return imp;
+}
+float MapVote_MoveUp(float pos)
+{
+       float imp;
+       if ( pos < 0 ) 
+               imp = mv_num_maps - 1;
+       else
+       {
+               imp = pos - mv_columns;
+               if ( imp < 0 )
+               {
+                       imp = floor(mv_num_maps/mv_columns)*mv_columns + pos % mv_columns;
+                       if ( imp >= mv_num_maps )
+                               imp -= mv_columns;
+               }
+       }
+       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+               imp = MapVote_MoveUp(imp);
+       return imp;
+}
+float MapVote_MoveDown(float pos)
+{
+       float imp;
+       if ( pos < 0 ) 
+               imp = 0;
+       else
+       {
+               imp = pos + mv_columns;
+               if ( imp >= mv_num_maps )
+                       imp = imp % mv_columns;
+       }
+       if ( mv_avail[imp] != GTV_AVAILABLE && imp != mv_ownvote )
+               imp = MapVote_MoveDown(imp);
+       return imp;
+}
+
 float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary)
 {
        float imp;
@@ -415,6 +676,7 @@ float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary)
        {
                mv_mousepos_x = nPrimary;
                mv_mousepos_y = nSecondary;
+               mv_selection_keyboard = 0;
                return true;
        }
 
@@ -440,48 +702,58 @@ float MapVote_InputEvent(float bInputType, float nPrimary, float nSecondary)
                case K_KP_8: localcmd("\nimpulse 8\n"); return true;
                case K_KP_9: localcmd("\nimpulse 9\n"); return true;
                case K_KP_0: localcmd("\nimpulse 10\n"); return true;
+
+               case K_RIGHTARROW:
+                       mv_selection_keyboard = 1;
+                       mv_selection = MapVote_MoveRight(mv_selection);
+                       return true;
+               case K_LEFTARROW:
+                       mv_selection_keyboard = 1;
+                       mv_selection = MapVote_MoveLeft(mv_selection);
+                       return true;
+               case K_DOWNARROW:
+                       mv_selection_keyboard = 1;
+                       mv_selection = MapVote_MoveDown(mv_selection);
+                       return true;
+               case K_UPARROW:
+                       mv_selection_keyboard = 1;
+                       mv_selection = MapVote_MoveUp(mv_selection);
+                       return true;
+               case K_KP_ENTER:
+               case K_ENTER:
+               case K_SPACE:
+                       if ( mv_selection_keyboard )
+                               MapVote_SendChoice(mv_selection);
+                       return true;
        }
 
        if (nPrimary == K_MOUSE1)
+       {
+               mv_selection_keyboard = 0;
+               mv_selection = mv_mouse_selection;
                if (mv_selection >= 0)
                {
                        imp = min(mv_selection + 1, mv_num_maps);
                        localcmd(strcat("\nimpulse ", ftos(imp), "\n"));
                        return true;
                }
+       }
 
        return false;
 }
 
 void MapVote_UpdateMask()
 {
-       float i, power;
-       float oldmask;
-
-       oldmask = mv_maps_mask;
-       if(mv_num_maps <= 8)
-               mv_maps_mask = ReadByte();
-       else
-               mv_maps_mask = ReadShort();
-
-       if((oldmask & mv_maps_mask) != oldmask)
-               if((oldmask & mv_maps_mask) == mv_maps_mask)
-                        sound(world, CH_INFO, "misc_invshot.wav", VOL_BASE, ATTEN_NONE);
-
-       // remove votes that no longer apply
-       for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
-               if (!(mv_maps_mask & power))
-                       mv_votes[i] = -1;
-
+       MapVote_ReadMask();
        mv_top2_time = time;
 }
 
 void MapVote_UpdateVotes()
 {
-       float i, power;
-       for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+       float i;
+       for(i = 0; i < mv_num_maps; ++i)
        {
-               if(mv_maps_mask & power)
+               if(mv_avail[i] == GTV_AVAILABLE)
                {
                        if(mv_detail)
                                mv_votes[i] = ReadByte();
index a4122d261f175961a4b52ae55a1c21418b3141f6..b536797ce4b1d05f5159b64eb4e2f623aa0f03cb 100644 (file)
@@ -1,4 +1,3 @@
-const float STAT_MOVEFLAGS = 225;
 const float MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE = 4;
 #define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
 
index 1a518c5a697f9079977a896ae21cf841cdedeb17..86a8b43395e199d83a1dc1676f5a7d234cf1a27f 100644 (file)
@@ -8,6 +8,7 @@ sys-post.qh
 Defs.qc
 ../dpdefs/keycodes.qc
 ../common/constants.qh
+../common/stats.qh
 
 ../warpzonelib/anglestransform.qh
 ../warpzonelib/mathlib.qh
@@ -16,6 +17,8 @@ Defs.qc
 
 ../common/teams.qh
 ../common/util.qh
+../common/nades.qh
+../common/buffs.qh
 ../common/test.qh
 ../common/counting.qh
 ../common/items.qh
@@ -117,6 +120,9 @@ command/cl_cmd.qc
 
 ../common/monsters/monsters.qc
 
+../common/nades.qc
+../common/buffs.qc
+
 ../warpzonelib/anglestransform.qc
 ../warpzonelib/mathlib.qc
 ../warpzonelib/common.qc
index 8cdcdf470c18c47dd2a97e5508f334b5ab647116..8ff5e0f911627e78be6315aa196989debded3b1c 100644 (file)
@@ -101,24 +101,16 @@ void Projectile_Draw()
                        case PROJECTILE_GRENADE_BOUNCING:
                                rot = '0 -1000 0'; // sideways
                                break;
-                       case PROJECTILE_NADE_RED_BURN:
-                       case PROJECTILE_NADE_RED:
-                       case PROJECTILE_NADE_BLUE_BURN:
-                       case PROJECTILE_NADE_BLUE:
-                       case PROJECTILE_NADE_YELLOW_BURN:
-                       case PROJECTILE_NADE_YELLOW:
-                       case PROJECTILE_NADE_PINK_BURN:
-                       case PROJECTILE_NADE_PINK:
-                       case PROJECTILE_NADE_BURN:
-                       case PROJECTILE_NADE:
-                               rot = self.avelocity;
-                               break;
                        case PROJECTILE_HOOKBOMB:
                                rot = '1000 0 0'; // forward
                                break;
                        default:
                                break;
                }
+
+               if(Nade_IDFromProjectile(self.cnt) != 0)
+                       rot = self.avelocity;
+
                self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
        }
 
@@ -136,18 +128,6 @@ void Projectile_Draw()
        trailorigin = self.origin;
        switch(self.cnt)
        {
-           case PROJECTILE_NADE_RED_BURN:
-               case PROJECTILE_NADE_RED:
-               case PROJECTILE_NADE_BLUE_BURN:
-               case PROJECTILE_NADE_BLUE:
-               case PROJECTILE_NADE_YELLOW_BURN:
-               case PROJECTILE_NADE_YELLOW:
-               case PROJECTILE_NADE_PINK_BURN:
-               case PROJECTILE_NADE_PINK:
-               case PROJECTILE_NADE_BURN:
-               case PROJECTILE_NADE:
-                       trailorigin += v_up * 4;
-                       break;
                case PROJECTILE_GRENADE:
                case PROJECTILE_GRENADE_BOUNCING:
                        trailorigin += v_right * 1 + v_forward * -10;
@@ -155,6 +135,10 @@ void Projectile_Draw()
                default:
                        break;
        }
+
+       if(Nade_IDFromProjectile(self.cnt) != 0)
+               trailorigin += v_up * 4;
+
        if(drawn)
                Projectile_DrawTrail(trailorigin);
        else
@@ -274,6 +258,8 @@ void Ent_Projectile()
                        self.fade_time = 0;
                        self.fade_rate = 0;
                }
+
+               self.team = ReadByte() - 1;
        }
 
        if(f & 2)
@@ -302,6 +288,7 @@ void Ent_Projectile()
                        case PROJECTILE_HOOKBOMB: setmodel(self, "models/grenademodel.md3");self.traileffect = particleeffectnum("TR_KNIGHTSPIKE"); break;
                        case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
                        case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl");self.traileffect = particleeffectnum("tr_hagar"); self.scale = 0.75; break;
+                       case PROJECTILE_NAPALM_FOUNTAIN: //self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("torch_small"); break;
                        case PROJECTILE_FIREBALL: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("fireball"); break; // particle effect is good enough
                        case PROJECTILE_FIREMINE: self.model = ""; self.modelindex = 0; self.traileffect = particleeffectnum("firemine"); break; // particle effect is good enough
                        case PROJECTILE_TAG: setmodel(self, "models/laser.mdl"); self.traileffect = particleeffectnum("TR_ROCKET"); break;
@@ -322,18 +309,8 @@ void Ent_Projectile()
                        case PROJECTILE_BUMBLE_GUN: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
                        case PROJECTILE_BUMBLE_BEAM: setmodel(self, "models/elaser.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
 
-                       case PROJECTILE_NADE_RED: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red"); break;
-                       case PROJECTILE_NADE_RED_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_red_burn"); break;
-                       case PROJECTILE_NADE_BLUE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue"); break;
-                       case PROJECTILE_NADE_BLUE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_blue_burn"); break;
-                       case PROJECTILE_NADE_YELLOW: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow"); break;
-                       case PROJECTILE_NADE_YELLOW_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_yellow_burn"); break;
-                       case PROJECTILE_NADE_PINK: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink"); break;
-                       case PROJECTILE_NADE_PINK_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_pink_burn"); break;
-                       case PROJECTILE_NADE: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade"); break;
-                       case PROJECTILE_NADE_BURN: setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum("nade_burn"); break;
-
                        default:
+                               if(Nade_IDFromProjectile(self.cnt) != 0) { setmodel(self, "models/weapons/v_ok_grenade.md3");self.traileffect = particleeffectnum(Nade_TrailEffect(self.cnt, self.team)); break; }
                                error("Received invalid CSQC projectile, can't work with this!");
                                break;
                }
@@ -366,17 +343,6 @@ void Ent_Projectile()
                                self.mins = '-3 -3 -3';
                                self.maxs = '3 3 3';
                                break;
-                       case PROJECTILE_NADE_RED_BURN:
-                       case PROJECTILE_NADE_RED:
-                       case PROJECTILE_NADE_BLUE_BURN:
-                       case PROJECTILE_NADE_BLUE:
-                               self.mins = '-3 -3 -3';
-                               self.maxs = '3 3 3';
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
-                               self.scale = 1.5;
-                               self.avelocity = randomvec() * 720;
-                               break;
                        case PROJECTILE_GRENADE_BOUNCING:
                                self.mins = '-3 -3 -3';
                                self.maxs = '3 3 3';
@@ -385,23 +351,6 @@ void Ent_Projectile()
                                self.move_bounce_factor = g_balance_grenadelauncher_bouncefactor;
                                self.move_bounce_stopspeed = g_balance_grenadelauncher_bouncestop;
                                break;
-                       case PROJECTILE_NADE_RED_BURN:
-                       case PROJECTILE_NADE_RED:
-                       case PROJECTILE_NADE_BLUE_BURN:
-                       case PROJECTILE_NADE_BLUE:
-                       case PROJECTILE_NADE_YELLOW_BURN:
-                       case PROJECTILE_NADE_YELLOW:
-                       case PROJECTILE_NADE_PINK_BURN:
-                       case PROJECTILE_NADE_PINK:
-                       case PROJECTILE_NADE_BURN:
-                       case PROJECTILE_NADE:
-                               self.mins = '-16 -16 -16';
-                               self.maxs = '16 16 16';
-                               self.move_movetype = MOVETYPE_BOUNCE;
-                               self.move_touch = func_null;
-                               self.scale = 1.5;
-                               self.avelocity = randomvec() * 720;
-                               break;
                        case PROJECTILE_SHAMBLER_LIGHTNING:
                                self.mins = '-8 -8 -8';
                                self.maxs = '8 8 8';
@@ -432,6 +381,7 @@ void Ent_Projectile()
                                self.move_movetype = MOVETYPE_BOUNCE;
                                self.move_touch = func_null;
                                break;
+                       case PROJECTILE_NAPALM_FOUNTAIN:
                        case PROJECTILE_FIREBALL:
                                loopsound(self, CH_SHOTS_SINGLE, "weapons/fireball_fly2.wav", VOL_BASE, ATTEN_NORM);
                                self.mins = '-16 -16 -16';
@@ -488,6 +438,22 @@ void Ent_Projectile()
                        default:
                                break;
                }
+
+               if(Nade_IDFromProjectile(self.cnt) != 0)
+               {
+                       self.mins = '-16 -16 -16';
+                       self.maxs = '16 16 16';
+                       self.colormod = Nade_Color(Nade_IDFromProjectile(self.cnt));
+                       self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+                       self.move_movetype = MOVETYPE_BOUNCE;
+                       self.move_touch = func_null;
+                       self.scale = 1.5;
+                       self.avelocity = randomvec() * 720;
+                       
+                       if(Nade_IDFromProjectile(self.cnt) == NADE_TYPE_TRANSLOCATE)
+                               self.solid = SOLID_TRIGGER;
+               }
+
                setsize(self, self.mins, self.maxs);
        }
 
@@ -526,6 +492,7 @@ void Projectile_Precache()
        precache_model("models/rocket.md3");
        precache_model("models/tagrocket.md3");
        precache_model("models/tracer.mdl");
+       precache_model("models/sphere/sphere.md3");
 
        precache_model("models/weapons/v_ok_grenade.md3");
 
index 46dcfb4c451f09c46287aa21a5a4bde008c8426e..657fa72ff9789bddf1b6e06c9f4e69a54027bd8d 100644 (file)
@@ -287,19 +287,15 @@ void Cmd_HUD_Help()
                "other gamemodes except DM.\n"));
 }
 
-string HUD_DefaultColumnLayout()
-{
-       return strcat( // fteqcc sucks
-               "ping pl name | ",
-               "-teams,race,lms/kills +freezetag/kills -teams,lms/deaths +freezetag/deaths -teams,lms,race,ka/suicides +freezetag/suicides -race,dm,tdm,ka,freezetag/frags ", // tdm already has this in "score"
-               "+tdm/kills +tdm/deaths +tdm/suicides ",
-               "+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns ",
-               "+lms/lives +lms/rank ",
-               "+kh/caps +kh/pushes +kh/destroyed ",
-               "?+race/laps ?+race/time ?+race/fastest ",
-               "+as/objectives +nexball/faults +nexball/goals +ka/pickups +ka/bckills +ka/bctime +freezetag/revivals ",
-               "-lms,race,nexball/score");
-}
+#define HUD_DefaultColumnLayout() \
+"ping pl name | " \
+"-teams,race,lms/kills +ft,tdm/kills -teams,lms/deaths +ft,tdm/deaths -teams,lms,race,ka/suicides +ft,tdm/suicides -race,dm,tdm,ka,ft/frags " /* tdm already has this in "score" */ \
+"+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns " \
+"+lms/lives +lms/rank " \
+"+kh/caps +kh/pushes +kh/destroyed " \
+"?+race/laps ?+race/time ?+race/fastest " \
+"+as/objectives +nb/faults +nb/goals +ka/pickups +ka/bckills +ka/bctime +ft/revivals " \
+"-lms,race,nb/score"
 
 void Cmd_HUD_SetFields(float argc)
 {
@@ -308,6 +304,16 @@ void Cmd_HUD_SetFields(float argc)
        float have_name = 0, have_primary = 0, have_secondary = 0, have_separator = 0;
        float missing;
 
+       if(!gametype)
+       {
+               // set up a temporary scoreboard layout
+               // no layout can be properly set up until score_info data haven't been received
+               argc = tokenizebyseparator("0 1 ping pl name | score", " ");
+               ps_primary = 0;
+               scores_label[ps_primary] = strzone("score");
+               scores_flags[ps_primary] = SFL_ALLOW_HIDE;
+       }
+
        // TODO: re enable with gametype dependant cvars?
        if(argc < 3) // no arguments provided
                argc = tokenizebyseparator(strcat("0 1 ", autocvar_scoreboard_columns), " ");
@@ -376,7 +382,7 @@ void Cmd_HUD_SetFields(float argc)
                        hud_field[hud_num_fields] = SP_PL;
                } else if(str == "kd" || str == "kdr" || str == "kdratio" || str == "k/d") {
                        hud_field[hud_num_fields] = SP_KDRATIO;
-               } else if(str == "sum" || str == "diff" || str == "f-d") {
+               } else if(str == "sum" || str == "diff" || str == "k-d") {
                        hud_field[hud_num_fields] = SP_SUM;
                } else if(str == "name" || str == "nick") {
                        hud_field[hud_num_fields] = SP_NAME;
@@ -670,7 +676,7 @@ string HUD_FixScoreboardColumnWidth(float i, string str)
        return str;
 }
 
-void HUD_PrintScoreboardItem(vector pos, entity pl, float is_self, float pl_number)
+void HUD_PrintScoreboardItem(vector pos, vector item_size, entity pl, float is_self, float pl_number)
 {
        vector tmp, rgb;
        rgb = Team_ColorRGB(pl.team);
@@ -684,18 +690,17 @@ void HUD_PrintScoreboardItem(vector pos, entity pl, float is_self, float pl_numb
                rgb_y = autocvar_scoreboard_color_bg_g + 0.5;
                rgb_z = autocvar_scoreboard_color_bg_b + 0.5; }
 
-       // Layout:
-       tmp_x = sbwidth;
-       tmp_y = hud_fontsize_y * 1.25;
-       tmp_z = 0;
-
+       vector h_pos = pos - '1 1 0';
+       vector h_size = item_size + '2 0 0';
        // alternated rows highlighting
        if(is_self)
-               drawfill(pos - '1 1 0', tmp + '2 0 0', rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
+               drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
        else if((scoreboard_highlight) && (!mod(pl_number,2)))
-               drawfill(pos - '1 1 0', tmp + '2 0 0', rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
+               drawfill(h_pos, h_size, rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
 
+       tmp_x = item_size_x;
        tmp_y = 0;
+       tmp_z = 0;
 
        for(i = 0; i < hud_num_fields; ++i)
        {
@@ -794,6 +799,9 @@ void HUD_PrintScoreboardItem(vector pos, entity pl, float is_self, float pl_numb
                        pos_x -= hud_size[i] + hud_fontsize_x;
                }
        }
+
+       if(pl.eliminated)
+               drawfill(h_pos, h_size, '0 0 0', 0.5, DRAWFLAG_NORMAL);
 }
 
 /*
@@ -907,6 +915,10 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
        pos_y += 1.25 * hud_fontsize_y; // skip the header
        pos_y += autocvar_scoreboard_border_thickness;
 
+       // item size
+       tmp_x = sbwidth;
+       tmp_y = hud_fontsize_y * 1.25;
+
        // fill the table and draw the rows
        i = 0;
        if (teamplay)
@@ -914,7 +926,7 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
                {
                        if(pl.team != tm.team)
                                continue;
-                       HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
+                       HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
                        pos_y += 1.25 * hud_fontsize_y;
                        ++i;
                }
@@ -923,7 +935,7 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
                {
                        if(pl.team == NUM_SPECTATOR)
                                continue;
-                       HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
+                       HUD_PrintScoreboardItem(pos, tmp, pl, (pl.sv_entnum == player_localnum), i);
                        pos_y += 1.25 * hud_fontsize_y;
                        ++i;
                }
@@ -965,7 +977,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
        float fontsize = height * 1/3;
        float weapon_height = height * 2/3;
        float weapon_width = sbwidth / weapon_cnt;
-       float g_minstagib = 0;
+       float g_instagib = 0;
 
        drawstring(pos, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
        pos_y += 1.25 * hud_fontsize_y + autocvar_scoreboard_border_thickness;
@@ -999,7 +1011,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
                pos_x += weapon_width / 2;
 
        if(switchweapon == WEP_MINSTANEX)
-               g_minstagib = 1; // TODO: real detection for minstagib?
+               g_instagib = 1; // TODO: real detection for instagib?
 
        float weapon_stats;
        if(autocvar_scoreboard_accuracy_nocolors)
@@ -1012,7 +1024,7 @@ vector HUD_DrawScoreboardAccuracyStats(vector pos, vector rgb, vector bg_size)
                self = get_weaponinfo(i);
                if (!self.weapon)
                        continue;
-               if ((i == WEP_NEX && g_minstagib) || i == WEP_PORTO || (i == WEP_MINSTANEX && !g_minstagib) || i == WEP_TUBA) // skip port-o-launch, nex || minstanex and tuba
+               if ((i == WEP_NEX && g_instagib) || i == WEP_PORTO || (i == WEP_MINSTANEX && !g_instagib) || i == WEP_TUBA) // skip port-o-launch, vortex || vaporizer and tuba
                        continue;
                weapon_stats = weapon_accuracy[i-WEP_FIRST];
 
@@ -1330,12 +1342,16 @@ void HUD_DrawScoreboard()
        float specs;
        specs = 0;
        tmp = pos;
+       vector item_size;
+       item_size_x = sbwidth;
+       item_size_y = hud_fontsize_y * 1.25;
+       item_size_z = 0;
        for(pl = players.sort_next; pl; pl = pl.sort_next)
        {
                if(pl.team != NUM_SPECTATOR)
                        continue;
                pos_y += 1.25 * hud_fontsize_y;
-               HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), specs);
+               HUD_PrintScoreboardItem(pos, item_size, pl, (pl.sv_entnum == player_localnum), specs);
                ++specs;
        }
 
index 413eaaf54714170958e354c59a6d5cf39c1bdffb..5deba45c41efe5b66636d4fdd5b65ebfb64c1111 100644 (file)
@@ -104,7 +104,7 @@ void Draw_ShowNames(entity ent)
                if(!ent.sameteam || (ent.sv_entnum == player_localentnum))
                        ent.alpha *= getplayeralpha(ent.sv_entnum-1);
 
-               if(ent.alpha < ALPHA_MIN_VISIBLE)
+               if(ent.alpha < ALPHA_MIN_VISIBLE && gametype != MAPINFO_TYPE_CTS)
                        return;
 
                float dist;
index a22347fe3ca3f53ebea4acbd59eb01aa05bc684f..38ce1090a12aea33334f64478bb69dd33bc27172 100644 (file)
@@ -63,15 +63,15 @@ void tubasound(entity e, float restart)
                                snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
                }
 
-               sound7(e, CH_TUBA, snd1, e.cnt * f1, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p1, 0);
+               sound7(e, CH_TUBA_SINGLE, snd1, e.cnt * f1, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p1, 0);
                if(f2)
-                       sound7(e.enemy, CH_TUBA, snd2, e.cnt * f2, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p2, 0);
+                       sound7(e.enemy, CH_TUBA_SINGLE, snd2, e.cnt * f2, e.attenuate * autocvar_g_balance_tuba_attenuation, 100 * p2, 0);
        }
        else
        {
                if(restart)
                        snd1 = TUBA_STARTNOTE(e.tuba_instrument, e.note);
-               sound(e, CH_TUBA, snd1, e.cnt, e.attenuate * autocvar_g_balance_tuba_attenuation);
+               sound(e, CH_TUBA_SINGLE, snd1, e.cnt, e.attenuate * autocvar_g_balance_tuba_attenuation);
        }
 }
 
@@ -86,10 +86,10 @@ void Ent_TubaNote_Think()
        self.nextthink = time;
        if(self.cnt <= 0)
        {
-               sound(self, CH_TUBA, "misc/null.wav", 0, 0);
+               sound(self, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
                if(self.enemy)
                {
-                       sound(self.enemy, CH_TUBA, "misc/null.wav", 0, 0);
+                       sound(self.enemy, CH_TUBA_SINGLE, "misc/null.wav", 0, 0);
                        remove(self.enemy);
                }
                remove(self);
index 1367501a8a3743ab17b2c2fa5dbb02c9a7870911..7ee34672c5caa087b242ef27aad7b8d3e64f8363 100644 (file)
@@ -241,6 +241,7 @@ vector spritelookupcolor(string s, vector def)
 }
 string spritelookuptext(string s)
 {
+       if(substring(s, 0, 5) == "buff-") { return Buff_PrettyName(Buff_Type_FromSprite(s)); }
        switch(s)
        {
                case "as-push": return _("Push");
@@ -309,7 +310,7 @@ string spritelookuptext(string s)
                case "item-shield": return _("Shield");
                case "item-fuelregen": return _("Fuel regen");
                case "item-jetpack": return _("Jet Pack");
-               case "freezetag_frozen": return _("Frozen!");
+               case "frozen": return _("Frozen!");
                case "tagged-target": return _("Tagged");
                case "vehicle": return _("Vehicle");
                default: return s;
diff --git a/qcsrc/common/buffs.qc b/qcsrc/common/buffs.qc
new file mode 100644 (file)
index 0000000..2f8e0fc
--- /dev/null
@@ -0,0 +1,63 @@
+vector Buff_Color(float buff_id)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_id == e.items)
+                       return e.colormod;
+       return '1 1 1';
+}
+
+string Buff_PrettyName(float buff_id)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_id == e.items)
+                       return e.message;
+       return "";
+}
+
+string Buff_Name(float buff_id)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_id == e.items)
+                       return e.netname;
+       return "";
+}
+
+float Buff_Type_FromName(string buff_name)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_name == e.netname)
+                       return e.items;
+       return 0;
+}
+
+float Buff_Type_FromSprite(string buff_sprite)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_sprite == e.model2)
+                       return e.items;
+       return 0;
+}
+
+
+float Buff_Skin(float buff_id)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_id == e.items)
+                       return e.skin;
+       return 0;
+}
+
+string Buff_Sprite(float buff_id)
+{
+       entity e;
+       for(e = Buff_Type_first; e; e = e.enemy)
+               if(buff_id == e.items)
+                       return e.model2;
+       return "";
+}
diff --git a/qcsrc/common/buffs.qh b/qcsrc/common/buffs.qh
new file mode 100644 (file)
index 0000000..c29dad6
--- /dev/null
@@ -0,0 +1,93 @@
+entity Buff_Type_first;
+entity Buff_Type_last;
+.entity enemy; // internal next pointer
+
+var float BUFF_LAST = 1;
+
+.float items; // buff ID
+.string netname; // buff name
+.string message; // human readable name
+.vector colormod; // buff color
+.string model2; // buff sprite
+.float skin; // buff skin
+
+#define REGISTER_BUFF(hname,sname,NAME,bskin,bcolor) \
+       var float BUFF_##NAME; \
+       var entity Buff_Type##sname; \
+       void RegisterBuffs_##sname() \
+       { \
+               BUFF_##NAME = BUFF_LAST * 2; \
+               BUFF_LAST = BUFF_##NAME; \
+               Buff_Type##sname = spawn(); \
+               Buff_Type##sname.items = BUFF_##NAME; \
+               Buff_Type##sname.netname = #sname; \
+               Buff_Type##sname.message = hname; \
+               Buff_Type##sname.skin = bskin; \
+               Buff_Type##sname.colormod = bcolor; \
+               Buff_Type##sname.model2 = strzone(strcat("buff-", #sname)); \
+               if(!Buff_Type_first) \
+                       Buff_Type_first = Buff_Type##sname; \
+               if(Buff_Type_last) \
+                       Buff_Type_last.enemy = Buff_Type##sname; \
+               Buff_Type_last = Buff_Type##sname; \
+       } \
+       ACCUMULATE_FUNCTION(RegisterBuffs, RegisterBuffs_##sname)
+
+REGISTER_BUFF(_("Ammo"),ammo,AMMO,3,'0.2 1 0.2');
+REGISTER_BUFF(_("Resistance"),resistance,RESISTANCE,0,'0.3 0.2 1');
+REGISTER_BUFF(_("Speed"),speed,SPEED,9,'1 1 0.2');
+REGISTER_BUFF(_("Medic"),medic,MEDIC,1,'1 0.3 1');
+REGISTER_BUFF(_("Bash"),bash,BASH,5,'1 0.4 0');
+REGISTER_BUFF(_("Vampire"),vampire,VAMPIRE,2,'1 0.15 0');
+REGISTER_BUFF(_("Disability"),disability,DISABILITY,7,'0.66 0.66 0.73');
+REGISTER_BUFF(_("Vengeance"),vengeance,VENGEANCE,15,'0.55 0.5 1');
+REGISTER_BUFF(_("Jump"),jump,JUMP,10,'0.7 0.2 1');
+REGISTER_BUFF(_("Flight"),flight,FLIGHT,11,'1 0.2 0.5');
+REGISTER_BUFF(_("Invisible"),invisible,INVISIBLE,12,'0.9 0.9 0.9');
+#undef REGISTER_BUFF
+
+#ifdef SVQC
+.float buffs;
+void buff_Init(entity ent);
+void buff_Init_Compat(entity ent, float replacement);
+
+#define BUFF_SPAWNFUNC(e,b,t) void spawnfunc_item_buff_##e() { self.buffs = b; self.team = t; buff_Init(self); }
+#define BUFF_SPAWNFUNC_Q3TA_COMPAT(o,r) void spawnfunc_item_##o() { buff_Init_Compat(self,r); }
+#define BUFF_SPAWNFUNCS(e,b)                         \
+        BUFF_SPAWNFUNC(e,           b,  0)           \
+        BUFF_SPAWNFUNC(e##_team1,   b,  NUM_TEAM_1) \
+        BUFF_SPAWNFUNC(e##_team2,   b,  NUM_TEAM_2) \
+        BUFF_SPAWNFUNC(e##_team3,   b,  NUM_TEAM_3) \
+        BUFF_SPAWNFUNC(e##_team4,   b,  NUM_TEAM_4) 
+
+BUFF_SPAWNFUNCS(resistance,            BUFF_RESISTANCE)
+BUFF_SPAWNFUNCS(ammo,                  BUFF_AMMO)
+BUFF_SPAWNFUNCS(speed,                 BUFF_SPEED)
+BUFF_SPAWNFUNCS(medic,                 BUFF_MEDIC)
+BUFF_SPAWNFUNCS(bash,                  BUFF_BASH)
+BUFF_SPAWNFUNCS(vampire,               BUFF_VAMPIRE)
+BUFF_SPAWNFUNCS(disability,            BUFF_DISABILITY)
+BUFF_SPAWNFUNCS(vengeance,             BUFF_VENGEANCE)
+BUFF_SPAWNFUNCS(jump,                  BUFF_JUMP)
+BUFF_SPAWNFUNCS(flight,                        BUFF_FLIGHT)
+BUFF_SPAWNFUNCS(invisible,             BUFF_INVISIBLE)
+BUFF_SPAWNFUNCS(random,                        0)
+
+BUFF_SPAWNFUNC_Q3TA_COMPAT(doubler,    BUFF_MEDIC)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(resistance, BUFF_RESISTANCE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(scout,      BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(ammoregen,  BUFF_AMMO)
+
+// actually Q3
+BUFF_SPAWNFUNC_Q3TA_COMPAT(haste,      BUFF_SPEED)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(invis,      BUFF_INVISIBLE)
+BUFF_SPAWNFUNC_Q3TA_COMPAT(medic,      BUFF_MEDIC)
+#endif
+
+vector Buff_Color(float buff_id);
+string Buff_PrettyName(float buff_id);
+string Buff_Name(float buff_id);
+float Buff_Type_FromName(string buff_name);
+float Buff_Type_FromSprite(string buff_sprite);
+float Buff_Skin(float buff_id);
+string Buff_Sprite(float buff_id);
index d4912ebb8dff59e7c389a60673b8fcdac61c4741..2be0112d79ea149954224636dfb225c70704392a 100644 (file)
@@ -96,11 +96,13 @@ const float ENT_CLIENT_BUMBLE_RAYGUN = 35;
 const float ENT_CLIENT_SPAWNPOINT = 36;
 const float ENT_CLIENT_SPAWNEVENT = 37;
 const float ENT_CLIENT_NOTIFICATION = 38;
-
+const float ENT_CLIENT_ELIMINATEDPLAYERS = 39;
 const float ENT_CLIENT_TURRET = 40;
 const float ENT_CLIENT_AUXILIARYXHAIR = 50;
 const float ENT_CLIENT_VEHICLE = 60;
 
+const float ENT_CLIENT_HEALING_ORB = 80;
+
 const float SPRITERULE_DEFAULT = 0;
 const float SPRITERULE_TEAMPLAY = 1;
 
@@ -139,99 +141,6 @@ const float CVAR_READONLY = 4;
 ///////////////////////////
 // csqc communication stuff
 
-const float STAT_KH_KEYS = 32;
-const float STAT_CTF_STATE = 33;
-const float STAT_WEAPONS = 35;
-const float STAT_SWITCHWEAPON = 36;
-const float STAT_GAMESTARTTIME = 37;
-const float STAT_STRENGTH_FINISHED = 38;
-const float STAT_INVINCIBLE_FINISHED = 39;
-const float STAT_PRESSED_KEYS = 42;
-const float STAT_ALLOW_OLDNEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config
-const float STAT_FUEL = 44;
-const float STAT_NB_METERSTART = 45;
-const float STAT_SHOTORG = 46; // compressShotOrigin
-const float STAT_LEADLIMIT = 47;
-const float STAT_WEAPON_CLIPLOAD = 48;
-const float STAT_WEAPON_CLIPSIZE = 49;
-const float STAT_NEX_CHARGE = 50;
-const float STAT_LAST_PICKUP = 51;
-const float STAT_HUD = 52;
-const float STAT_NEX_CHARGEPOOL = 53;
-const float STAT_HIT_TIME = 54;
-const float STAT_TYPEHIT_TIME = 55;
-const float STAT_LAYED_MINES = 56;
-const float STAT_HAGAR_LOAD = 57;
-const float STAT_SWITCHINGWEAPON = 58;
-const float STAT_SUPERWEAPONS_FINISHED = 59;
-
-const float STAT_VEHICLESTAT_HEALTH = 60;
-const float STAT_VEHICLESTAT_SHIELD = 61;
-const float STAT_VEHICLESTAT_ENERGY = 62;
-const float STAT_VEHICLESTAT_AMMO1 = 63;
-const float STAT_VEHICLESTAT_RELOAD1 = 64;
-const float STAT_VEHICLESTAT_AMMO2 = 65;
-const float STAT_VEHICLESTAT_RELOAD2 = 66;
-
-const float STAT_SECRETS_TOTAL = 70;
-const float STAT_SECRETS_FOUND = 71;
-
-const float STAT_RESPAWN_TIME = 72;
-const float STAT_ROUNDSTARTTIME = 73;
-
-const float STAT_WEAPONS2 = 74;
-const float STAT_WEAPONS3 = 75;
-
-const float STAT_MONSTERS_TOTAL = 76;
-const float STAT_MONSTERS_KILLED = 77;
-
-// mod stats (1xx)
-const float STAT_REDALIVE = 100;
-const float STAT_BLUEALIVE = 101;
-const float STAT_YELLOWALIVE = 102;
-const float STAT_PINKALIVE = 103;
-
-// freeze tag
-const float STAT_FROZEN = 104;
-const float STAT_REVIVE_PROGRESS = 105;
-
-// domination
-const float STAT_DOM_TOTAL_PPS = 100;
-const float STAT_DOM_PPS_RED = 101;
-const float STAT_DOM_PPS_BLUE = 102;
-const float STAT_DOM_PPS_PINK = 103;
-const float STAT_DOM_PPS_YELLOW = 104;
-
-//const float STAT_SPIDERBOT_AIM 53 // compressShotOrigin
-//const float STAT_SPIDERBOT_TARGET 54 // compressShotOrigin
-
-// see DP source, quakedef.h
-const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
-const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223;
-const float STAT_MOVEVARS_MAXSPEED = 244;
-const float STAT_MOVEVARS_AIRACCEL_QW = 254;
-
-// new properties
-const float STAT_MOVEVARS_JUMPVELOCITY = 250;
-const float STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR = 220;
-const float STAT_MOVEVARS_MAXAIRSTRAFESPEED = 233;
-const float STAT_MOVEVARS_MAXAIRSPEED = 252;
-const float STAT_MOVEVARS_AIRSTRAFEACCELERATE = 232;
-const float STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL = 229;
-const float STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION = 255;
-const float STAT_MOVEVARS_AIRCONTROL = 234;
-const float STAT_MOVEVARS_AIRCONTROL_POWER = 224;
-const float STAT_MOVEVARS_AIRCONTROL_PENALTY = 221;
-const float STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL = 226;
-const float STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED = 228;
-const float STAT_MOVEVARS_WARSOWBUNNY_ACCEL = 227;
-const float STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO = 230;
-const float STAT_MOVEVARS_FRICTION = 238;
-const float STAT_MOVEVARS_ACCELERATE = 246;
-const float STAT_MOVEVARS_STOPSPEED = 243;
-const float STAT_MOVEVARS_AIRACCELERATE = 247;
-const float STAT_MOVEVARS_AIRSTOPACCELERATE = 231;
-
 const float CTF_STATE_ATTACK = 1;
 const float CTF_STATE_DEFEND = 2;
 const float CTF_STATE_COMMANDER = 3;
@@ -251,7 +160,7 @@ const vector eZ = '0 0 1';
 
 // moved that here so the client knows the max.
 // # of maps, I'll use arrays for them :P
-#define MAPVOTE_COUNT 10
+#define MAPVOTE_COUNT 30
 
 /**
  * Lower scores are better (e.g. suicides)
@@ -301,23 +210,6 @@ const vector eZ = '0 0 1';
 #define SP_SCORE 3
 // game mode specific indices are not in common/, but in server/scores_rules.qc!
 
-#ifdef COMPAT_XON010_CHANNELS
-const float CH_INFO = 0; // only on world and csqc
-const float CH_TRIGGER = 0; // only on players; compat: FALSELY CONTROLLED BY "Info"
-const float CH_WEAPON_A = 1; // only on players and entities
-const float CH_WEAPON_SINGLE = 5; // only on players and entities
-const float CH_VOICE = 2; // only on players
-const float CH_BGM_SINGLE = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
-const float CH_AMBIENT = 2; // only on csqc; compat: FALSELY CONTROLLED BY "Voice"
-const float CH_TRIGGER_SINGLE = 3; // only on players, entities, csqc
-const float CH_SHOTS = 4; // only on players, entities, csqc
-const float CH_SHOTS_SINGLE = 4; // only on players, entities, csqc
-const float CH_WEAPON_B = 5; // only on players and entities
-const float CH_PAIN = 6; // only on players and csqc
-const float CH_PAIN_SINGLE = 6; // only on players and csqc
-const float CH_PLAYER = 7; // only on players and entities
-const float CH_TUBA = 5; // only on csqc
-#else
 const float CH_INFO = 0;
 const float CH_TRIGGER = -3;
 const float CH_WEAPON_A = -1;
@@ -332,8 +224,8 @@ const float CH_WEAPON_B = -1;
 const float CH_PAIN = -6;
 const float CH_PAIN_SINGLE = 6;
 const float CH_PLAYER = -7;
-const float CH_TUBA = 5;
-#endif
+const float CH_PLAYER_SINGLE = 7;
+const float CH_TUBA_SINGLE = 5;
 
 const float ATTEN_NONE = 0;
 const float ATTEN_MIN = 0.015625;
@@ -381,17 +273,6 @@ const float PROJECTILE_BUMBLE_BEAM = 31;
 const float PROJECTILE_MAGE_SPIKE = 32;
 const float PROJECTILE_SHAMBLER_LIGHTNING = 33;
 
-const float PROJECTILE_NADE_RED = 50;
-const float PROJECTILE_NADE_RED_BURN = 51;
-const float PROJECTILE_NADE_BLUE = 52;
-const float PROJECTILE_NADE_BLUE_BURN = 53;
-const float PROJECTILE_NADE_YELLOW = 54;
-const float PROJECTILE_NADE_YELLOW_BURN = 55;
-const float PROJECTILE_NADE_PINK = 56;
-const float PROJECTILE_NADE_PINK_BURN = 57;
-const float PROJECTILE_NADE = 58;
-const float PROJECTILE_NADE_BURN = 59;
-
 const float SPECIES_HUMAN = 0;
 const float SPECIES_ROBOT_SOLID = 1;
 const float SPECIES_ALIEN = 2;
@@ -476,3 +357,8 @@ noref var vector autocvar_sv_player_headsize = '24 24 12';
 #define URI_GET_UPDATENOTIFICATION 33
 #define URI_GET_URLLIB 128
 #define URI_GET_URLLIB_END 191
+
+// gametype votes
+#define GTV_AVAILABLE 0
+// for later use in per-map gametype filtering
+#define GTV_FORBIDDEN 2
index 1265e7eea05736d3ac2270e1e0b3a33af5e141c5..c8512cdcf25c7039bc352946e328bdb0566c19a8 100644 (file)
@@ -4,6 +4,7 @@
 
 #define DEATHTYPES \
        DEATHTYPE(DEATH_AUTOTEAMCHANGE,         DEATH_SELF_AUTOTEAMCHANGE,          NO_MSG,                        DEATH_SPECIAL_START) \
+       DEATHTYPE(DEATH_BUFF_VENGEANCE,         NO_MSG,                             DEATH_MURDER_VENGEANCE,        NORMAL_POS) \
        DEATHTYPE(DEATH_CAMP,                   DEATH_SELF_CAMP,                    NO_MSG,                        NORMAL_POS) \
        DEATHTYPE(DEATH_CHEAT,                  DEATH_SELF_CHEAT,                   DEATH_MURDER_CHEAT,            NORMAL_POS) \
        DEATHTYPE(DEATH_CUSTOM,                 DEATH_SELF_CUSTOM,                  NO_MSG,                        NORMAL_POS) \
        DEATHTYPE(DEATH_MONSTER_WYVERN,                 DEATH_SELF_MON_WYVERN,                          DEATH_MURDER_MONSTER,              NORMAL_POS) \
        DEATHTYPE(DEATH_MONSTER_ZOMBIE_JUMP,    DEATH_SELF_MON_ZOMBIE_JUMP,                     DEATH_MURDER_MONSTER,              NORMAL_POS) \
        DEATHTYPE(DEATH_MONSTER_ZOMBIE_MELEE,   DEATH_SELF_MON_ZOMBIE_MELEE,            DEATH_MURDER_MONSTER,              DEATH_MONSTER_LAST) \
-       DEATHTYPE(DEATH_NADE,                                   DEATH_SELF_NADE,                                        DEATH_MURDER_NADE,                         NORMAL_POS) \
+       DEATHTYPE(DEATH_NADE,                   DEATH_SELF_NADE,                    DEATH_MURDER_NADE,             NORMAL_POS) \
+       DEATHTYPE(DEATH_NADE_NAPALM,            DEATH_SELF_NADE_NAPALM,             DEATH_MURDER_NADE_NAPALM,      NORMAL_POS) \
+       DEATHTYPE(DEATH_NADE_ICE,               DEATH_SELF_NADE_ICE,                DEATH_MURDER_NADE_ICE,         NORMAL_POS) \
+       DEATHTYPE(DEATH_NADE_ICE_FREEZE,        DEATH_SELF_NADE_ICE_FREEZE,         DEATH_MURDER_NADE_ICE_FREEZE,  NORMAL_POS) \
+       DEATHTYPE(DEATH_NADE_HEAL,              DEATH_SELF_NADE_HEAL,               DEATH_MURDER_NADE_HEAL,        NORMAL_POS) \
        DEATHTYPE(DEATH_NOAMMO,                 DEATH_SELF_NOAMMO,                  NO_MSG,                        NORMAL_POS) \
        DEATHTYPE(DEATH_ROT,                    DEATH_SELF_ROT,                     NO_MSG,                        NORMAL_POS) \
        DEATHTYPE(DEATH_SHOOTING_STAR,          DEATH_SELF_SHOOTING_STAR,           DEATH_MURDER_SHOOTING_STAR,    NORMAL_POS) \
index b8fe58b34481a868bb7883e773d887183af876d7..84df17516d09f7c1a7873618eaa0874ccb27d660 100644 (file)
@@ -688,6 +688,18 @@ float MapInfo_Type_FromString(string t)
                t = "inv";
                print("'. Should use '", t, "'.\n");
        }
+       if(t == "assault")
+       {
+               print("MapInfo_Type_FromString (probably ", MapInfo_Map_bspname, "): using deprecated name '", t);
+               t = "as";
+               print("'. Should use '", t, "'.\n");
+       }
+       if(t == "race")
+       {
+               print("MapInfo_Type_FromString (probably ", MapInfo_Map_bspname, "): using deprecated name '", t);
+               t = "rc";
+               print("'. Should use '", t, "'.\n");
+       }
        if(t == "all")
                return MAPINFO_TYPE_ALL;
        for(e = MapInfo_Type_first; e; e = e.enemy)
@@ -696,6 +708,15 @@ float MapInfo_Type_FromString(string t)
        return 0;
 }
 
+string MapInfo_Type_Description(float t)
+{
+       entity e;
+       for(e = MapInfo_Type_first; e; e = e.enemy)
+               if(t == e.items)
+                       return e.gametype_description;
+       return "";
+}
+
 string MapInfo_Type_ToString(float t)
 {
        entity e;
@@ -1006,7 +1027,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, float pAllowGenerate, flo
                {
                        t = car(s); s = cdr(s);
                        f = MapInfo_Type_FromString(t);
-                       print("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.\n");
+                       dprint("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.\n");
                        if(f)
                                _MapInfo_Map_ApplyGametype (s, pGametypeToSet, f, TRUE);
                        else
@@ -1203,7 +1224,7 @@ float MapInfo_CurrentFeatures()
 {
        float req;
        req = 0;
-       if(!(cvar("g_lms") || cvar("g_minstagib") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") || cvar("g_race") || cvar("g_cts") || cvar("g_nexball")))
+       if(!(cvar("g_lms") || cvar("g_instagib") || cvar("g_nix") || cvar("g_weaponarena") || !cvar("g_pickup_items") || cvar("g_race") || cvar("g_cts") || cvar("g_nexball")))
                req |= MAPINFO_FEATURE_WEAPONS;
        return req;
 }
@@ -1265,14 +1286,14 @@ void MapInfo_LoadMap(string s, float reinit)
                localcmd(strcat("\nchangelevel ", s, "\n"));
 }
 
-string MapInfo_ListAllowedMaps(float pRequiredFlags, float pForbiddenFlags)
+string MapInfo_ListAllowedMaps(float type, float pRequiredFlags, float pForbiddenFlags)
 {
        string out;
        float i;
 
        // to make absolutely sure:
        MapInfo_Enumerate();
-       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
+       MapInfo_FilterGametype(type, MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
 
        out = "";
        for(i = 0; i < MapInfo_count; ++i)
index 3c0afec9827f87010a6c7fe4a7b67117dfb178b5..3eae41ea676871158176370606ab65bb136be9a3 100644 (file)
@@ -8,8 +8,9 @@ entity MapInfo_Type_last;
 .string mdl; // game type short name
 .string message; // human readable name
 .string model2; // game type defaults
+.string gametype_description; // game type description
 
-#define REGISTER_GAMETYPE(hname,sname,g_name,NAME,defaults) \
+#define REGISTER_GAMETYPE(hname,sname,g_name,NAME,defaults,gdescription) \
        var float MAPINFO_TYPE_##NAME; \
        var entity MapInfo_Type##g_name; \
        void RegisterGametypes_##g_name() \
@@ -22,6 +23,7 @@ entity MapInfo_Type_last;
                MapInfo_Type##g_name.mdl = #sname; \
                MapInfo_Type##g_name.message = hname; \
                MapInfo_Type##g_name.model2 = defaults; \
+               MapInfo_Type##g_name.gametype_description = gdescription; \
                if(!MapInfo_Type_first) \
                        MapInfo_Type_first = MapInfo_Type##g_name; \
                if(MapInfo_Type_last) \
@@ -33,52 +35,52 @@ entity MapInfo_Type_last;
 #define IS_GAMETYPE(NAME) \
        (MapInfo_LoadedGametype == MAPINFO_TYPE_##NAME)
 
-REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,"timelimit=20 pointlimit=30 leadlimit=0");
+REGISTER_GAMETYPE(_("Deathmatch"),dm,g_dm,DEATHMATCH,"timelimit=20 pointlimit=30 leadlimit=0",_("Kill all enemies"));
 #define g_dm IS_GAMETYPE(DEATHMATCH)
 
-REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 leadlimit=0");
+REGISTER_GAMETYPE(_("Last Man Standing"),lms,g_lms,LMS,"timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
 #define g_lms IS_GAMETYPE(LMS)
 
-REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0");
+REGISTER_GAMETYPE(_("Race"),rc,g_race,RACE,"timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"));
 #define g_race IS_GAMETYPE(RACE)
 
-REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,"timelimit=20 skill=-1");
+REGISTER_GAMETYPE(_("Race CTS"),cts,g_cts,CTS,"timelimit=20 skill=-1",_("Race for fastest time"));
 #define g_cts IS_GAMETYPE(CTS)
 
-REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,"timelimit=20 pointlimit=50 teams=2 leadlimit=0");
+REGISTER_GAMETYPE(_("Team Deathmatch"),tdm,g_tdm,TEAM_DEATHMATCH,"timelimit=20 pointlimit=50 teams=2 leadlimit=0",_("Kill all enemy teammates"));
 #define g_tdm IS_GAMETYPE(TEAM_DEATHMATCH)
 
-REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,"timelimit=20 caplimit=10 leadlimit=0");
+REGISTER_GAMETYPE(_("Capture the Flag"),ctf,g_ctf,CTF,"timelimit=20 caplimit=10 leadlimit=0",_("Find and bring the enemy flag to your base to capture it"));
 #define g_ctf IS_GAMETYPE(CTF)
 
-REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,"timelimit=20 pointlimit=10 leadlimit=0");
+REGISTER_GAMETYPE(_("Clan Arena"),ca,g_ca,CA,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round"));
 #define g_ca IS_GAMETYPE(CA)
 
-REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,"timelimit=20 pointlimit=200 teams=2 leadlimit=0");
+REGISTER_GAMETYPE(_("Domination"),dom,g_domination,DOMINATION,"timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture all the control points to win"));
 #define g_domination IS_GAMETYPE(DOMINATION)
 
-REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0");
+REGISTER_GAMETYPE(_("Key Hunt"),kh,g_keyhunt,KEYHUNT,"timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"));
 #define g_keyhunt IS_GAMETYPE(KEYHUNT)
 
-REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,"timelimit=20");
+REGISTER_GAMETYPE(_("Assault"),as,g_assault,ASSAULT,"timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
 #define g_assault IS_GAMETYPE(ASSAULT)
 
-REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,"timelimit=20");
+REGISTER_GAMETYPE(_("Onslaught"),ons,g_onslaught,ONSLAUGHT,"timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
 #define g_onslaught IS_GAMETYPE(ONSLAUGHT)
 
-REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,"timelimit=20 pointlimit=5 leadlimit=0");
+REGISTER_GAMETYPE(_("Nexball"),nb,g_nexball,NEXBALL,"timelimit=20 pointlimit=5 leadlimit=0",_("XonSports"));
 #define g_nexball IS_GAMETYPE(NEXBALL)
 
-REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,"timelimit=20 pointlimit=10 teams=2 leadlimit=0");
+REGISTER_GAMETYPE(_("Freeze Tag"),ft,g_freezetag,FREEZETAG,"timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to teammates to revive them"));
 #define g_freezetag IS_GAMETYPE(FREEZETAG)
 
-REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,"timelimit=20 pointlimit=30");
+REGISTER_GAMETYPE(_("Keepaway"),ka,g_keepaway,KEEPAWAY,"timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
 #define g_keepaway IS_GAMETYPE(KEEPAWAY)
 
-REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,"pointlimit=50 teams=0");
+REGISTER_GAMETYPE(_("Invasion"),inv,g_invasion,INVASION,"pointlimit=50 teams=0",_("Survive against waves of monsters"));
 #define g_invasion IS_GAMETYPE(INVASION)
 
-const float MAPINFO_FEATURE_WEAPONS       = 1; // not defined for minstagib-only maps
+const float MAPINFO_FEATURE_WEAPONS       = 1; // not defined for instagib-only maps
 const float MAPINFO_FEATURE_VEHICLES      = 2;
 const float MAPINFO_FEATURE_TURRETS       = 4;
 const float MAPINFO_FEATURE_MONSTERS      = 8;
@@ -134,13 +136,14 @@ float MapInfo_CheckMap(string s); // returns 0 if the map can't be played with t
 void MapInfo_LoadMap(string s, float reinit);
 
 // list all maps for the current game type
-string MapInfo_ListAllowedMaps(float pFlagsRequired, float pFlagsForbidden);
+string MapInfo_ListAllowedMaps(float type, float pFlagsRequired, float pFlagsForbidden);
 // list all allowed maps (for any game type)
 string MapInfo_ListAllAllowedMaps(float pFlagsRequired, float pFlagsForbidden);
 
 // gets a gametype from a string
 string _MapInfo_GetDefaultEx(float t);
 float MapInfo_Type_FromString(string t);
+string MapInfo_Type_Description(float t);
 string MapInfo_Type_ToString(float t);
 string MapInfo_Type_ToText(float t);
 void MapInfo_SwitchGameType(float t);
index bda48d5cb91dee7ae2fd20b5c1cb3d001c17d1b7..26bb0a9afda23c20909e5e35c5c7ed03a5df10a6 100644 (file)
@@ -60,7 +60,7 @@ float friend_needshelp(entity e)
                return FALSE;
        if(DIFF_TEAM(e, self) && e != self.monster_owner)
                return FALSE;
-       if(e.freezetag_frozen)
+       if(e.frozen)
                return FALSE;
        if(!IS_PLAYER(e))
                return ((e.flags & FL_MONSTER) && e.health < e.max_health);
index 34e7ceb9901ebbb30583e88b3862ba3204cd28fb..6d06de50ebb30e9c8ff98ee6c5fefcb5542dbcf7 100644 (file)
@@ -94,7 +94,7 @@ float monster_isvalidtarget (entity targ, entity ent)
        if(SAME_TEAM(targ, ent))
                return FALSE; // enemy is on our team
 
-       if (targ.freezetag_frozen)
+       if (targ.frozen)
                return FALSE; // ignore frozen
 
        if(autocvar_g_monsters_target_infront || (ent.spawnflags & MONSTERFLAG_INFRONT))
@@ -480,7 +480,7 @@ vector monster_pickmovetarget(entity targ)
                
                if((self.enemy == world)
                        || (self.enemy.deadflag != DEAD_NO || self.enemy.health < 1)
-                       || (self.enemy.freezetag_frozen)
+                       || (self.enemy.frozen)
                        || (self.enemy.flags & FL_NOTARGET)
                        || (self.enemy.alpha < 0.5)
                        || (self.enemy.takedamage == DAMAGE_NO)
@@ -605,6 +605,51 @@ void monster_move(float runspeed, float walkspeed, float stopspeed, float manim_
 
        entity targ;
 
+       if(self.frozen == 2)
+       {
+               self.revive_progress = bound(0, self.revive_progress + self.ticrate * self.revive_speed, 1);
+               self.health = max(1, self.revive_progress * self.max_health);
+               self.iceblock.alpha = bound(0.2, 1 - self.revive_progress, 1);
+
+               WaypointSprite_UpdateHealth(self.sprite, self.health);
+
+               movelib_beak_simple(stopspeed);
+               self.frame = manim_idle;
+
+               self.enemy = world;
+               self.nextthink = time + self.ticrate;
+
+               if(self.revive_progress >= 1)
+                       Unfreeze(self);
+
+               return;
+       }
+       else if(self.frozen == 3)
+       {
+               self.revive_progress = bound(0, self.revive_progress - self.ticrate * self.revive_speed, 1);
+               self.health = max(0, autocvar_g_nades_ice_health + (self.max_health-autocvar_g_nades_ice_health) * self.revive_progress );
+
+               WaypointSprite_UpdateHealth(self.sprite, self.health);
+
+               movelib_beak_simple(stopspeed);
+               self.frame = manim_idle;
+
+               self.enemy = world;
+               self.nextthink = time + self.ticrate;
+
+               if(self.health < 1)
+               {
+                       Unfreeze(self);
+                       self.health = 0;
+                       self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0');
+               }
+
+               else if ( self.revive_progress <= 0 )
+                       Unfreeze(self);
+
+               return;
+       }
+
        if(self.flags & FL_SWIM)
        {
                if(self.waterlevel < WATERLEVEL_WETFEET)
@@ -776,6 +821,9 @@ void monster_remove(entity mon)
        if(mon.weaponentity)
                remove(mon.weaponentity);
 
+       if(mon.iceblock)
+               remove(mon.iceblock);
+
        WaypointSprite_Kill(mon.sprite);
 
        remove(mon);
@@ -827,6 +875,8 @@ void monsters_reset()
        setorigin(self, self.pos1);
        self.angles = self.pos2;
 
+       Unfreeze(self); // remove any icy remains
+
        self.health = self.max_health;
        self.velocity = '0 0 0';
        self.enemy = world;
@@ -860,6 +910,12 @@ void monster_die(entity attacker, float gibbed)
        self.nextthink = time;
        self.monster_lifetime = time + 5;
 
+       if(self.frozen)
+       {
+               Unfreeze(self); // remove any icy remains
+               self.health = 0; // reset by Unfreeze
+       }
+
        monster_dropitem();
 
        MonsterSound(monstersound_death, 0, FALSE, CH_VOICE);
@@ -900,6 +956,9 @@ void monster_die(entity attacker, float gibbed)
 
 void monsters_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
+       if(self.frozen && deathtype != DEATH_KILL && deathtype != DEATH_NADE_ICE_FREEZE)
+               return;
+
        if((self.spawnflags & MONSTERFLAG_INVINCIBLE) && deathtype != DEATH_KILL)
                return;
 
diff --git a/qcsrc/common/nades.qc b/qcsrc/common/nades.qc
new file mode 100644 (file)
index 0000000..03b1552
--- /dev/null
@@ -0,0 +1,82 @@
+.float healer_lifetime;
+.float healer_radius;
+
+#ifdef SVQC
+float healer_send(entity to, float sf)
+{
+       WriteByte(MSG_ENTITY, ENT_CLIENT_HEALING_ORB);
+       WriteByte(MSG_ENTITY, sf);
+
+       if(sf & 1)
+       {
+               WriteCoord(MSG_ENTITY, self.origin_x);
+               WriteCoord(MSG_ENTITY, self.origin_y);
+               WriteCoord(MSG_ENTITY, self.origin_z);
+
+               WriteByte(MSG_ENTITY, self.healer_lifetime);
+               //WriteByte(MSG_ENTITY, self.ltime - time + 1);
+               WriteShort(MSG_ENTITY, self.healer_radius);
+               // round time delta to a 1/10th of a second
+               WriteByte(MSG_ENTITY, (self.ltime - time)*10.0+0.5);
+       }
+
+       return TRUE;
+}
+#endif // SVQC
+
+#ifdef CSQC
+.float ltime;
+void healer_draw()
+{
+       float dt = time - self.move_time;
+       self.move_time = time;
+       if(dt <= 0)
+               return;
+
+       self.alpha = (self.ltime - time) / self.healer_lifetime;
+       self.scale = min((1 - self.alpha)*self.healer_lifetime*4,1)*self.healer_radius;
+
+}
+
+void healer_setup()
+{
+       setmodel(self, "models/ctf/shield.md3");
+
+       setorigin(self, self.origin);
+       
+       float model_radius = self.maxs_x;
+       vector size = '1 1 1' * self.healer_radius / 2;
+       setsize(self,-size,size);
+       self.healer_radius = self.healer_radius/model_radius*0.6;
+
+       self.draw = healer_draw;
+       self.health = 255;
+       self.movetype = MOVETYPE_NONE;
+       self.solid = SOLID_NOT;
+       self.drawmask = MASK_NORMAL;
+       self.scale = 0.01;
+       self.avelocity = self.move_avelocity = '7 0 11';
+       self.colormod = '1 0 0';
+       self.renderflags |= RF_ADDITIVE;
+}
+
+void ent_healer()
+{
+       float sf = ReadByte();
+
+       if(sf & TNSF_SETUP)
+       {
+               self.origin_x = ReadCoord();
+               self.origin_y = ReadCoord();
+               self.origin_z = ReadCoord();
+               setorigin(self, self.origin);
+
+               self.healer_lifetime = ReadByte();
+               self.healer_radius = ReadShort();
+               self.ltime = time + ReadByte()/10.0;
+               //self.ltime = time + self.healer_lifetime;
+
+               healer_setup();
+       }
+}
+#endif // CSQC
\ No newline at end of file
diff --git a/qcsrc/common/nades.qh b/qcsrc/common/nades.qh
new file mode 100644 (file)
index 0000000..1004e1e
--- /dev/null
@@ -0,0 +1,103 @@
+// use slots 70-100
+const float PROJECTILE_NADE = 71;
+const float PROJECTILE_NADE_BURN = 72;
+const float PROJECTILE_NADE_NAPALM = 73;
+const float PROJECTILE_NADE_NAPALM_BURN = 74;
+const float PROJECTILE_NAPALM_FOUNTAIN = 75;
+const float PROJECTILE_NADE_ICE = 76;
+const float PROJECTILE_NADE_ICE_BURN = 77;
+const float PROJECTILE_NADE_TRANSLOCATE = 78;
+const float PROJECTILE_NADE_SPAWN = 79;
+const float PROJECTILE_NADE_HEAL = 80;
+const float PROJECTILE_NADE_HEAL_BURN = 81;
+const float PROJECTILE_NADE_MONSTER = 82;
+const float PROJECTILE_NADE_MONSTER_BURN = 83;
+
+const float NADE_TYPE_NORMAL = 1;
+const float NADE_TYPE_NAPALM = 2;
+const float NADE_TYPE_ICE = 3;
+const float NADE_TYPE_TRANSLOCATE = 4;
+const float NADE_TYPE_SPAWN = 5;
+const float NADE_TYPE_HEAL = 6;
+const float NADE_TYPE_MONSTER = 7;
+
+const float NADE_TYPE_LAST = 7; // a check to prevent using higher values & crashing
+
+vector Nade_Color(float nadeid)
+{
+       switch(nadeid)
+       {
+               case NADE_TYPE_NORMAL: return '1 1 1';
+               case NADE_TYPE_NAPALM: return '2 0.5 0';
+               case NADE_TYPE_ICE: return '0 0.5 2';
+               case NADE_TYPE_TRANSLOCATE: return '1 0.0625 1';
+               case NADE_TYPE_SPAWN: return '1 0.9 0.06';
+        case NADE_TYPE_HEAL: return '1 0 0';
+               case NADE_TYPE_MONSTER: return '1 0.5 0';
+       }
+
+       return '0 0 0';
+}
+
+float Nade_IDFromProjectile(float proj)
+{
+       switch(proj)
+       {
+               case PROJECTILE_NADE:
+               case PROJECTILE_NADE_BURN: return NADE_TYPE_NORMAL;
+               case PROJECTILE_NADE_NAPALM:
+               case PROJECTILE_NADE_NAPALM_BURN: return NADE_TYPE_NAPALM;
+               case PROJECTILE_NADE_ICE:
+               case PROJECTILE_NADE_ICE_BURN: return NADE_TYPE_ICE;
+               case PROJECTILE_NADE_TRANSLOCATE: return NADE_TYPE_TRANSLOCATE;
+               case PROJECTILE_NADE_SPAWN: return NADE_TYPE_SPAWN;
+        case PROJECTILE_NADE_HEAL:
+        case PROJECTILE_NADE_HEAL_BURN: return NADE_TYPE_HEAL;
+               case PROJECTILE_NADE_MONSTER:
+               case PROJECTILE_NADE_MONSTER_BURN: return NADE_TYPE_MONSTER;
+       }
+
+       return 0;
+}
+
+float Nade_ProjectileFromID(float proj, float burn)
+{
+       switch(proj)
+       {
+               case NADE_TYPE_NORMAL: return (burn) ? PROJECTILE_NADE_BURN : PROJECTILE_NADE;
+               case NADE_TYPE_NAPALM: return (burn) ? PROJECTILE_NADE_NAPALM_BURN : PROJECTILE_NADE_NAPALM;
+               case NADE_TYPE_ICE: return (burn) ? PROJECTILE_NADE_ICE_BURN : PROJECTILE_NADE_ICE;
+               case NADE_TYPE_TRANSLOCATE: return PROJECTILE_NADE_TRANSLOCATE;
+               case NADE_TYPE_SPAWN: return PROJECTILE_NADE_SPAWN;
+        case NADE_TYPE_HEAL: return (burn) ? PROJECTILE_NADE_HEAL_BURN : PROJECTILE_NADE_HEAL;
+               case NADE_TYPE_MONSTER: return (burn) ? PROJECTILE_NADE_MONSTER_BURN : PROJECTILE_NADE_MONSTER;
+       }
+
+       return 0;
+}
+
+string Nade_TrailEffect(float proj, float nade_team)
+{
+       switch(proj)
+       {
+               case PROJECTILE_NADE: return strcat("nade_", Static_Team_ColorName_Lower(nade_team));
+               case PROJECTILE_NADE_BURN: return strcat("nade_", Static_Team_ColorName_Lower(nade_team), "_burn");
+               case PROJECTILE_NADE_NAPALM: return "TR_ROCKET";
+               case PROJECTILE_NADE_NAPALM_BURN: return "spiderbot_rocket_thrust";
+               case PROJECTILE_NADE_ICE: return "TR_NEXUIZPLASMA";
+               case PROJECTILE_NADE_ICE_BURN: return "wakizashi_rocket_thrust";
+               case PROJECTILE_NADE_TRANSLOCATE: return "TR_CRYLINKPLASMA";
+               case PROJECTILE_NADE_SPAWN: return "nade_yellow";
+        case PROJECTILE_NADE_HEAL: return "nade_red";
+        case PROJECTILE_NADE_HEAL_BURN: return "nade_red_burn";
+               case PROJECTILE_NADE_MONSTER: return "nade_red";
+               case PROJECTILE_NADE_MONSTER_BURN: return "nade_red_burn";
+       }
+       
+       return "";
+}
+
+#ifdef CSQC
+// misc functions
+void ent_healer();
+#endif // CSQC
index 4fd6e1f25dcc37373a00a04a565aec114867ddb2..a5a2ff445e60d376463d1265af9ba19657cd5575 100644 (file)
@@ -1007,7 +1007,7 @@ void Dump_Notifications(float fh, float alsoprint)
                if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
 
                NOTIF_WRITE_ENTITY(
-                       "Notification control cvar: 0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled)"
+                       "0 = disabled, 1 = enabled if gentle mode is off, 2 = always enabled"
                );
        }
 
@@ -1018,7 +1018,7 @@ void Dump_Notifications(float fh, float alsoprint)
                if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
 
                NOTIF_WRITE_ENTITY(
-                       "Notification control cvar: 0 = off, 1 = print to console, "
+                       "0 = off, 1 = print to console, "
                        "2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
                );
        }
@@ -1030,7 +1030,7 @@ void Dump_Notifications(float fh, float alsoprint)
                if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
 
                NOTIF_WRITE_ENTITY(
-                       "Notification control cvar: 0 = off, 1 = centerprint"
+                       "0 = off, 1 = centerprint"
                );
        }
 
@@ -1041,7 +1041,7 @@ void Dump_Notifications(float fh, float alsoprint)
                if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
 
                NOTIF_WRITE_ENTITY(
-                       "Notification control cvar: 0 = off, 1 = trigger subcalls"
+                       "Enable this multiple notification"
                );
        }
 
@@ -1052,8 +1052,8 @@ void Dump_Notifications(float fh, float alsoprint)
                if (!e) { backtrace("Dump_Notifications(): Missing notification entity!\n"); return; }
 
                NOTIF_WRITE_ENTITY_CHOICE(
-                       "Notification control cvar: 0 = off, 1 = trigger option A subcall, 2 = trigger option B subcall",
-                       "Notification control cvar: 0 = off, 1 = allowed in warmup mode, 2 = always allowed"
+                       "Choice for this notification 0 = off, 1 = default message, 2 = verbose message",
+                       "Allow choice for this notification 0 = off, 1 = only in warmup mode, 2 = always"
                );
        }
 
@@ -1062,8 +1062,10 @@ void Dump_Notifications(float fh, float alsoprint)
 
        NOTIF_WRITE_HARDCODED(
                "allow_chatboxprint", "1",
-               "Allow notifications to be printed to chat box by setting notification cvar to 2 "
-               "(You can also set this cvar to 2 to force ALL notifications to be printed to the chatbox)"
+               "Allow INFO notifications to be printed to chat box"
+               "0 = do not allow, "
+               "1 = allow only if allowed by individual notification_INFO* cvars, "
+               "2 = force all INFO notifications to be printed to the chatbox"
        );
 
        NOTIF_WRITE_HARDCODED(
@@ -2027,7 +2029,7 @@ void Send_Notification(
                #define RECURSE_FROM_CHOICE(ent,action) \
                        if(notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) \
                        { \
-                               switch(ent.msg_choice_choices[net_name]) \
+                               switch(ent.msg_choice_choices[net_name - 1]) \
                                { \
                                        case 1: found_choice = notif.nent_optiona; break; \
                                        case 2: found_choice = notif.nent_optionb; break; \
index 117965f7bb016aacb21fbb0ce5733197db86e231..fe7f4ec2aa507680dd6ae545cc1c86730a68aa64 100644 (file)
@@ -248,9 +248,9 @@ void Send_Notification_WOCOVA(
        MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_20,             CH_INFO, "20kills",           VOL_BASEVOICE, ATTEN_NONE) \
        MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_25,             CH_INFO, "25kills",           VOL_BASEVOICE, ATTEN_NONE) \
        MSG_ANNCE_NOTIF(1, ANNCE_KILLSTREAK_30,             CH_INFO, "30kills",           VOL_BASEVOICE, ATTEN_NONE) \
-       MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_LASTSECOND,      CH_INFO, "lastsecond",        VOL_BASEVOICE, ATTEN_NONE) \
-       MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_NARROWLY,        CH_INFO, "narrowly",          VOL_BASEVOICE, ATTEN_NONE) \
-       MSG_ANNCE_NOTIF(1, ANNCE_MINSTAGIB_TERMINATED,      CH_INFO, "terminated",        VOL_BASEVOICE, ATTEN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_LASTSECOND,      CH_INFO, "lastsecond",        VOL_BASEVOICE, ATTEN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_NARROWLY,        CH_INFO, "narrowly",          VOL_BASEVOICE, ATTEN_NONE) \
+       MSG_ANNCE_NOTIF(1, ANNCE_INSTAGIB_TERMINATED,      CH_INFO, "terminated",        VOL_BASEVOICE, ATTEN_NONE) \
        MSG_ANNCE_NOTIF(0, ANNCE_MULTIFRAG,                 CH_INFO, "multifrag",         VOL_BASEVOICE, ATTEN_NONE) \
        MSG_ANNCE_NOTIF(2, ANNCE_NUM_1,                     CH_INFO, "1",                 VOL_BASEVOICE, ATTEN_NONE) \
        MSG_ANNCE_NOTIF(2, ANNCE_NUM_2,                     CH_INFO, "2",                 VOL_BASEVOICE, ATTEN_NONE) \
@@ -360,7 +360,11 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_FIRE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was burnt up into a crisp by ^BG%s^K1%s%s"), _("^BG%s%s^K1 felt a little hot from ^BG%s^K1's fire^K1%s%s")) \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_LAVA,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_lava",          _("^BG%s%s^K1 was cooked by ^BG%s^K1%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_MONSTER,           3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was pushed infront of a monster by ^BG%s^K1%s%s"), "") \
-       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_nade",          _("^BG%s%s^K1 was blown up by ^BG%s^K1's Nade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_NAPALM,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_nade_napalm",   _("^BG%s%s^K1 was burned to death by ^BG%s^K1's Napalm Nade%s%s"), _("^BG%s%s^K1 got too close to a napalm explosion%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE,          3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_nade_ice",      _("^BG%s%s^K1 was blown up by ^BG%s^K1's Ice Nade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_ICE_FREEZE,   3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_nade_ice",      _("^BG%s%s^K1 was frozen to death by ^BG%s^K1's Ice Nade%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_NADE_HEAL,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_nade_heal",     _("^BG%s%s^K1 has not been healed by ^BG%s^K1's Healing Nade%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SHOOTING_STAR,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_shootingstar",  _("^BG%s%s^K1 was shot into space by ^BG%s^K1%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SLIME,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was slimed by ^BG%s^K1%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_SWAMP,             3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_slime",         _("^BG%s%s^K1 was preserved by ^BG%s^K1%s%s"), "") \
@@ -378,6 +382,7 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_DEATH,     3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 got caught in the blast when ^BG%s^K1's Racer exploded%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_GUN,       3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was bolted down by ^BG%s^K1's Racer%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VH_WAKI_ROCKET,    3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 couldn't find shelter from ^BG%s^K1's Racer%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VENGEANCE,         3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_death",         _("^BG%s%s^K1 was destroyed by the vengeful ^BG%s^K1%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_MURDER_VOID,              3, 2, "spree_inf s1 s2 s3loc spree_end", "s2 s1",  "notify_void",          _("^BG%s%s^K1 was thrown into a world of hurt by ^BG%s^K1%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_AUTOTEAMCHANGE,      2, 1, "s1 s2loc death_team", "",         "",                     _("^BG%s^K1 was moved into the %s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_BETRAYAL,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_teamkill_red",  _("^BG%s^K1 became enemies with the Lord of Teamplay%s%s"), "") \
@@ -389,7 +394,6 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_FIRE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 became a bit too crispy%s%s"), _("^BG%s^K1 felt a little hot%s%s")) \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_GENERIC,             2, 1, "s1 s2loc spree_lost", "s1",       "notify_selfkill",      _("^BG%s^K1 died%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_LAVA,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_lava",          _("^BG%s^K1 turned into hot slag%s%s"), _("^BG%s^K1 found a hot place%s%s")) \
-       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_MAGE,                2, 1, "s1 s2loc spree_lost", "s1",           "notify_death",                 _("^BG%s^K1 was exploded by a Mage%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_CLAW,   2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1's innards became outwards by a Shambler%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_SHAMBLER_SMASH,  2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was smashed by a Shambler%s%s"), "") \
@@ -398,6 +402,11 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_WYVERN,          2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was fireballed by a Wyvern%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_JUMP,     2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 joins the Zombies%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_MON_ZOMBIE_MELEE,    2, 1, "s1 s2loc spree_lost", "s1",               "notify_death",                 _("^BG%s^K1 was given kung fu lessons by a Zombie%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_nade",          _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_NAPALM,         2, 1, "s1 s2loc spree_lost", "s1",       "notify_nade_napalm",   _("^BG%s^K1 was burned to death by their own Napalm Nade%s%s"), _("^BG%s^K1 decided to take a look at the results of their napalm explosion%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE,            2, 1, "s1 s2loc spree_lost", "s1",       "notify_nade_ice",      _("^BG%s^K1 mastered the art of self-nading%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_ICE_FREEZE,     2, 1, "s1 s2loc spree_lost", "s1",       "notify_nade_ice",      _("^BG%s^K1 was frozen to death by their own Ice Nade%s%s"), _("^BG%s^K1 felt a little chilly%s%s")) \
+       MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NADE_HEAL,           2, 1, "s1 s2loc spree_lost", "s1",       "notify_nade_heal",     _("^BG%s^K1's Healing Nade didn't quite heal them%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_NOAMMO,              2, 1, "s1 s2loc spree_lost", "s1",       "notify_outofammo",     _("^BG%s^K1 died%s%s. What's the point of living without ammo?"), _("^BG%s^K1 ran out of ammo%s%s")) \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_ROT,                 2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 rotted away%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_SHOOTING_STAR,       2, 1, "s1 s2loc spree_lost", "s1",       "notify_shootingstar",  _("^BG%s^K1 became a shooting star%s%s"), "") \
@@ -429,9 +438,13 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VH_WAKI_ROCKET,      2, 1, "s1 s2loc spree_lost", "s1",       "notify_death",         _("^BG%s^K1 couldn't find shelter from a Racer rocket%s%s"), "") \
        MSG_INFO_NOTIF(1, INFO_DEATH_SELF_VOID,                2, 1, "s1 s2loc spree_lost", "s1",       "notify_void",          _("^BG%s^K1 was in the wrong place%s%s"), "") \
        MULTITEAM_INFO(1, INFO_DEATH_TEAMKILL_, 4,             3, 1, "s1 s2 s3loc spree_end", "s2 s1",  "notify_teamkill_%s",   _("^BG%s^K1 was betrayed by ^BG%s^K1%s%s"), "") \
+       MSG_INFO_NOTIF(1, INFO_CA_JOIN_LATE,                   0, 0, "", "",                            "",                     _("^F1Round already started, you will join the game in the next round"), "") \
+       MSG_INFO_NOTIF(1, INFO_CA_LEAVE,                       0, 0, "", "",                            "",                     _("^F2You will spectate in the next round"), "") \
+       MSG_INFO_NOTIF(1, INFO_DOMINATION_CAPTURE_TIME,        2, 2, "s1 s2 f1 f2", "",                 "",                     _("^BG%s^BG%s^BG (%s points every %s seconds)"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_FREEZE,               2, 0, "s1 s2", "",                       "",                     _("^BG%s^K1 was frozen by ^BG%s"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED,              2, 0, "s1 s2", "",                       "",                     _("^BG%s^K3 was revived by ^BG%s"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_FALL,         1, 0, "s1", "",                          "",                     _("^BG%s^K3 was revived by falling"), "") \
+       MSG_INFO_NOTIF(1, INFO_FREEZETAG_REVIVED_NADE,         1, 0, "s1", "",                          "",                     _("^BG%s^K3 was revived by their Nade explosion"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_AUTO_REVIVED,         1, 1, "s1 f1", "",                       "",                     _("^BG%s^K3 was automatically revived after %s second(s)"), "") \
        MULTITEAM_INFO(1, INFO_ROUND_TEAM_WIN_, 4,             0, 0, "", "",                            "",                     _("^TC^TT^BG team wins the round"), "") \
        MSG_INFO_NOTIF(1, INFO_ROUND_PLAYER_WIN,               1, 0, "s1", "",                          "",                     _("^BG%s^BG wins the round"), "") \
@@ -439,6 +452,10 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_ROUND_OVER,                     0, 0, "", "",                            "",                     _("^BGRound over, there's no winner"), "") \
        MSG_INFO_NOTIF(1, INFO_FREEZETAG_SELF,                 1, 0, "s1", "",                          "",                     _("^BG%s^K1 froze themself"), "") \
        MSG_INFO_NOTIF(1, INFO_GODMODE_OFF,                    0, 1, "f1", "",                          "",                     _("^BGGodmode saved you %s units of damage, cheater!"), "") \
+       MSG_INFO_NOTIF(1, INFO_ITEM_BUFF,                      1, 1, "s1 item_buffname", "",            "",                     _("^BG%s^BG got the %s^BG Buff!"), "") \
+       MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_LOST,                 1, 1, "s1 item_buffname", "",            "",                     _("^BG%s^BG lost the %s^BG Buff!"), "") \
+       MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_DROP,                 0, 1, "item_buffname", "",               "",                     _("^BGYou dropped the %s^BG Buff!"), "") \
+       MSG_INFO_NOTIF(1, INFO_ITEM_BUFF_GOT,                  0, 1, "item_buffname", "",               "",                     _("^BGYou got the %s^BG Buff!"), "") \
        MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DONTHAVE,           0, 1, "item_wepname", "",                      "",               _("^BGYou do not have the ^F1%s"), "") \
        MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_DROP,               1, 1, "item_wepname item_wepammo", "",         "",               _("^BGYou dropped the ^F1%s^BG%s"), "") \
        MSG_INFO_NOTIF(0, INFO_ITEM_WEAPON_GOT,                0, 1, "item_wepname", "",                      "",               _("^BGYou got the ^F1%s"), "") \
@@ -475,7 +492,9 @@ void Send_Notification_WOCOVA(
        MSG_INFO_NOTIF(1, INFO_RACE_NEW_SET,                   1, 2, "s1 race_col f1ord race_col f2race_time", "s1 f2race_time",                  "race_newrecordserver",  _("^BG%s^BG set the %s%s^BG place record with %s%s"), "") \
        MULTITEAM_INFO(1, INFO_SCORES_, 4,                     0, 0, "", "",                            "",                     _("^TC^TT ^BGteam scores!"), "") \
        MSG_INFO_NOTIF(1, INFO_SPECTATE_WARNING,               0, 1, "f1secs", "",                      "",                     _("^F2You have to become a player within the next %s, otherwise you will be kicked, because spectating isn't allowed at this time!"), "") \
-       MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up a Superweapon"), "") \
+       MSG_INFO_NOTIF(1, INFO_SUPERWEAPON_PICKUP,             1, 0, "s1", "s1",                        "superweapons",         _("^BG%s^K1 picked up a Superweapon"), "") \
+       MSG_INFO_NOTIF(1, INFO_TEAMCHANGE_LARGERTEAM,          0, 0, "", "",                            "",                     _("^BGYou cannot change to a larger team"), "") \
+       MSG_INFO_NOTIF(1, INFO_TEAMCHANGE_NOTALLOWED,          0, 0, "", "",                            "",                     _("^BGYou are not allowed to change teams"), "") \
        MSG_INFO_NOTIF(2, INFO_VERSION_BETA,                   2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s (beta)^BG, you have ^F2Xonotic %s"), "") \
        MSG_INFO_NOTIF(2, INFO_VERSION_OLD,                    2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^BGThe server is running ^F1Xonotic %s^BG, you have ^F2Xonotic %s"), "") \
        MSG_INFO_NOTIF(2, INFO_VERSION_OUTDATED,               2, 0, "s1 s2", "",                       "",                     _("^F4NOTE: ^F1Xonotic %s^BG is out, and you still have ^F2Xonotic %s^BG - get the update from ^F3http://www.xonotic.org/^BG!"), "") \
@@ -545,6 +564,7 @@ void Send_Notification_WOCOVA(
        MULTITEAM_CENTER##teams(default,prefix,strnum,flnum,args,cpid,durcnt,normal,gentle)
 
 #define MSG_CENTER_NOTIFICATIONS \
+       MSG_CENTER_NOTIF(1, CENTER_ALONE,                       0, 0, "",             NO_CPID,             "0 0", _("^F4You are now alone!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_ASSAULT_ATTACKING,           0, 0, "",             CPID_ASSAULT_ROLE,   "0 0", _("^BGYou are attacking!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_ASSAULT_DEFENDING,           0, 0, "",             CPID_ASSAULT_ROLE,   "0 0", _("^BGYou are defending!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_COUNTDOWN_BEGIN,             0, 0, "",             CPID_ROUND,          "2 0", _("^F4Begin!"), "") \
@@ -580,6 +600,7 @@ void Send_Notification_WOCOVA(
        MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAGGED_VERBOSE,  1, 4, "spree_cen s1 frag_stats",  NO_CPID, "0 0", _("^K1%sYou were typefragged by ^BG%s^BG%s"), _("^K1%sYou were scored against by ^BG%s^K1 while typing^BG%s")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_MURDER_TYPEFRAG_VERBOSE,     1, 2, "spree_cen s1 frag_ping",   NO_CPID, "0 0", _("^K1%sYou typefragged ^BG%s^BG%s"), _("^K1%sYou scored against ^BG%s^K1 while they were typing^BG%s")) \
        MSG_CENTER_NOTIF(1, CENTER_NADE_THROW,                          0, 0, "",             CPID_NADES,          "0 0", _("^BGPress ^F2DROPWEAPON^BG again to toss the nade!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_NADE_BONUS,                          0, 0, "",             CPID_NADES,          "0 0", _("^F2You got a ^K1BONUS GRENADE^F2!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_AUTOTEAMCHANGE,   0, 1, "death_team",   NO_CPID,             "0 0", _("^BGYou have been moved into a different team\nYou are now on: %s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_BETRAYAL,         0, 0, "",             NO_CPID,             "0 0", _("^K1Don't shoot your team mates!"), _("^K1Don't go against your team mates!")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_CAMP,             0, 0, "",             NO_CPID,             "0 0", _("^K1Die camper!"), _("^K1Reconsider your tactics, camper!")) \
@@ -592,6 +613,9 @@ void Send_Notification_WOCOVA(
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_LAVA,             0, 0, "",             NO_CPID,             "0 0", _("^K1You couldn't stand the heat!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_MONSTER,          0, 0, "",             NO_CPID,             "0 0", _("^K1You were killed by a monster!"), _("^K1You need to watch out for monsters!")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE,                             0, 0, "",                         NO_CPID,                         "0 0", _("^K1You forgot to put the pin back in!"), _("^K1Tastes like chicken!")) \
+       MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_NAPALM,              0, 0, "",                         NO_CPID,                         "0 0", _("^K1Hanging around a napalm explosion is bad!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_ICE_FREEZE,  0, 0, "",                         NO_CPID,                         "0 0", _("^K1You got a little bit too cold!"), _("^K1You felt a little chilly!")) \
+       MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NADE_HEAL,        0, 0, "",             NO_CPID,             "0 0", _("^K1Your Healing Nade is a bit defective"), "") \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_NOAMMO,           0, 0, "",             NO_CPID,             "0 0", _("^K1You were killed for running out of ammo..."), _("^K1You are respawning for running out of ammo...")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_ROT,              0, 0, "",             NO_CPID,             "0 0", _("^K1You grew too old without taking your medicine"), _("^K1You need to preserve your health")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_SELF_SHOOTING_STAR,    0, 0, "",             NO_CPID,             "0 0", _("^K1You became a shooting star!"), "") \
@@ -615,11 +639,14 @@ void Send_Notification_WOCOVA(
        MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAG,         1, 0, "s1",           NO_CPID,             "0 0", _("^K1Moron! You fragged ^BG%s^K1, a team mate!"), _("^K1Moron! You went against ^BG%s^K1, a team mate!")) \
        MSG_CENTER_NOTIF(1, CENTER_DEATH_TEAMKILL_FRAGGED,      1, 0, "s1",           NO_CPID,             "0 0", _("^K1You were fragged by ^BG%s^K1, a team mate"), _("^K1You were scored against by ^BG%s^K1, a team mate")) \
        MSG_CENTER_NOTIF(1, CENTER_DISCONNECT_IDLING,           0, 1, "",             CPID_IDLING,         "1 f1", _("^K1Stop idling!\n^BGDisconnecting in ^COUNT..."), "") \
+       MSG_CENTER_NOTIF(1, CENTER_DOOR_LOCKED_NEED,            0, 0, "",             NO_CPID,             "0 0", _("^BGYou need %s^BG!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_DOOR_LOCKED_ALSONEED,        0, 0, "",             NO_CPID,             "0 0", _("^BGYou also need %s^BG!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_DOOR_UNLOCKED,               0, 0, "",             NO_CPID,             "0 0", _("^BGDoor unlocked!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_EXTRALIVES,                          0, 0, "",             NO_CPID,             "0 0", _("^F2You picked up some extra lives"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FREEZE,            1, 0, "s1",           NO_CPID,             "0 0", _("^K3You froze ^BG%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_FROZEN,            1, 0, "s1",           NO_CPID,             "0 0", _("^K1You were frozen by ^BG%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE,            1, 0, "s1",           NO_CPID,             "0 0", _("^K3You revived ^BG%s"), "") \
-       MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE_FALL,       0, 0, "",             NO_CPID,             "0 0", _("^K3You revived yourself"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVE_SELF,       0, 0, "",             NO_CPID,             "0 0", _("^K3You revived yourself"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_REVIVED,           1, 0, "s1",           NO_CPID,             "0 0", _("^K3You were revived by ^BG%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_AUTO_REVIVED,      0, 1, "f1",           NO_CPID,             "0 0", _("^K3You were automatically revived after %s second(s)"), "") \
        MULTITEAM_CENTER(1, CENTER_ROUND_TEAM_WIN_, 4,          0, 0, "",             CPID_ROUND,          "0 0", _("^TC^TT^BG team wins the round"), "") \
@@ -627,6 +654,8 @@ void Send_Notification_WOCOVA(
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SELF,              0, 0, "",             NO_CPID,             "0 0", _("^K1You froze yourself"), "") \
        MSG_CENTER_NOTIF(1, CENTER_FREEZETAG_SPAWN_LATE,        0, 0, "",             NO_CPID,             "0 0", _("^K1Round already started, you spawn as frozen"), "") \
        MSG_CENTER_NOTIF(1, CENTER_INVASION_SUPERMONSTER,       1, 0, "s1",           NO_CPID,             "0 0", _("^K1A %s has arrived!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_ITEM_BUFF_DROP,              0, 1, "item_buffname",                     CPID_ITEM, "item_centime 0", _("^BGYou dropped the %s^BG Buff!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_ITEM_BUFF_GOT,               0, 1, "item_buffname",                     CPID_ITEM, "item_centime 0", _("^BGYou got the %s^BG Buff!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DONTHAVE,        0, 1, "item_wepname",                      CPID_ITEM, "item_centime 0", _("^BGYou do not have the ^F1%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_DROP,            1, 1, "item_wepname item_wepammo",         CPID_ITEM, "item_centime 0", _("^BGYou dropped the ^F1%s^BG%s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_ITEM_WEAPON_GOT,             0, 1, "item_wepname",                      CPID_ITEM, "item_centime 0", _("^BGYou got the ^F1%s"), "") \
@@ -645,8 +674,8 @@ void Send_Notification_WOCOVA(
        MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_ROUNDSTART,          0, 1, "",              CPID_KEYHUNT_OTHER,    "1 f1", _("^F4Round will start in ^COUNT"), "") \
        MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_SCAN,                0, 1, "",              CPID_KEYHUNT_OTHER,    "f1 0", _("^BGScanning frequency range..."), "") \
        MULTITEAM_CENTER(1, CENTER_KEYHUNT_START_, 4,           0, 0, "",              CPID_KEYHUNT,          "0 0", _("^BGYou are starting with the ^TC^TT Key"), "") \
-       MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_WAIT,                0, 4, "missing_teams", CPID_KEYHUNT_OTHER,    "0 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
-       MSG_CENTER_NOTIF(1, CENTER_MISSING_TEAMS,               0, 4, "missing_teams", CPID_MISSING_TEAMS,    "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_KEYHUNT_WAIT,                0, 1, "missing_teams", CPID_KEYHUNT_OTHER,    "0 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_MISSING_TEAMS,               0, 1, "missing_teams", CPID_MISSING_TEAMS,    "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "") \
        MSG_CENTER_NOTIF(1, CENTER_MISSING_PLAYERS,             0, 1, "f1",            CPID_MISSING_PLAYERS,  "-1 0", _("^BGWaiting for %s player(s) to join..."), "") \
        MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO,             0, 0, "",              CPID_MINSTA_FINDAMMO,  "1 9", _("^F4^COUNT^BG left to find some ammo!"), "") \
        MSG_CENTER_NOTIF(1, CENTER_MINSTA_FINDAMMO_FIRST,       0, 0, "",              CPID_MINSTA_FINDAMMO,  "1 10", _("^BGGet some ammo or you'll be dead in ^F4^COUNT^BG!"), _("^BGGet some ammo! ^F4^COUNT^BG left!")) \
@@ -667,6 +696,9 @@ void Send_Notification_WOCOVA(
        MSG_CENTER_NOTIF(1, CENTER_POWERUP_SPEED,               0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You are on speed"), "") \
        MSG_CENTER_NOTIF(1, CENTER_POWERUP_STRENGTH,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Strength infuses your weapons with devastating power"), "") \
        MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP,              0, 0, "",              CPID_RACE_FINISHLAP,   "0 0", _("^F2The race is over, finish your lap!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COMPLETED,          0, 0, "",              NO_CPID,               "0 0", _("^BGSequence completed!"), "") \
+       MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COUNTER,            0, 0, "",              NO_CPID,               "0 0", _("^BGThere are more to go..."), "") \
+       MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COUNTER_FEWMORE,    0, 1, "f1",            NO_CPID,               "0 0", _("^BGOnly %s^BG more to go..."), "") \
        MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_BROKEN,          0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Superweapons have broken down"), "") \
        MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_LOST,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Superweapons have been lost"), "") \
        MSG_CENTER_NOTIF(1, CENTER_SUPERWEAPON_PICKUP,          0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You now have a superweapon"), "") \
@@ -700,6 +732,10 @@ void Send_Notification_WOCOVA(
        MSG_MULTI_NOTIF(1, DEATH_MURDER_LAVA,                    NO_MSG,        INFO_DEATH_MURDER_LAVA,                    NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_MONSTER,                 NO_MSG,        INFO_DEATH_MURDER_MONSTER,                 CENTER_DEATH_SELF_MONSTER) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE,                    NO_MSG,        INFO_DEATH_MURDER_NADE,                    NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_NAPALM,             NO_MSG,        INFO_DEATH_MURDER_NADE_NAPALM,             NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_ICE,                NO_MSG,        INFO_DEATH_MURDER_NADE_ICE,                NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_ICE_FREEZE,         NO_MSG,        INFO_DEATH_MURDER_NADE_ICE_FREEZE,         NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_NADE_HEAL,               NO_MSG,        INFO_DEATH_MURDER_NADE_HEAL,               NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_SHOOTING_STAR,           NO_MSG,        INFO_DEATH_MURDER_SHOOTING_STAR,           NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_SLIME,                   NO_MSG,        INFO_DEATH_MURDER_SLIME,                   NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_SWAMP,                   NO_MSG,        INFO_DEATH_MURDER_SWAMP,                   NO_MSG) \
@@ -717,6 +753,7 @@ void Send_Notification_WOCOVA(
        MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_DEATH,           NO_MSG,        INFO_DEATH_MURDER_VH_WAKI_DEATH,           NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_GUN,             NO_MSG,        INFO_DEATH_MURDER_VH_WAKI_GUN,             NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_VH_WAKI_ROCKET,          NO_MSG,        INFO_DEATH_MURDER_VH_WAKI_ROCKET,          NO_MSG) \
+       MSG_MULTI_NOTIF(1, DEATH_MURDER_VENGEANCE,               NO_MSG,        INFO_DEATH_MURDER_VENGEANCE,               NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_MURDER_VOID,                    NO_MSG,        INFO_DEATH_MURDER_VOID,                    NO_MSG) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_AUTOTEAMCHANGE,            NO_MSG,        INFO_DEATH_SELF_AUTOTEAMCHANGE,            CENTER_DEATH_SELF_AUTOTEAMCHANGE) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_BETRAYAL,                  NO_MSG,        INFO_DEATH_SELF_BETRAYAL,                  CENTER_DEATH_SELF_BETRAYAL) \
@@ -737,6 +774,10 @@ void Send_Notification_WOCOVA(
        MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_JUMP,                   NO_MSG,        INFO_DEATH_SELF_MON_ZOMBIE_JUMP,                   CENTER_DEATH_SELF_MONSTER) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_MON_ZOMBIE_MELEE,                  NO_MSG,        INFO_DEATH_SELF_MON_ZOMBIE_MELEE,                  CENTER_DEATH_SELF_MONSTER) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_NADE,                                              NO_MSG,                INFO_DEATH_SELF_NADE,                                      CENTER_DEATH_SELF_NADE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_NAPALM,                               NO_MSG,                INFO_DEATH_SELF_NADE_NAPALM,                       CENTER_DEATH_SELF_NADE_NAPALM) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_ICE,                                  NO_MSG,                INFO_DEATH_SELF_NADE_ICE,                                  CENTER_DEATH_SELF_NADE_ICE_FREEZE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_ICE_FREEZE,           NO_MSG,                INFO_DEATH_SELF_NADE_ICE_FREEZE,           CENTER_DEATH_SELF_NADE_ICE_FREEZE) \
+       MSG_MULTI_NOTIF(1, DEATH_SELF_NADE_HEAL,                 NO_MSG,        INFO_DEATH_SELF_NADE_HEAL,                 CENTER_DEATH_SELF_NADE_HEAL) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_NOAMMO,                    NO_MSG,        INFO_DEATH_SELF_NOAMMO,                    CENTER_DEATH_SELF_NOAMMO) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_ROT,                       NO_MSG,        INFO_DEATH_SELF_ROT,                       CENTER_DEATH_SELF_ROT) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_SHOOTING_STAR,             NO_MSG,        INFO_DEATH_SELF_SHOOTING_STAR,             CENTER_DEATH_SELF_SHOOTING_STAR) \
@@ -767,6 +808,8 @@ void Send_Notification_WOCOVA(
        MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_DEATH,             NO_MSG,        INFO_DEATH_SELF_VH_WAKI_DEATH,             CENTER_DEATH_SELF_VH_WAKI_DEATH) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_VH_WAKI_ROCKET,            NO_MSG,        INFO_DEATH_SELF_VH_WAKI_ROCKET,            CENTER_DEATH_SELF_VH_WAKI_ROCKET) \
        MSG_MULTI_NOTIF(1, DEATH_SELF_VOID,                      NO_MSG,        INFO_DEATH_SELF_VOID,                      CENTER_DEATH_SELF_VOID) \
+       MSG_MULTI_NOTIF(1, ITEM_BUFF_DROP,                       NO_MSG,        INFO_ITEM_BUFF_DROP,                       CENTER_ITEM_BUFF_DROP) \
+       MSG_MULTI_NOTIF(1, ITEM_BUFF_GOT,                        NO_MSG,        INFO_ITEM_BUFF_GOT,                        CENTER_ITEM_BUFF_GOT) \
        MSG_MULTI_NOTIF(1, ITEM_WEAPON_DONTHAVE,                 NO_MSG,        INFO_ITEM_WEAPON_DONTHAVE,                 CENTER_ITEM_WEAPON_DONTHAVE) \
        MSG_MULTI_NOTIF(1, ITEM_WEAPON_DROP,                     NO_MSG,        INFO_ITEM_WEAPON_DROP,                     CENTER_ITEM_WEAPON_DROP) \
        MSG_MULTI_NOTIF(1, ITEM_WEAPON_GOT,                      NO_MSG,        INFO_ITEM_WEAPON_GOT,                      CENTER_ITEM_WEAPON_GOT) \
@@ -934,6 +977,7 @@ var float autocvar_notification_show_sprees_center_specialonly = TRUE;
     item_wepname: return full name of a weapon from weaponid
     item_wepammo: ammo display for weapon from string
     item_centime: amount of time to display weapon message in centerprint
+    item_buffname: return full name of a buff from buffid
     death_team: show the full name of the team a player is switching from
 */
 
@@ -976,7 +1020,7 @@ string arg_slot[NOTIF_MAX_ARGS];
     ARG_CASE(ARG_CS_SV_HA,  "f3race_time",   mmssss(f3)) \
     ARG_CASE(ARG_CS_SV,     "race_col",      CCR(((f1 == 1) ? "^F1" : "^F2"))) \
     ARG_CASE(ARG_CS_SV,     "race_diff",     ((f2 > f3) ? sprintf(CCR("^1[+%s]"), mmssss(f2 - f3)) : sprintf(CCR("^2[-%s]"), mmssss(f3 - f2)))) \
-    ARG_CASE(ARG_CS,        "missing_teams", notif_arg_missing_teams(f1, f2, f3, f4)) \
+    ARG_CASE(ARG_CS,        "missing_teams", notif_arg_missing_teams(f1)) \
     ARG_CASE(ARG_CS,        "pass_key",      ((((tmp_s = getcommandkey("pass", "+use")) != "pass") && !(strstrofs(tmp_s, "not bound", 0) >= 0)) ? sprintf(CCR(_(" ^F1(Press %s)")), tmp_s) : "")) \
     ARG_CASE(ARG_CS,        "frag_ping",     notif_arg_frag_ping(TRUE, f2)) \
     ARG_CASE(ARG_CS,        "frag_stats",    notif_arg_frag_stats(f2, f3, f4)) \
@@ -986,6 +1030,7 @@ string arg_slot[NOTIF_MAX_ARGS];
     ARG_CASE(ARG_CS_SV,     "spree_end",     (autocvar_notification_show_sprees ? notif_arg_spree_inf(-1, "", "", f1) : "")) \
     ARG_CASE(ARG_CS_SV,     "spree_lost",    (autocvar_notification_show_sprees ? notif_arg_spree_inf(-2, "", "", f1) : "")) \
     ARG_CASE(ARG_CS_SV,     "item_wepname",  W_Name(f1)) \
+    ARG_CASE(ARG_CS_SV,     "item_buffname", sprintf("%s%s", rgb_to_hexcolor(Buff_Color(f1)), Buff_PrettyName(f1))) \
     ARG_CASE(ARG_CS_SV,     "item_wepammo",  (s1 != "" ? sprintf(_(" with %s"), s1) : "")) \
     ARG_CASE(ARG_DC,        "item_centime",  ftos(autocvar_notification_item_centerprinttime)) \
     ARG_CASE(ARG_SV,        "death_team",    Team_ColoredFullName(f1)) \
@@ -1020,26 +1065,26 @@ string notif_arg_frag_stats(float fhealth, float farmor, float fping)
                return sprintf(CCR(_("\n(^F4Dead^BG)%s")), notif_arg_frag_ping(FALSE, fping));
 }
 
-string notif_arg_missing_teams(float f1, float f2, float f3, float f4)
+string notif_arg_missing_teams(float f1)
 {
        return sprintf("%s%s%s%s",
-               (f1 ?
-                       sprintf("%s%s", Team_ColoredFullName(f1 - 1), ((f2 + f3 + f4) ? ", " : ""))
+               ((f1 & 1) ?
+                       sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_1), ((f1 & (2 + 4 + 8)) ? ", " : ""))
                        :
                        ""
                ),
-               (f2 ?
-                       sprintf("%s%s", Team_ColoredFullName(f2 - 1), ((f3 + f4) ? ", " : ""))
+               ((f1 & 2) ?
+                       sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_2), ((f1 & (4 + 8)) ? ", " : ""))
                        :
                        ""
                ),
-               (f3 ?
-                       sprintf("%s%s", Team_ColoredFullName(f3 - 1), (f4 ? ", " : ""))
+               ((f1 & 4) ?
+                       sprintf("%s%s", Team_ColoredFullName(NUM_TEAM_3), ((f1 & 8) ? ", " : ""))
                        :
                        ""
                ),
-               (f4 ?
-                       Team_ColoredFullName(f4 - 1)
+               ((f1 & 8) ?
+                       Team_ColoredFullName(NUM_TEAM_4)
                        :
                        ""
                )
@@ -1490,6 +1535,7 @@ void RegisterNotifications_First()
        #endif
 
        printf("Beginning notification initialization on %s%s program...\n", dedi, PROGNAME);
+       #undef dedi
 
        // maybe do another implementation of this with checksums? for now, we don't need versioning
        /*if(autocvar_notification_version != NOTIF_VERSION)
diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh
new file mode 100644 (file)
index 0000000..f358069
--- /dev/null
@@ -0,0 +1,290 @@
+// Full list of all stat constants, icnluded in a single location for easy reference
+// 255 is the current limit (MAX_CL_STATS - 1), engine will need to be modified if you wish to add more stats
+
+const float MAX_CL_STATS                = 256;
+const float STAT_HEALTH                 = 0;
+// 1 empty?
+const float STAT_WEAPON                 = 2;
+const float STAT_AMMO                   = 3;
+const float STAT_ARMOR                  = 4;
+const float STAT_WEAPONFRAME            = 5;
+const float STAT_SHELLS                 = 6;
+const float STAT_NAILS                  = 7;
+const float STAT_ROCKETS                = 8;
+const float STAT_CELLS                  = 9;
+const float STAT_ACTIVEWEAPON           = 10;
+const float STAT_TOTALSECRETS           = 11;
+const float STAT_TOTALMONSTERS          = 12;
+const float STAT_SECRETS                = 13;
+const float STAT_MONSTERS               = 14;
+const float STAT_ITEMS                  = 15;
+const float STAT_VIEWHEIGHT             = 16;
+// 17 empty?
+// 18 empty?
+// 19 empty?
+// 20 empty?
+const float STAT_VIEWZOOM               = 21;
+// 22 empty?
+// 23 empty?
+// 24 empty?
+// 25 empty?
+// 26 empty?
+// 27 empty?
+// 28 empty?
+// 29 empty?
+// 30 empty?
+// 31 empty?
+const float STAT_KH_KEYS                = 32;
+const float STAT_CTF_STATE              = 33;
+// 34 empty?
+const float STAT_WEAPONS                = 35;
+const float STAT_SWITCHWEAPON           = 36;
+const float STAT_GAMESTARTTIME          = 37;
+const float STAT_STRENGTH_FINISHED      = 38;
+const float STAT_INVINCIBLE_FINISHED    = 39;
+// 40 empty?
+// 41 empty?
+const float STAT_PRESSED_KEYS           = 42;
+const float STAT_ALLOW_OLDNEXBEAM       = 43; // this stat could later contain some other bits of info, like, more server-side particle config
+const float STAT_FUEL                   = 44;
+const float STAT_NB_METERSTART          = 45;
+const float STAT_SHOTORG                = 46; // compressShotOrigin
+const float STAT_LEADLIMIT              = 47;
+const float STAT_WEAPON_CLIPLOAD        = 48;
+const float STAT_WEAPON_CLIPSIZE        = 49;
+const float STAT_NEX_CHARGE             = 50;
+const float STAT_LAST_PICKUP            = 51;
+const float STAT_HUD                    = 52;
+const float STAT_NEX_CHARGEPOOL         = 53;
+const float STAT_DAMAGE_DEALT_TOTAL     = 54;
+const float STAT_TYPEHIT_TIME           = 55;
+const float STAT_LAYED_MINES            = 56;
+const float STAT_HAGAR_LOAD             = 57;
+const float STAT_SWITCHINGWEAPON        = 58;
+const float STAT_SUPERWEAPONS_FINISHED  = 59;
+const float STAT_VEHICLESTAT_HEALTH     = 60;
+const float STAT_VEHICLESTAT_SHIELD     = 61;
+const float STAT_VEHICLESTAT_ENERGY     = 62;
+const float STAT_VEHICLESTAT_AMMO1      = 63;
+const float STAT_VEHICLESTAT_RELOAD1    = 64;
+const float STAT_VEHICLESTAT_AMMO2      = 65;
+const float STAT_VEHICLESTAT_RELOAD2    = 66;
+const float STAT_VEHICLESTAT_W2MODE     = 67;
+// 68 empty?
+const float STAT_NADE_TIMER             = 69;
+const float STAT_SECRETS_TOTAL          = 70;
+const float STAT_SECRETS_FOUND          = 71;
+const float STAT_RESPAWN_TIME           = 72;
+const float STAT_ROUNDSTARTTIME         = 73;
+const float STAT_WEAPONS2               = 74;
+const float STAT_WEAPONS3               = 75;
+const float STAT_MONSTERS_TOTAL         = 76;
+const float STAT_MONSTERS_KILLED        = 77;
+const float STAT_BUFFS                  = 78;
+const float STAT_NADE_BONUS             = 79;
+const float STAT_NADE_BONUS_TYPE        = 80;
+const float STAT_NADE_BONUS_SCORE       = 81;
+const float STAT_HEALING_ORB            = 82;
+const float STAT_HEALING_ORB_ALPHA      = 83;
+// 84 empty?
+// 85 empty?
+// 86 empty?
+// 87 empty?
+// 88 empty?
+// 89 empty?
+// 90 empty?
+// 91 empty?
+// 92 empty?
+// 93 empty?
+// 94 empty?
+// 95 empty?
+// 96 empty?
+// 97 empty?
+// 98 empty?
+// 99 empty?
+
+
+/* The following stats change depending on the gamemode, so can share the same ID */
+// IDs 100 to 104 reserved for gamemodes
+
+// freeze tag, clan arena, jailbreak
+const float STAT_REDALIVE               = 100;
+const float STAT_BLUEALIVE              = 101;
+const float STAT_YELLOWALIVE            = 102;
+const float STAT_PINKALIVE              = 103;
+
+// domination
+const float STAT_DOM_TOTAL_PPS          = 100;
+const float STAT_DOM_PPS_RED            = 101;
+const float STAT_DOM_PPS_BLUE           = 102;
+const float STAT_DOM_PPS_YELLOW         = 103;
+const float STAT_DOM_PPS_PINK           = 104;
+
+// vip
+const float STAT_VIP                    = 100;
+const float STAT_VIP_RED                = 101;
+const float STAT_VIP_BLUE               = 102;
+const float STAT_VIP_YELLOW             = 103;
+const float STAT_VIP_PINK               = 104;
+
+// key hunt
+const float STAT_KH_REDKEY_TEAM         = 100;
+const float STAT_KH_BLUEKEY_TEAM        = 101;
+const float STAT_KH_YELLOWKEY_TEAM      = 102;
+const float STAT_KH_PINKKEY_TEAM        = 103;
+
+/* Gamemode-specific stats end here */
+
+
+const float STAT_FROZEN                 = 105;
+const float STAT_REVIVE_PROGRESS        = 106;
+// 107 empty?
+// 108 empty?
+// 109 empty?
+// 110 empty?
+// 111 empty?
+// 112 empty?
+// 113 empty?
+// 114 empty?
+// 115 empty?
+// 116 empty?
+// 117 empty?
+// 118 empty?
+// 119 empty?
+// 120 empty?
+// 121 empty?
+// 122 empty?
+// 123 empty?
+// 124 empty?
+// 125 empty?
+// 126 empty?
+// 127 empty?
+// 128 empty?
+// 129 empty?
+// 130 empty?
+// 131 empty?
+// 132 empty?
+// 133 empty?
+// 134 empty?
+// 135 empty?
+// 136 empty?
+// 137 empty?
+// 138 empty?
+// 139 empty?
+// 140 empty?
+// 141 empty?
+// 142 empty?
+// 143 empty?
+// 144 empty?
+// 145 empty?
+// 146 empty?
+// 147 empty?
+// 148 empty?
+// 149 empty?
+// 150 empty?
+// 151 empty?
+// 152 empty?
+// 153 empty?
+// 154 empty?
+// 155 empty?
+// 156 empty?
+// 157 empty?
+// 158 empty?
+// 159 empty?
+// 160 empty?
+// 161 empty?
+// 162 empty?
+// 162 empty?
+// 163 empty?
+// 164 empty?
+// 165 empty?
+// 166 empty?
+// 167 empty?
+// 168 empty?
+// 169 empty?
+// 170 empty?
+// 171 empty?
+// 172 empty?
+// 173 empty?
+// 174 empty?
+// 175 empty?
+// 176 empty?
+// 177 empty?
+// 178 empty?
+// 179 empty?
+// 180 empty?
+// 181 empty?
+// 182 empty?
+// 183 empty?
+// 184 empty?
+// 185 empty?
+// 186 empty?
+// 187 empty?
+// 188 empty?
+// 189 empty?
+// 190 empty?
+// 191 empty?
+// 192 empty?
+// 193 empty?
+// 194 empty?
+// 195 empty?
+// 196 empty?
+// 197 empty?
+// 198 empty?
+// 199 empty?
+// 200 empty?
+// 201 empty?
+// 202 empty?
+// 203 empty?
+// 204 empty?
+// 205 empty?
+// 206 empty?
+// 207 empty?
+// 208 empty?
+// 209 empty?
+// 210 empty?
+// 211 empty?
+// 212 empty?
+// 213 empty?
+// 214 empty?
+// 215 empty?
+// 216 empty?
+// 217 empty?
+// 218 empty?
+// 219 empty?
+const float STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR     = 220;
+const float STAT_MOVEVARS_AIRCONTROL_PENALTY            = 221;
+const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW           = 222;
+const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW             = 223;
+const float STAT_MOVEVARS_AIRCONTROL_POWER              = 224;
+const float STAT_MOVEFLAGS                              = 225;
+const float STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL   = 226;
+const float STAT_MOVEVARS_WARSOWBUNNY_ACCEL             = 227;
+const float STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED          = 228;
+const float STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL         = 229;
+const float STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO   = 230;
+const float STAT_MOVEVARS_AIRSTOPACCELERATE             = 231;
+const float STAT_MOVEVARS_AIRSTRAFEACCELERATE           = 232;
+const float STAT_MOVEVARS_MAXAIRSTRAFESPEED             = 233;
+const float STAT_MOVEVARS_AIRCONTROL                    = 234;
+const float STAT_FRAGLIMIT                              = 235;
+const float STAT_TIMELIMIT                              = 236;
+const float STAT_MOVEVARS_WALLFRICTION                  = 237;
+const float STAT_MOVEVARS_FRICTION                      = 238;
+const float STAT_MOVEVARS_WATERFRICTION                 = 239;
+const float STAT_MOVEVARS_TICRATE                       = 240;
+const float STAT_MOVEVARS_TIMESCALE                     = 241;
+const float STAT_MOVEVARS_GRAVITY                       = 242;
+const float STAT_MOVEVARS_STOPSPEED                     = 243;
+const float STAT_MOVEVARS_MAXSPEED                      = 244;
+const float STAT_MOVEVARS_SPECTATORMAXSPEED             = 245;
+const float STAT_MOVEVARS_ACCELERATE                    = 246;
+const float STAT_MOVEVARS_AIRACCELERATE                 = 247;
+const float STAT_MOVEVARS_WATERACCELERATE               = 248;
+const float STAT_MOVEVARS_ENTGRAVITY                    = 249;
+const float STAT_MOVEVARS_JUMPVELOCITY                  = 250;
+const float STAT_MOVEVARS_EDGEFRICTION                  = 251;
+const float STAT_MOVEVARS_MAXAIRSPEED                   = 252;
+const float STAT_MOVEVARS_STEPHEIGHT                    = 253;
+const float STAT_MOVEVARS_AIRACCEL_QW                   = 254;
+const float STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION    = 255;
index f39c30c0007cb03165d06d181c6c04e534497e25..4e8e1b59c8d35ac69ea37fe0f410f74eb1f79d92 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifndef NOCOMPAT
 //# define WORKAROUND_XON010
-//# define COMPAT_XON010_CHANNELS
 //# define COMPAT_XON050_ENGINE
 # define COMPAT_NO_MOD_IS_XONOTIC
 # define COMPAT_XON060_DONTCRASH_CHECKPVS
index c50a3ba5350d3b1fd1bdb394bc0b3ca5852026dd..2c6636a3b9a8bd8169ba0cacbc3c9b47cf9d6b92 100644 (file)
@@ -2106,6 +2106,8 @@ float get_model_parameters(string m, float sk)
                        get_model_parameters_weight = stof(s);
                if(c == "age")
                        get_model_parameters_age = stof(s);
+               if(c == "description")
+                       get_model_parameters_description = s;
                if(c == "bone_upperbody")
                        get_model_parameters_bone_upperbody = s;
                if(c == "bone_weapon")
index 503aa2d2a0f9452fa81232493caa94e95383477b..9ddc925795b8add1c3fef863aff21c2f8a37b8c7 100644 (file)
@@ -273,6 +273,7 @@ float get_model_parameters_species;
 string get_model_parameters_sex;
 float get_model_parameters_weight;
 float get_model_parameters_age;
+string get_model_parameters_description;
 string get_model_parameters_bone_upperbody;
 string get_model_parameters_bone_weapon;
 #define MAX_AIM_BONES 4
@@ -305,9 +306,9 @@ const float XENCODE_LEN = 5;
 string xencode(float f);
 float xdecode(string s);
 
-#ifndef COMPAT_XON010_CHANNELS
+// Play all sounds via sound7, for access to the extra channels.
+// Otherwise, channels 8 to 15 would be blocked for a weird QW feature.
 #define sound(e,c,s,v,a) sound7(e,c,s,v,a,0,0)
-#endif
 
 float lowestbit(float f);
 
index ff1210c74780fe2d6a512854a75723748c60ba13..46d0c0269e01d8a3532941343457e1cb39fe346b 100644 (file)
 #include "xonotic/dialog_hudpanel_weapons.c"
 #include "xonotic/dialog_hudpanel_physics.c"
 #include "xonotic/dialog_hudpanel_centerprint.c"
+#include "xonotic/dialog_hudpanel_buffs.c"
 #include "xonotic/slider_picmip.c"
+#include "xonotic/slider_particles.c"
index f14a4ceb7c90c949a41ff322e3d2a3258e5e73ba..091891a671a7c5c41e1e87f166b6c93c5575b815 100644 (file)
@@ -15,6 +15,7 @@ CLASS(Container) EXTENDS(Item)
        METHOD(Container, moveItemAfter, void(entity, entity, entity))
        METHOD(Container, removeItem, void(entity, entity))
        METHOD(Container, setFocus, void(entity, entity))
+       METHOD(Container, saveFocus, void(entity))
        METHOD(Container, setAlphaOf, void(entity, entity, float))
        METHOD(Container, itemFromPoint, entity(entity, vector))
        METHOD(Container, showNotify, void(entity))
@@ -24,6 +25,7 @@ CLASS(Container) EXTENDS(Item)
        ATTRIB(Container, firstChild, entity, NULL)
        ATTRIB(Container, lastChild, entity, NULL)
        ATTRIB(Container, focusedChild, entity, NULL)
+       ATTRIB(Container, savedFocus, entity, NULL)
        ATTRIB(Container, shown, float, 0)
 
        METHOD(Container, enterSubitem, void(entity, entity))
@@ -346,23 +348,46 @@ void Container_removeItem(entity me, entity other)
 
 void Container_setFocus(entity me, entity other)
 {
-       if(other)
-               if (!me.focused)
-                       error("Trying to set focus in a non-focused control!");
        if(me.focusedChild == other)
                return;
-       //print(etos(me), ": focus changes from ", etos(me.focusedChild), " to ", etos(other), "\n");
+
        if(me.focusedChild)
        {
                me.focusedChild.focused = 0;
                me.focusedChild.focusLeave(me.focusedChild);
+               me.focusedChild = NULL;
        }
+
        if(other)
        {
-               other.focused = 1;
-               other.focusEnter(other);
+               if(!me.focused)
+                       error("Trying to set focus in a non-focused control!");
+
+               if(me.savedFocus)
+               {
+                       me.focusedChild = me.savedFocus;
+                       me.savedFocus = NULL;
+                       me.focusedChild.focused = 1;
+                       me.focusedChild.focusEnter(me.focusedChild);
+
+                       if(me.focusedChild.instanceOfContainer)
+                               me.focusedChild.setFocus(me.focusedChild, me.focusedChild.savedFocus);
+               }
+               else
+               {
+                       me.focusedChild = other;
+                       me.focusedChild.focused = 1;
+                       me.focusedChild.focusEnter(me.focusedChild);
+               }
        }
-       me.focusedChild = other;
+}
+
+void Container_saveFocus(entity me)
+{
+       me.savedFocus = me.focusedChild;
+
+       if(me.focusedChild.instanceOfContainer)
+               me.focusedChild.saveFocus(me.focusedChild);
 }
 
 void Container_moveItemAfter(entity me, entity other, entity dest)
index 8406af01f6be3e68f3ab80260641d7d1145cf93c..0f6f96647198e5a4e5605cf13cd1c7608aa9737f 100644 (file)
@@ -20,7 +20,7 @@ CLASS(Label) EXTENDS(Item)
        ATTRIB(Label, realFontSize, vector, '0 0 0')
        ATTRIB(Label, realOrigin, vector, '0 0 0')
        ATTRIB(Label, alpha, float, 0.7)
-       ATTRIB(Label, colorL, vector, '1 1 1')
+       ATTRIB(Label, colorL, vector, SKINCOLOR_TEXT)
        ATTRIB(Label, disabled, float, 0)
        ATTRIB(Label, disabledAlpha, float, 0.3)
        ATTRIB(Label, textEntity, entity, NULL)
index 5a5541dc7b0da4706800380998b531d67e5de329..6aab958e65da938937a0572cb75cc00514509cef 100644 (file)
@@ -87,6 +87,8 @@ void DialogOpenButton_Click_withCoords(entity button, entity tab, vector theOrig
                return;
        if(button)
                button.forcePressed = 1;
+       if(tab.parent.focusedChild)
+               tab.parent.focusedChild.saveFocus(tab.parent.focusedChild);
        tab.ModalController_controllingButton = button;
        tab.parent.showChild(tab.parent, tab, theOrigin, theSize, 0);
 }
index 382a19d2ded3074b4fae4dabc92c9e73e13b819f..d7fd581a32f9a3f15125d8ed246bcc90cbffc05a 100644 (file)
@@ -666,7 +666,7 @@ void m_tooltip(vector pos)
                        while(getWrappedLine_remaining)
                        {
                                s = getWrappedLine(SKINWIDTH_TOOLTIP, fontsize, draw_TextWidth_WithoutColors);
-                               draw_Text(p, s, fontsize, '1 1 1', SKINALPHA_TOOLTIP * menuTooltipAlpha, FALSE);
+                               draw_Text(p, s, fontsize, SKINCOLOR_TOOLTIP, SKINALPHA_TOOLTIP * menuTooltipAlpha, FALSE);
                                p_y += fontsize_y;
                        }
                }
index 6b5cac042ca970af7df0cc83c1c4e9f5e5e14585..6583898bc7ff8dfc5c50f4e0fa59291a91bcbd6b 100644 (file)
@@ -45,10 +45,11 @@ SKINBEGIN
        SKINSTRING(GFX_TOOLTIP, "tooltip");
        SKINVECTOR(MARGIN_TOOLTIP, '5 5 0');
        SKINVECTOR(BORDER_TOOLTIP, '1 1 0');
+       SKINVECTOR(AVOID_TOOLTIP, '8 8 0');
+       SKINFLOAT(WIDTH_TOOLTIP, 0.3);
        SKINFLOAT(FONTSIZE_TOOLTIP, 12);
        SKINFLOAT(ALPHA_TOOLTIP, 0.7);
-       SKINFLOAT(WIDTH_TOOLTIP, 0.3);
-       SKINVECTOR(AVOID_TOOLTIP, '8 8 0');
+       SKINVECTOR(COLOR_TOOLTIP, '1 1 1');
 
        // the individual dialog background colors
        SKINVECTOR(COLOR_DIALOG_FIRSTRUN, '0.7 0.7 1');
@@ -97,7 +98,8 @@ SKINBEGIN
        SKINFLOAT(ALPHA_DISABLED, 0.2);
        SKINFLOAT(ALPHA_BEHIND, 0.5);
        SKINFLOAT(ALPHA_TEXT, 0.7);
-
+       SKINVECTOR(COLOR_TEXT, '1 1 1');
+       
        // item: button
        SKINSTRING(GFX_BUTTON, "button");
        SKINSTRING(GFX_BUTTON_GRAY, "buttongray");
@@ -201,7 +203,6 @@ SKINBEGIN
 
        // item: player color button
        SKINSTRING(GFX_COLORBUTTON, "colorbutton");
-       SKINSTRING(GFX_COLORBUTTON_COLOR, "color");
 
        // item: player model
        SKINVECTOR(COLOR_MODELTITLE, '1 1 1');
@@ -227,6 +228,8 @@ SKINBEGIN
        SKINFLOAT(WIDTH_SCROLLBAR, 16);
 
        // item: server list
+       SKINFLOAT(ALPHA_SERVERLIST_CATEGORY, 0.7);
+       SKINVECTOR(COLOR_SERVERLIST_CATEGORY, '1 1 1');
        SKINFLOAT(ALPHA_SERVERLIST_FULL, 0.4);
        SKINFLOAT(ALPHA_SERVERLIST_EMPTY, 0.7);
        SKINVECTOR(COLOR_SERVERLIST_LOWPING, '0 1 0');
index 772c9e452cdfb72e6e74fd1a7f2b52ff86624acb..bcbdfee8db9d3585a4aa4e51567492207cd392bc 100644 (file)
@@ -3,9 +3,8 @@ CLASS(XonoticColorButton) EXTENDS(RadioButton)
        METHOD(XonoticColorButton, configureXonoticColorButton, void(entity, float, float, float))
        METHOD(XonoticColorButton, setChecked, void(entity, float))
        METHOD(XonoticColorButton, draw, void(entity))
-       ATTRIB(XonoticColorButton, fontSize, float, SKINFONTSIZE_NORMAL)
+       ATTRIB(XonoticColorButton, fontSize, float, 0)
        ATTRIB(XonoticColorButton, image, string, SKINGFX_COLORBUTTON)
-       ATTRIB(XonoticColorButton, image2, string, SKINGFX_COLORBUTTON_COLOR)
 
        ATTRIB(XonoticColorButton, useDownAsChecked, float, 1)
 
@@ -54,8 +53,6 @@ void XonoticColorButton_configureXonoticColorButton(entity me, float theGroup, f
        me.cvarPart = theColor;
        me.loadCvars(me);
        me.configureRadioButton(me, string_null, me.fontSize, me.image, theGroup, 0);
-       me.srcMulti = 1;
-       me.src2 = me.image2;
 }
 void XonoticColorButton_setChecked(entity me, float val)
 {
@@ -94,7 +91,10 @@ void XonoticColorButton_saveCvars(entity me)
 }
 void XonoticColorButton_draw(entity me)
 {
-       me.color2 = colormapPaletteColor(me.cvarValueFloat, me.cvarPart);
+       me.color  = colormapPaletteColor(me.cvarValueFloat, me.cvarPart);
+       me.colorC = me.color;
+       me.colorF = me.color;
+       me.colorD = me.color;
        SUPER(XonoticColorButton).draw(me);
 }
 #endif
index ee8cf6a4f613c3e3db2ac8df019cfdcf3b5ac22e..cf0e987c0a475dc34fbe920dfc9fa5cd9b6c3686 100644 (file)
@@ -104,7 +104,7 @@ void XonoticDemoList_drawListBoxItem(entity me, float i, vector absSize, float i
 
        s = me.demoName(me,i);
        s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
-       draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+       draw_Text(me.realUpperMargin * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
 }
 
 void XonoticDemoList_showNotify(entity me)
diff --git a/qcsrc/menu/xonotic/dialog_hudpanel_buffs.c b/qcsrc/menu/xonotic/dialog_hudpanel_buffs.c
new file mode 100644 (file)
index 0000000..ac1033c
--- /dev/null
@@ -0,0 +1,22 @@
+#ifdef INTERFACE
+CLASS(XonoticHUDBuffsDialog) EXTENDS(XonoticRootDialog)
+       METHOD(XonoticHUDBuffsDialog, fill, void(entity))
+       ATTRIB(XonoticHUDBuffsDialog, title, string, _("Buffs Panel"))
+       ATTRIB(XonoticHUDBuffsDialog, color, vector, SKINCOLOR_DIALOG_TEAMSELECT)
+       ATTRIB(XonoticHUDBuffsDialog, intendedWidth, float, 0.4)
+       ATTRIB(XonoticHUDBuffsDialog, rows, float, 15)
+       ATTRIB(XonoticHUDBuffsDialog, columns, float, 4)
+       ATTRIB(XonoticHUDBuffsDialog, name, string, "HUDbuffs")
+       ATTRIB(XonoticHUDBuffsDialog, requiresConnection, float, TRUE)
+ENDCLASS(XonoticHUDBuffsDialog)
+#endif
+
+#ifdef IMPLEMENTATION
+void XonoticHUDBuffsDialog_fill(entity me)
+{
+       entity e;
+       string panelname = "buffs";
+
+       DIALOG_HUDPANEL_COMMON();
+}
+#endif
index f3811f5b94c3e52e83cd0b7b352bc1c5690142e8..e4aa1d6d97d30600e76a779ee1d26ce228f920d5 100644 (file)
@@ -2,6 +2,7 @@
 CLASS(XonoticServerCreateTab) EXTENDS(XonoticTab)
        METHOD(XonoticServerCreateTab, fill, void(entity))
        METHOD(XonoticServerCreateTab, gameTypeChangeNotify, void(entity))
+       METHOD(XonoticServerCreateTab, gameTypeSelectNotify, void(entity))
        ATTRIB(XonoticServerCreateTab, title, string, _("Create"))
        ATTRIB(XonoticServerCreateTab, intendedWidth, float, 0.9)
        ATTRIB(XonoticServerCreateTab, rows, float, 22)
@@ -165,4 +166,9 @@ void XonoticServerCreateTab_gameTypeChangeNotify(entity me)
        me.mapListBox.refilter(me.mapListBox);
 }
 
+void XonoticServerCreateTab_gameTypeSelectNotify(entity me)
+{
+       me.setFocus(me, me.mapListBox);
+}
+
 #endif
index 8e4bc5a23cb153c815da6a06a48477b154229a06..e5dec8fff5478e8948d14539f259cfec3026cd35 100644 (file)
@@ -46,7 +46,7 @@ void XonoticMapInfoDialog_loadMapInfo(entity me, float i, entity mlb)
        me.currentMapTitle = strzone(strdecolorize(MapInfo_Map_title));
        me.currentMapAuthor = strzone(strdecolorize(MapInfo_Map_author));
        me.currentMapDescription = strzone(MapInfo_Map_description);
-       me.currentMapFeaturesText = strzone((MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS) ? _("Full item placement") : _("MinstaGib only"));
+       me.currentMapFeaturesText = strzone((MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS) ? _("Full item placement") : _("InstaGib only"));
        me.currentMapPreviewImage = strzone(strcat("/maps/", MapInfo_Map_bspname));
 
        me.frame.setText(me.frame, me.currentMapBSPName);
index 18c376b503dda2463b9b3f776de54e66048ad2ed..3bac353053bc9a69e5213a3190efa4acbbf05046 100644 (file)
@@ -29,7 +29,7 @@ string WeaponArenaString()
        s = cvar_string("g_weaponarena");
        if(s == "0")
                return "";
-       if(s == "all")
+       if(s == "all" || s == "1")
                return _("All Weapons Arena");
        if(s == "most")
                return _("Most Weapons Arena");
@@ -66,8 +66,8 @@ string XonoticMutatorsDialog_toString(entity me)
        s = "";
        if(cvar("g_dodging"))
                s = strcat(s, ", ", _("Dodging"));
-       if(cvar("g_minstagib"))
-               s = strcat(s, ", ", _("MinstaGib"));
+       if(cvar("g_instagib"))
+               s = strcat(s, ", ", _("InstaGib"));
        if(cvar("g_new_toys"))
                s = strcat(s, ", ", _("New Toys"));
        if(cvar("g_nix"))
@@ -112,7 +112,7 @@ string XonoticMutatorsDialog_toString(entity me)
 
 float checkCompatibility_pinata(entity me)
 {
-       if(cvar("g_minstagib"))
+       if(cvar("g_instagib"))
                return 0;
        if(cvar("g_nix"))
                return 0;
@@ -126,11 +126,11 @@ float checkCompatibility_weaponstay(entity me)
 }
 float checkCompatibility_newtoys(entity me)
 {
-       if(cvar("g_minstagib"))
+       if(cvar("g_instagib"))
                return 0;
        if(cvar_string("g_weaponarena") == "most")
                return 1;
-       if(cvar_string("g_weaponarena") == "all")
+       if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1")
                return 1;
        if(cvar_string("g_weaponarena") != "0")
                return 0;
@@ -138,11 +138,11 @@ float checkCompatibility_newtoys(entity me)
 }
 float checkCompatibility_weaponarena_weapon(entity me)
 {
-       if(cvar("g_minstagib"))
+       if(cvar("g_instagib"))
                return 0;
        if(cvar_string("g_weaponarena") == "most")
                return 0;
-       if(cvar_string("g_weaponarena") == "all")
+       if(cvar_string("g_weaponarena") == "all" || cvar_string("g_weaponarena") == "1")
                return 0;
        if(cvar_string("g_weaponarena") == "0")
                return 0;
@@ -172,12 +172,12 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_vampire", _("Vampire")));
-                       setDependent(e, "g_minstagib", 0, 0);
+                       setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
                me.TDempty(me, 0.2);
                s = makeXonoticSlider(10, 50, 1, "g_bloodloss");
                me.TD(me, 1, 1.8, e = makeXonoticSliderCheckBox(0, 1, s, _("Blood loss")));
-                       setDependent(e, "g_minstagib", 0, 0);
+                       setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
                me.TDempty(me, 0.4);
                me.TD(me, 1, 1.6, s);
@@ -202,7 +202,7 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_invincible_projectiles", _("Invincible Projectiles")));
-                       setDependent(e, "g_minstagib", 0, 0);
+                       setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_new_toys", _("New Toys")));
@@ -210,7 +210,7 @@ void XonoticMutatorsDialog_fill(entity me)
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_rocket_flying", _("Rocket Flying")));
-                       setDependent(e, "g_minstagib", 0, 0);
+                       setDependent(e, "g_instagib", 0, 0);
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "g_pinata", _("Piñata")));
@@ -251,7 +251,7 @@ void XonoticMutatorsDialog_fill(entity me)
                me.TD(me, 1, 4, makeXonoticTextLabel(0, _("Special arenas:")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_minstagib", "1", _("MinstaGib")));
+               me.TD(me, 1, 1.8, e = makeXonoticRadioButton(1, "g_instagib", "1", _("InstaGib")));
                        e.cvarOffValue = "0";
        me.TR(me);
                me.TDempty(me, 0.2);
index a963d1e3099862fb485fff19d842f5f5206522b8..c56d972d9da92eac957a6a3888709eef3a444456 100644 (file)
@@ -47,8 +47,7 @@ void XonoticEffectsSettingsTab_fill(entity me)
                if(cvar("developer"))
                        me.TD(me, 1, 5 / n, e = makeXonoticCommandButton(ZCTX(_("PRE^Ultimate")), '0.5 0 0', "exec effects-ultimate.cfg", 0));
 
-       me.TR(me);
-       me.TR(me);
+       me.gotoRC(me, 1.25, 0);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Geometry detail:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider("r_subdivisions_tolerance"));
                        e.addValue(e, ZCTX(_("DET^Lowest")), "16");
@@ -60,7 +59,13 @@ void XonoticEffectsSettingsTab_fill(entity me)
                        e.configureXonoticTextSliderValues(e);
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Player detail:")));
-               me.TD(me, 1, 2, e = makeXonoticSlider(4, 0, -0.1, "cl_playerdetailreduction"));
+               me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_playerdetailreduction"));
+                       e.addValue(e, ZCTX(_("PDET^Low")), "4");
+                       e.addValue(e, ZCTX(_("PDET^Medium")), "3");
+                       e.addValue(e, ZCTX(_("PDET^Normal")), "2");
+                       e.addValue(e, ZCTX(_("PDET^Good")), "1");
+                       e.addValue(e, ZCTX(_("PDET^Best")), "0");
+                       e.configureXonoticTextSliderValues(e);
        me.TR(me);
                me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Texture resolution:")));
                        setDependent(e, "r_showsurfaces", 0, 0);
@@ -126,23 +131,23 @@ void XonoticEffectsSettingsTab_fill(entity me)
                        setDependentAND(e, "vid_gl20", 1, 1, "r_water", 1, 1);
        me.TR(me);
        me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Particles quality:")));
-               me.TD(me, 1, 2, e = makeXonoticSlider(0.2, 1.0, 0.1, "cl_particles_quality"));
-       me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Particles distance:")));
-               me.TD(me, 1, 2, e = makeXonoticSlider(500, 2000, 100, "r_drawparticles_drawdistance"));
+               me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_decals", _("Decals")));
+               me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models")));
+                       setDependent(e, "cl_decals", 1, 1);
        me.TR(me);
-       me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Damage effects:")));
-               me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_damageeffect"));
-                       e.addValue(e, ZCTX(_("DMGPRTCLS^Disabled")), "0");
-                       e.addValue(e, ZCTX(_("DMGPRTCLS^Skeletal")), "1");
-                       e.addValue(e, ZCTX(_("DMGPRTCLS^All")), "2");
-                       e.configureXonoticTextSliderValues(e);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:")));
+                       setDependent(e, "cl_decals", 1, 1);
+               me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawdecals_drawdistance"));
+                       setDependent(e, "cl_decals", 1, 1);
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_spawn_point_particles", _("Particle effects for spawnpoints")));
-               makeMulti(e, "cl_spawn_event_particles");
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:")));
+                       setDependent(e, "cl_decals", 1, 1);
+               me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_fadetime"));
+                       setDependent(e, "cl_decals", 1, 1);
 
-       me.gotoRC(me, 2, 3.2); me.setFirstColumn(me, me.currentColumn);
+       me.gotoRC(me, 1.25, 3.2); me.setFirstColumn(me, me.currentColumn);
                me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "r_coronas", "0", _("No dynamic lighting")));
        me.TR(me);
                me.TD(me, 1, 3, e = makeXonoticRadioButton(1, "gl_flashblend", string_null, _("Fake corona lighting")));
@@ -180,21 +185,28 @@ void XonoticEffectsSettingsTab_fill(entity me)
                me.TD(me, 1, 2, s);
        me.TR(me);
        me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_decals", _("Decals")));
-               me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_decals_models", _("Decals on models")));
-                       setDependent(e, "cl_decals", 1, 1);
+               me.TD(me, 1, 1, e = makeXonoticCheckBox(0, "cl_particles", _("Particles")));
+               me.TD(me, 1, 2, e = makeXonoticCheckBox(0, "cl_spawn_point_particles", _("Spawnpoint effects")));
+                       makeMulti(e, "cl_spawn_event_particles");
+                       setDependent(e, "cl_particles", 1, 1);
        me.TR(me);
+               me.TDempty(me, 0.2);
+               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Quality:")));
+                       setDependent(e, "cl_particles", 1, 1);
+               me.TD(me, 1, 2, e = makeXonoticParticlesSlider());
+                       setDependent(e, "cl_particles", 1, 1);
+               me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Distance:")));
                        setDependent(e, "cl_decals", 1, 1);
                me.TD(me, 1, 2, e = makeXonoticSlider(200, 500, 20, "r_drawdecals_drawdistance"));
                        setDependent(e, "cl_decals", 1, 1);
-       me.TR(me);
+               me.TR(me);
                me.TDempty(me, 0.2);
-           me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:")));
-               setDependent(e, "cl_decals", 1, 1);
-           me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_time"));
-               setDependent(e, "cl_decals", 1, 1);
+               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Time:")));
+                       setDependent(e, "cl_decals", 1, 1);
+               me.TD(me, 1, 2, e = makeXonoticSlider(1, 20, 1, "cl_decals_fadetime"));
+                       setDependent(e, "cl_decals", 1, 1);
 
        me.gotoRC(me, me.rows - 1, 0);
                me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "vid_restart", COMMANDBUTTON_APPLY));
index 56c25314da697317fdebfa66dceec917577dfc54..8883e8bbe4aff519e8c020d4295db2e227154a66 100644 (file)
@@ -7,6 +7,7 @@ CLASS(XonoticGametypeList) EXTENDS(XonoticListBox)
        METHOD(XonoticGametypeList, setSelected, void(entity, float))
        METHOD(XonoticGametypeList, loadCvars, void(entity))
        METHOD(XonoticGametypeList, saveCvars, void(entity))
+       METHOD(XonoticGametypeList, keyDown, float(entity, float, float, float))
 
        ATTRIB(XonoticGametypeList, realFontSize, vector, '0 0 0')
        ATTRIB(XonoticGametypeList, realUpperMargin1, float, 0)
@@ -83,9 +84,9 @@ void XonoticGametypeList_drawListBoxItem(entity me, float i, vector absSize, flo
 
        draw_Picture(me.columnIconOrigin * eX, GameType_GetIcon(i), me.columnIconSize * eX + eY, '1 1 1', SKINALPHA_LISTBOX_SELECTED);
        s = GameType_GetName(i);
-       draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.5 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+       draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.5 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
        //s = GameType_GetTeams(i);
-       //draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+       //draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 1.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
 }
 void XonoticGametypeList_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
 {
@@ -101,4 +102,15 @@ void XonoticGametypeList_resizeNotify(entity me, vector relOrigin, vector relSiz
        me.columnNameOrigin = me.columnIconOrigin + me.columnIconSize;
        me.columnNameSize = 1 - me.columnIconSize - 2 * me.realFontSize_x;
 }
+
+float XonoticGametypeList_keyDown(entity me, float scan, float ascii, float shift)
+{
+       if(scan == K_ENTER || scan == K_KP_ENTER)
+       {
+               me.parent.gameTypeSelectNotify(me.parent);
+               return 1;
+       }
+
+       return SUPER(XonoticGametypeList).keyDown(me, scan, ascii, shift);
+}
 #endif
index b91610a30ed01e452ccf1eb607f07e53c14596f3..56d074115a4c6a788ba49d83e558739c86244cb3 100644 (file)
@@ -65,13 +65,13 @@ void XonoticLanguageList_drawListBoxItem(entity me, float i, vector absSize, flo
 
        s = me.languageParameter(me, i, LANGPARM_NAME_LOCALIZED);
        s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
-       draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+       draw_Text(me.realUpperMargin * eY + me.columnNameOrigin * eX, s, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
 
        p = me.languageParameter(me, i, LANGPARM_PERCENTAGE);
        if(p != "")
        {
                p = draw_TextShortenToWidth(p, me.columnPercentageSize, 0, me.realFontSize);
-               draw_Text(me.realUpperMargin * eY + (me.columnPercentageOrigin + (me.columnPercentageSize - draw_TextWidth(p, 0, me.realFontSize))) * eX, p, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+               draw_Text(me.realUpperMargin * eY + (me.columnPercentageOrigin + (me.columnPercentageSize - draw_TextWidth(p, 0, me.realFontSize))) * eX, p, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
        }
 }
 
index debe6bd975c0f5dcfe3fde58b185c595363358fe..5c58025fca1f5e3ac87501e585ffee2828e7aed3 100644 (file)
@@ -126,6 +126,10 @@ void MainWindow_configureMainWindow(entity me)
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
 
+       i = spawnXonoticHUDBuffsDialog();
+       i.configureDialog(i);
+       me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
 
        // dialogs used by settings
        me.userbindEditDialog = i = spawnXonoticUserbindEditDialog();
index ce937e4add00cca264c454249a3094785a2654d6..60eeb445c6c4877caf508aa145ccf9c403d9e5ef 100644 (file)
@@ -142,25 +142,24 @@ void XonoticMapList_resizeNotify(entity me, vector relOrigin, vector relSize, ve
 void XonoticMapList_clickListBoxItem(entity me, float i, vector where)
 {
        if(where_x <= me.columnPreviewOrigin + me.columnPreviewSize)
-       {
                if(where_x >= 0)
                        me.g_maplistCacheToggle(me, i);
-       }
+
        if(where_x >= me.columnNameOrigin)
                if(where_x <= 1)
-                       {
-                               if(i == me.lastClickedMap)
-                                       if(time < me.lastClickedTime + 0.3)
-                                       {
-                                               // DOUBLE CLICK!
-                                               // pop up map info screen
-                                               main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me);
-                                               DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize));
-                                               return;
-                                       }
-                               me.lastClickedMap = i;
-                               me.lastClickedTime = time;
-                       }
+               {
+                       if(i == me.lastClickedMap)
+                               if(time < me.lastClickedTime + 0.3)
+                               {
+                                       // DOUBLE CLICK!
+                                       // pop up map info screen
+                                       main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, i, me);
+                                       DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * i - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize));
+                                       return;
+                               }
+                       me.lastClickedMap = i;
+                       me.lastClickedTime = time;
+               }
 }
 
 void XonoticMapList_drawListBoxItem(entity me, float i, vector absSize, float isSelected)
@@ -301,13 +300,13 @@ float XonoticMapList_keyDown(entity me, float scan, float ascii, float shift)
        string ch, save;
        if(me.nItems <= 0)
                return SUPER(XonoticMapList).keyDown(me, scan, ascii, shift);
-       if(scan == K_ENTER || scan == K_KP_ENTER)
+       if(scan == K_MOUSE2 || scan == K_SPACE || scan == K_ENTER || scan == K_KP_ENTER)
        {
                // pop up map info screen
                main.mapInfoDialog.loadMapInfo(main.mapInfoDialog, me.selectedItem, me);
                DialogOpenButton_Click_withCoords(NULL, main.mapInfoDialog, me.origin + eX * (me.columnNameOrigin * me.size_x) + eY * ((me.itemHeight * me.selectedItem - me.scrollPos) * me.size_y), eY * me.itemAbsSize_y + eX * (me.itemAbsSize_x * me.columnNameSize));
        }
-       else if(scan == K_SPACE)
+       else if(scan == K_MOUSE3 || scan == K_INS || scan == K_KP_INS)
        {
                me.g_maplistCacheToggle(me, me.selectedItem);
        }
index a0f64ca39e424c97a05a83e1064b205fa4a3a65d..315a68caa731b4c15657ca4e0d20c13b60814c60 100644 (file)
@@ -108,7 +108,7 @@ void XonoticPlayerList_drawListBoxItem(entity me, float i, vector absSize, float
        else if(t == 4)
                rgb = colormapPaletteColor(9, 0);
        else
-               rgb = '1 1 1';
+               rgb = SKINCOLOR_TEXT;
 
        s = me.getPlayerList(me, i, PLAYERPARM_NAME);
        score = me.getPlayerList(me, i, PLAYERPARM_SCORE);
index f37aaeb0750d8568dea1d8cf79b9a6f738bb71ff..652c581c00f6110e3cc66785d009adcb6cb89319 100644 (file)
@@ -5,6 +5,7 @@ CLASS(XonoticPlayerModelSelector) EXTENDS(XonoticImage)
        METHOD(XonoticPlayerModelSelector, saveCvars, void(entity))
        METHOD(XonoticPlayerModelSelector, draw, void(entity))
        METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector))
+       METHOD(XonoticPlayerModelSelector, showNotify, void(entity))
        ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null)
        ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0)
        ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null)
@@ -42,6 +43,8 @@ entity makeXonoticPlayerModelSelector()
 #define BUFMODELS_DESC 4
 #define BUFMODELS_COUNT 5
 
+#define XONVOTE186 1 // (nyov) removal of model text description
+
 void XonoticPlayerModelSelector_configureXonoticPlayerModelSelector(entity me)
 {
        float sortbuf, glob, i;
@@ -76,12 +79,19 @@ void XonoticPlayerModelSelector_configureXonoticPlayerModelSelector(entity me)
                bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname);
                bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN, ftos(get_model_parameters_modelskin));
                get_model_parameters_desc = strcat(get_model_parameters_desc, "\n");
+#if XONVOTE186
+               if(get_model_parameters_sex)
+                       get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s", get_model_parameters_sex));
+#else
+               if(get_model_parameters_description)
+                       get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s\n", get_model_parameters_description));
                if(get_model_parameters_sex)
                        get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nSex: %s", get_model_parameters_sex));
                if(get_model_parameters_weight)
                        get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nWeight: %g kg", get_model_parameters_weight));
                if(get_model_parameters_age)
                        get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nAge: %g", get_model_parameters_age));
+#endif
                while(substring(get_model_parameters_desc, -1, 1) == "\n")
                        get_model_parameters_desc = substring(get_model_parameters_desc, 0, -2);
                bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_DESC, get_model_parameters_desc);
@@ -174,7 +184,7 @@ void XonoticPlayerModelSelector_draw(entity me)
 
        if (me.numModels <= 0)
        {
-               draw_CenterText('0.5 0.5 0', _("<no model found>"), me.realFontSize, '1 1 1', 0.6, FALSE);
+               draw_CenterText('0.5 0.5 0', _("<no model found>"), me.realFontSize, SKINCOLOR_TEXT, 0.6, FALSE);
                return;
        }
 
@@ -183,14 +193,18 @@ void XonoticPlayerModelSelector_draw(entity me)
 
        draw_beginBoldFont();
 
+#if XONVOTE186 // (nyov) lower name display looks better when there is no description text
+       draw_CenterText('0.5 0.8 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE);
+#else
        draw_CenterText('0.5 0 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, FALSE);
+#endif
 
        draw_endBoldFont();
 
        o = '0.5 1 0' - eY * me.realFontSize_y * ((n = tokenizebyseparator(me.currentModelDescription, "\n")) + 0.5);
        for(i = 0; i < n; ++i)
        {
-               draw_CenterText(o, argv(i), me.realFontSize, '1 1 1', 1, FALSE);
+               draw_CenterText(o, argv(i), me.realFontSize, SKINCOLOR_TEXT, 1, FALSE);
                o += eY * me.realFontSize_y;
        }
 }
@@ -201,4 +215,9 @@ void XonoticPlayerModelSelector_resizeNotify(entity me, vector relOrigin, vector
        me.realFontSize_y = me.fontSize / absSize_y;
        me.realFontSize_x = me.fontSize / absSize_x;
 }
+
+void XonoticPlayerModelSelector_showNotify(entity me)
+{
+       me.configureXonoticPlayerModelSelector(me);
+}
 #endif
index 0c7fe148be6ea7b0eed1c01ec353c6d59ffbd282..ed68acd713ed1861de710deb46c1fdbe449ba81b 100644 (file)
@@ -152,7 +152,7 @@ float category_draw_count;
        SLIST_CATEGORY(CAT_XPM,          "CAT_NORMAL",  "CAT_SERVERS",  ZCTX(_("SLCAT^Competitive Mode"))) \
        SLIST_CATEGORY(CAT_MODIFIED,     "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Modified Servers"))) \
        SLIST_CATEGORY(CAT_OVERKILL,     "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Overkill Mode"))) \
-       SLIST_CATEGORY(CAT_MINSTAGIB,    "",            "CAT_SERVERS",  ZCTX(_("SLCAT^MinstaGib Mode"))) \
+       SLIST_CATEGORY(CAT_INSTAGIB,     "",            "CAT_SERVERS",  ZCTX(_("SLCAT^InstaGib Mode"))) \
        SLIST_CATEGORY(CAT_DEFRAG,       "",            "CAT_SERVERS",  ZCTX(_("SLCAT^Defrag Mode")))
 
 #define SLIST_CATEGORY_AUTOCVAR(name) autocvar_menu_slist_categories_##name##_override
@@ -361,8 +361,9 @@ float CheckCategoryForEntry(float entry)
                        // old servers which don't report their mod name are considered modified now
                        case "": { return CAT_MODIFIED; }
                        
-                       case "xpm": { return CAT_XPM; } 
-                       case "minstagib": { return CAT_MINSTAGIB; }
+                       case "xpm": { return CAT_XPM; }
+                       case "minstagib":
+                       case "instagib": { return CAT_INSTAGIB; }
                        case "overkill": { return CAT_OVERKILL; }
                        //case "nix": { return CAT_NIX; }
                        //case "newtoys": { return CAT_NEWTOYS; }
@@ -1013,8 +1014,8 @@ void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float
                                strcat(catent.cat_string, ":"),
 #endif
                                me.realFontSize,
-                               '1 1 1',
-                               SKINALPHA_TEXT,
+                               SKINCOLOR_SERVERLIST_CATEGORY,
+                               SKINALPHA_SERVERLIST_CATEGORY,
                                0
                        );
                        SET_YRANGE(me.categoriesHeight / (me.categoriesHeight + 1), 1);
@@ -1067,7 +1068,7 @@ void XonoticServerList_drawListBoxItem(entity me, float i, vector absSize, float
 
        // list the mods here on which the pure server check actually works
        if(modname != "Xonotic")
-       if(modname != "MinstaGib")
+       if(modname != "InstaGib" || modname != "MinstaGib")
        if(modname != "CTS")
        if(modname != "NIX")
        if(modname != "NewToys")
index 3e094e7d7e7ce91d28c380b8fe94ada5874b56f9..0387303ea3d2a041f7c91cf09ecc1c6c811b8d66 100644 (file)
@@ -162,8 +162,7 @@ void XonoticSkinList_drawListBoxItem(entity me, float i, vector absSize, float i
        s = me.skinParameter(me, i, SKINPARM_PREVIEW);
        draw_Picture(me.columnPreviewOrigin * eX, s, me.columnPreviewSize * eX + eY, '1 1 1', 1);
 
-       s = me.skinParameter(me, i, SKINPARM_NAME);
-       s = sprintf(_("%s: %s"), s, me.skinParameter(me, i, SKINPARM_TITLE));
+       s = me.skinParameter(me, i, SKINPARM_TITLE);
        s = draw_TextShortenToWidth(s, me.columnNameSize, 0, me.realFontSize);
        draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0, me.realFontSize))) * eX, s, me.realFontSize, SKINCOLOR_SKINLIST_TITLE, SKINALPHA_TEXT, 0);
 
index 0577207ca284bb56baf90ef001c83abb6c48975a..aba15ecae625d244fda71f4eb60f9c623a61787b 100644 (file)
@@ -33,20 +33,24 @@ entity makeXonoticSlider(float theValueMin, float theValueMax, float theValueSte
 }
 void XonoticSlider_configureXonoticSlider(entity me, float theValueMin, float theValueMax, float theValueStep, string theCvar)
 {
-       float v, vk, vp;
-       v = theValueMin;
-       vk = theValueStep;
+       float vp;
        vp = theValueStep * 10;
        while(fabs(vp) < fabs(theValueMax - theValueMin) / 40)
                vp *= 10;
+
        me.configureSliderVisuals(me, me.fontSize, me.align, me.valueSpace, me.image);
-       me.configureSliderValues(me, theValueMin, v, theValueMax, theValueStep, vk, vp);
+
        if(theCvar)
        {
+               // Prevent flickering of the slider button by initialising the
+               // slider out of bounds to hide the button before loading the cvar
+               me.configureSliderValues(me, theValueMin, theValueMin-theValueStep, theValueMax, theValueStep, theValueStep, vp);
                me.cvarName = theCvar;
                me.loadCvars(me);
                me.tooltip = getZonedTooltipForIdentifier(theCvar);
        }
+       else
+               me.configureSliderValues(me, theValueMin, theValueMin, theValueMax, theValueStep, theValueStep, vp);
 }
 void XonoticSlider_setValue(entity me, float val)
 {
diff --git a/qcsrc/menu/xonotic/slider_particles.c b/qcsrc/menu/xonotic/slider_particles.c
new file mode 100644 (file)
index 0000000..db29f55
--- /dev/null
@@ -0,0 +1,48 @@
+#ifdef INTERFACE
+CLASS(XonoticParticlesSlider) EXTENDS(XonoticTextSlider)
+       METHOD(XonoticParticlesSlider, configureXonoticParticlesSlider, void(entity))
+       METHOD(XonoticParticlesSlider, loadCvars, void(entity))
+       METHOD(XonoticParticlesSlider, saveCvars, void(entity))
+ENDCLASS(XonoticParticlesSlider)
+entity makeXonoticParticlesSlider();
+#endif
+
+#ifdef IMPLEMENTATION
+entity makeXonoticParticlesSlider()
+{
+       entity me;
+       me = spawnXonoticParticlesSlider();
+       me.configureXonoticParticlesSlider(me);
+       return me;
+}
+void XonoticParticlesSlider_configureXonoticParticlesSlider(entity me)
+{
+       me.configureXonoticTextSlider(me, "cl_particles_quality");
+       if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^OMG")),      "0.4 250 0"); }
+       me.addValue(me,                         ZCTX(_("PART^Low")),      "0.4 500 0");
+       me.addValue(me,                         ZCTX(_("PART^Medium")),   "0.8 750 0");
+       me.addValue(me,                         ZCTX(_("PART^Normal")),   "1.0 1000 1");
+       me.addValue(me,                         ZCTX(_("PART^High")),     "1.0 1500 1");
+       me.addValue(me,                         ZCTX(_("PART^Ultra")),    "1.0 2000 2");
+       if(cvar("developer")) { me.addValue(me, ZCTX(_("PART^Ultimate")), "1.0 3000 2"); }
+       me.configureXonoticTextSliderValues(me);
+}
+void XonoticParticlesSlider_loadCvars(entity me)
+{
+       me.setValueFromIdentifier(me, sprintf("%s %s %s",
+               cvar_string("cl_particles_quality"),
+               cvar_string("r_drawparticles_drawdistance"),
+               cvar_string("cl_damageeffect")
+       ));
+}
+void XonoticParticlesSlider_saveCvars(entity me)
+{
+       if(me.value >= 0 || me.value < me.nValues)
+       {
+               tokenize_console(me.getIdentifier(me));
+               cvar_set("cl_particles_quality", argv(0));
+               cvar_set("r_drawparticles_drawdistance", argv(1));
+               cvar_set("cl_damageeffect", argv(2)); 
+       }
+}
+#endif
index ad4071060f99ec53c97359ed2f04ebd6bb23556e..b6c536a90441cf7bf1cedc471bcc12280f786b84 100644 (file)
@@ -100,7 +100,7 @@ void XonoticWeaponsList_drawListBoxItem(entity me, float i, vector absSize, floa
        string msg = e.message;
        if(e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
                msg = sprintf(_("%s (mutator weapon)"), msg);
-       draw_Text(me.realUpperMargin * eY, msg, me.realFontSize, '1 1 1', SKINALPHA_TEXT, 0);
+       draw_Text(me.realUpperMargin * eY, msg, me.realFontSize, SKINCOLOR_TEXT, SKINALPHA_TEXT, 0);
 }
 
 float XonoticWeaponsList_keyDown(entity me, float scan, float ascii, float shift)
index 958504be04ab07c22bc65eec41f065f2282a47a7..33c82913116b2b350ba1ff0ea1c3917a09da76df 100644 (file)
@@ -76,8 +76,7 @@ float movement_oddity(vector m0, vector m1)
 
 void anticheat_physics()
 {
-       float f, wishspeed;
-       vector wishvel;
+       float f;
 
        // div0_evade -> SPECTATORS
        makevectors(self.v_angle);
@@ -160,52 +159,6 @@ void anticheat_physics()
                self.anticheat_speedhack_accu = 1;
                self.anticheat_speedhack_lasttime = servertime;
        }
-
-       // race/CTS: force kbd movement for fairness
-       if(g_race || g_cts)
-       {
-               // if record times matter
-               // ensure nothing EVIL is being done (i.e. div0_evade)
-               // this hinders joystick users though
-               // but it still gives SOME analog control
-               wishvel_x = fabs(self.movement_x);
-               wishvel_y = fabs(self.movement_y);
-               if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y)
-               {
-                       wishvel_z = 0;
-                       wishspeed = vlen(wishvel);
-                       if(wishvel_x >= 2 * wishvel_y)
-                       {
-                               // pure X motion
-                               if(self.movement_x > 0)
-                                       self.movement_x = wishspeed;
-                               else
-                                       self.movement_x = -wishspeed;
-                               self.movement_y = 0;
-                       }
-                       else if(wishvel_y >= 2 * wishvel_x)
-                       {
-                               // pure Y motion
-                               self.movement_x = 0;
-                               if(self.movement_y > 0)
-                                       self.movement_y = wishspeed;
-                               else
-                                       self.movement_y = -wishspeed;
-                       }
-                       else
-                       {
-                               // diagonal
-                               if(self.movement_x > 0)
-                                       self.movement_x = M_SQRT1_2 * wishspeed;
-                               else
-                                       self.movement_x = -M_SQRT1_2 * wishspeed;
-                               if(self.movement_y > 0)
-                                       self.movement_y = M_SQRT1_2 * wishspeed;
-                               else
-                                       self.movement_y = -M_SQRT1_2 * wishspeed;
-                       }
-               }
-       }
 }
 
 void anticheat_spectatecopy(entity spectatee)
index 47765df06526a344101570f5de9f908ab02f86d6..33660f1ba925ed83e4ec7c3561ba027f9ffe3897 100644 (file)
@@ -792,6 +792,10 @@ float autocvar_g_domination_disable_frags;
 float autocvar_g_domination_point_amt;
 float autocvar_g_domination_point_fullbright;
 float autocvar_g_domination_point_leadlimit;
+float autocvar_g_domination_roundbased;
+float autocvar_g_domination_roundbased_point_limit;
+float autocvar_g_domination_round_timelimit;
+float autocvar_g_domination_warmup;
 #define autocvar_g_domination_point_limit cvar("g_domination_point_limit")
 float autocvar_g_domination_point_rate;
 float autocvar_g_domination_teams_override;
@@ -801,10 +805,13 @@ string autocvar_g_forced_team_otherwise;
 string autocvar_g_forced_team_pink;
 string autocvar_g_forced_team_red;
 string autocvar_g_forced_team_yellow;
+float autocvar_g_freezetag_frozen_damage_trigger;
 float autocvar_g_freezetag_frozen_force;
 float autocvar_g_freezetag_frozen_maxtime;
 float autocvar_g_freezetag_revive_falldamage;
 float autocvar_g_freezetag_revive_falldamage_health;
+float autocvar_g_freezetag_revive_nade;
+float autocvar_g_freezetag_revive_nade_health;
 float autocvar_g_freezetag_point_leadlimit;
 float autocvar_g_freezetag_point_limit;
 float autocvar_g_freezetag_revive_extra_size;
@@ -879,11 +886,11 @@ float autocvar_g_maxplayers_spectator_blocktime;
 float autocvar_g_maxpushtime;
 float autocvar_g_maxspeed;
 float autocvar_g_midair_shieldtime;
-#define autocvar_g_minstagib cvar("g_minstagib")
-float autocvar_g_minstagib_ammo_drop;
-float autocvar_g_minstagib_extralives;
-float autocvar_g_minstagib_speed_highspeed;
-float autocvar_g_minstagib_invis_alpha;
+#define autocvar_g_instagib cvar("g_instagib")
+float autocvar_g_instagib_ammo_drop;
+float autocvar_g_instagib_extralives;
+float autocvar_g_instagib_speed_highspeed;
+float autocvar_g_instagib_invis_alpha;
 #define autocvar_g_mirrordamage cvar("g_mirrordamage")
 #define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
 
@@ -966,6 +973,8 @@ float autocvar_g_spawnpoints_auto_move_out_of_solid;
 #define autocvar_g_spawnshieldtime cvar("g_spawnshieldtime")
 #define autocvar_g_start_weapon_laser cvar("g_start_weapon_laser")
 float autocvar_g_tdm_team_spawns;
+float autocvar_g_tdm_point_limit;
+float autocvar_g_tdm_point_leadlimit;
 float autocvar_g_tdm_teams;
 float autocvar_g_tdm_teams_override;
 float autocvar_g_teamdamage_resetspeed;
@@ -1094,6 +1103,7 @@ float autocvar_sv_dodging_up_speed;
 float autocvar_sv_dodging_wall_distance_threshold;
 float autocvar_sv_dodging_wall_dodging;
 float autocvar_sv_dodging_frozen;
+float autocvar_sv_dodging_frozen_doubletap;
 float autocvar_sv_doublejump;
 float autocvar_sv_eventlog;
 float autocvar_sv_eventlog_console;
@@ -1141,6 +1151,11 @@ float autocvar_sv_timeout_resumetime;
 float autocvar_sv_vote_call;
 float autocvar_sv_vote_change;
 string autocvar_sv_vote_commands;
+float autocvar_sv_vote_gametype;
+float autocvar_sv_vote_gametype_timeout;
+string autocvar_sv_vote_gametype_options;
+float autocvar_sv_vote_gametype_keeptwotime;
+float autocvar_sv_vote_gametype_default_current;
 float autocvar_sv_vote_limit;
 float autocvar_sv_vote_majority_factor;
 float autocvar_sv_vote_majority_factor_of_voted;
@@ -1243,6 +1258,8 @@ float autocvar_g_random_gravity_negative;
 float autocvar_g_random_gravity_delay;
 float autocvar_g_nades;
 float autocvar_g_nades_spawn;
+float autocvar_g_nades_spawn_count;
+float autocvar_g_nades_client_select;
 float autocvar_g_nades_nade_lifetime;
 float autocvar_g_nades_nade_minforce;
 float autocvar_g_nades_nade_maxforce;
@@ -1253,6 +1270,44 @@ float autocvar_g_nades_nade_edgedamage;
 float autocvar_g_nades_nade_radius;
 float autocvar_g_nades_nade_force;
 float autocvar_g_nades_nade_newton_style;
+float autocvar_g_nades_napalm_ball_count;
+float autocvar_g_nades_napalm_ball_spread;
+float autocvar_g_nades_napalm_ball_damage;
+float autocvar_g_nades_napalm_ball_damageforcescale;
+float autocvar_g_nades_napalm_ball_lifetime;
+float autocvar_g_nades_napalm_ball_radius;
+float autocvar_g_nades_napalm_blast;
+float autocvar_g_nades_napalm_fountain_lifetime;
+float autocvar_g_nades_napalm_fountain_delay;
+float autocvar_g_nades_napalm_fountain_radius;
+float autocvar_g_nades_napalm_fountain_damage;
+float autocvar_g_nades_napalm_fountain_edgedamage;
+float autocvar_g_nades_napalm_burntime;
+float autocvar_g_nades_napalm_selfdamage;
+float autocvar_g_nades_nade_type;
+float autocvar_g_nades_bonus_type;
+float autocvar_g_nades_bonus;
+float autocvar_g_nades_bonus_onstrength;
+float autocvar_g_nades_bonus_client_select;
+float autocvar_g_nades_bonus_max;
+float autocvar_g_nades_bonus_score_max;
+float autocvar_g_nades_bonus_score_time;
+float autocvar_g_nades_bonus_score_time_flagcarrier;
+float autocvar_g_nades_bonus_score_minor;
+float autocvar_g_nades_bonus_score_low;
+float autocvar_g_nades_bonus_score_high;
+float autocvar_g_nades_bonus_score_medium;
+float autocvar_g_nades_bonus_score_spree;
+float autocvar_g_nades_ice_freeze_time;
+float autocvar_g_nades_ice_health;
+float autocvar_g_nades_ice_explode;
+float autocvar_g_nades_ice_teamcheck;
+float autocvar_g_nades_heal_time;
+float autocvar_g_nades_heal_rate;
+float autocvar_g_nades_heal_friend;
+float autocvar_g_nades_heal_foe;
+string autocvar_g_nades_pokenade_monster_type;
+float autocvar_g_nades_pokenade_monster_lifetime;
 float autocvar_g_campcheck_damage;
 float autocvar_g_campcheck_distance;
 float autocvar_g_campcheck_interval;
@@ -1265,4 +1320,32 @@ float autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
 float autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
 float autocvar_g_physics_clientselect;
 string autocvar_g_physics_clientselect_options;
-
+float autocvar_g_buffs_waypoint_distance;
+float autocvar_g_buffs_randomize;
+float autocvar_g_buffs_random_lifetime;
+float autocvar_g_buffs_random_location;
+float autocvar_g_buffs_random_location_attempts;
+float autocvar_g_buffs_spawn_count;
+float autocvar_g_buffs_replace_powerups;
+float autocvar_g_buffs_cooldown_activate;
+float autocvar_g_buffs_cooldown_respawn;
+float autocvar_g_buffs_resistance_blockpercent;
+float autocvar_g_buffs_medic_survive_chance;
+float autocvar_g_buffs_medic_survive_health;
+float autocvar_g_buffs_medic_rot;
+float autocvar_g_buffs_medic_max;
+float autocvar_g_buffs_medic_regen;
+float autocvar_g_buffs_vengeance_damage_multiplier;
+float autocvar_g_buffs_bash_force;
+float autocvar_g_buffs_bash_force_self;
+float autocvar_g_buffs_disability_time;
+float autocvar_g_buffs_disability_speed;
+float autocvar_g_buffs_disability_rate;
+float autocvar_g_buffs_speed_speed;
+float autocvar_g_buffs_speed_rate;
+float autocvar_g_buffs_speed_damage_take;
+float autocvar_g_buffs_speed_regen;
+float autocvar_g_buffs_vampire_damage_steal;
+float autocvar_g_buffs_invisible_alpha;
+float autocvar_g_buffs_flight_gravity;
+float autocvar_g_buffs_jump_height;
index 3467e2b395d61c7c1f28357fe0460b0a97011394..61f4ab5e8f307b8bc421b4f250090c5169652c0e 100644 (file)
@@ -111,7 +111,7 @@ float bot_shouldattack(entity e)
                        return FALSE;
        }
 
-       if(e.freezetag_frozen)
+       if(e.frozen)
                return FALSE;
 
        // If neither player has ball then don't attack unless the ball is on the
index b93d87ad29f229736686045c546f26d0af1101a6..40b769ddd3fb4a78f3b156995a2cf53153800869 100644 (file)
@@ -43,7 +43,7 @@ void bot_think()
        //self.bot_painintensity = self.bot_painintensity + self.bot_oldhealth - self.health;
        //self.bot_painintensity = bound(0, self.bot_painintensity, 100);
 
-       if (autocvar_g_campaign && !campaign_bots_may_start)
+       if (!IS_PLAYER(self) || (autocvar_g_campaign && !campaign_bots_may_start))
        {
                self.bot_nextthink = time + 0.5;
                return;
index 45f5a6e692c4bbc0cda20f2a1d99a10caa0f805c..2104c3443a00f79930061b0e63975c54c7b6dd33 100644 (file)
@@ -221,50 +221,11 @@ void havocbot_role_dm()
        }
 }
 
-//Race:
-//go to next checkpoint, and annoy enemies
-.float race_checkpoint;
-void havocbot_role_race()
-{
-       if(self.deadflag != DEAD_NO)
-               return;
-
-       entity e;
-       if (self.bot_strategytime < time)
-       {
-               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
-               navigation_goalrating_start();
-               /*
-               havocbot_goalrating_items(100, self.origin, 10000);
-               havocbot_goalrating_enemyplayers(500, self.origin, 20000);
-               */
-
-               for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
-               {
-                       if(e.cnt == self.race_checkpoint)
-                       {
-                               navigation_routerating(e, 1000000, 5000);
-                       }
-                       else if(self.race_checkpoint == -1)
-                       {
-                               navigation_routerating(e, 1000000, 5000);
-                       }
-               }
-
-               navigation_goalrating_end();
-       }
-}
-
 void havocbot_chooserole_dm()
 {
        self.havocbot_role = havocbot_role_dm;
 }
 
-void havocbot_chooserole_race()
-{
-       self.havocbot_role = havocbot_role_race;
-}
-
 void havocbot_chooserole()
 {
        dprint("choosing a role...\n");
@@ -273,8 +234,6 @@ void havocbot_chooserole()
                return;
        else if (g_keyhunt)
                havocbot_chooserole_kh();
-       else if (g_race || g_cts)
-               havocbot_chooserole_race();
        else if (g_onslaught)
                havocbot_chooserole_ons();
        else // assume anything else is deathmatch
index 4ab1836e8c0e242828aa2b0e7cf470b1897ea71b..578e8707e026796ce227b5724d201a637554b3d2 100644 (file)
@@ -1,6 +1,3 @@
-void race_send_recordtime(float msg);
-void race_SendRankings(float pos, float prevpos, float del, float msg);
-
 void send_CSQC_teamnagger() {
        WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
        WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
@@ -140,7 +137,8 @@ void PutObserverInServer (void)
 {
        entity  spot;
     self.hud = HUD_NORMAL;
-       race_PreSpawnObserver();
+
+       if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
 
        spot = SelectSpawnPoint (TRUE);
        if(!spot)
@@ -154,20 +152,14 @@ void PutObserverInServer (void)
                WriteEntity(MSG_ONE, self);
        }
 
-       if((g_race && g_race_qualifying) || g_cts)
-       {
-               if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
-                       self.frags = FRAGS_LMS_LOSER;
-               else
-                       self.frags = FRAGS_SPECTATOR;
-       }
-       else
-               self.frags = FRAGS_SPECTATOR;
+       self.frags = FRAGS_SPECTATOR;
 
        MUTATOR_CALLHOOK(MakePlayerObserver);
 
        Portal_ClearAll(self);
 
+       Unfreeze(self);
+
        if(self.alivetime)
        {
                if(!warmup_stage)
@@ -239,6 +231,7 @@ void PutObserverInServer (void)
        self.angles_z = 0;
        self.fixangle = TRUE;
        self.crouch = FALSE;
+       self.revival_time = 0;
 
        setorigin (self, (spot.origin + PL_VIEW_OFS)); // offset it so that the spectator spawns higher off the ground, looks better this way
        self.prevorigin = self.origin;
@@ -265,6 +258,7 @@ void PutObserverInServer (void)
        self.punchvector = '0 0 0';
        self.oldvelocity = self.velocity;
        self.fire_endtime = -1;
+       self.event_damage = func_null;
 }
 
 .float model_randomizer;
@@ -391,8 +385,6 @@ void PutClientInServer (void)
                if(self.team < 0)
                        JoinBestTeam(self, FALSE, TRUE);
 
-               race_PreSpawn();
-
                spot = SelectSpawnPoint (FALSE);
                if(!spot)
                {
@@ -512,6 +504,8 @@ void PutClientInServer (void)
                self.angles = spot.angles;
 
                self.angles_z = 0; // never spawn tilted even if the spot says to
+               if(IS_BOT_CLIENT(self))
+                       self.v_angle = self.angles;
                self.fixangle = TRUE; // turn this way immediately
                self.velocity = '0 0 0';
                self.avelocity = '0 0 0';
@@ -519,11 +513,15 @@ void PutClientInServer (void)
                self.punchvector = '0 0 0';
                self.oldvelocity = self.velocity;
                self.fire_endtime = -1;
+               self.revival_time = 0;
 
                entity spawnevent = spawn();
                spawnevent.owner = self;
                Net_LinkEntity(spawnevent, FALSE, 0.5, SpawnEvent_Send);
 
+               // Cut off any still running player sounds.
+               stopsound(self, CH_PLAYER_SINGLE);
+
                self.model = "";
                FixPlayermodel();
                self.drawonlytoclient = world;
@@ -562,8 +560,6 @@ void PutClientInServer (void)
 
                self.speedrunning = FALSE;
 
-               race_PostSpawn(spot);
-
                //stuffcmd(self, "chase_active 0");
                //stuffcmd(self, "set viewsize $tmpviewsize \n");
 
@@ -592,6 +588,8 @@ void PutClientInServer (void)
                        activator = world;
                self = oldself;
 
+               Unfreeze(self);
+
                spawn_spot = spot;
                MUTATOR_CALLHOOK(PlayerSpawn);
 
@@ -786,8 +784,8 @@ void ClientKill_Now()
        if(self.killindicator_teamchange)
                ClientKill_Now_TeamChange();
 
-       // in any case:
-       Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
+       if(IS_PLAYER(self))
+               Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');
 
        // now I am sure the player IS dead
 }
@@ -941,7 +939,7 @@ void ClientKill (void)
 {
        if(gameover) return;
        if(self.player_blocked) return;
-       if(self.freezetag_frozen) return;
+       if(self.frozen) return;
 
        ClientKill_TeamChange(0);
 }
@@ -1057,8 +1055,6 @@ void ClientConnect (void)
 
        anticheat_init();
 
-       race_PreSpawnObserver();
-
        // identify the right forced team
        if(autocvar_g_campaign)
        {
@@ -1209,27 +1205,7 @@ void ClientConnect (void)
        else
                self.hitplotfh = -1;
 
-       if(g_race || g_cts) {
-               string rr;
-               if(g_cts)
-                       rr = CTS_RECORD;
-               else
-                       rr = RACE_RECORD;
-
-               msg_entity = self;
-               race_send_recordtime(MSG_ONE);
-               race_send_speedaward(MSG_ONE);
-
-               speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
-               speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
-               race_send_speedaward_alltimebest(MSG_ONE);
-
-               float i;
-               for (i = 1; i <= RANKINGS_CNT; ++i) {
-                       race_SendRankings(i, 0, 0, MSG_ONE);
-               }
-       }
-       else if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca) // teamnagger is currently bad for ca
+       if(autocvar_sv_teamnagger && !(autocvar_bot_vs_human && (c3==-1 && c4==-1)) && !g_ca && !g_cts && !g_race) // teamnagger is currently bad for ca, race & cts
                send_CSQC_teamnagger();
 
        CheatInitClient();
@@ -1263,6 +1239,8 @@ void ClientDisconnect (void)
                return;
        }
 
+       if(IS_PLAYER(self)) { pointparticles(particleeffectnum("spawn_event_neutral"), self.origin, '0 0 0', 1); }
+
        PlayerStats_AddGlobalInfo(self);
 
        CheatShutdownClient();
@@ -1292,6 +1270,8 @@ void ClientDisconnect (void)
 
        Portal_ClearAll(self);
 
+       Unfreeze(self);
+
        RemoveGrapplingHook(self);
 
        // Here, everything has been done that requires this player to be a client.
@@ -1438,7 +1418,7 @@ void player_powerups (void)
        Fire_ApplyDamage(self);
        Fire_ApplyEffect(self);
 
-       if (!g_minstagib)
+       if (!g_instagib)
        {
                if (self.items & IT_STRENGTH)
                {
@@ -1585,17 +1565,27 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
 
 void player_regen (void)
 {
+       float max_mod, regen_mod, rot_mod, limit_mod;
+       max_mod = regen_mod = rot_mod = limit_mod = 1;
+       regen_mod_max = max_mod;
+       regen_mod_regen = regen_mod;
+       regen_mod_rot = rot_mod;
+       regen_mod_limit = limit_mod;
        if(!MUTATOR_CALLHOOK(PlayerRegen))
+       if(!self.frozen)
        {
-               float minh, mina, maxh, maxa, limith, limita, max_mod, regen_mod, rot_mod, limit_mod;
+               float minh, mina, maxh, maxa, limith, limita;
                maxh = autocvar_g_balance_health_rotstable;
                maxa = autocvar_g_balance_armor_rotstable;
                minh = autocvar_g_balance_health_regenstable;
                mina = autocvar_g_balance_armor_regenstable;
                limith = autocvar_g_balance_health_limit;
                limita = autocvar_g_balance_armor_limit;
-
-               max_mod = regen_mod = rot_mod = limit_mod = 1;
+               
+               max_mod = regen_mod_max;
+               regen_mod = regen_mod_regen;
+               rot_mod = regen_mod_rot;
+               limit_mod = regen_mod_limit;
 
                maxh = maxh * max_mod;
                minh = minh * max_mod;
@@ -1731,6 +1721,8 @@ void SpectateCopy(entity spectatee) {
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.v_angle = spectatee.v_angle;
        self.angles = spectatee.v_angle;
+       self.frozen = spectatee.frozen;
+       self.revive_progress = spectatee.revive_progress;
        if(!self.BUTTON_USE)
                self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
@@ -1936,6 +1928,7 @@ void LeaveSpectatorMode()
                if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0)
                {
                        self.classname = "player";
+                       nades_RemoveBonus(self);
 
                        if(autocvar_g_campaign || autocvar_g_balance_teams)
                                { JoinBestTeam(self, FALSE, TRUE); }
@@ -1991,7 +1984,7 @@ float nJoinAllowed(entity ignore) {
 
        float currentlyPlaying = 0;
        FOR_EACH_REALCLIENT(e)
-               if(IS_PLAYER(e) || e.caplayer == 1)
+               if(IS_PLAYER(e) || e.caplayer)
                        currentlyPlaying += 1;
 
        if(currentlyPlaying < autocvar_g_maxplayers)
@@ -2005,7 +1998,10 @@ float nJoinAllowed(entity ignore) {
  * g_maxplayers_spectator_blocktime seconds
  */
 void checkSpectatorBlock() {
-       if(IS_SPEC(self) || IS_OBSERVER(self)) {
+       if(IS_SPEC(self) || IS_OBSERVER(self))
+       if(!self.caplayer)
+       if(IS_REAL_CLIENT(self))
+       {
                if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) {
                        Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING);
                        dropclient(self);
@@ -2241,6 +2237,30 @@ void PlayerPreThink (void)
                return;
 #endif
 
+       if(self.frozen == 2)
+       {
+               self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1);
+               self.health = max(1, self.revive_progress * start_health);
+               self.iceblock.alpha = bound(0.2, 1 - self.revive_progress, 1);
+
+               if(self.revive_progress >= 1)
+                       Unfreeze(self);
+       }
+       else if(self.frozen == 3)
+       {
+               self.revive_progress = bound(0, self.revive_progress - frametime * self.revive_speed, 1);
+               self.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * self.revive_progress );
+               
+               if(self.health < 1)
+               {
+                       if(self.vehicle)
+                               vehicles_exit(VHEF_RELESE);
+                       self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0');
+               }
+               else if ( self.revive_progress <= 0 )
+                       Unfreeze(self);
+       }
+
        MUTATOR_CALLHOOK(PlayerPreThink);
 
        if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button
@@ -2365,7 +2385,7 @@ void PlayerPreThink (void)
                        do_crouch = 0;
                if(self.vehicle)
                        do_crouch = 0;
-               if(self.freezetag_frozen)
+               if(self.frozen)
                        do_crouch = 0;
                if(self.weapon == WEP_SHOTGUN && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink)
                        do_crouch = 0;
@@ -2455,8 +2475,6 @@ void PlayerPreThink (void)
        if(self.spectatee_status != oldspectatee_status)
        {
                ClientData_Touch(self);
-               if(g_race || g_cts)
-                       race_InitSpectator();
        }
 
        if(self.teamkill_soundtime)
@@ -2615,22 +2633,5 @@ void PlayerPostThink (void)
 
        playerdemo_write();
 
-       if((g_cts || g_race) && self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
-       {
-               if (!self.stored_netname)
-                       self.stored_netname = strzone(uid2name(self.crypto_idfp));
-               if(self.stored_netname != self.netname)
-               {
-                       db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
-                       strunzone(self.stored_netname);
-                       self.stored_netname = strzone(self.netname);
-               }
-       }
-
-       /*
-       if(g_race)
-               dprintf("%f %.6f\n", time, race_GetFractionalLapCount(self));
-       */
-
        CSQCMODEL_AUTOUPDATE();
 }
index 91f91e89e1ddeace24264cb274c416272b1dff90..797226717cfe3129677584c626a83cabc5bd6c44 100644 (file)
@@ -40,18 +40,22 @@ When you press the jump key
 */
 void PlayerJump (void)
 {
+       if(self.frozen)
+               return; // no jumping in freezetag when frozen
+
        if(self.player_blocked)
                return; // no jumping while blocked
 
        float doublejump = FALSE;
+       float mjumpheight = self.stat_sv_jumpvelocity;
 
        player_multijump = doublejump;
+       player_jumpheight = mjumpheight;
        if(MUTATOR_CALLHOOK(PlayerJump))
                return;
 
        doublejump = player_multijump;
-
-       float mjumpheight;
+       mjumpheight = player_jumpheight;
 
        if (autocvar_sv_doublejump)
        {
@@ -68,7 +72,6 @@ void PlayerJump (void)
                }
        }
 
-       mjumpheight = self.stat_sv_jumpvelocity;
        if (self.waterlevel >= WATERLEVEL_SWIMMING)
        {
                self.velocity_z = self.stat_sv_maxspeed * 0.7;
@@ -834,6 +837,28 @@ void SV_PlayerPhysics()
                self.stat_sv_airspeedlimit_nonqw *= 0.5;
        }
 
+       if(self.frozen)
+       {
+               if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
+               {
+                       self.movement_x = bound(-5, self.movement_x, 5);
+                       self.movement_y = bound(-5, self.movement_y, 5);
+                       self.movement_z = bound(-5, self.movement_z, 5);
+               }
+               else
+                       self.movement = '0 0 0';
+               self.disableclientprediction = 1;
+
+               vector midpoint = ((self.absmin + self.absmax) * 0.5);
+               if(pointcontents(midpoint) == CONTENT_WATER)
+               {
+                       self.velocity = self.velocity * 0.5;
+
+                       if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
+                               { self.velocity_z = 200; }
+               }
+       }
+
        MUTATOR_CALLHOOK(PlayerPhysics);
 
        if(self.player_blocked)
@@ -1035,7 +1060,7 @@ void SV_PlayerPhysics()
                        PM_Accelerate(wishdir, wishspeed, wishspeed, self.stat_sv_accelerate*maxspd_mod, 1, 0, 0, 0);
                }
        }
-       else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.freezetag_frozen)
+       else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!autocvar_g_jetpack_fuel || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO) && !self.frozen)
        {
                //makevectors(self.v_angle_y * '0 1 0');
                makevectors(self.v_angle);
@@ -1292,22 +1317,22 @@ void SV_PlayerPhysics()
                }
        }
 
-       if((g_cts || g_race) && !IS_OBSERVER(self)) {
-               if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed) {
+       if((g_cts || g_race) && !IS_OBSERVER(self))
+       {
+               if(vlen(self.velocity - self.velocity_z * '0 0 1') > speedaward_speed)
+               {
                        speedaward_speed = vlen(self.velocity - self.velocity_z * '0 0 1');
                        speedaward_holder = self.netname;
                        speedaward_uid = self.crypto_idfp;
                        speedaward_lastupdate = time;
                }
-               if(speedaward_speed > speedaward_lastsent && time - speedaward_lastupdate > 1) {
-                       string rr;
-                       if(g_cts)
-                               rr = CTS_RECORD;
-                       else
-                               rr = RACE_RECORD;
+               if(speedaward_speed > speedaward_lastsent && time - speedaward_lastupdate > 1)
+               {
+                       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
                        race_send_speedaward(MSG_ALL);
                        speedaward_lastsent = speedaward_speed;
-                       if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "") {
+                       if (speedaward_speed > speedaward_alltimebest && speedaward_uid != "")
+                       {
                                speedaward_alltimebest = speedaward_speed;
                                speedaward_alltimebest_holder = speedaward_holder;
                                speedaward_alltimebest_uid = speedaward_uid;
index 0fe71f1448c7dd72fbfad0ab3e23066e1f9f166f..a3221a1bc103f7e3fcfb49efc95b813abc20dd41 100644 (file)
@@ -240,13 +240,20 @@ void player_setupanimsformodel()
 void player_anim (void)
 {
        float deadbits = (self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
-       if(self.deadflag && !deadbits)
-               if(random() < 0.5)
-                       deadbits = ANIMSTATE_DEAD1;
-               else
-                       deadbits = ANIMSTATE_DEAD2;
+       if(self.deadflag) {
+               if (!deadbits) {
+                       // Decide on which death animation to use.
+                       if(random() < 0.5)
+                               deadbits = ANIMSTATE_DEAD1;
+                       else
+                               deadbits = ANIMSTATE_DEAD2;
+               }
+       } else {
+               // Clear a previous death animation.
+               deadbits = 0;
+       }
        float animbits = deadbits;
-       if(self.freezetag_frozen)
+       if(self.frozen)
                animbits |= ANIMSTATE_FROZEN;
        if(self.crouch)
                animbits |= ANIMSTATE_DUCK;
@@ -336,6 +343,9 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, float
 
 void calculate_player_respawn_time()
 {
+       if(g_ca)
+               return;
+
        float gametype_setting_tmp;
        float sdelay_max = GAMETYPE_DEFAULTED_SETTING(respawn_delay_max);
        float sdelay_small = GAMETYPE_DEFAULTED_SETTING(respawn_delay_small);
@@ -414,7 +424,7 @@ void calculate_player_respawn_time()
        else
                self.respawn_countdown = -1; // do not count down
 
-       if(g_cts || autocvar_g_forced_respawn)
+       if(autocvar_g_forced_respawn)
                self.respawn_flags = self.respawn_flags | RESPAWN_FORCE;
 }
 
@@ -535,7 +545,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                        self.health = self.health - take;
                        // pause regeneration for 5 seconds
                        if(take)
-                self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
+                               self.pauseregen_finished = max(self.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
 
                        if (time > self.pain_finished)          //Don't switch pain sequences like crazy
                        {
@@ -570,12 +580,16 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                                                        PlayerSound(playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND);
                                        }
                                }
+                       }
 
-                               // throw off bot aim temporarily
-                               float shake;
+                       // throw off bot aim temporarily
+                       float shake;
+                       if(IS_BOT_CLIENT(self) && self.health >= 1)
+                       {
                                shake = damage * 5 / (bound(0,skill,100) + 1);
                                self.v_angle_x = self.v_angle_x + (random() * 2 - 1) * shake;
                                self.v_angle_y = self.v_angle_y + (random() * 2 - 1) * shake;
+                               self.v_angle_x = bound(-90, self.v_angle_x, 90);
                        }
                }
                else
@@ -652,7 +666,6 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                // print an obituary message
                Obituary (attacker, inflictor, self, deathtype);
-               race_PreDie();
 
         // increment frag counter for used weapon type
         float w;
@@ -685,6 +698,9 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
 
                // when we get here, player actually dies
 
+               Unfreeze(self); // remove any icy remains
+               self.health = 0; // Unfreeze resets health, so we need to set it back
+
                // clear waypoints
                WaypointSprite_PlayerDead();
                // throw a weapon
@@ -708,6 +724,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                self.flags &= ~FL_ONGROUND;
                // dying animation
                self.deadflag = DEAD_DYING;
+
                // when to allow respawn
                calculate_player_respawn_time();
 
index 2885e6dc51b7412570bd14b06aea394a43eca1ab..41cdd2b05e289edff14ebd35f20fa8700056d287 100644 (file)
@@ -301,8 +301,6 @@ float W_IsWeaponThrowable(float w)
                return 0;
        if (g_weaponarena)
                return 0;
-       if (g_cts)
-               return 0;
        if (g_nexball && w == WEP_GRENADE_LAUNCHER)
                return 0;
     if(w == 0)
@@ -330,6 +328,8 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce)
        w = self.weapon;
        if (w == 0)
                return; // just in case
+       if(self.frozen)
+               return;
        if(MUTATOR_CALLHOOK(ForbidThrowCurrentWeapon))
                return;
        if(!autocvar_g_weapon_throwable)
@@ -358,7 +358,7 @@ float forbidWeaponUse()
                return 1;
        if(self.player_blocked)
                return 1;
-       if(self.freezetag_frozen)
+       if(self.frozen)
                return 1;
        return 0;
 }
index c36033a2818886ff62ba943a24ca1aa49874f625..dac383633c105f98e3cb9d74ae843c51e072f309 100644 (file)
@@ -14,6 +14,10 @@ float W_WeaponRateFactor()
        float t;
        t = 1.0 / g_weaponratefactor;
 
+       weapon_rate = t;
+       MUTATOR_CALLHOOK(WeaponRateFactor);
+       t = weapon_rate;
+
        return t;
 }
 
index 1321f26b3a2a6dd42c92586e46ed935ea7cb05da..14ffd3468aca61adf180bb6277df95c43510c2dc 100644 (file)
@@ -152,6 +152,8 @@ void ClientCommand_join(float request)
                        {
                                if(!IS_PLAYER(self) && !lockteams)
                                {
+                                       if(self.caplayer)
+                                               return;
                                        if(nJoinAllowed(self))
                                        {
                                                if(autocvar_g_campaign) { campaign_bots_may_start = 1; }
@@ -289,7 +291,7 @@ void ClientCommand_mobspawn(float request, float argc)
                        else if(MUTATOR_CALLHOOK(AllowMobSpawning)) { sprint(self, "Monster spawning is currently disabled by a mutator.\n"); return; }
                        else if(!autocvar_g_monsters) { Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_MONSTERS_DISABLED); return; }
                        else if(self.vehicle) { sprint(self, "You can't spawn monsters while driving a vehicle.\n"); return; }
-                       else if(self.freezetag_frozen) { sprint(self, "You can't spawn monsters while frozen.\n"); return; }
+                       else if(self.frozen) { sprint(self, "You can't spawn monsters while frozen.\n"); return; }
                        else if(autocvar_g_campaign) { sprint(self, "You can't spawn monsters in campaign mode.\n"); return; }
                        else if(self.deadflag != DEAD_NO) { sprint(self, "You can't spawn monsters while dead.\n"); return; }
                        else if(monstercount >= autocvar_g_monsters_max_perplayer) { sprint(self, "You have spawned too many monsters, kill some before trying to spawn any more.\n"); return; }
@@ -620,15 +622,11 @@ void ClientCommand_spectate(float request)
                                        }
                                }
 
-                               if(IS_PLAYER(self) && autocvar_sv_spectate == 1)
-                                       ClientKill_TeamChange(-2); // observe
-
-                               // in CA, allow a dead player to move to spectators (without that, caplayer!=0 will be moved back to the player list)
-                               // note: if arena game mode is ever done properly, this needs to be removed.
-                               if(self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
+                               if((IS_PLAYER(self) || self.caplayer) && autocvar_sv_spectate == 1)
                                {
-                                       sprint(self, "WARNING: you will spectate in the next round.\n");
-                                       self.caplayer = 0;
+                                       if(self.caplayer && (IS_SPEC(self) || IS_OBSERVER(self)))
+                                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_LEAVE);
+                                       ClientKill_TeamChange(-2); // observe
                                }
                        }
                        return; // never fall through to usage
index 29e817ea6249ef9c1b5293c313f6e52e53d25401..aadc629587da0d2cda4e821b9dfae011570cfeab 100644 (file)
@@ -113,10 +113,7 @@ string getladder()
        float i, j, k, uidcnt = 0, thiscnt;
        string s, temp_s, rr, myuid, thisuid;
 
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
+       rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
 
        for(k = 0; k < MapInfo_count; ++k)
        {
index c0da029c51248b0fbafb4eaee9053a4f898acfde..edeb571c0dd62f0ec374699f2ac8c82e37233d01 100644 (file)
@@ -213,6 +213,8 @@ void GameCommand_allspec(float request, float argc)
                        FOR_EACH_REALPLAYER(client)
                        {
                                self = client;
+                               if(self.caplayer)
+                                       self.caplayer = 0;
                                PutObserverInServer();
                                ++i;
                        }
@@ -1045,6 +1047,8 @@ void GameCommand_moveplayer(float request, float argc)
                                                if(!IS_SPEC(client) && !IS_OBSERVER(client))
                                                {
                                                        self = client;
+                                                       if(self.caplayer)
+                                                               self.caplayer = 0;
                                                        PutObserverInServer();
 
                                                        successful = strcat(successful, (successful ? ", " : ""), client.netname);
@@ -1150,9 +1154,10 @@ void GameCommand_nospectators(float request)
                {
                        blockSpectators = 1;
                        entity plr;
-                       FOR_EACH_CLIENT(plr) //give every spectator <g_maxplayers_spectator_blocktime> seconds time to become a player
+                       FOR_EACH_REALCLIENT(plr) //give every spectator <g_maxplayers_spectator_blocktime> seconds time to become a player
                        {
                                if(IS_SPEC(plr) || IS_OBSERVER(plr))
+                               if(!plr.caplayer)
                                {
                                        plr.spectatortime = time;
                                        Send_Notification(NOTIF_ONE_ONLY, plr, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime);
index f92a0a40cd37a140df63da39f7aa1d0a73b00c0e..fdb53ace94e1f5b3b11d5aaeb0c621ab03ae776d 100644 (file)
@@ -326,9 +326,7 @@ void reset_map(float dorespawn)
        if(time <= game_starttime && round_handler_IsActive())
                round_handler_Reset(game_starttime);
 
-       if(g_race || g_cts)
-               race_ReadyRestart();
-       else MUTATOR_CALLHOOK(reset_map_global);
+       MUTATOR_CALLHOOK(reset_map_global);
 
        for(self = world; (self = nextent(self)); )
        if(IS_NOT_A_CLIENT(self))
index 4d208ebda808341f778f242ba0135d7255bd29d9..3c747bdbb2633c439df886e6b470da9aa82f5165 100644 (file)
@@ -48,6 +48,8 @@ float CSQCProjectile_SendEntity(entity to, float sf)
                        WriteByte(MSG_ENTITY, ft);
                        WriteByte(MSG_ENTITY, fr);
                }
+
+               WriteByte(MSG_ENTITY, self.realowner.team);
        }
 
        if(sf & 2)
index bca382396247932426ee96811293e6d78562398c..388a1279d783066362013b06e0b23c6b8aeef1ef 100644 (file)
@@ -16,11 +16,10 @@ noref float require_spawnfunc_prefix; // if this float exists, only functions wi
 
 // Globals
 
-float g_cloaked, g_footsteps, g_grappling_hook, g_minstagib;
+float g_cloaked, g_footsteps, g_grappling_hook, g_instagib;
 float g_warmup_limit;
 float g_warmup_allguns;
 float g_warmup_allow_timeout;
-float g_race_qualifying;
 float warmup_stage;
 float g_pickup_respawntime_weapon;
 float g_pickup_respawntime_superweapon;
@@ -156,7 +155,7 @@ void setanim(entity e, vector anim, float looping, float override, float restart
 .float         dmgtime;
 
 .float         killcount;
-.float hitsound, typehitsound;
+.float damage_dealt, typehitsound;
 
 .float watersound_finished;
 .float iscreature;
@@ -543,6 +542,8 @@ string matchid;
 .float hit_time;
 .float typehit_time;
 
+.float damage_dealt_total; 
+
 .float stat_leadlimit;
 
 float radar_showennemies;
@@ -607,7 +608,12 @@ float serverflags;
 
 .float player_blocked;
 
-.float freezetag_frozen;
+.float frozen; // for freeze attacks
+.float revive_progress;
+.float revival_time; // time at which player was last revived
+.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
+.entity iceblock;
+.entity frozen_by; // for ice fields
 
 .entity muzzle_flash;
 .float misc_bulletcounter;     // replaces uzi & hlac bullet counter.
index 42dee6a98fc479c89fb260bfaa593e5e7c831859..02488b8b11be4a517573f601ac439a01a25577ed 100644 (file)
@@ -549,6 +549,86 @@ void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
        if(targ.killcount) { targ.killcount = 0; }
 }
 
+void Ice_Think()
+{
+       if(!self.owner.frozen || self.owner.iceblock != self)
+       {
+               remove(self);
+               return;
+       }
+       setorigin(self, self.owner.origin - '0 0 16');
+       self.nextthink = time;
+}
+
+void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypoint)
+{
+       if(!IS_PLAYER(targ) && !(targ.flags & FL_MONSTER)) // only specified entities can be freezed
+               return;
+
+       if(targ.frozen)
+               return;
+
+       float targ_maxhealth = ((targ.flags & FL_MONSTER) ? targ.max_health : start_health);
+
+       targ.frozen = frozen_type;
+       targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
+       targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
+       targ.revive_speed = freeze_time;
+
+       entity ice, head;
+       ice = spawn();
+       ice.owner = targ;
+       ice.classname = "ice";
+       ice.scale = targ.scale;
+       ice.think = Ice_Think;
+       ice.nextthink = time;
+       ice.frame = floor(random() * 21); // ice model has 20 different looking frames
+       setmodel(ice, "models/ice/ice.md3");
+       ice.alpha = 1;
+       ice.colormod = Team_ColorRGB(targ.team);
+       ice.glowmod = ice.colormod;
+       targ.iceblock = ice;
+       targ.revival_time = 0;
+
+       entity oldself;
+       oldself = self;
+       self = ice;
+       Ice_Think();
+       self = oldself;
+
+       RemoveGrapplingHook(targ);
+
+       FOR_EACH_PLAYER(head)
+       if(head.hook.aiment == targ)
+               RemoveGrapplingHook(head);
+
+       // add waypoint
+       if(show_waypoint)       
+               WaypointSprite_Spawn("frozen", 0, 0, targ, '0 0 64', world, targ.team, targ, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
+}
+
+void Unfreeze (entity targ)
+{
+       if(targ.frozen && targ.frozen != 3) // only reset health if target was frozen
+               targ.health = ((IS_PLAYER(targ)) ? start_health : targ.max_health);
+
+       entity head;
+       targ.frozen = 0;
+       targ.revive_progress = 0;
+       targ.revival_time = time;
+       
+       WaypointSprite_Kill(targ.waypointsprite_attached);
+       
+       FOR_EACH_PLAYER(head)
+       if(head.hook.aiment == targ)
+               RemoveGrapplingHook(head);
+
+       // remove the ice block
+       if(targ.iceblock)
+               remove(targ.iceblock);
+       targ.iceblock = world;
+}
+
 // these are updated by each Damage call for use in button triggering and such
 entity damage_targ;
 entity damage_inflictor;
@@ -690,7 +770,63 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                mirrordamage = frag_mirrordamage;
                force = frag_force;
 
-               if (!g_minstagib)
+               if(targ.frozen)
+               if(deathtype != DEATH_HURTTRIGGER && deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_AUTOTEAMCHANGE)
+               {
+                       if(autocvar_g_freezetag_revive_falldamage > 0)
+                       if(deathtype == DEATH_FALL)
+                       if(damage >= autocvar_g_freezetag_revive_falldamage)
+                       {
+                               Unfreeze(targ);
+                               targ.health = autocvar_g_freezetag_revive_falldamage_health;
+                               pointparticles(particleeffectnum("iceorglass"), targ.origin, '0 0 0', 3);
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, targ.netname);
+                               Send_Notification(NOTIF_ONE, targ, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
+                       }
+
+                       damage = 0;
+                       force *= autocvar_g_freezetag_frozen_force;
+               }
+               
+               if(targ.frozen && deathtype == DEATH_HURTTRIGGER && !autocvar_g_freezetag_frozen_damage_trigger)
+               {
+                       pointparticles(particleeffectnum("teleport"), targ.origin, '0 0 0', 1);
+               
+                       entity oldself = self;
+                       self = targ;
+                       entity spot = SelectSpawnPoint (FALSE);
+                       
+                       if(spot)
+                       {
+                               damage = 0;
+                               self.deadflag = DEAD_NO;
+
+                               self.angles = spot.angles;
+                               
+                               self.effects = 0;
+                               self.effects |= EF_TELEPORT_BIT;
+
+                               self.angles_z = 0; // never spawn tilted even if the spot says to
+                               self.fixangle = TRUE; // turn this way immediately
+                               self.velocity = '0 0 0';
+                               self.avelocity = '0 0 0';
+                               self.punchangle = '0 0 0';
+                               self.punchvector = '0 0 0';
+                               self.oldvelocity = self.velocity;
+                               
+                               self.spawnorigin = spot.origin;
+                               setorigin (self, spot.origin + '0 0 1' * (1 - self.mins_z - 24));
+                               // don't reset back to last position, even if new position is stuck in solid
+                               self.oldorigin = self.origin;
+                               self.prevorigin = self.origin;
+                               
+                               pointparticles(particleeffectnum("teleport"), self.origin, '0 0 0', 1);
+                       }
+                       
+                       self = oldself;
+               }
+
+               if(!g_instagib)
                {
                        // apply strength multiplier
                        if (attacker.items & IT_STRENGTH)
@@ -713,12 +849,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                }
 
                if (targ == attacker)
-               {
-                       if(g_cts && !autocvar_g_cts_selfdamage)
-                               damage = 0;
-                       else
-                               damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
-               }
+                       damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
 
                // count the damage
                if(attacker)
@@ -743,7 +874,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                                                        if(victim.BUTTON_CHAT)
                                                                attacker.typehitsound += 1;
                                                        else
-                                                               attacker.hitsound += 1;
+                                                               attacker.damage_dealt += damage;
                                                }
 
                                                damage_goodhits += 1;
@@ -1200,24 +1331,24 @@ void Fire_ApplyDamage(entity e)
                e.fire_endtime = 0;
 
        // ice stops fire
-       if(e.freezetag_frozen)
+       if(e.frozen)
                e.fire_endtime = 0;
 
        t = min(frametime, e.fire_endtime - time);
        d = e.fire_damagepersec * t;
 
-       hi = e.fire_owner.hitsound;
+       hi = e.fire_owner.damage_dealt;
        ty = e.fire_owner.typehitsound;
        Damage(e, e, e.fire_owner, d, e.fire_deathtype, e.origin, '0 0 0');
        if(e.fire_hitsound && e.fire_owner)
        {
-               e.fire_owner.hitsound = hi;
+               e.fire_owner.damage_dealt = hi;
                e.fire_owner.typehitsound = ty;
        }
        e.fire_hitsound = TRUE;
 
        if (!IS_INDEPENDENT_PLAYER(e))
-       if(!e.freezetag_frozen)
+       if(!e.frozen)
        FOR_EACH_PLAYER(other) if(e != other)
        {
                if(IS_PLAYER(other))
index 02c1c8f75856c07aa0dc5b82ed31cdc8bc44dddb..63ff16434d1861b3b33b2782fe12cd3ed3c670af 100644 (file)
@@ -55,7 +55,6 @@ const float SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS = 1;
 string redirection_target;
 float world_initialized;
 
-string GetMapname();
 string GetGametype();
 void GotoNextMap(float reinit);
 void ShuffleMaplist();
@@ -216,7 +215,6 @@ void cvar_changes_init()
                // private
                BADCVAR("developer");
                BADCVAR("log_dest_udp");
-               BADCVAR("log_file");
                BADCVAR("net_address");
                BADCVAR("net_address_ipv6");
                BADCVAR("port");
@@ -237,6 +235,7 @@ void cvar_changes_init()
                BADPREFIX("g_playerstats_");
                BADPREFIX("g_respawn_ghosts");
                BADPREFIX("g_voice_flood_");
+               BADPREFIX("log_file");
                BADPREFIX("rcon_");
                BADPREFIX("sv_allowdownloads");
                BADPREFIX("sv_autodemo");
@@ -421,7 +420,7 @@ void cvar_changes_init()
                BADPREFIX("sv_ready_restart_");
 
                // mutators that announce themselves properly to the server browser
-               BADCVAR("g_minstagib");
+               BADCVAR("g_instagib");
                BADCVAR("g_new_toys");
                BADCVAR("g_nix");
                BADCVAR("g_grappling_hook");
@@ -546,6 +545,7 @@ void spawnfunc___init_dedicated_server(void)
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
+       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
 
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
@@ -595,6 +595,7 @@ void spawnfunc_worldspawn (void)
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
+       CALL_ACCUMULATED_FUNCTION(RegisterBuffs);
 
        ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
 
@@ -785,7 +786,7 @@ void spawnfunc_worldspawn (void)
        addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load);
        addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size);
        addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup);
-       addstat(STAT_HIT_TIME, AS_FLOAT, hit_time);
+       addstat(STAT_DAMAGE_DEALT_TOTAL, AS_INT, damage_dealt_total);
        addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time);
        addstat(STAT_LAYED_MINES, AS_INT, minelayer_mines);
 
@@ -794,6 +795,10 @@ void spawnfunc_worldspawn (void)
 
        addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
 
+       // freeze attacks
+       addstat(STAT_FROZEN, AS_INT, frozen);
+       addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress);
+
        // g_movementspeed hack
        addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw);
        addstat(STAT_MOVEVARS_MAXSPEED, AS_FLOAT, stat_sv_maxspeed);
@@ -917,7 +922,6 @@ string GetGametype()
        return MapInfo_Type_ToString(MapInfo_LoadedGametype);
 }
 
-string getmapname_stored;
 string GetMapname()
 {
        return mapname;
@@ -1242,13 +1246,27 @@ float DoNextMapOverride(float reinit)
                return TRUE;
        }
        if(autocvar_nextmap != "")
-               if(MapInfo_CheckMap(autocvar_nextmap))
+       {
+               string m;
+               m = GameTypeVote_MapInfo_FixName(autocvar_nextmap);
+               cvar_set("nextmap",m);
+       
+               if(!m || gametypevote)
+                       return FALSE;
+               if(autocvar_sv_vote_gametype)
+               {
+                       Map_Goto_SetStr(m);
+                       return FALSE;
+               }
+               
+               if(MapInfo_CheckMap(m))
                {
-                       Map_Goto_SetStr(autocvar_nextmap);
+                       Map_Goto_SetStr(m);
                        Map_Goto(reinit);
                        alreadychangedlevel = TRUE;
                        return TRUE;
                }
+       }
        if(!reinit && autocvar_lastlevel)
        {
                cvar_settemp_restore();
@@ -1285,9 +1303,6 @@ When the player presses attack or jump, change to the next level
 ============
 */
 .float autoscreenshot;
-void() MapVote_Start;
-void() MapVote_Think;
-float mapvote_initialized;
 void IntermissionThink()
 {
        FixIntermissionClient(self);
@@ -2052,17 +2067,6 @@ void CheckRules_World()
 
        SetDefaultAlpha();
 
-       /*
-       MapVote_Think should now do that part
-       if (intermission_running)
-               if (time >= intermission_exittime + 60)
-               {
-                       if(!DoNextMapOverride())
-                               GotoNextMap();
-                       return;
-               }
-       */
-
        if (gameover)   // someone else quit the game already
        {
                if(player_count == 0) // Nobody there? Then let's go to the next map
@@ -2224,517 +2228,14 @@ void CheckRules_World()
        }
 }
 
-float mapvote_nextthink;
-float mapvote_initialized;
-float mapvote_keeptwotime;
-float mapvote_timeout;
-string mapvote_message;
-#define MAPVOTE_SCREENSHOT_DIRS_COUNT 4
-string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT];
-float mapvote_screenshot_dirs_count;
-
-float mapvote_count;
-float mapvote_count_real;
-string mapvote_maps[MAPVOTE_COUNT];
-float mapvote_maps_screenshot_dir[MAPVOTE_COUNT];
-string mapvote_maps_pakfile[MAPVOTE_COUNT];
-float mapvote_maps_suggested[MAPVOTE_COUNT];
-string mapvote_suggestions[MAPVOTE_COUNT];
-float mapvote_suggestion_ptr;
-float mapvote_voters;
-float mapvote_selections[MAPVOTE_COUNT];
-float mapvote_run;
-float mapvote_detail;
-float mapvote_abstain;
-.float mapvote;
-
-void MapVote_ClearAllVotes()
-{
-       FOR_EACH_CLIENT(other)
-               other.mapvote = 0;
-}
-
-string MapVote_Suggest(string m)
+string GotoMap(string m)
 {
-       float i;
-       if(m == "")
-               return "That's not how to use this command.";
-       if(!autocvar_g_maplist_votable_suggestions)
-               return "Suggestions are not accepted on this server.";
-       if(mapvote_initialized)
-               return "Can't suggest - voting is already in progress!";
-       m = MapInfo_FixName(m);
+       m = GameTypeVote_MapInfo_FixName(m);
        if (!m)
                return "The map you suggested is not available on this server.";
-       if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
-               if(Map_IsRecent(m))
-                       return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
-
+       if (!autocvar_sv_vote_gametype)
        if(!MapInfo_CheckMap(m))
                return "The map you suggested does not support the current game mode.";
-       for(i = 0; i < mapvote_suggestion_ptr; ++i)
-               if(mapvote_suggestions[i] == m)
-                       return "This map was already suggested.";
-       if(mapvote_suggestion_ptr >= MAPVOTE_COUNT)
-       {
-               i = floor(random() * mapvote_suggestion_ptr);
-       }
-       else
-       {
-               i = mapvote_suggestion_ptr;
-               mapvote_suggestion_ptr += 1;
-       }
-       if(mapvote_suggestions[i] != "")
-               strunzone(mapvote_suggestions[i]);
-       mapvote_suggestions[i] = strzone(m);
-       if(autocvar_sv_eventlog)
-               GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid)));
-       return strcat("Suggestion of ", m, " accepted.");
-}
-
-void MapVote_AddVotable(string nextMap, float isSuggestion)
-{
-       float j, i, o;
-       string pakfile, mapfile;
-
-       if(nextMap == "")
-               return;
-       for(j = 0; j < mapvote_count; ++j)
-               if(mapvote_maps[j] == nextMap)
-                       return;
-       // suggestions might be no longer valid/allowed after gametype switch!
-       if(isSuggestion)
-               if(!MapInfo_CheckMap(nextMap))
-                       return;
-       mapvote_maps[mapvote_count] = strzone(nextMap);
-       mapvote_maps_suggested[mapvote_count] = isSuggestion;
-
-       pakfile = string_null;
-       for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
-       {
-               mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);
-               pakfile = whichpack(strcat(mapfile, ".tga"));
-               if(pakfile == "")
-                       pakfile = whichpack(strcat(mapfile, ".jpg"));
-               if(pakfile == "")
-                       pakfile = whichpack(strcat(mapfile, ".png"));
-               if(pakfile != "")
-                       break;
-       }
-       if(i >= mapvote_screenshot_dirs_count)
-               i = 0; // FIXME maybe network this error case, as that means there is no mapshot on the server?
-       for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1)
-               pakfile = substring(pakfile, o, -1);
-
-       mapvote_maps_screenshot_dir[mapvote_count] = i;
-       mapvote_maps_pakfile[mapvote_count] = strzone(pakfile);
-
-       mapvote_count += 1;
-}
-
-void MapVote_Spawn();
-void MapVote_Init()
-{
-       float i;
-       float nmax, smax;
-
-       MapVote_ClearAllVotes();
-
-       mapvote_count = 0;
-       mapvote_detail = !autocvar_g_maplist_votable_nodetail;
-       mapvote_abstain = autocvar_g_maplist_votable_abstain;
-
-       if(mapvote_abstain)
-               nmax = min(MAPVOTE_COUNT - 1, autocvar_g_maplist_votable);
-       else
-               nmax = min(MAPVOTE_COUNT, autocvar_g_maplist_votable);
-       smax = min3(nmax, autocvar_g_maplist_votable_suggestions, mapvote_suggestion_ptr);
-
-       // we need this for AddVotable, as that cycles through the screenshot dirs
-       mapvote_screenshot_dirs_count = tokenize_console(autocvar_g_maplist_votable_screenshot_dir);
-       if(mapvote_screenshot_dirs_count == 0)
-               mapvote_screenshot_dirs_count = tokenize_console("maps levelshots");
-       mapvote_screenshot_dirs_count = min(mapvote_screenshot_dirs_count, MAPVOTE_SCREENSHOT_DIRS_COUNT);
-       for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
-               mapvote_screenshot_dirs[i] = strzone(argv(i));
-
-       if(mapvote_suggestion_ptr)
-               for(i = 0; i < 100 && mapvote_count < smax; ++i)
-                       MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], TRUE);
-
-       for(i = 0; i < 100 && mapvote_count < nmax; ++i)
-               MapVote_AddVotable(GetNextMap(), FALSE);
-
-       if(mapvote_count == 0)
-       {
-               bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
-               cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
-               if(autocvar_g_maplist_shuffle)
-                       ShuffleMaplist();
-               localcmd("\nmenu_cmd sync\n");
-               for(i = 0; i < 100 && mapvote_count < nmax; ++i)
-                       MapVote_AddVotable(GetNextMap(), FALSE);
-       }
-
-       mapvote_count_real = mapvote_count;
-       if(mapvote_abstain)
-               MapVote_AddVotable("don't care", 0);
-
-       //dprint("mapvote count is ", ftos(mapvote_count), "\n");
-
-       mapvote_keeptwotime = time + autocvar_g_maplist_votable_keeptwotime;
-       mapvote_timeout = time + autocvar_g_maplist_votable_timeout;
-       if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
-               mapvote_keeptwotime = 0;
-       mapvote_message = "Choose a map and press its key!";
-
-       MapVote_Spawn();
-}
-
-void MapVote_SendPicture(float id)
-{
-       msg_entity = self;
-       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-       WriteByte(MSG_ONE, TE_CSQC_PICTURE);
-       WriteByte(MSG_ONE, id);
-       WritePicture(MSG_ONE, strcat(mapvote_screenshot_dirs[mapvote_maps_screenshot_dir[id]], "/", mapvote_maps[id]), 3072);
-}
-
-float MapVote_GetMapMask()
-{
-       float mask, i, power;
-       mask = 0;
-       for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
-               if(mapvote_maps[i] != "")
-                       mask |= power;
-       return mask;
-}
-
-entity mapvote_ent;
-float MapVote_SendEntity(entity to, float sf)
-{
-       float i;
-
-       if(sf & 1)
-               sf &= ~2; // if we send 1, we don't need to also send 2
-
-       WriteByte(MSG_ENTITY, ENT_CLIENT_MAPVOTE);
-       WriteByte(MSG_ENTITY, sf);
-
-       if(sf & 1)
-       {
-               // flag 1 == initialization
-               for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
-                       WriteString(MSG_ENTITY, mapvote_screenshot_dirs[i]);
-               WriteString(MSG_ENTITY, "");
-               WriteByte(MSG_ENTITY, mapvote_count);
-               WriteByte(MSG_ENTITY, mapvote_abstain);
-               WriteByte(MSG_ENTITY, mapvote_detail);
-               WriteCoord(MSG_ENTITY, mapvote_timeout);
-               if(mapvote_count <= 8)
-                       WriteByte(MSG_ENTITY, MapVote_GetMapMask());
-               else
-                       WriteShort(MSG_ENTITY, MapVote_GetMapMask());
-               for(i = 0; i < mapvote_count; ++i)
-                       if(mapvote_maps[i] != "")
-                       {
-                               if(mapvote_abstain && i == mapvote_count - 1)
-                               {
-                                       WriteString(MSG_ENTITY, ""); // abstain needs no text
-                                       WriteString(MSG_ENTITY, ""); // abstain needs no pack
-                                       WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir
-                               }
-                               else
-                               {
-                                       WriteString(MSG_ENTITY, mapvote_maps[i]);
-                                       WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]);
-                                       WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]);
-                               }
-                       }
-       }
-
-       if(sf & 2)
-       {
-               // flag 2 == update of mask
-               if(mapvote_count <= 8)
-                       WriteByte(MSG_ENTITY, MapVote_GetMapMask());
-               else
-                       WriteShort(MSG_ENTITY, MapVote_GetMapMask());
-       }
-
-       if(sf & 4)
-       {
-               if(mapvote_detail)
-                       for(i = 0; i < mapvote_count; ++i)
-                               if(mapvote_maps[i] != "")
-                                       WriteByte(MSG_ENTITY, mapvote_selections[i]);
-
-               WriteByte(MSG_ENTITY, to.mapvote);
-       }
-
-       return TRUE;
-}
-
-void MapVote_Spawn()
-{
-       Net_LinkEntity(mapvote_ent = spawn(), FALSE, 0, MapVote_SendEntity);
-}
-
-void MapVote_TouchMask()
-{
-       mapvote_ent.SendFlags |= 2;
-}
-
-void MapVote_TouchVotes(entity voter)
-{
-       mapvote_ent.SendFlags |= 4;
-}
-
-float MapVote_Finished(float mappos)
-{
-       string result;
-       float i;
-       float didntvote;
-
-       if(autocvar_sv_eventlog)
-       {
-               result = strcat(":vote:finished:", mapvote_maps[mappos]);
-               result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::");
-               didntvote = mapvote_voters;
-               for(i = 0; i < mapvote_count; ++i)
-                       if(mapvote_maps[i] != "")
-                       {
-                               didntvote -= mapvote_selections[i];
-                               if(i != mappos)
-                               {
-                                       result = strcat(result, ":", mapvote_maps[i]);
-                                       result = strcat(result, ":", ftos(mapvote_selections[i]));
-                               }
-                       }
-               result = strcat(result, ":didn't vote:", ftos(didntvote));
-
-               GameLogEcho(result);
-               if(mapvote_maps_suggested[mappos])
-                       GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]));
-       }
-
-       FOR_EACH_REALCLIENT(other)
-               FixClientCvars(other);
-
-       Map_Goto_SetStr(mapvote_maps[mappos]);
-       Map_Goto(0);
-       alreadychangedlevel = TRUE;
-       return TRUE;
-}
-void MapVote_CheckRules_1()
-{
-       float i;
-
-       for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "")
-       {
-               //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
-               mapvote_selections[i] = 0;
-       }
-
-       mapvote_voters = 0;
-       FOR_EACH_REALCLIENT(other)
-       {
-               ++mapvote_voters;
-               if(other.mapvote)
-               {
-                       i = other.mapvote - 1;
-                       //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n");
-                       mapvote_selections[i] = mapvote_selections[i] + 1;
-               }
-       }
-}
-
-float MapVote_CheckRules_2()
-{
-       float i;
-       float firstPlace, secondPlace;
-       float firstPlaceVotes, secondPlaceVotes;
-       float mapvote_voters_real;
-       string result;
-
-       if(mapvote_count_real == 1)
-               return MapVote_Finished(0);
-
-       mapvote_voters_real = mapvote_voters;
-       if(mapvote_abstain)
-               mapvote_voters_real -= mapvote_selections[mapvote_count - 1];
-
-       RandomSelection_Init();
-       for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
-               RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
-       firstPlace = RandomSelection_chosen_float;
-       firstPlaceVotes = RandomSelection_best_priority;
-       //dprint("First place: ", ftos(firstPlace), "\n");
-       //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
-
-       RandomSelection_Init();
-       for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
-               if(i != firstPlace)
-                       RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
-       secondPlace = RandomSelection_chosen_float;
-       secondPlaceVotes = RandomSelection_best_priority;
-       //dprint("Second place: ", ftos(secondPlace), "\n");
-       //dprint("Second place votes: ", ftos(secondPlaceVotes), "\n");
-
-       if(firstPlace == -1)
-               error("No first place in map vote... WTF?");
-
-       if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes)
-               return MapVote_Finished(firstPlace);
-
-       if(mapvote_keeptwotime)
-               if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
-               {
-                       float didntvote;
-                       MapVote_TouchMask();
-                       mapvote_message = "Now decide between the TOP TWO!";
-                       mapvote_keeptwotime = 0;
-                       result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]);
-                       result = strcat(result, ":", ftos(firstPlaceVotes));
-                       result = strcat(result, ":", mapvote_maps[secondPlace]);
-                       result = strcat(result, ":", ftos(secondPlaceVotes), "::");
-                       didntvote = mapvote_voters;
-                       for(i = 0; i < mapvote_count; ++i)
-                               if(mapvote_maps[i] != "")
-                               {
-                                       didntvote -= mapvote_selections[i];
-                                       if(i != firstPlace)
-                                               if(i != secondPlace)
-                                               {
-                                                       result = strcat(result, ":", mapvote_maps[i]);
-                                                       result = strcat(result, ":", ftos(mapvote_selections[i]));
-                                                       if(i < mapvote_count_real)
-                                                       {
-                                                               strunzone(mapvote_maps[i]);
-                                                               mapvote_maps[i] = "";
-                                                               strunzone(mapvote_maps_pakfile[i]);
-                                                               mapvote_maps_pakfile[i] = "";
-                                                       }
-                                               }
-                               }
-                       result = strcat(result, ":didn't vote:", ftos(didntvote));
-                       if(autocvar_sv_eventlog)
-                               GameLogEcho(result);
-               }
-
-       return FALSE;
-}
-void MapVote_Tick()
-{
-       float keeptwo;
-       float totalvotes;
-
-       keeptwo = mapvote_keeptwotime;
-       MapVote_CheckRules_1(); // count
-       if(MapVote_CheckRules_2()) // decide
-               return;
-
-       totalvotes = 0;
-       FOR_EACH_REALCLIENT(other)
-       {
-               // hide scoreboard again
-               if(other.health != 2342)
-               {
-                       other.health = 2342;
-                       other.impulse = 0;
-                       if(IS_REAL_CLIENT(other))
-                       {
-                               msg_entity = other;
-                               WriteByte(MSG_ONE, SVC_FINALE);
-                               WriteString(MSG_ONE, "");
-                       }
-               }
-
-               // clear possibly invalid votes
-               if(mapvote_maps[other.mapvote - 1] == "")
-                       other.mapvote = 0;
-               // use impulses as new vote
-               if(other.impulse >= 1 && other.impulse <= mapvote_count)
-                       if(mapvote_maps[other.impulse - 1] != "")
-                       {
-                               other.mapvote = other.impulse;
-                               MapVote_TouchVotes(other);
-                       }
-               other.impulse = 0;
-
-               if(other.mapvote)
-                       ++totalvotes;
-       }
-
-       MapVote_CheckRules_1(); // just count
-}
-void MapVote_Start()
-{
-       if(mapvote_run)
-               return;
-
-       // wait for stats to be sent first
-       if(!playerstats_waitforme)
-               return;
-
-       MapInfo_Enumerate();
-       if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
-               mapvote_run = TRUE;
-}
-void MapVote_Think()
-{
-       if(!mapvote_run)
-               return;
-
-       if(alreadychangedlevel)
-               return;
-
-       if(time < mapvote_nextthink)
-               return;
-       //dprint("tick\n");
-
-       mapvote_nextthink = time + 0.5;
-
-       if(!mapvote_initialized)
-       {
-               if(autocvar_rescan_pending == 1)
-               {
-                       cvar_set("rescan_pending", "2");
-                       localcmd("fs_rescan\nrescan_pending 3\n");
-                       return;
-               }
-               else if(autocvar_rescan_pending == 2)
-               {
-                       return;
-               }
-               else if(autocvar_rescan_pending == 3)
-               {
-                       // now build missing mapinfo files
-                       if(!MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
-                               return;
-
-                       // we're done, start the timer
-                       cvar_set("rescan_pending", "0");
-               }
-
-               mapvote_initialized = TRUE;
-               if(DoNextMapOverride(0))
-                       return;
-               if(!autocvar_g_maplist_votable || player_count <= 0)
-               {
-                       GotoNextMap(0);
-                       return;
-               }
-               MapVote_Init();
-       }
-
-       MapVote_Tick();
-}
-
-string GotoMap(string m)
-{
-       if(!MapInfo_CheckMap(m))
-               return "The map you chose is not available on this server.";
        cvar_set("nextmap", m);
        cvar_set("timelimit", "-1");
        if(mapvote_initialized || alreadychangedlevel)
@@ -2756,19 +2257,21 @@ void EndFrame()
        float altime;
        FOR_EACH_REALCLIENT(self)
        {
+               self.damage_dealt_total = 0;
+       
                if(IS_SPEC(self))
                {
                        if(self.enemy.typehitsound)
                                self.typehit_time = time;
-                       else if(self.enemy.hitsound)
-                               self.hit_time = time;
+                       else if(self.enemy.damage_dealt)
+                               self.damage_dealt_total = ceil(self.enemy.damage_dealt);
                }
                else
                {
                        if(self.typehitsound)
                                self.typehit_time = time;
-                       else if(self.hitsound)
-                               self.hit_time = time;
+                       else if(self.damage_dealt)
+                               self.damage_dealt_total = ceil(self.damage_dealt);
                }
        }
        altime = time + frametime * (1 + autocvar_g_antilag_nudge);
@@ -2779,10 +2282,12 @@ void EndFrame()
        // needed!
        FOR_EACH_CLIENT(self)
        {
-               self.hitsound = FALSE;
                self.typehitsound = FALSE;
+               self.damage_dealt = 0;
                antilag_record(self, altime);
        }
+       FOR_EACH_MONSTER(self)
+               antilag_record(self, altime);
 }
 
 
diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc
new file mode 100644 (file)
index 0000000..3e1a866
--- /dev/null
@@ -0,0 +1,742 @@
+float GameTypeVote_AvailabilityStatus(string gtname) 
+{ 
+       float type = MapInfo_Type_FromString(gtname);
+       if( type == 0 )
+               return GTV_FORBIDDEN;
+       
+       if ( autocvar_nextmap != "" )
+       {
+               if ( !MapInfo_Get_ByName(autocvar_nextmap, FALSE, 0) )
+                       return GTV_FORBIDDEN;
+               if (!(MapInfo_Map_supportedGametypes & type))
+                       return GTV_FORBIDDEN;
+       }
+       
+       return GTV_AVAILABLE;
+}
+
+float GameTypeVote_GetMask()
+{
+       float n, j, gametype_mask;
+       n = tokenizebyseparator(autocvar_sv_vote_gametype_options, " ");
+       n = min(MAPVOTE_COUNT, n);
+       gametype_mask = 0;
+       for(j = 0; j < n; ++j)
+               gametype_mask |= MapInfo_Type_FromString(argv(j));
+       return gametype_mask;
+}
+
+string GameTypeVote_MapInfo_FixName(string m)
+{
+       if ( autocvar_sv_vote_gametype )
+       {
+               MapInfo_Enumerate();
+               MapInfo_FilterGametype(GameTypeVote_GetMask(), 0, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+       }
+       return MapInfo_FixName(m);
+}
+
+void MapVote_ClearAllVotes()
+{
+       FOR_EACH_CLIENT(other)
+               other.mapvote = 0;
+}
+
+void MapVote_UnzoneStrings()
+{
+       float j;
+       for(j = 0; j < mapvote_count; ++j)
+       {
+               if ( mapvote_maps[j] )
+               {
+                       strunzone(mapvote_maps[j]);
+                       mapvote_maps[j] = string_null;
+               }
+               if ( mapvote_maps_pakfile[j] )
+               {
+                       strunzone(mapvote_maps_pakfile[j]);
+                       mapvote_maps_pakfile[j] = string_null;
+               }
+       }
+}
+
+string MapVote_Suggest(string m)
+{
+       float i;
+       if(m == "")
+               return "That's not how to use this command.";
+       if(!autocvar_g_maplist_votable_suggestions)
+               return "Suggestions are not accepted on this server.";
+       if(mapvote_initialized)
+       if(!gametypevote)
+               return "Can't suggest - voting is already in progress!";
+       m = GameTypeVote_MapInfo_FixName(m);
+       if (!m)
+               return "The map you suggested is not available on this server.";
+       if(!autocvar_g_maplist_votable_suggestions_override_mostrecent)
+               if(Map_IsRecent(m))
+                       return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
+
+       if (!autocvar_sv_vote_gametype)
+       if(!MapInfo_CheckMap(m))
+               return "The map you suggested does not support the current game mode.";
+       for(i = 0; i < mapvote_suggestion_ptr; ++i)
+               if(mapvote_suggestions[i] == m)
+                       return "This map was already suggested.";
+       if(mapvote_suggestion_ptr >= MAPVOTE_COUNT)
+       {
+               i = floor(random() * mapvote_suggestion_ptr);
+       }
+       else
+       {
+               i = mapvote_suggestion_ptr;
+               mapvote_suggestion_ptr += 1;
+       }
+       if(mapvote_suggestions[i] != "")
+               strunzone(mapvote_suggestions[i]);
+       mapvote_suggestions[i] = strzone(m);
+       if(autocvar_sv_eventlog)
+               GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid)));
+       return strcat("Suggestion of ", m, " accepted.");
+}
+
+void MapVote_AddVotable(string nextMap, float isSuggestion)
+{
+       float j, i, o;
+       string pakfile, mapfile;
+
+       if(nextMap == "")
+               return;
+       for(j = 0; j < mapvote_count; ++j)
+               if(mapvote_maps[j] == nextMap)
+                       return;
+       // suggestions might be no longer valid/allowed after gametype switch!
+       if(isSuggestion)
+               if(!MapInfo_CheckMap(nextMap))
+                       return;
+       mapvote_maps[mapvote_count] = strzone(nextMap);
+       mapvote_maps_suggested[mapvote_count] = isSuggestion;
+
+       pakfile = string_null;
+       for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
+       {
+               mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]);
+               pakfile = whichpack(strcat(mapfile, ".tga"));
+               if(pakfile == "")
+                       pakfile = whichpack(strcat(mapfile, ".jpg"));
+               if(pakfile == "")
+                       pakfile = whichpack(strcat(mapfile, ".png"));
+               if(pakfile != "")
+                       break;
+       }
+       if(i >= mapvote_screenshot_dirs_count)
+               i = 0; // FIXME maybe network this error case, as that means there is no mapshot on the server?
+       for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1)
+               pakfile = substring(pakfile, o, -1);
+
+       mapvote_maps_screenshot_dir[mapvote_count] = i;
+       mapvote_maps_pakfile[mapvote_count] = strzone(pakfile);
+       mapvote_maps_availability[mapvote_count] = GTV_AVAILABLE;
+
+       mapvote_count += 1;
+}
+
+void MapVote_Init()
+{
+       float i;
+       float nmax, smax;
+
+       MapVote_ClearAllVotes();
+       MapVote_UnzoneStrings();
+
+       mapvote_count = 0;
+       mapvote_detail = !autocvar_g_maplist_votable_nodetail;
+       mapvote_abstain = autocvar_g_maplist_votable_abstain;
+
+       if(mapvote_abstain)
+               nmax = min(MAPVOTE_COUNT - 1, autocvar_g_maplist_votable);
+       else
+               nmax = min(MAPVOTE_COUNT, autocvar_g_maplist_votable);
+       smax = min3(nmax, autocvar_g_maplist_votable_suggestions, mapvote_suggestion_ptr);
+
+       // we need this for AddVotable, as that cycles through the screenshot dirs
+       mapvote_screenshot_dirs_count = tokenize_console(autocvar_g_maplist_votable_screenshot_dir);
+       if(mapvote_screenshot_dirs_count == 0)
+               mapvote_screenshot_dirs_count = tokenize_console("maps levelshots");
+       mapvote_screenshot_dirs_count = min(mapvote_screenshot_dirs_count, MAPVOTE_SCREENSHOT_DIRS_COUNT);
+       for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
+               mapvote_screenshot_dirs[i] = strzone(argv(i));
+
+       if(mapvote_suggestion_ptr)
+               for(i = 0; i < 100 && mapvote_count < smax; ++i)
+                       MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], TRUE);
+
+       for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+               MapVote_AddVotable(GetNextMap(), FALSE);
+
+       if(mapvote_count == 0)
+       {
+               bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
+               cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_CurrentGametype(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()));
+               if(autocvar_g_maplist_shuffle)
+                       ShuffleMaplist();
+               localcmd("\nmenu_cmd sync\n");
+               for(i = 0; i < 100 && mapvote_count < nmax; ++i)
+                       MapVote_AddVotable(GetNextMap(), FALSE);
+       }
+
+       mapvote_count_real = mapvote_count;
+       if(mapvote_abstain)
+               MapVote_AddVotable("don't care", 0);
+
+       //dprint("mapvote count is ", ftos(mapvote_count), "\n");
+
+       mapvote_keeptwotime = time + autocvar_g_maplist_votable_keeptwotime;
+       mapvote_timeout = time + autocvar_g_maplist_votable_timeout;
+       if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
+               mapvote_keeptwotime = 0;
+       mapvote_message = "Choose a map and press its key!";
+
+       MapVote_Spawn();
+}
+
+void MapVote_SendPicture(float id)
+{
+       msg_entity = self;
+       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+       WriteByte(MSG_ONE, TE_CSQC_PICTURE);
+       WriteByte(MSG_ONE, id);
+       WritePicture(MSG_ONE, strcat(mapvote_screenshot_dirs[mapvote_maps_screenshot_dir[id]], "/", mapvote_maps[id]), 3072);
+}
+
+
+void MapVote_WriteMask()
+{
+       float i;
+       if ( mapvote_count < 24 )
+       {
+               float mask,power;
+               mask = 0;
+               for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
+                       if(mapvote_maps_availability[i] == GTV_AVAILABLE )
+                               mask |= power;
+                       
+               if(mapvote_count < 8)
+                       WriteByte(MSG_ENTITY, mask);
+               else if (mapvote_count < 16)
+                       WriteShort(MSG_ENTITY,mask);
+               else
+                       WriteLong(MSG_ENTITY, mask);
+       }
+       else
+       {
+               for ( i = 0; i < mapvote_count; ++i )
+                       WriteByte(MSG_ENTITY, mapvote_maps_availability[i]);
+       }
+}
+
+float MapVote_SendEntity(entity to, float sf)
+{
+       float i;
+
+       if(sf & 1)
+               sf &= ~2; // if we send 1, we don't need to also send 2
+
+       WriteByte(MSG_ENTITY, ENT_CLIENT_MAPVOTE);
+       WriteByte(MSG_ENTITY, sf);
+
+       if(sf & 1)
+       {
+               // flag 1 == initialization
+               for(i = 0; i < mapvote_screenshot_dirs_count; ++i)
+                       WriteString(MSG_ENTITY, mapvote_screenshot_dirs[i]);
+               WriteString(MSG_ENTITY, "");
+               WriteByte(MSG_ENTITY, mapvote_count);
+               WriteByte(MSG_ENTITY, mapvote_abstain);
+               WriteByte(MSG_ENTITY, mapvote_detail);
+               WriteCoord(MSG_ENTITY, mapvote_timeout);
+               
+               if ( gametypevote )
+               {
+                       // gametype vote
+                       WriteByte(MSG_ENTITY, 1);
+                       WriteString(MSG_ENTITY, autocvar_nextmap);
+               }
+               else if ( autocvar_sv_vote_gametype )
+               {
+                        // map vote but gametype has been chosen via voting screen
+                       WriteByte(MSG_ENTITY, 2);
+                       WriteString(MSG_ENTITY, MapInfo_Type_ToText(MapInfo_CurrentGametype()));
+               }
+               else
+                       WriteByte(MSG_ENTITY, 0); // map vote
+
+               MapVote_WriteMask();
+
+               for(i = 0; i < mapvote_count; ++i)
+               {
+                       if(mapvote_abstain && i == mapvote_count - 1)
+                       {
+                               WriteString(MSG_ENTITY, ""); // abstain needs no text
+                               WriteString(MSG_ENTITY, ""); // abstain needs no pack
+                               WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir
+                               WriteByte(MSG_ENTITY, GTV_AVAILABLE);
+                       }
+                       else
+                       {
+                               WriteString(MSG_ENTITY, mapvote_maps[i]);
+                               WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]);
+                               WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]);
+                               WriteByte(MSG_ENTITY, mapvote_maps_availability[i]);
+                       }
+               }
+       }
+
+       if(sf & 2)
+       {
+               // flag 2 == update of mask
+               MapVote_WriteMask();
+       }
+
+       if(sf & 4)
+       {
+               if(mapvote_detail)
+                       for(i = 0; i < mapvote_count; ++i)
+                               if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+                                       WriteByte(MSG_ENTITY, mapvote_selections[i]);
+
+               WriteByte(MSG_ENTITY, to.mapvote);
+       }
+
+       return TRUE;
+}
+
+void MapVote_Spawn()
+{
+       Net_LinkEntity(mapvote_ent = spawn(), FALSE, 0, MapVote_SendEntity);
+}
+
+void MapVote_TouchMask()
+{
+       mapvote_ent.SendFlags |= 2;
+}
+
+void MapVote_TouchVotes(entity voter)
+{
+       mapvote_ent.SendFlags |= 4;
+}
+
+float MapVote_Finished(float mappos)
+{
+       if(alreadychangedlevel)
+               return FALSE;
+
+       string result;
+       float i;
+       float didntvote;
+
+       if(autocvar_sv_eventlog)
+       {
+               result = strcat(":vote:finished:", mapvote_maps[mappos]);
+               result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::");
+               didntvote = mapvote_voters;
+               for(i = 0; i < mapvote_count; ++i)
+                       if(mapvote_maps_availability[i] == GTV_AVAILABLE )
+                       {
+                               didntvote -= mapvote_selections[i];
+                               if(i != mappos)
+                               {
+                                       result = strcat(result, ":", mapvote_maps[i]);
+                                       result = strcat(result, ":", ftos(mapvote_selections[i]));
+                               }
+                       }
+               result = strcat(result, ":didn't vote:", ftos(didntvote));
+
+               GameLogEcho(result);
+               if(mapvote_maps_suggested[mappos])
+                       GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos]));
+       }
+
+       FOR_EACH_REALCLIENT(other)
+               FixClientCvars(other);
+
+       if(gametypevote)
+       {
+               if ( GameTypeVote_Finished(mappos) )
+               {
+                       gametypevote = FALSE;
+                       if(autocvar_nextmap != "")
+                       {
+                               Map_Goto_SetStr(autocvar_nextmap);
+                               Map_Goto(0);
+                               alreadychangedlevel = TRUE;
+                               return TRUE;
+                       }
+                       else
+                               MapVote_Init();
+               }
+               return FALSE;
+       }
+       
+       Map_Goto_SetStr(mapvote_maps[mappos]);
+       Map_Goto(0);
+       alreadychangedlevel = TRUE;
+       
+       return TRUE;
+}
+
+void MapVote_CheckRules_1()
+{
+       float i;
+
+       for(i = 0; i < mapvote_count; ++i) 
+               if( mapvote_maps_availability[i] == GTV_AVAILABLE )
+               {
+                       //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n");
+                       mapvote_selections[i] = 0;
+               }
+
+       mapvote_voters = 0;
+       FOR_EACH_REALCLIENT(other)
+       {
+               ++mapvote_voters;
+               if(other.mapvote)
+               {
+                       i = other.mapvote - 1;
+                       //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n");
+                       mapvote_selections[i] = mapvote_selections[i] + 1;
+               }
+       }
+}
+
+float MapVote_CheckRules_2()
+{
+       float i;
+       float firstPlace, secondPlace, currentPlace;
+       float firstPlaceVotes, secondPlaceVotes, currentVotes;
+       float mapvote_voters_real;
+       string result;
+
+       if(mapvote_count_real == 1)
+               return MapVote_Finished(0);
+
+       mapvote_voters_real = mapvote_voters;
+       if(mapvote_abstain)
+               mapvote_voters_real -= mapvote_selections[mapvote_count - 1];
+
+       RandomSelection_Init();
+       currentPlace = 0;
+       currentVotes = -1;
+       for(i = 0; i < mapvote_count_real; ++i) 
+               if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+               {
+                       RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
+                       if ( gametypevote &&  mapvote_maps[i] == MapInfo_Type_ToString(MapInfo_CurrentGametype()) )
+                       {
+                               currentVotes = mapvote_selections[i];
+                               currentPlace = i;
+                       }
+               }
+       firstPlaceVotes = RandomSelection_best_priority;
+       if ( autocvar_sv_vote_gametype_default_current && currentVotes == firstPlaceVotes )
+               firstPlace = currentPlace;
+       else
+               firstPlace = RandomSelection_chosen_float;
+       
+       //dprint("First place: ", ftos(firstPlace), "\n");
+       //dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
+
+       RandomSelection_Init();
+       for(i = 0; i < mapvote_count_real; ++i)
+               if(i != firstPlace)
+               if ( mapvote_maps_availability[i] == GTV_AVAILABLE )
+                       RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]);
+       secondPlace = RandomSelection_chosen_float;
+       secondPlaceVotes = RandomSelection_best_priority;
+       //dprint("Second place: ", ftos(secondPlace), "\n");
+       //dprint("Second place votes: ", ftos(secondPlaceVotes), "\n");
+
+       if(firstPlace == -1)
+               error("No first place in map vote... WTF?");
+
+       if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes)
+               return MapVote_Finished(firstPlace);
+
+       if(mapvote_keeptwotime)
+               if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
+               {
+                       float didntvote;
+                       MapVote_TouchMask();
+                       mapvote_message = "Now decide between the TOP TWO!";
+                       mapvote_keeptwotime = 0;
+                       result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]);
+                       result = strcat(result, ":", ftos(firstPlaceVotes));
+                       result = strcat(result, ":", mapvote_maps[secondPlace]);
+                       result = strcat(result, ":", ftos(secondPlaceVotes), "::");
+                       didntvote = mapvote_voters;
+                       for(i = 0; i < mapvote_count; ++i)
+                       {
+                               didntvote -= mapvote_selections[i];
+                               if(i != firstPlace)
+                                       if(i != secondPlace)
+                                       {
+                                               result = strcat(result, ":", mapvote_maps[i]);
+                                               result = strcat(result, ":", ftos(mapvote_selections[i]));
+                                               if(i < mapvote_count_real)
+                                               {
+                                                       mapvote_maps_availability[i] = GTV_FORBIDDEN;
+                                               }
+                                       }
+                       }
+                       result = strcat(result, ":didn't vote:", ftos(didntvote));
+                       if(autocvar_sv_eventlog)
+                               GameLogEcho(result);
+               }
+
+       return FALSE;
+}
+
+void MapVote_Tick()
+{
+       float keeptwo;
+       float totalvotes;
+
+       keeptwo = mapvote_keeptwotime;
+       MapVote_CheckRules_1(); // count
+       if(MapVote_CheckRules_2()) // decide
+               return;
+
+       totalvotes = 0;
+       FOR_EACH_REALCLIENT(other)
+       {
+               // hide scoreboard again
+               if(other.health != 2342)
+               {
+                       other.health = 2342;
+                       other.impulse = 0;
+                       if(IS_REAL_CLIENT(other))
+                       {
+                               msg_entity = other;
+                               WriteByte(MSG_ONE, SVC_FINALE);
+                               WriteString(MSG_ONE, "");
+                       }
+               }
+
+               // clear possibly invalid votes
+               if ( mapvote_maps_availability[other.mapvote-1] != GTV_AVAILABLE )
+                       other.mapvote = 0;
+               // use impulses as new vote
+               if(other.impulse >= 1 && other.impulse <= mapvote_count)
+                       if( mapvote_maps_availability[other.impulse - 1] == GTV_AVAILABLE )
+                       {
+                               other.mapvote = other.impulse;
+                               MapVote_TouchVotes(other);
+                       }
+               other.impulse = 0;
+
+               if(other.mapvote)
+                       ++totalvotes;
+       }
+
+       MapVote_CheckRules_1(); // just count
+}
+
+void MapVote_Start()
+{
+       if(mapvote_run)
+               return;
+
+       // wait for stats to be sent first
+       if(!playerstats_waitforme)
+               return;
+
+       MapInfo_Enumerate();
+       if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
+               mapvote_run = TRUE;
+}
+
+void MapVote_Think()
+{
+       if(!mapvote_run)
+               return;
+
+       if(alreadychangedlevel)
+               return;
+
+       if(time < mapvote_nextthink)
+               return;
+       //dprint("tick\n");
+
+       mapvote_nextthink = time + 0.5;
+
+       if(!mapvote_initialized)
+       {
+               if(autocvar_rescan_pending == 1)
+               {
+                       cvar_set("rescan_pending", "2");
+                       localcmd("fs_rescan\nrescan_pending 3\n");
+                       return;
+               }
+               else if(autocvar_rescan_pending == 2)
+               {
+                       return;
+               }
+               else if(autocvar_rescan_pending == 3)
+               {
+                       // now build missing mapinfo files
+                       if(!MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
+                               return;
+
+                       // we're done, start the timer
+                       cvar_set("rescan_pending", "0");
+               }
+
+               mapvote_initialized = TRUE;
+               if(DoNextMapOverride(0))
+                       return;
+               if(!autocvar_g_maplist_votable || player_count <= 0)
+               {
+                       GotoNextMap(0);
+                       return;
+               }
+               
+               if(autocvar_sv_vote_gametype) { GameTypeVote_Start(); }
+               else if(autocvar_nextmap == "") { MapVote_Init(); }
+       }
+
+       MapVote_Tick();
+}
+
+float GameTypeVote_SetGametype(float type)
+{
+       if (MapInfo_CurrentGametype() == type)
+               return TRUE;
+               
+       float tsave = MapInfo_CurrentGametype();
+
+       MapInfo_SwitchGameType(type);
+
+       MapInfo_Enumerate();
+       MapInfo_FilterGametype(type, MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+       if(MapInfo_count > 0)
+       {
+               // update lsmaps in case the gametype changed, this way people can easily list maps for it
+               if(lsmaps_reply != "") { strunzone(lsmaps_reply); }
+               lsmaps_reply = strzone(getlsmaps());
+               bprint("Game type successfully switched to ", MapInfo_Type_ToString(type), "\n");
+       }
+       else
+       {
+               bprint("Cannot use this game type: no map for it found\n");
+               MapInfo_SwitchGameType(tsave);
+               MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
+               return FALSE;
+       }
+
+       //localcmd("gametype ", MapInfo_Type_ToString(type), "\n");
+
+       cvar_set("g_maplist", MapInfo_ListAllowedMaps(type, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()) );
+       if(autocvar_g_maplist_shuffle)
+               ShuffleMaplist();
+
+       return TRUE;
+}
+
+float gametypevote_finished;
+float GameTypeVote_Finished(float pos)
+{
+       if(!gametypevote || gametypevote_finished)
+               return FALSE;
+       
+       if ( !GameTypeVote_SetGametype(MapInfo_Type_FromString(mapvote_maps[pos])) )
+       {
+               dprint("Selected gametype is not supported by any map");
+       }
+       
+       localcmd("sv_vote_gametype_hook_all\n");
+       localcmd("sv_vote_gametype_hook_", mapvote_maps[pos], "\n");
+       
+       gametypevote_finished = TRUE;
+       
+       return TRUE;
+}
+
+float GameTypeVote_AddVotable(string nextMode)
+{
+       float j;
+       if ( nextMode == "" || MapInfo_Type_FromString(nextMode) == 0 )
+               return FALSE;
+       for(j = 0; j < mapvote_count; ++j)
+               if(mapvote_maps[j] == nextMode)
+                       return FALSE;
+       
+       mapvote_maps[mapvote_count] = strzone(nextMode);
+       mapvote_maps_suggested[mapvote_count] = FALSE;
+
+       mapvote_maps_screenshot_dir[mapvote_count] = 0;
+       mapvote_maps_pakfile[mapvote_count] = strzone("");
+       mapvote_maps_availability[mapvote_count] = GameTypeVote_AvailabilityStatus(nextMode);
+
+       mapvote_count += 1;
+       
+       return TRUE;
+       
+}
+
+float GameTypeVote_Start()
+{
+       float j;
+       MapVote_ClearAllVotes();
+       MapVote_UnzoneStrings();
+       
+       mapvote_count = 0;
+       mapvote_timeout = time + autocvar_sv_vote_gametype_timeout;
+       mapvote_abstain = 0;
+       mapvote_detail = !autocvar_g_maplist_votable_nodetail;
+       
+       float n = tokenizebyseparator(autocvar_sv_vote_gametype_options, " ");
+       n = min(MAPVOTE_COUNT, n);
+       
+       float really_available, which_available;
+       really_available = 0;
+       which_available = -1;
+       for(j = 0; j < n; ++j)
+       {
+               if ( GameTypeVote_AddVotable(argv(j)) )
+               if ( mapvote_maps_availability[j] == GTV_AVAILABLE )
+               {
+                       really_available++;
+                       which_available = j;
+               }
+       }
+
+       mapvote_count_real = mapvote_count;
+       
+       gametypevote = 1;
+       
+       if ( really_available == 0 )
+       {
+               if ( mapvote_count > 0 )
+                       strunzone(mapvote_maps[0]);
+               mapvote_maps[0] = strzone(MapInfo_Type_ToString(MapInfo_CurrentGametype()));
+               //GameTypeVote_Finished(0);
+               MapVote_Finished(0);
+               return FALSE;
+       }
+       if ( really_available == 1 )
+       {
+               //GameTypeVote_Finished(which_available);
+               MapVote_Finished(which_available);
+               return FALSE;
+       }
+       
+       mapvote_count_real = mapvote_count;
+
+       mapvote_keeptwotime = time + autocvar_sv_vote_gametype_keeptwotime;
+       if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
+               mapvote_keeptwotime = 0;
+       
+       MapVote_Spawn();
+       
+       return TRUE;
+}
diff --git a/qcsrc/server/mapvoting.qh b/qcsrc/server/mapvoting.qh
new file mode 100644 (file)
index 0000000..6875958
--- /dev/null
@@ -0,0 +1,39 @@
+// definitions for functions used outside mapvoting.qc
+void MapVote_Start();
+void MapVote_Spawn();
+void MapVote_Think();
+float GameTypeVote_Start();
+float GameTypeVote_Finished(float pos);
+string GameTypeVote_MapInfo_FixName(string m);
+
+// definitions
+float gametypevote;
+string getmapname_stored;
+float mapvote_initialized;
+
+float mapvote_nextthink;
+float mapvote_initialized;
+float mapvote_keeptwotime;
+float mapvote_timeout;
+string mapvote_message;
+#define MAPVOTE_SCREENSHOT_DIRS_COUNT 4
+string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT];
+float mapvote_screenshot_dirs_count;
+
+float mapvote_count;
+float mapvote_count_real;
+string mapvote_maps[MAPVOTE_COUNT];
+float mapvote_maps_screenshot_dir[MAPVOTE_COUNT];
+string mapvote_maps_pakfile[MAPVOTE_COUNT];
+float mapvote_maps_suggested[MAPVOTE_COUNT];
+string mapvote_suggestions[MAPVOTE_COUNT];
+float mapvote_suggestion_ptr;
+float mapvote_voters;
+float mapvote_selections[MAPVOTE_COUNT];
+float mapvote_maps_availability[MAPVOTE_COUNT];
+float mapvote_run;
+float mapvote_detail;
+float mapvote_abstain;
+.float mapvote;
+
+entity mapvote_ent;
index 9ee5daff6b5a0491a38f165cc5cc36a289ec46a2..d76ffdee4b413e1169ecc0d5df0f4b36305ec816 100644 (file)
@@ -709,7 +709,7 @@ void readplayerstartcvars()
        {
                // forcibly turn off weaponarena
        }
-       else if (s == "all")
+       else if (s == "all" || s == "1")
        {
                g_weaponarena = 1;
                g_weaponarena_list = "All Weapons";
@@ -905,34 +905,11 @@ float sv_autotaunt;
 float sv_taunt;
 
 string GetGametype(); // g_world.qc
+void mutators_add(); // mutators.qc
 void readlevelcvars(void)
 {
        // load mutators
-       #define CHECK_MUTATOR_ADD(mut_cvar,mut_name,dependence) \
-               { if(cvar(mut_cvar) && dependence) { MUTATOR_ADD(mut_name); } }
-
-       CHECK_MUTATOR_ADD("g_dodging", mutator_dodging, 1);
-       CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, teamplay);
-       CHECK_MUTATOR_ADD("g_physical_items", mutator_physical_items, 1);
-       CHECK_MUTATOR_ADD("g_touchexplode", mutator_touchexplode, 1);
-       CHECK_MUTATOR_ADD("g_minstagib", mutator_minstagib, 1);
-       CHECK_MUTATOR_ADD("g_invincible_projectiles", mutator_invincibleprojectiles, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_new_toys", mutator_new_toys, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_nix", mutator_nix, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_rocket_flying", mutator_rocketflying, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_vampire", mutator_vampire, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_superspectate", mutator_superspec, 1);
-       CHECK_MUTATOR_ADD("g_pinata", mutator_pinata, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_midair", mutator_midair, 1);
-       CHECK_MUTATOR_ADD("g_bloodloss", mutator_bloodloss, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_random_gravity", mutator_random_gravity, 1);
-       CHECK_MUTATOR_ADD("g_multijump", mutator_multijump, 1);
-       CHECK_MUTATOR_ADD("g_melee_only", mutator_melee_only, !cvar("g_minstagib"));
-       CHECK_MUTATOR_ADD("g_nades", mutator_nades, 1);
-       CHECK_MUTATOR_ADD("g_sandbox", sandbox, 1);
-       CHECK_MUTATOR_ADD("g_campcheck", mutator_campcheck, 1);
-
-       #undef CHECK_MUTATOR_ADD
+       mutators_add();
 
        if(cvar("sv_allow_fullbright"))
                serverflags |= SERVERFLAG_ALLOW_FULLBRIGHT;
@@ -953,13 +930,11 @@ void readlevelcvars(void)
     g_bugrigs_speed_pow = cvar("g_bugrigs_speed_pow");
     g_bugrigs_steer = cvar("g_bugrigs_steer");
 
-       g_minstagib = cvar("g_minstagib");
+       g_instagib = cvar("g_instagib");
 
        sv_clones = cvar("sv_clones");
        sv_foginterval = cvar("sv_foginterval");
        g_cloaked = cvar("g_cloaked");
-    if(g_cts)
-        g_cloaked = 1; // always enable cloak in CTS
        g_footsteps = cvar("g_footsteps");
        g_grappling_hook = cvar("g_grappling_hook");
        g_jetpack = cvar("g_jetpack");
@@ -1083,15 +1058,6 @@ float sound_allowed(float dest, entity e)
     return TRUE;
 }
 
-#ifdef COMPAT_XON010_CHANNELS
-void(entity e, float chan, string samp, float vol, float atten) builtin_sound = #8;
-void sound(entity e, float chan, string samp, float vol, float atten)
-{
-    if (!sound_allowed(MSG_BROADCAST, e))
-        return;
-    builtin_sound(e, chan, samp, vol, atten);
-}
-#else
 #undef sound
 void sound(entity e, float chan, string samp, float vol, float atten)
 {
@@ -1099,7 +1065,6 @@ void sound(entity e, float chan, string samp, float vol, float atten)
         return;
     sound7(e, chan, samp, vol, atten, 0, 0);
 }
-#endif
 
 void soundtoat(float dest, entity e, vector o, float chan, string samp, float vol, float atten)
 {
@@ -1304,6 +1269,7 @@ void precache()
 {
     // gamemode related things
     precache_model ("models/misc/chatbubble.spr");
+       precache_model("models/ice/ice.md3");
 
 #ifdef TTURRETS_ENABLED
     if (autocvar_g_turrets)
@@ -1625,6 +1591,44 @@ void Net_LinkEntity(entity e, float docull, float dt, float(entity, float) sendf
     }
 }
 
+
+entity eliminatedPlayers;
+.float(entity) isEliminated;
+float EliminatedPlayers_SendEntity(entity to, float sendflags)
+{
+       float i, f, b;
+       entity e;
+       WriteByte(MSG_ENTITY, ENT_CLIENT_ELIMINATEDPLAYERS);
+       WriteByte(MSG_ENTITY, sendflags);
+
+       if(sendflags & 1)
+       {
+               for(i = 1; i <= maxclients; i += 8)
+               {
+                       for(f = 0, e = edict_num(i), b = 1; b < 256; b *= 2, e = nextent(e))
+                       {
+                               if(eliminatedPlayers.isEliminated(e))
+                                       f |= b;
+                       }
+                       WriteByte(MSG_ENTITY, f);
+               }
+       }
+
+       return TRUE;
+}
+
+void EliminatedPlayers_Init(float(entity) isEliminated_func)
+{
+       if(eliminatedPlayers)
+       {
+               backtrace("Can't spawn eliminatedPlayers again!");
+               return;
+       }
+       Net_LinkEntity(eliminatedPlayers = spawn(), FALSE, 0, EliminatedPlayers_SendEntity);
+       eliminatedPlayers.isEliminated = isEliminated_func;
+}
+
+
 void adaptor_think2touch()
 {
     entity o;
@@ -1827,82 +1831,6 @@ string uid2name(string myuid) {
        return s;
 }
 
-float race_readTime(string map, float pos)
-{
-       string rr;
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
-
-       return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos))));
-}
-
-string race_readUID(string map, float pos)
-{
-       string rr;
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
-
-       return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)));
-}
-
-float race_readPos(string map, float t) {
-       float i;
-       for (i = 1; i <= RANKINGS_CNT; ++i)
-               if (race_readTime(map, i) == 0 || race_readTime(map, i) > t)
-                       return i;
-
-       return 0; // pos is zero if unranked
-}
-
-void race_writeTime(string map, float t, string myuid)
-{
-       string rr;
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
-
-       float newpos;
-       newpos = race_readPos(map, t);
-
-       float i, prevpos = 0;
-       for(i = 1; i <= RANKINGS_CNT; ++i)
-       {
-               if(race_readUID(map, i) == myuid)
-                       prevpos = i;
-       }
-       if (prevpos) { // player improved his existing record, only have to iterate on ranks between new and old recs
-               for (i = prevpos; i > newpos; --i) {
-                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
-                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
-               }
-       } else { // player has no ranked record yet
-               for (i = RANKINGS_CNT; i > newpos; --i) {
-                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
-                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
-               }
-       }
-
-       // store new time itself
-       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(newpos)), ftos(t));
-       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(newpos)), myuid);
-}
-
-string race_readName(string map, float pos)
-{
-       string rr;
-       if(g_cts)
-               rr = CTS_RECORD;
-       else
-               rr = RACE_RECORD;
-
-       return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
-}
-
 float MoveToRandomMapLocation(entity e, float goodcontents, float badcontents, float badsurfaceflags, float attempts, float maxaboveground, float minviewdistance)
 {
     float m, i;
index d2cec391b90e1a167fd920cfd87a3a8b688b5165..1ba8f2663e730b8796da2e6fb8cd3b1592d61eb0 100644 (file)
@@ -91,7 +91,7 @@ float CallbackChain_Call(entity cb)
        return r; // callbacks return an error status, so 0 is default return value
 }
 
-#define MAX_MUTATORS 8
+#define MAX_MUTATORS 15
 string loaded_mutators[MAX_MUTATORS];
 float Mutator_Add(mutatorfunc_t func, string name)
 {
index 78a08c551e540dc77a3dd5c2e8b4d56bebdb3ddd..f4021eb4c0a45b33a2f2741363ea50d36cc68848 100644 (file)
@@ -77,6 +77,7 @@ MUTATOR_HOOKABLE(PlayerJump);
        // called when a player presses the jump key
        // INPUT, OUTPUT:
                float player_multijump;
+               float player_jumpheight;
 
 MUTATOR_HOOKABLE(GiveFragsForKill);
        // called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill
@@ -102,6 +103,11 @@ MUTATOR_HOOKABLE(SpectateCopy);
 MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon);
        // returns 1 if throwing the current weapon shall not be allowed
 
+MUTATOR_HOOKABLE(WeaponRateFactor);
+       // allows changing attack rate
+       // INPUT, OUTPUT:
+               float weapon_rate;
+
 MUTATOR_HOOKABLE(SetStartItems);
        // adjusts {warmup_}start_{items,weapons,ammo_{cells,rockets,nails,shells,fuel}}
 
@@ -222,6 +228,11 @@ MUTATOR_HOOKABLE(PlayerPowerups);
 MUTATOR_HOOKABLE(PlayerRegen);
        // called every player think frame
        // return 1 to disable regen
+       // INPUT, OUTPUT:
+               float regen_mod_max;
+               float regen_mod_regen;
+               float regen_mod_rot;
+               float regen_mod_limit;
 
 MUTATOR_HOOKABLE(PlayerUseKey);
        // called when the use key is pressed
index 8a6315c4236bd1673758253449af1889fe2e35e8..e3c07f59e3807ddab5fa4f75eafb993fe1177650 100644 (file)
@@ -67,12 +67,15 @@ float CA_GetWinnerTeam()
 #define CA_ALIVE_TEAMS_OK() (CA_ALIVE_TEAMS() == ca_teams)
 float CA_CheckWinner()
 {
+       entity e;
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
        {
                Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
                Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
                allowed_to_spawn = FALSE;
                round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
+               FOR_EACH_PLAYER(e)
+                       nades_Clear(e);
                return 1;
        }
 
@@ -95,6 +98,10 @@ float CA_CheckWinner()
 
        allowed_to_spawn = FALSE;
        round_handler_Init(5, autocvar_g_ca_warmup, autocvar_g_ca_round_timelimit);
+
+       FOR_EACH_PLAYER(e)
+               nades_Clear(e);
+
        return 1;
 }
 
@@ -106,42 +113,57 @@ void CA_RoundStart()
                allowed_to_spawn = FALSE;
 }
 
-float prev_total_players;
+float prev_missing_teams_mask;
 float CA_CheckTeams()
 {
        allowed_to_spawn = TRUE;
        CA_count_alive_players();
        if(CA_ALIVE_TEAMS_OK())
        {
-               if(prev_total_players > 0)
+               if(prev_missing_teams_mask > 0)
                        Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
-               prev_total_players = -1;
+               prev_missing_teams_mask = -1;
                return 1;
        }
-       if(prev_total_players != total_players)
+       if(total_players == 0)
+       {
+               if(prev_missing_teams_mask > 0)
+                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+               prev_missing_teams_mask = -1;
+               return 0;
+       }
+       float missing_teams_mask = (!redalive) + (!bluealive) * 2;
+       if(ca_teams >= 3) missing_teams_mask += (!yellowalive) * 4;
+       if(ca_teams >= 4) missing_teams_mask += (!pinkalive) * 8;
+       if(prev_missing_teams_mask != missing_teams_mask)
        {
-               float p1 = 0, p2 = 0, p3 = 0, p4 = 0;
-               if(!redalive) p1 = NUM_TEAM_1;
-               if(!bluealive) p2 = NUM_TEAM_2;
-               if(ca_teams >= 3)
-               if(!yellowalive) p3 = NUM_TEAM_3;
-               if(ca_teams >= 4)
-               if(!pinkalive) p4 = NUM_TEAM_4;
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, p1, p2, p3, p4);
-               prev_total_players = total_players;
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+               prev_missing_teams_mask = missing_teams_mask;
        }
        return 0;
 }
 
+float ca_isEliminated(entity e)
+{
+       if(e.caplayer == 1 && (e.deadflag != DEAD_NO || e.frags == FRAGS_LMS_LOSER))
+               return TRUE;
+       if(e.caplayer == 0.5)
+               return TRUE;
+       return FALSE;
+}
+
 MUTATOR_HOOKFUNCTION(ca_PlayerSpawn)
 {
        self.caplayer = 1;
+       if(!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
        return 1;
 }
 
 MUTATOR_HOOKFUNCTION(ca_PutClientInServer)
 {
        if(!allowed_to_spawn)
+       if(IS_PLAYER(self)) // this is true even when player is trying to join
        {
                self.classname = "observer";
                if(self.jointime != time) //not when connecting
@@ -149,7 +171,7 @@ MUTATOR_HOOKFUNCTION(ca_PutClientInServer)
                {
                        self.caplayer = 0.5;
                        if(IS_REAL_CLIENT(self))
-                               sprint(self, "You will join the game in the next round.\n");
+                               Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_CA_JOIN_LATE);
                }
        }
        return 1;
@@ -160,6 +182,11 @@ MUTATOR_HOOKFUNCTION(ca_reset_map_players)
        FOR_EACH_CLIENT(self)
        {
                self.killcount = 0;
+               if(!self.caplayer && IS_BOT_CLIENT(self))
+               {
+                       self.team = -1;
+                       self.caplayer = 1;
+               }
                if(self.caplayer)
                {
                        self.classname = "player";
@@ -188,10 +215,47 @@ MUTATOR_HOOKFUNCTION(ca_GetTeamCount)
        return 0;
 }
 
+entity ca_LastPlayerForTeam()
+{
+       entity pl, last_pl = world;
+       FOR_EACH_PLAYER(pl)
+       {
+               if(pl.health >= 1)
+               if(pl != self)
+               if(pl.team == self.team)
+               if(!last_pl)
+                       last_pl = pl;
+               else
+                       return world;
+       }
+       return last_pl;
+}
+
+void ca_LastPlayerForTeam_Notify()
+{
+       if(round_handler_IsActive())
+       if(round_handler_IsRoundStarted())
+       {
+               entity pl = ca_LastPlayerForTeam();
+               if(pl)
+                       Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
+       }
+}
+
 MUTATOR_HOOKFUNCTION(ca_PlayerDies)
 {
+       ca_LastPlayerForTeam_Notify();
        if(!allowed_to_spawn)
                self.respawn_flags =  RESPAWN_SILENT;
+       if(!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(ca_ClientDisconnect)
+{
+       if(self.caplayer == 1)
+               ca_LastPlayerForTeam_Notify();
        return 1;
 }
 
@@ -202,10 +266,14 @@ MUTATOR_HOOKFUNCTION(ca_ForbidPlayerScore_Clear)
 
 MUTATOR_HOOKFUNCTION(ca_MakePlayerObserver)
 {
+       if(self.caplayer == 1)
+               ca_LastPlayerForTeam_Notify();
        if(self.killindicator_teamchange == -2)
                self.caplayer = 0;
        if(self.caplayer)
                self.frags = FRAGS_LMS_LOSER;
+       if(!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
        return 1;
 }
 
@@ -292,6 +360,8 @@ void ca_Initialize()
        addstat(STAT_BLUEALIVE, AS_INT, bluealive_stat);
        addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
        addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
+
+       EliminatedPlayers_Init(ca_isEliminated);
 }
 
 MUTATOR_DEFINITION(gamemode_ca)
@@ -304,6 +374,7 @@ MUTATOR_DEFINITION(gamemode_ca)
        MUTATOR_HOOK(reset_map_players, ca_reset_map_players, CBC_ORDER_ANY);
        MUTATOR_HOOK(GetTeamCount, ca_GetTeamCount, CBC_ORDER_EXCLUSIVE);
        MUTATOR_HOOK(PlayerDies, ca_PlayerDies, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ClientDisconnect, ca_ClientDisconnect, CBC_ORDER_ANY);
        MUTATOR_HOOK(ForbidPlayerScore_Clear, ca_ForbidPlayerScore_Clear, CBC_ORDER_ANY);
        MUTATOR_HOOK(ForbidThrowCurrentWeapon, ca_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
        MUTATOR_HOOK(GiveFragsForKill, ca_GiveFragsForKill, CBC_ORDER_FIRST);
index c9c9b4584b14af089b437c5b81f4c26e105dae95..4e051d197298ba1ac9cdb0b6da519a515fd42d3c 100644 (file)
@@ -176,7 +176,7 @@ void ctf_CaptureShield_Touch()
        vector othermid = (other.absmin + other.absmax) * 0.5;
 
        Damage(other, self, self, 0, DEATH_HURTTRIGGER, mymid, normalize(othermid - mymid) * ctf_captureshield_force);
-       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED);
+       if(IS_REAL_CLIENT(other)) { Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_CTF_CAPTURESHIELD_SHIELDED); }
 }
 
 void ctf_CaptureShield_Spawn(entity flag)
@@ -257,8 +257,17 @@ void ctf_Handle_Retrieve(entity flag, entity player)
        flag.owner.flagcarried = flag;
 
        // reset flag
-       setattachment(flag, player, "");
-       setorigin(flag, FLAG_CARRY_OFFSET);
+       if(player.vehicle)
+       {
+               setattachment(flag, player.vehicle, "");
+               setorigin(flag, VEHICLE_FLAG_OFFSET);
+               flag.scale = VEHICLE_FLAG_SCALE;
+       }
+       else
+       {
+               setattachment(flag, player, "");
+               setorigin(flag, FLAG_CARRY_OFFSET);
+       }
        flag.movetype = MOVETYPE_NONE;
        flag.takedamage = DAMAGE_NO;
        flag.solid = SOLID_NOT;
@@ -388,6 +397,8 @@ void ctf_Handle_Capture(entity flag, entity toucher, float capturetype)
 
        if (!player) { return; } // without someone to give the reward to, we can't possibly cap
 
+       nades_GiveBonus(player, autocvar_g_nades_bonus_score_high );
+
        // messages and sounds
        Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_2(enemy_flag, CENTER_CTF_CAPTURE_));
        ctf_CaptureRecord(enemy_flag, player);
@@ -448,6 +459,8 @@ void ctf_Handle_Return(entity flag, entity player)
        {
                PlayerTeamScore_AddScore(player, autocvar_g_ctf_score_return); // reward for return
                PlayerScore_Add(player, SP_CTF_RETURNS, 1); // add to count of returns
+
+               nades_GiveBonus(player,autocvar_g_nades_bonus_score_medium);
        }
 
        TeamScore_AddToTeam(flag.team, ST_SCORE, -autocvar_g_ctf_score_penalty_returned); // punish the team who was last carrying it
@@ -471,8 +484,17 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
        // attach the flag to the player
        flag.owner = player;
        player.flagcarried = flag;
-       setattachment(flag, player, "");
-       setorigin(flag, FLAG_CARRY_OFFSET);
+       if(player.vehicle)
+       {
+               setattachment(flag, player.vehicle, "");
+               setorigin(flag, VEHICLE_FLAG_OFFSET);
+               flag.scale = VEHICLE_FLAG_SCALE;
+       }
+       else
+       {
+               setattachment(flag, player, "");
+               setorigin(flag, FLAG_CARRY_OFFSET);
+       }
 
        // flag setup
        flag.movetype = MOVETYPE_NONE;
@@ -500,6 +522,7 @@ void ctf_Handle_Pickup(entity flag, entity player, float pickuptype)
 
        // scoring
        PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
+       nades_GiveBonus(player, autocvar_g_nades_bonus_score_minor);
        switch(pickuptype)
        {
                case PICKUP_BASE:
@@ -752,6 +775,7 @@ void ctf_FlagThink()
 
                        if((self.pass_target == world)
                                || (self.pass_target.deadflag != DEAD_NO)
+                               || (self.pass_target.flagcarried)
                                || (vlen(self.origin - targ_origin) > autocvar_g_ctf_pass_radius)
                                || ((trace_fraction < 1) && (trace_ent != self.pass_target))
                                || (time > self.ctf_droptime + autocvar_g_ctf_pass_timelimit))
@@ -778,6 +802,7 @@ void ctf_FlagThink()
 void ctf_FlagTouch()
 {
        if(gameover) { return; }
+       if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
 
        entity toucher = other;
        float is_not_monster = (!(toucher.flags & FL_MONSTER));
@@ -791,7 +816,8 @@ void ctf_FlagTouch()
        }
 
        // special touch behaviors
-       if(toucher.vehicle_flags & VHF_ISVEHICLE)
+       if(toucher.frozen) { return; }
+       else if(toucher.vehicle_flags & VHF_ISVEHICLE)
        {
                if(autocvar_g_ctf_allow_vehicle_touch && toucher.owner)
                        toucher = toucher.owner; // the player is actually the vehicle owner, not other
@@ -878,6 +904,9 @@ void ctf_RespawnFlag(entity flag)
                        ctf_FakeTimeLimit(flag.owner, -1);
        }
 
+       if((flag.owner) && (flag.owner.vehicle))
+               flag.scale = FLAG_SCALE;
+
        if((flag.ctf_status == FLAG_DROPPED) && (flag.wps_flagdropped))
                { WaypointSprite_Kill(flag.wps_flagdropped); }
 
@@ -901,6 +930,8 @@ void ctf_RespawnFlag(entity flag)
        flag.ctf_dropper = world;
        flag.ctf_pickuptime = 0;
        flag.ctf_droptime = 0;
+
+       ctf_CheckStalemate();
 }
 
 void ctf_Reset()
@@ -1258,7 +1289,7 @@ void havocbot_ctf_reset_role(entity bot)
        // if there is only me on the team switch to offense
        c = 0;
        FOR_EACH_PLAYER(head)
-       if(head.team==bot.team)
+       if(SAME_TEAM(head, bot))
                ++c;
 
        if(c==1)
@@ -1624,7 +1655,7 @@ void havocbot_role_ctf_defense()
                }
 
                if(closestplayer)
-               if(closestplayer.team!=self.team)
+               if(DIFF_TEAM(closestplayer, self))
                if(vlen(org - self.origin)>1000)
                if(checkpvs(self.origin,closestplayer)||random()<0.5)
                        havocbot_goalrating_ctf_ourbase(30000);
diff --git a/qcsrc/server/mutators/gamemode_cts.qc b/qcsrc/server/mutators/gamemode_cts.qc
new file mode 100644 (file)
index 0000000..9c674d4
--- /dev/null
@@ -0,0 +1,326 @@
+// legacy bot roles
+.float race_checkpoint;
+void havocbot_role_cts()
+{
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       entity e;
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
+               {
+                       if(e.cnt == self.race_checkpoint)
+                       {
+                               navigation_routerating(e, 1000000, 5000);
+                       }
+                       else if(self.race_checkpoint == -1)
+                       {
+                               navigation_routerating(e, 1000000, 5000);
+                       }
+               }
+
+               navigation_goalrating_end();
+       }
+}
+
+void cts_ScoreRules()
+{
+       ScoreRules_basics(0, 0, 0, FALSE);
+       if(g_race_qualifying)
+       {
+               ScoreInfo_SetLabel_PlayerScore(SP_CTS_FASTEST, "fastest",   SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+       }
+       else
+       {
+               ScoreInfo_SetLabel_PlayerScore(SP_CTS_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
+               ScoreInfo_SetLabel_PlayerScore(SP_CTS_TIME,    "time",      SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+               ScoreInfo_SetLabel_PlayerScore(SP_CTS_FASTEST, "fastest",   SFL_LOWER_IS_BETTER | SFL_TIME);
+       }
+       ScoreRules_basics_end();
+}
+
+void cts_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
+{
+       if(autocvar_sv_eventlog)
+               GameLogEcho(strcat(":cts:", mode, ":", ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerPhysics)
+{
+       // force kbd movement for fairness
+       float wishspeed;
+       vector wishvel;
+
+       // if record times matter
+       // ensure nothing EVIL is being done (i.e. div0_evade)
+       // this hinders joystick users though
+       // but it still gives SOME analog control
+       wishvel_x = fabs(self.movement_x);
+       wishvel_y = fabs(self.movement_y);
+       if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y)
+       {
+               wishvel_z = 0;
+               wishspeed = vlen(wishvel);
+               if(wishvel_x >= 2 * wishvel_y)
+               {
+                       // pure X motion
+                       if(self.movement_x > 0)
+                               self.movement_x = wishspeed;
+                       else
+                               self.movement_x = -wishspeed;
+                       self.movement_y = 0;
+               }
+               else if(wishvel_y >= 2 * wishvel_x)
+               {
+                       // pure Y motion
+                       self.movement_x = 0;
+                       if(self.movement_y > 0)
+                               self.movement_y = wishspeed;
+                       else
+                               self.movement_y = -wishspeed;
+               }
+               else
+               {
+                       // diagonal
+                       if(self.movement_x > 0)
+                               self.movement_x = M_SQRT1_2 * wishspeed;
+                       else
+                               self.movement_x = -M_SQRT1_2 * wishspeed;
+                       if(self.movement_y > 0)
+                               self.movement_y = M_SQRT1_2 * wishspeed;
+                       else
+                               self.movement_y = -M_SQRT1_2 * wishspeed;
+               }
+       }
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ResetMap)
+{
+       float s;
+
+       Score_NicePrint(world);
+
+       race_ClearRecords();
+       PlayerScore_Sort(race_place, 0, 1, 0);
+
+       entity e;
+       FOR_EACH_CLIENT(e)
+       {
+               if(e.race_place)
+               {
+                       s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
+                       if(!s)
+                               e.race_place = 0;
+               }
+               cts_EventLog(ftos(e.race_place), e);
+       }
+
+       if(g_race_qualifying == 2)
+       {
+               g_race_qualifying = 0;
+               independent_players = 0;
+               cvar_set("fraglimit", ftos(race_fraglimit));
+               cvar_set("leadlimit", ftos(race_leadlimit));
+               cvar_set("timelimit", ftos(race_timelimit));
+               cts_ScoreRules();
+       }
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerPreThink)
+{
+       if(IS_SPEC(self) || IS_OBSERVER(self))
+       if(g_race_qualifying)
+       if(msg_entity.enemy.race_laptime)
+               race_SendNextCheckpoint(msg_entity.enemy, 1);
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ClientConnect)
+{
+       race_PreparePlayer();
+       self.race_checkpoint = -1;
+       
+       if(IS_REAL_CLIENT(self))
+       {
+               string rr = CTS_RECORD;
+
+               msg_entity = self;
+               race_send_recordtime(MSG_ONE);
+               race_send_speedaward(MSG_ONE);
+
+               speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
+               speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
+               race_send_speedaward_alltimebest(MSG_ONE);
+
+               float i;
+               for (i = 1; i <= RANKINGS_CNT; ++i)
+               {
+                       race_SendRankings(i, 0, 0, MSG_ONE);
+               }
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_MakePlayerObserver)
+{
+       if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+               self.frags = FRAGS_LMS_LOSER;
+       else
+               self.frags = FRAGS_SPECTATOR;
+
+       race_PreparePlayer();
+       self.race_checkpoint = -1;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerSpawn)
+{
+       if(spawn_spot.target == "")
+               // Emergency: this wasn't a real spawnpoint. Can this ever happen?
+               race_PreparePlayer();
+
+       // if we need to respawn, do it right
+       self.race_respawn_checkpoint = self.race_checkpoint;
+       self.race_respawn_spotref = spawn_spot;
+
+       self.race_place = 0;
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PutClientInServer)
+{
+       if(IS_PLAYER(self))
+       if(!gameover)
+       {
+               if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
+                       race_PreparePlayer();
+               else // respawn
+                       race_RetractPlayer();
+
+               race_AbandonRaceCheck(self);
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerDies)
+{
+       self.respawn_flags |= RESPAWN_FORCE;
+       race_AbandonRaceCheck(self);
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_BotRoles)
+{
+       self.havocbot_role = havocbot_role_cts;
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerPostThink)
+{
+       if(self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
+       {
+               if (!self.stored_netname)
+                       self.stored_netname = strzone(uid2name(self.crypto_idfp));
+               if(self.stored_netname != self.netname)
+               {
+                       db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
+                       strunzone(self.stored_netname);
+                       self.stored_netname = strzone(self.netname);
+               }
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ForbidThrowing)
+{
+       // no weapon dropping in CTS
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_FilterItem)
+{
+       if(self.classname == "droppedweapon")
+               return TRUE;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_PlayerDamage)
+{
+       if(frag_target == frag_attacker || frag_deathtype == DEATH_FALL)
+       if(!autocvar_g_cts_selfdamage)
+               frag_damage = 0;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(cts_ForbidClearPlayerScore)
+{
+       return TRUE; // in CTS, you don't lose score by observing
+}
+
+MUTATOR_HOOKFUNCTION(cts_SetMods)
+{
+       g_cloaked = 1; // always enable cloak in CTS
+
+       return FALSE;
+}
+
+void cts_Initialize()
+{
+       cts_ScoreRules();
+}
+
+MUTATOR_DEFINITION(gamemode_cts)
+{
+       MUTATOR_HOOK(PlayerPhysics, cts_PlayerPhysics, CBC_ORDER_ANY);
+       MUTATOR_HOOK(reset_map_global, cts_ResetMap, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPreThink, cts_PlayerPreThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ClientConnect, cts_ClientConnect, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MakePlayerObserver, cts_MakePlayerObserver, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerSpawn, cts_PlayerSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PutClientInServer, cts_PutClientInServer, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDies, cts_PlayerDies, CBC_ORDER_ANY);
+       MUTATOR_HOOK(HavocBot_ChooseRole, cts_BotRoles, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GetPressedKeys, cts_PlayerPostThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ForbidThrowCurrentWeapon, cts_ForbidThrowing, CBC_ORDER_ANY);
+       MUTATOR_HOOK(FilterItem, cts_FilterItem, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDamage_Calculate, cts_PlayerDamage, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ForbidPlayerScore_Clear, cts_ForbidClearPlayerScore, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetModname, cts_SetMods, CBC_ORDER_ANY);
+
+       MUTATOR_ONADD
+       {
+               if(time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               cts_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back cts_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/qcsrc/server/mutators/gamemode_cts.qh b/qcsrc/server/mutators/gamemode_cts.qh
new file mode 100644 (file)
index 0000000..f02caf0
--- /dev/null
@@ -0,0 +1,7 @@
+float g_race_qualifying;
+
+// scores
+#define ST_CTS_LAPS 1
+#define SP_CTS_LAPS 4
+#define SP_CTS_TIME 5
+#define SP_CTS_FASTEST 6
index a6d737205c493a6f83d0e0ffdc85f1b89063a686..2569a49d3188c49c57dca27cb5c1c3f8e5559aec 100644 (file)
@@ -9,9 +9,9 @@ void set_dom_state(entity e)
        e.dom_total_pps = total_pps;
        e.dom_pps_red = pps_red;
        e.dom_pps_blue = pps_blue;
-       if(c3 >= 0)
+       if(domination_teams >= 3)
                e.dom_pps_yellow = pps_yellow;
-       if(c4 >= 0)
+       if(domination_teams >= 4)
                e.dom_pps_pink = pps_pink;
 }
 
@@ -45,11 +45,10 @@ void dompoint_captured ()
        else
                wait_time = self.wait;
 
-       bprint("^3", head.netname, "^3", self.message);
-       if (points != 1)
-               bprint(" ^7(", ftos(points), " points every ", ftos(wait_time), " seconds)\n");
+       if(domination_roundbased)
+               bprint(sprintf("^3%s^3%s\n", head.netname, self.message));
        else
-               bprint(" ^7(", ftos(points), " point every ", ftos(wait_time), " seconds)\n");
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_DOMINATION_CAPTURE_TIME, head.netname, self.message, points, wait_time);
 
        if(self.enemy.playerid == self.enemy_playerid)
                PlayerScore_Add(self.enemy, SP_DOM_TAKES, 1);
@@ -110,6 +109,7 @@ void dompoint_captured ()
                                break;
                        case NUM_TEAM_4:
                                pps_pink += points/wait_time;
+                               break;
                }
                total_pps += points/wait_time;
        }
@@ -159,6 +159,7 @@ void dompointthink()
 
        // give credit to the team
        // NOTE: this defaults to 0
+       if (!domination_roundbased)
        if (self.goalentity.netname != "")
        {
                if(autocvar_g_domination_point_amt)
@@ -187,6 +188,9 @@ void dompointtouch()
        if (other.health < 1)
                return;
 
+       if(round_handler_IsActive() && !round_handler_IsRoundStarted())
+               return;
+
        if(time < self.captime + 0.3)
                return;
 
@@ -286,6 +290,94 @@ void dom_controlpoint_setup()
        WaypointSprite_SpawnFixed("dom-neut", self.origin + '0 0 32', self, sprite, RADARICON_DOMPOINT, '0 1 1');
 }
 
+float total_controlpoints, redowned, blueowned, yellowowned, pinkowned;
+void Domination_count_controlpoints()
+{
+       entity e;
+       total_controlpoints = redowned = blueowned = yellowowned = pinkowned = 0;
+       for(e = world; (e = find(e, classname, "dom_controlpoint")) != world; )
+       {
+               ++total_controlpoints;
+               redowned += (e.goalentity.team == NUM_TEAM_1);
+               blueowned += (e.goalentity.team == NUM_TEAM_2);
+               yellowowned += (e.goalentity.team == NUM_TEAM_3);
+               pinkowned += (e.goalentity.team == NUM_TEAM_4);
+       }
+}
+
+float Domination_GetWinnerTeam()
+{
+       float winner_team = 0;
+       if(redowned == total_controlpoints)
+               winner_team = NUM_TEAM_1;
+       if(blueowned == total_controlpoints)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_2;
+       }
+       if(yellowowned == total_controlpoints)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_3;
+       }
+       if(pinkowned == total_controlpoints)
+       {
+               if(winner_team) return 0;
+               winner_team = NUM_TEAM_4;
+       }
+       if(winner_team)
+               return winner_team;
+       return -1; // no control points left?
+}
+
+#define DOM_OWNED_CONTROLPOINTS() ((redowned > 0) + (blueowned > 0) + (yellowowned > 0) + (pinkowned > 0))
+#define DOM_OWNED_CONTROLPOINTS_OK() (DOM_OWNED_CONTROLPOINTS() < total_controlpoints)
+float Domination_CheckWinner()
+{
+       if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_OVER);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_OVER);
+               round_handler_Init(5, autocvar_g_domination_warmup, autocvar_g_domination_round_timelimit);
+               return 1;
+       }
+
+       Domination_count_controlpoints();
+
+       float winner_team = Domination_GetWinnerTeam();
+
+       if(winner_team == -1)
+               return 0;
+
+       if(winner_team > 0)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, APP_TEAM_NUM_4(winner_team, CENTER_ROUND_TEAM_WIN_));
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(winner_team, INFO_ROUND_TEAM_WIN_));
+               TeamScore_AddToTeam(winner_team, ST_DOM_CAPS, +1);
+       }
+       else if(winner_team == -1)
+       {
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_ROUND_TIED);
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ROUND_TIED);
+       }
+
+       round_handler_Init(5, autocvar_g_domination_warmup, autocvar_g_domination_round_timelimit);
+
+       return 1;
+}
+
+float Domination_CheckPlayers()
+{
+       return 1;
+}
+
+void Domination_RoundStart()
+{
+       entity e;
+       FOR_EACH_PLAYER(e)
+               e.player_blocked = 0;
+}
+
 //go to best items, or control points you don't own
 void havocbot_role_dom()
 {
@@ -304,6 +396,35 @@ void havocbot_role_dom()
        }
 }
 
+MUTATOR_HOOKFUNCTION(dom_GetTeamCount)
+{
+       ret_float = domination_teams;
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(dom_ResetMap)
+{
+       total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
+       FOR_EACH_PLAYER(self)
+       {
+               PutClientInServer();
+               self.player_blocked = 1;
+               if(IS_REAL_CLIENT(self))
+                       set_dom_state(self);
+       }
+       return 1;
+}
+
+MUTATOR_HOOKFUNCTION(dom_PlayerSpawn)
+{
+       if(domination_roundbased)
+       if(!round_handler_IsRoundStarted())
+               self.player_blocked = 1;
+       else
+               self.player_blocked = 0;
+       return FALSE;
+}
+
 MUTATOR_HOOKFUNCTION(dom_ClientConnect)
 {
        set_dom_state(self);
@@ -388,20 +509,29 @@ void spawnfunc_dom_team()
 }
 
 // scoreboard setup
-void ScoreRules_dom()
+void ScoreRules_dom(float teams)
 {
-       float sp_domticks, sp_score;
-       sp_score = sp_domticks = 0;
-       if(autocvar_g_domination_disable_frags)
-               sp_domticks = SFL_SORT_PRIO_PRIMARY;
+       if(domination_roundbased)
+       {
+               ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, 0, TRUE);
+               ScoreInfo_SetLabel_TeamScore  (ST_DOM_CAPS, "caps", SFL_SORT_PRIO_PRIMARY);
+               ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES, "takes", 0);
+               ScoreRules_basics_end();
+       }
        else
-               sp_score = SFL_SORT_PRIO_PRIMARY;
-       CheckAllowedTeams(world);
-       ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), sp_score, sp_score, TRUE);
-       ScoreInfo_SetLabel_TeamScore  (ST_DOM_TICKS,    "ticks",     sp_domticks);
-       ScoreInfo_SetLabel_PlayerScore(SP_DOM_TICKS,    "ticks",     sp_domticks);
-       ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES,    "takes",     0);
-       ScoreRules_basics_end();
+       {
+               float sp_domticks, sp_score;
+               sp_score = sp_domticks = 0;
+               if(autocvar_g_domination_disable_frags)
+                       sp_domticks = SFL_SORT_PRIO_PRIMARY;
+               else
+                       sp_score = SFL_SORT_PRIO_PRIMARY;
+               ScoreRules_basics(teams, sp_score, sp_score, TRUE);
+               ScoreInfo_SetLabel_TeamScore  (ST_DOM_TICKS,    "ticks",     sp_domticks);
+               ScoreInfo_SetLabel_PlayerScore(SP_DOM_TICKS,    "ticks",     sp_domticks);
+               ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES,    "takes",     0);
+               ScoreRules_basics_end();
+       }
 }
 
 // code from here on is just to support maps that don't have control point and team entities
@@ -446,15 +576,13 @@ void dom_spawnpoint(vector org)
 }
 
 // spawn some default teams if the map is not set up for domination
-void dom_spawnteams()
+void dom_spawnteams(float teams)
 {
-       float numteams = ((autocvar_g_domination_teams_override < 2) ? autocvar_g_domination_default_teams : autocvar_g_domination_teams_override);
-
        dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
        dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
-       if(numteams > 2)
+       if(teams >= 3)
                dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
-       if(numteams > 3)
+       if(teams >= 4)
                dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
        dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
 }
@@ -465,10 +593,28 @@ void dom_DelayedInit() // Do this check with a delay so we can wait for teams to
        if(find(world, classname, "dom_team") == world || autocvar_g_domination_teams_override >= 2)
        {
                print("No ""dom_team"" entities found on this map, creating them anyway.\n");
-               dom_spawnteams();
+               domination_teams = bound(2, ((autocvar_g_domination_teams_override < 2) ? autocvar_g_domination_default_teams : autocvar_g_domination_teams_override), 4);
+               dom_spawnteams(domination_teams);
        }
+       
+       CheckAllowedTeams(world);
+       domination_teams = ((c4>=0) ? 4 : (c3>=0) ? 3 : 2);
+
+       addstat(STAT_DOM_TOTAL_PPS, AS_FLOAT, dom_total_pps);
+       addstat(STAT_DOM_PPS_RED, AS_FLOAT, dom_pps_red);
+       addstat(STAT_DOM_PPS_BLUE, AS_FLOAT, dom_pps_blue);
+       if(domination_teams >= 3) addstat(STAT_DOM_PPS_YELLOW, AS_FLOAT, dom_pps_yellow);
+       if(domination_teams >= 4) addstat(STAT_DOM_PPS_PINK, AS_FLOAT, dom_pps_pink);
+
+       domination_roundbased = autocvar_g_domination_roundbased;
+
+       ScoreRules_dom(domination_teams);
 
-       ScoreRules_dom();
+       if(domination_roundbased)
+       {
+               round_handler_Spawn(Domination_CheckPlayers, Domination_CheckWinner, Domination_RoundStart);
+               round_handler_Init(5, autocvar_g_domination_warmup, autocvar_g_domination_round_timelimit);
+       }
 }
 
 void dom_Initialize()
@@ -480,18 +626,15 @@ void dom_Initialize()
        precache_model("models/domination/dom_unclaimed.md3");
        precache_sound("domination/claim.wav");
 
-       addstat(STAT_DOM_TOTAL_PPS, AS_FLOAT, dom_total_pps);
-       addstat(STAT_DOM_PPS_RED, AS_FLOAT, dom_pps_red);
-       addstat(STAT_DOM_PPS_BLUE, AS_FLOAT, dom_pps_blue);
-       if(c3 >= 0) addstat(STAT_DOM_PPS_YELLOW, AS_FLOAT, dom_pps_yellow);
-       if(c4 >= 0) addstat(STAT_DOM_PPS_PINK, AS_FLOAT, dom_pps_pink);
-
        InitializeEntity(world, dom_DelayedInit, INITPRIO_GAMETYPE);
 }
 
 
 MUTATOR_DEFINITION(gamemode_domination)
 {
+       MUTATOR_HOOK(GetTeamCount, dom_GetTeamCount, CBC_ORDER_ANY);
+       MUTATOR_HOOK(reset_map_players, dom_ResetMap, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerSpawn, dom_PlayerSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(ClientConnect, dom_ClientConnect, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRole, dom_BotRoles, CBC_ORDER_ANY);
 
index a7d18530ca86c1d32d58aedb0bb24d20e176eb45..6b5b334e4906ef969597e3600070d172e8ecb49e 100644 (file)
@@ -4,6 +4,8 @@
 #define ST_DOM_TICKS 1
 #define SP_DOM_TICKS 4
 #define SP_DOM_TAKES 5
+#define ST_DOM_CAPS 1
+#define SP_DOM_CAPS 4
 
 // pps: points per second
 .float dom_total_pps;
@@ -20,4 +22,8 @@ float pps_pink;
 // capture declarations
 .float enemy_playerid;
 .entity sprite;
-.float captime;
\ No newline at end of file
+.float captime;
+
+// misc globals
+float domination_roundbased;
+float domination_teams;
index 26e19910ad0f3f571a19f779bec902872b9de8e7..9034887d82712e61b1144d312a424ea5812694b9 100644 (file)
@@ -1,7 +1,6 @@
 .float freezetag_frozen_time;
 .float freezetag_frozen_timeout;
 .float freezetag_revive_progress;
-.entity freezetag_ice;
 #define ICE_MAX_ALPHA 1
 #define ICE_MIN_ALPHA 0.1
 float freezetag_teams;
@@ -10,59 +9,53 @@ void freezetag_count_alive_players()
 {
        entity e;
        total_players = redalive = bluealive = yellowalive = pinkalive = 0;
-       FOR_EACH_PLAYER(e) {
-               if(e.team == NUM_TEAM_1 && e.health >= 1)
-               {
-                       ++total_players;
-                       if (!e.freezetag_frozen) ++redalive;
-               }
-               else if(e.team == NUM_TEAM_2 && e.health >= 1)
-               {
-                       ++total_players;
-                       if (!e.freezetag_frozen) ++bluealive;
-               }
-               else if(e.team == NUM_TEAM_3 && e.health >= 1)
-               {
-                       ++total_players;
-                       if (!e.freezetag_frozen) ++yellowalive;
-               }
-               else if(e.team == NUM_TEAM_4 && e.health >= 1)
+       FOR_EACH_PLAYER(e)
+       {
+               switch(e.team)
                {
-                       ++total_players;
-                       if (!e.freezetag_frozen) ++pinkalive;
+                       case NUM_TEAM_1: ++total_players; if(e.health >= 1 && e.frozen != 1) ++redalive; break;
+                       case NUM_TEAM_2: ++total_players; if(e.health >= 1 && e.frozen != 1) ++bluealive; break;
+                       case NUM_TEAM_3: ++total_players; if(e.health >= 1 && e.frozen != 1) ++yellowalive; break;
+                       case NUM_TEAM_4: ++total_players; if(e.health >= 1 && e.frozen != 1) ++pinkalive; break;
                }
        }
-       FOR_EACH_REALCLIENT(e) {
+       FOR_EACH_REALCLIENT(e)
+       {
                e.redalive_stat = redalive;
                e.bluealive_stat = bluealive;
                e.yellowalive_stat = yellowalive;
                e.pinkalive_stat = pinkalive;
        }
+
+       eliminatedPlayers.SendFlags |= 1;
 }
 #define FREEZETAG_ALIVE_TEAMS() ((redalive > 0) + (bluealive > 0) + (yellowalive > 0) + (pinkalive > 0))
 #define FREEZETAG_ALIVE_TEAMS_OK() (FREEZETAG_ALIVE_TEAMS() == freezetag_teams)
 
-float prev_total_players;
+float prev_missing_teams_mask;
 float freezetag_CheckTeams()
 {
        if(FREEZETAG_ALIVE_TEAMS_OK())
        {
-               if(prev_total_players > 0)
+               if(prev_missing_teams_mask > 0)
                        Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
-               prev_total_players = -1;
+               prev_missing_teams_mask = -1;
                return 1;
        }
-       if(prev_total_players != total_players)
+       if(total_players == 0)
+       {
+               if(prev_missing_teams_mask > 0)
+                       Kill_Notification(NOTIF_ALL, world, MSG_CENTER_CPID, CPID_MISSING_TEAMS);
+               prev_missing_teams_mask = -1;
+               return 0;
+       }
+       float missing_teams_mask = (!redalive) + (!bluealive) * 2;
+       if(freezetag_teams >= 3) missing_teams_mask += (!yellowalive) * 4;
+       if(freezetag_teams >= 4) missing_teams_mask += (!pinkalive) * 8;
+       if(prev_missing_teams_mask != missing_teams_mask)
        {
-               float p1 = 0, p2 = 0, p3 = 0, p4 = 0;
-               if(!redalive) p1 = NUM_TEAM_1;
-               if(!bluealive) p2 = NUM_TEAM_2;
-               if(freezetag_teams >= 3)
-               if(!yellowalive) p3 = NUM_TEAM_3;
-               if(freezetag_teams >= 4)
-               if(!pinkalive) p4 = NUM_TEAM_4;
-               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, p1, p2, p3, p4);
-               prev_total_players = total_players;
+               Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_MISSING_TEAMS, missing_teams_mask);
+               prev_missing_teams_mask = missing_teams_mask;
        }
        return 0;
 }
@@ -102,7 +95,7 @@ float freezetag_CheckWinner()
                FOR_EACH_PLAYER(e)
                {
                        e.freezetag_frozen_timeout = 0;
-                       e.freezetag_revive_progress = 0;
+                       nades_Clear(e);
                }
                round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
                return 1;
@@ -128,19 +121,38 @@ float freezetag_CheckWinner()
        FOR_EACH_PLAYER(e)
        {
                e.freezetag_frozen_timeout = 0;
-               e.freezetag_revive_progress = 0;
+               nades_Clear(e);
        }
        round_handler_Init(5, autocvar_g_freezetag_warmup, autocvar_g_freezetag_round_timelimit);
        return 1;
 }
 
-// this is needed to allow the player to turn his view around (fixangle can't
-// be used to freeze his view, as that also changes the angles), while not
-// turning that ice object with the player
-void freezetag_Ice_Think()
+entity freezetag_LastPlayerForTeam()
 {
-       setorigin(self, self.owner.origin - '0 0 16');
-       self.nextthink = time;
+       entity pl, last_pl = world;
+       FOR_EACH_PLAYER(pl)
+       {
+               if(pl.health >= 1)
+               if(!pl.frozen)
+               if(pl != self)
+               if(pl.team == self.team)
+               if(!last_pl)
+                       last_pl = pl;
+               else
+                       return world;
+       }
+       return last_pl;
+}
+
+void freezetag_LastPlayerForTeam_Notify()
+{
+       if(round_handler_IsActive())
+       if(round_handler_IsRoundStarted())
+       {
+               entity pl = freezetag_LastPlayerForTeam();
+               if(pl)
+                       Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_ALONE);
+       }
 }
 
 void freezetag_Add_Score(entity attacker)
@@ -163,51 +175,32 @@ void freezetag_Add_Score(entity attacker)
 
 void freezetag_Freeze(entity attacker)
 {
-       if(self.freezetag_frozen)
+       if(self.frozen)
                return;
-       self.freezetag_frozen = 1;
-       self.freezetag_frozen_time = time;
-       self.freezetag_revive_progress = 0;
-       self.health = 1;
+
        if(autocvar_g_freezetag_frozen_maxtime > 0)
                self.freezetag_frozen_timeout = time + autocvar_g_freezetag_frozen_maxtime;
 
-       freezetag_count_alive_players();
-
-       entity ice;
-       ice = spawn();
-       ice.owner = self;
-       ice.classname = "freezetag_ice";
-       ice.think = freezetag_Ice_Think;
-       ice.nextthink = time;
-       ice.frame = floor(random() * 21); // ice model has 20 different looking frames
-       ice.alpha = ICE_MAX_ALPHA;
-       ice.colormod = Team_ColorRGB(self.team);
-       ice.glowmod = ice.colormod;
-       setmodel(ice, "models/ice/ice.md3");
-
-       self.freezetag_ice = ice;
-
-       RemoveGrapplingHook(self);
+       Freeze(self, 0, 1, TRUE);
 
-       // add waypoint
-       WaypointSprite_Spawn("freezetag_frozen", 0, 0, self, '0 0 64', world, self.team, self, waypointsprite_attached, TRUE, RADARICON_WAYPOINT, '0.25 0.90 1');
+       freezetag_count_alive_players();
 
        freezetag_Add_Score(attacker);
 }
 
 void freezetag_Unfreeze(entity attacker)
 {
-       self.freezetag_frozen = 0;
        self.freezetag_frozen_time = 0;
        self.freezetag_frozen_timeout = 0;
-       self.freezetag_revive_progress = 0;
 
-       remove(self.freezetag_ice);
-       self.freezetag_ice = world;
+       Unfreeze(self);
+}
 
-       if(self.waypointsprite_attached)
-               WaypointSprite_Kill(self.waypointsprite_attached);
+float freezetag_isEliminated(entity e)
+{
+       if(e.frozen == 1 || e.deadflag != DEAD_NO)
+               return TRUE;
+       return FALSE;
 }
 
 
@@ -227,7 +220,7 @@ void havocbot_goalrating_freeplayers(float ratingscale, vector org, float sradiu
        {
                if ((head != self) && (head.team == self.team))
                {
-                       if (head.freezetag_frozen)
+                       if (head.frozen == 1)
                        {
                                distance = vlen(head.origin - org);
                                if (distance > sradius)
@@ -259,12 +252,12 @@ void havocbot_role_ft_offense()
        unfrozen = 0;
        FOR_EACH_PLAYER(head)
        {
-               if ((head.team == self.team) && (!head.freezetag_frozen))
+               if ((head.team == self.team) && (head.frozen != 1))
                        unfrozen++;
        }
 
        // If only one left on team or if role has timed out then start trying to free players.
-       if (((unfrozen == 0) && (!self.freezetag_frozen)) || (time > self.havocbot_role_timeout))
+       if (((unfrozen == 0) && (!self.frozen)) || (time > self.havocbot_role_timeout))
        {
                dprint("changing role to freeing\n");
                self.havocbot_role = havocbot_role_ft_freeing;
@@ -322,6 +315,8 @@ void havocbot_role_ft_freeing()
 MUTATOR_HOOKFUNCTION(freezetag_RemovePlayer)
 {
        self.health = 0; // neccessary to update correctly alive stats
+       if(!self.frozen)
+               freezetag_LastPlayerForTeam_Notify();
        freezetag_Unfreeze(world);
        freezetag_count_alive_players();
        return 1;
@@ -332,7 +327,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
        if(round_handler_IsActive())
        if(round_handler_CountdownRunning())
        {
-               if(self.freezetag_frozen)
+               if(self.frozen)
                        freezetag_Unfreeze(world);
                freezetag_count_alive_players();
                return 1; // let the player die so that he can respawn whenever he wants
@@ -344,21 +339,24 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
                || frag_deathtype == DEATH_TEAMCHANGE || frag_deathtype == DEATH_AUTOTEAMCHANGE)
        {
                // let the player die, he will be automatically frozen when he respawns
-               if(!self.freezetag_frozen)
+               if(self.frozen != 1)
                {
                        freezetag_Add_Score(frag_attacker);
                        freezetag_count_alive_players();
+                       freezetag_LastPlayerForTeam_Notify();
                }
                else
                        freezetag_Unfreeze(world); // remove ice
+               self.health = 0; // Unfreeze resets health
                self.freezetag_frozen_timeout = -2; // freeze on respawn
                return 1;
        }
 
-       if(self.freezetag_frozen)
+       if(self.frozen)
                return 1;
 
        freezetag_Freeze(frag_attacker);
+       freezetag_LastPlayerForTeam_Notify();
 
        if(frag_attacker == frag_target || frag_attacker == world)
        {
@@ -375,8 +373,6 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerDies)
                Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_FREEZE, frag_target.netname, frag_attacker.netname);
        }
 
-       frag_target.health = 1; // "respawn" the player :P
-
        return 1;
 }
 
@@ -408,8 +404,6 @@ MUTATOR_HOOKFUNCTION(freezetag_reset_map_players)
        FOR_EACH_PLAYER(self)
        {
                self.killcount = 0;
-               if (self.freezetag_frozen)
-                       freezetag_Unfreeze(world);
                self.freezetag_frozen_timeout = -1;
                PutClientInServer();
                self.freezetag_frozen_timeout = 0;
@@ -432,7 +426,7 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
        if(gameover)
                return 1;
 
-       if(self.freezetag_frozen)
+       if(self.frozen == 1)
        {
                // keep health = 1
                self.pauseregen_finished = time + autocvar_g_balance_pause_health_regen;
@@ -444,8 +438,9 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
 
        entity o;
        o = world;
-       if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
-               self.freezetag_ice.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
+       //if(self.frozen)
+       //if(self.freezetag_frozen_timeout > 0 && time < self.freezetag_frozen_timeout)
+               //self.iceblock.alpha = ICE_MIN_ALPHA + (ICE_MAX_ALPHA - ICE_MIN_ALPHA) * (self.freezetag_frozen_timeout - time) / (self.freezetag_frozen_timeout - self.freezetag_frozen_time);
 
        if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
                n = -1;
@@ -453,34 +448,27 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
        {
                vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
                n = 0;
-               FOR_EACH_PLAYER(other) if(self != other)
+               FOR_EACH_PLAYER(other)
+               if(self != other)
+               if(other.frozen == 0)
+               if(other.deadflag == DEAD_NO)
+               if(SAME_TEAM(other, self))
+               if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
                {
-                       if(other.freezetag_frozen == 0)
-                       {
-                               if(other.team == self.team)
-                               {
-                                       if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
-                                       {
-                                               if(!o)
-                                                       o = other;
-                                               if(self.freezetag_frozen)
-                                                       other.reviving = TRUE;
-                                               ++n;
-                                       }
-                               }
-                       }
+                       if(!o)
+                               o = other;
+                       if(self.frozen == 1)
+                               other.reviving = TRUE;
+                       ++n;
                }
        }
 
-       if(n && self.freezetag_frozen) // OK, there is at least one teammate reviving us
+       if(n && self.frozen == 1) // OK, there is at least one teammate reviving us
        {
-               self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
-               if(warmup_stage)
-                       self.health = max(1, self.freezetag_revive_progress * warmup_start_health);
-               else
-                       self.health = max(1, self.freezetag_revive_progress * start_health);
+               self.revive_progress = bound(0, self.revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
+               self.health = max(1, self.revive_progress * ((warmup_stage) ? warmup_start_health : start_health));
 
-               if(self.freezetag_revive_progress >= 1)
+               if(self.revive_progress >= 1)
                {
                        freezetag_Unfreeze(self);
                        freezetag_count_alive_players();
@@ -499,6 +487,8 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
                                {
                                        PlayerScore_Add(other, SP_FREEZETAG_REVIVALS, +1);
                                        PlayerScore_Add(other, SP_SCORE, +1);
+
+                                       nades_GiveBonus(other,autocvar_g_nades_bonus_score_low);
                                }
                        }
 
@@ -511,88 +501,24 @@ MUTATOR_HOOKFUNCTION(freezetag_PlayerPreThink)
                {
                        if(other.reviving)
                        {
-                               other.freezetag_revive_progress = self.freezetag_revive_progress;
+                               other.revive_progress = self.revive_progress;
                                other.reviving = FALSE;
                        }
                }
        }
-       else if(!n && self.freezetag_frozen) // only if no teammate is nearby will we reset
-       {
-               self.freezetag_revive_progress = bound(0, self.freezetag_revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
-               if(warmup_stage)
-                       self.health = max(1, self.freezetag_revive_progress * warmup_start_health);
-               else
-                       self.health = max(1, self.freezetag_revive_progress * start_health);
-       }
-       else if(!n)
+       else if(!n && self.frozen == 1) // only if no teammate is nearby will we reset
        {
-               self.freezetag_revive_progress = 0; // thawing nobody
+               self.revive_progress = bound(0, self.revive_progress - frametime * autocvar_g_freezetag_revive_clearspeed, 1);
+               self.health = max(1, self.revive_progress * ((warmup_stage) ? warmup_start_health : start_health));
        }
-
-       return 1;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_PlayerPhysics)
-{
-       if(self.freezetag_frozen)
+       else if(!n && !self.frozen)
        {
-               if(autocvar_sv_dodging_frozen && IS_REAL_CLIENT(self))
-               {
-                       self.movement_x = bound(-5, self.movement_x, 5);
-                       self.movement_y = bound(-5, self.movement_y, 5);
-                       self.movement_z = bound(-5, self.movement_z, 5);
-               }
-               else
-                       self.movement = '0 0 0';
-
-               self.disableclientprediction = 1;
+               self.revive_progress = 0; // thawing nobody
        }
-       return 1;
-}
 
-MUTATOR_HOOKFUNCTION(freezetag_PlayerDamage_Calculate)
-{
-       if(frag_target.freezetag_frozen && frag_deathtype != DEATH_HURTTRIGGER)
-       {
-               if(autocvar_g_freezetag_revive_falldamage > 0)
-               if(frag_deathtype == DEATH_FALL)
-               if(frag_damage >= autocvar_g_freezetag_revive_falldamage)
-               {
-                       freezetag_Unfreeze(frag_target);
-                       frag_target.health = autocvar_g_freezetag_revive_falldamage_health;
-                       pointparticles(particleeffectnum("iceorglass"), frag_target.origin, '0 0 0', 3);
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_FALL, frag_target.netname);
-                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_REVIVE_FALL);
-               }
-
-               frag_damage = 0;
-               frag_force = frag_force * autocvar_g_freezetag_frozen_force;
-       }
        return 1;
 }
 
-MUTATOR_HOOKFUNCTION(freezetag_PlayerJump)
-{
-       if(self.freezetag_frozen)
-               return TRUE; // no jumping in freezetag when frozen
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_ForbidThrowCurrentWeapon)
-{
-       if (self.freezetag_frozen)
-               return 1;
-       return 0;
-}
-
-MUTATOR_HOOKFUNCTION(freezetag_ItemTouch)
-{
-       if (other.freezetag_frozen)
-               return MUT_ITEMTOUCH_RETURN;
-       return MUT_ITEMTOUCH_CONTINUE;
-}
-
 MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
 {
        if (!self.deadflag)
@@ -606,31 +532,14 @@ MUTATOR_HOOKFUNCTION(freezetag_BotRoles)
        return TRUE;
 }
 
-MUTATOR_HOOKFUNCTION(freezetag_SpectateCopy)
-{
-       self.freezetag_frozen = other.freezetag_frozen;
-       self.freezetag_revive_progress = other.freezetag_revive_progress;
-       return 0;
-}
-
 MUTATOR_HOOKFUNCTION(freezetag_GetTeamCount)
 {
        ret_float = freezetag_teams;
        return 0;
 }
 
-MUTATOR_HOOKFUNCTION(freezetag_VehicleTouch)
-{
-       if(other.freezetag_frozen)
-               return TRUE;
-
-       return FALSE;
-}
-
 void freezetag_Initialize()
 {
-       precache_model("models/ice/ice.md3");
-
        freezetag_teams = autocvar_g_freezetag_teams_override;
        if(freezetag_teams < 2)
                freezetag_teams = autocvar_g_freezetag_teams;
@@ -645,8 +554,7 @@ void freezetag_Initialize()
        addstat(STAT_YELLOWALIVE, AS_INT, yellowalive_stat);
        addstat(STAT_PINKALIVE, AS_INT, pinkalive_stat);
 
-       addstat(STAT_FROZEN, AS_INT, freezetag_frozen);
-       addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, freezetag_revive_progress);
+       EliminatedPlayers_Init(freezetag_isEliminated);
 }
 
 MUTATOR_DEFINITION(gamemode_freezetag)
@@ -658,15 +566,8 @@ MUTATOR_DEFINITION(gamemode_freezetag)
        MUTATOR_HOOK(reset_map_players, freezetag_reset_map_players, CBC_ORDER_ANY);
        MUTATOR_HOOK(GiveFragsForKill, freezetag_GiveFragsForKill, CBC_ORDER_FIRST);
        MUTATOR_HOOK(PlayerPreThink, freezetag_PlayerPreThink, CBC_ORDER_FIRST);
-       MUTATOR_HOOK(PlayerPhysics, freezetag_PlayerPhysics, CBC_ORDER_FIRST);
-       MUTATOR_HOOK(PlayerDamage_Calculate, freezetag_PlayerDamage_Calculate, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerJump, freezetag_PlayerJump, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, freezetag_ForbidThrowCurrentWeapon, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ItemTouch, freezetag_ItemTouch, CBC_ORDER_ANY);
        MUTATOR_HOOK(HavocBot_ChooseRole, freezetag_BotRoles, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SpectateCopy, freezetag_SpectateCopy, CBC_ORDER_ANY);
        MUTATOR_HOOK(GetTeamCount, freezetag_GetTeamCount, CBC_ORDER_EXCLUSIVE);
-       MUTATOR_HOOK(VehicleTouch, freezetag_VehicleTouch, CBC_ORDER_ANY);
 
        MUTATOR_ONADD
        {
index 8448a215e93bdbc989c01bfcfadbcf6d4702ab8c..364cb7fe3b513630e6e990db2334ed7e1b0ddb1e 100644 (file)
@@ -416,8 +416,6 @@ void invasion_DelayedInit() // Do this check with a delay so we can wait for tea
        round_handler_Spawn(Invasion_CheckPlayers, Invasion_CheckWinner, Invasion_RoundStart);
        round_handler_Init(5, autocvar_g_invasion_warmup, autocvar_g_invasion_round_timelimit);
 
-       allowed_to_spawn = TRUE;
-
        inv_roundcnt = 0;
        inv_maxrounds = 15; // 15?
 }
index 79058b0cf0c806ec98f1d1796bc1c9eb3b83873d..7e1006ec1d92252e624fda40366e08dee47feb99 100644 (file)
@@ -71,6 +71,7 @@ void ka_TouchEvent() // runs any time that the ball comes in contact with someth
                return;
        }
        if(other.deadflag != DEAD_NO) { return; }
+       if(other.frozen) { return; }
        if (!IS_PLAYER(other))
        {  // The ball just touched an object, most likely the world
                pointparticles(particleeffectnum("kaball_sparks"), self.origin, '0 0 0', 1);
index 34d87f97bb677aaaa3c87c99a1b4a808938df8f3..ab67a4821259b27115be5a9e89c2001a9d3d04c2 100644 (file)
@@ -500,6 +500,7 @@ void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TE
                f = DistributeEvenly_Get(1);
                kh_Scores_Event(key.owner, key, "capture", f, 0);
                PlayerTeamScore_Add(key.owner, SP_KH_CAPS, ST_KH_CAPS, 1);
+               nades_GiveBonus(key.owner, autocvar_g_nades_bonus_score_high);
        }
 
        first = TRUE;
index 014d37ec20169fd6497b6f3b50764b51deb1d91c..8695ca31b2b95b13103f2735d46a0141ffc18a86 100644 (file)
@@ -288,7 +288,7 @@ void basketball_touch(void)
                football_touch();
                return;
        }
-       if(!self.cnt && IS_PLAYER(other) && (other != self.nb_dropper || time > self.nb_droptime + autocvar_g_nexball_delay_collect))
+       if(!self.cnt && IS_PLAYER(other) && !other.frozen && (other != self.nb_dropper || time > self.nb_droptime + autocvar_g_nexball_delay_collect))
        {
                if(other.health <= 0)
                        return;
diff --git a/qcsrc/server/mutators/gamemode_race.qc b/qcsrc/server/mutators/gamemode_race.qc
new file mode 100644 (file)
index 0000000..da5ca4c
--- /dev/null
@@ -0,0 +1,312 @@
+// legacy bot roles
+.float race_checkpoint;
+void havocbot_role_race()
+{
+       if(self.deadflag != DEAD_NO)
+               return;
+
+       entity e;
+       if (self.bot_strategytime < time)
+       {
+               self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+               navigation_goalrating_start();
+
+               for(e = world; (e = find(e, classname, "trigger_race_checkpoint")) != world; )
+               {
+                       if(e.cnt == self.race_checkpoint)
+                       {
+                               navigation_routerating(e, 1000000, 5000);
+                       }
+                       else if(self.race_checkpoint == -1)
+                       {
+                               navigation_routerating(e, 1000000, 5000);
+                       }
+               }
+
+               navigation_goalrating_end();
+       }
+}
+
+void race_ScoreRules()
+{
+       ScoreRules_basics(race_teams, 0, 0, FALSE);
+       if(race_teams)
+       {
+               ScoreInfo_SetLabel_TeamScore(  ST_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME,    "time",      SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest",   SFL_LOWER_IS_BETTER | SFL_TIME);
+       }
+       else if(g_race_qualifying)
+       {
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest",   SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+       }
+       else
+       {
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME,    "time",      SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
+               ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest",   SFL_LOWER_IS_BETTER | SFL_TIME);
+       }
+       ScoreRules_basics_end();
+}
+
+void race_EventLog(string mode, entity actor) // use an alias for easy changing and quick editing later
+{
+       if(autocvar_sv_eventlog)
+               GameLogEcho(strcat(":race:", mode, ":", ((actor != world) ? (strcat(":", ftos(actor.playerid))) : "")));
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerPhysics)
+{
+       // force kbd movement for fairness
+       float wishspeed;
+       vector wishvel;
+
+       // if record times matter
+       // ensure nothing EVIL is being done (i.e. div0_evade)
+       // this hinders joystick users though
+       // but it still gives SOME analog control
+       wishvel_x = fabs(self.movement_x);
+       wishvel_y = fabs(self.movement_y);
+       if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y)
+       {
+               wishvel_z = 0;
+               wishspeed = vlen(wishvel);
+               if(wishvel_x >= 2 * wishvel_y)
+               {
+                       // pure X motion
+                       if(self.movement_x > 0)
+                               self.movement_x = wishspeed;
+                       else
+                               self.movement_x = -wishspeed;
+                       self.movement_y = 0;
+               }
+               else if(wishvel_y >= 2 * wishvel_x)
+               {
+                       // pure Y motion
+                       self.movement_x = 0;
+                       if(self.movement_y > 0)
+                               self.movement_y = wishspeed;
+                       else
+                               self.movement_y = -wishspeed;
+               }
+               else
+               {
+                       // diagonal
+                       if(self.movement_x > 0)
+                               self.movement_x = M_SQRT1_2 * wishspeed;
+                       else
+                               self.movement_x = -M_SQRT1_2 * wishspeed;
+                       if(self.movement_y > 0)
+                               self.movement_y = M_SQRT1_2 * wishspeed;
+                       else
+                               self.movement_y = -M_SQRT1_2 * wishspeed;
+               }
+       }
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_ResetMap)
+{
+       float s;
+
+       Score_NicePrint(world);
+
+       race_ClearRecords();
+       PlayerScore_Sort(race_place, 0, 1, 0);
+
+       entity e;
+       FOR_EACH_CLIENT(e)
+       {
+               if(e.race_place)
+               {
+                       s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
+                       if(!s)
+                               e.race_place = 0;
+               }
+               race_EventLog(ftos(e.race_place), e);
+       }
+
+       if(g_race_qualifying == 2)
+       {
+               g_race_qualifying = 0;
+               independent_players = 0;
+               cvar_set("fraglimit", ftos(race_fraglimit));
+               cvar_set("leadlimit", ftos(race_leadlimit));
+               cvar_set("timelimit", ftos(race_timelimit));
+               race_ScoreRules();
+       }
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerPreThink)
+{
+       if(IS_SPEC(self) || IS_OBSERVER(self))
+       if(g_race_qualifying)
+       if(msg_entity.enemy.race_laptime)
+               race_SendNextCheckpoint(msg_entity.enemy, 1);
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_ClientConnect)
+{
+       race_PreparePlayer();
+       self.race_checkpoint = -1;
+
+       string rr = RACE_RECORD;
+
+       if(IS_REAL_CLIENT(self))
+       {
+               msg_entity = self;
+               race_send_recordtime(MSG_ONE);
+               race_send_speedaward(MSG_ONE);
+
+               speedaward_alltimebest = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/speed")));
+               speedaward_alltimebest_holder = uid2name(db_get(ServerProgsDB, strcat(GetMapname(), rr, "speed/crypto_idfp")));
+               race_send_speedaward_alltimebest(MSG_ONE);
+
+               float i;
+               for (i = 1; i <= RANKINGS_CNT; ++i)
+               {
+                       race_SendRankings(i, 0, 0, MSG_ONE);
+               }
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_MakePlayerObserver)
+{
+       if(g_race_qualifying)
+       if(PlayerScore_Add(self, SP_RACE_FASTEST, 0))
+               self.frags = FRAGS_LMS_LOSER;
+       else
+               self.frags = FRAGS_SPECTATOR;
+
+       race_PreparePlayer();
+       self.race_checkpoint = -1;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerSpawn)
+{
+       if(spawn_spot.target == "")
+               // Emergency: this wasn't a real spawnpoint. Can this ever happen?
+               race_PreparePlayer();
+
+       // if we need to respawn, do it right
+       self.race_respawn_checkpoint = self.race_checkpoint;
+       self.race_respawn_spotref = spawn_spot;
+
+       self.race_place = 0;
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PutClientInServer)
+{
+       if(IS_PLAYER(self))
+       if(!gameover)
+       {
+               if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
+                       race_PreparePlayer();
+               else // respawn
+                       race_RetractPlayer();
+
+               race_AbandonRaceCheck(self);
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerDies)
+{
+       self.respawn_flags |= RESPAWN_FORCE;
+       race_AbandonRaceCheck(self);
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_BotRoles)
+{
+       self.havocbot_role = havocbot_role_race;
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(race_PlayerPostThink)
+{
+       if(self.cvar_cl_allow_uidtracking == 1 && self.cvar_cl_allow_uid2name == 1)
+       {
+               if (!self.stored_netname)
+                       self.stored_netname = strzone(uid2name(self.crypto_idfp));
+               if(self.stored_netname != self.netname)
+               {
+                       db_put(ServerProgsDB, strcat("/uid2name/", self.crypto_idfp), self.netname);
+                       strunzone(self.stored_netname);
+                       self.stored_netname = strzone(self.netname);
+               }
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_ForbidClearPlayerScore)
+{
+       if(g_race_qualifying)
+               return TRUE; // in qualifying, you don't lose score by observing
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(race_GetTeamCount)
+{
+       ret_float = race_teams;
+       return FALSE;
+}
+
+void race_Initialize()
+{
+       race_ScoreRules();
+       if(g_race_qualifying == 2)
+               warmup_stage = 0;
+}
+
+MUTATOR_DEFINITION(gamemode_race)
+{
+       MUTATOR_HOOK(PlayerPhysics, race_PlayerPhysics, CBC_ORDER_ANY);
+       MUTATOR_HOOK(reset_map_global, race_ResetMap, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPreThink, race_PlayerPreThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ClientConnect, race_ClientConnect, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MakePlayerObserver, race_MakePlayerObserver, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerSpawn, race_PlayerSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PutClientInServer, race_PutClientInServer, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDies, race_PlayerDies, CBC_ORDER_ANY);
+       MUTATOR_HOOK(HavocBot_ChooseRole, race_BotRoles, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GetPressedKeys, race_PlayerPostThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ForbidPlayerScore_Clear, race_ForbidClearPlayerScore, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GetTeamCount, race_GetTeamCount, CBC_ORDER_ANY);
+
+       MUTATOR_ONADD
+       {
+               if(time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               race_Initialize();
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back race_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/qcsrc/server/mutators/gamemode_race.qh b/qcsrc/server/mutators/gamemode_race.qh
new file mode 100644 (file)
index 0000000..32829a2
--- /dev/null
@@ -0,0 +1,8 @@
+float g_race_qualifying;
+float race_teams;
+
+// scores
+#define ST_RACE_LAPS 1
+#define SP_RACE_LAPS 4
+#define SP_RACE_TIME 5
+#define SP_RACE_FASTEST 6
diff --git a/qcsrc/server/mutators/gamemode_tdm.qc b/qcsrc/server/mutators/gamemode_tdm.qc
new file mode 100644 (file)
index 0000000..59f0927
--- /dev/null
@@ -0,0 +1,79 @@
+/*QUAKED spawnfunc_tdm_team (0 .5 .8) (-16 -16 -24) (16 16 32)
+Team declaration for TDM gameplay, this allows you to decide what team names and control point models are used in your map.
+Note: If you use spawnfunc_tdm_team entities you must define at least 2!  However, unlike domination, you don't need to make a blank one too.
+Keys:
+"netname" Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc)...
+"cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
+void spawnfunc_tdm_team()
+{
+       if(!g_tdm) { remove(self); return; }
+
+       self.classname = "tdm_team";
+       self.team = self.cnt + 1;
+}
+
+// code from here on is just to support maps that don't have team entities
+void tdm_SpawnTeam (string teamname, float teamcolor)
+{
+       entity oldself;
+       oldself = self;
+       self = spawn();
+       self.classname = "tdm_team";
+       self.netname = teamname;
+       self.cnt = teamcolor;
+
+       spawnfunc_tdm_team();
+
+       self = oldself;
+}
+
+void tdm_DelayedInit()
+{
+       // if no teams are found, spawn defaults
+       if(find(world, classname, "tdm_team") == world)
+       {
+               print("No ""tdm_team"" entities found on this map, creating them anyway.\n");
+
+               float numteams = min(4, autocvar_g_tdm_teams_override);
+
+               if(numteams < 2) { numteams = autocvar_g_tdm_teams; }
+               numteams = bound(2, numteams, 4);
+
+               float i;
+               for(i = 1; i <= numteams; ++i)
+                       tdm_SpawnTeam(Team_ColorName(Team_NumberToTeam(i)), Team_NumberToTeam(i) - 1);
+       }
+}
+
+MUTATOR_HOOKFUNCTION(tdm_GetTeamCount)
+{
+       ret_string = "tdm_team";
+       return TRUE;
+}
+
+MUTATOR_DEFINITION(gamemode_tdm)
+{
+       MUTATOR_HOOK(GetTeamCount, tdm_GetTeamCount, CBC_ORDER_ANY);
+
+       MUTATOR_ONADD
+       {
+               if(time > 1) // game loads at time 1
+                       error("This is a game type and it cannot be added at runtime.");
+               InitializeEntity(world, tdm_DelayedInit, INITPRIO_GAMETYPE);
+       }
+
+       MUTATOR_ONROLLBACK_OR_REMOVE
+       {
+               // we actually cannot roll back tdm_Initialize here
+               // BUT: we don't need to! If this gets called, adding always
+               // succeeds.
+       }
+
+       MUTATOR_ONREMOVE
+       {
+               print("This is a game type and it cannot be removed at runtime.");
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/qcsrc/server/mutators/mutator_buffs.qc b/qcsrc/server/mutators/mutator_buffs.qc
new file mode 100644 (file)
index 0000000..4da3e1a
--- /dev/null
@@ -0,0 +1,785 @@
+float buffs_BuffModel_Customize()
+{
+       entity player, myowner;
+       float same_team;
+
+       player = WaypointSprite_getviewentity(other);
+       myowner = self.owner;
+       same_team = (SAME_TEAM(player, myowner) || SAME_TEAM(player, myowner));
+
+       if(myowner.alpha <= 0.5 && !same_team && myowner.alpha != 0)
+               return FALSE;
+
+       if(player == myowner || (IS_SPEC(other) && other.enemy == myowner))
+       {
+               // somewhat hide the model, but keep the glow
+               self.effects = 0;
+               self.alpha = -1;
+       }
+       else
+       {
+               self.effects = EF_FULLBRIGHT | EF_LOWPRECISION;
+               self.alpha = 1;
+       }
+       return TRUE;
+}
+
+// buff item
+float buff_Waypoint_visible_for_player(entity plr)
+{
+    if(!self.owner.buff_active && !self.owner.buff_activetime)
+        return FALSE;
+
+       if(plr.buffs)
+       {
+               if(plr.cvar_cl_buffs_autoreplace)
+               {
+                       if(plr.buffs == self.owner.buffs)
+                               return FALSE;
+               }
+               else
+                       return FALSE;
+       }
+
+    return WaypointSprite_visible_for_player(plr);
+}
+
+void buff_Waypoint_Spawn(entity e)
+{
+    WaypointSprite_Spawn(Buff_Sprite(e.buffs), 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs_z, world, e.team, e, buff_waypoint, TRUE, RADARICON_POWERUP, e.glowmod);
+    WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_POWERUP, e.glowmod);
+    e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
+}
+
+void buff_SetCooldown(float cd)
+{
+       cd = max(0, cd);
+
+       if(!self.buff_waypoint)
+               buff_Waypoint_Spawn(self);
+
+       WaypointSprite_UpdateBuildFinished(self.buff_waypoint, time + cd);
+       self.buff_activetime = cd;
+       self.buff_active = !cd;
+}
+
+void buff_Respawn(entity ent)
+{
+       if(gameover) { return; }
+       
+       vector oldbufforigin = ent.origin;
+       
+       if(!MoveToRandomMapLocation(ent, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, ((autocvar_g_buffs_random_location_attempts > 0) ? autocvar_g_buffs_random_location_attempts : 10), 1024, 256))
+       {
+               entity spot = SelectSpawnPoint(TRUE);
+               setorigin(ent, ((spot.origin + '0 0 200') + (randomvec() * 300)));
+               ent.angles = spot.angles;
+       }
+       
+       tracebox(ent.origin, ent.mins * 1.5, self.maxs * 1.5, ent.origin, MOVE_NOMONSTERS, ent);
+       
+       setorigin(ent, trace_endpos); // attempt to unstick
+       
+       ent.movetype = MOVETYPE_TOSS;
+       
+       makevectors(ent.angles);
+       ent.velocity = '0 0 200';
+       ent.angles = '0 0 0';
+       if(autocvar_g_buffs_random_lifetime > 0)
+               ent.lifetime = time + autocvar_g_buffs_random_lifetime;
+
+       pointparticles(particleeffectnum("electro_combo"), oldbufforigin + ((ent.mins + ent.maxs) * 0.5), '0 0 0', 1);
+       pointparticles(particleeffectnum("electro_combo"), CENTER_OR_VIEWOFS(ent), '0 0 0', 1);
+       
+       WaypointSprite_Ping(ent.buff_waypoint);
+       
+       sound(ent, CH_TRIGGER, "keepaway/respawn.wav", VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
+}
+
+void buff_Touch()
+{
+       if(gameover) { return; }
+
+       if(ITEM_TOUCH_NEEDKILL())
+       {
+               buff_Respawn(self);
+               return;
+       }
+
+       if((self.team && DIFF_TEAM(other, self))
+       || (other.frozen)
+       || (other.vehicle)
+       || (!IS_PLAYER(other))
+       || (!self.buff_active)
+       )
+       {
+               // can't touch this
+               return;
+       }
+
+       if(other.buffs)
+       {
+               if(other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
+               {
+                       //Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_DROP, other.buffs);
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ITEM_BUFF_LOST, other.netname, other.buffs);
+
+                       other.buffs = 0;
+                       //sound(other, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
+               }
+               else { return; } // do nothing
+       }
+               
+       self.owner = other;
+       self.buff_active = FALSE;
+       self.lifetime = 0;
+       
+       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, self.buffs);
+       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, self.buffs);
+
+       pointparticles(particleeffectnum("item_pickup"), CENTER_OR_VIEWOFS(self), '0 0 0', 1);
+       sound(other, CH_TRIGGER, "misc/shield_respawn.wav", VOL_BASE, ATTN_NORM);
+       other.buffs |= (self.buffs);
+}
+
+float buff_Available(float buffid)
+{
+       if(buffid == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
+               return FALSE;
+
+       if(buffid == BUFF_VAMPIRE && cvar("g_vampire"))
+               return FALSE;
+
+       if(!cvar(strcat("g_buffs_", Buff_Name(buffid))))
+               return FALSE;
+
+       return TRUE;
+}
+
+void buff_NewType(entity ent, float cb)
+{
+       entity e;
+       RandomSelection_Init();
+       for(e = Buff_Type_first; e; e = e.enemy)
+       if(buff_Available(e.items))
+       {
+               RandomSelection_Add(world, e.items, string_null, 1, 1 / e.count); // if it's already been chosen, give it a lower priority
+               e.count += 1;
+       }
+       ent.buffs = RandomSelection_chosen_float;
+}
+
+void buff_Think()
+{
+       if(self.buffs != self.oldbuffs)
+       {
+               self.color = Buff_Color(self.buffs);
+               self.glowmod = ((self.team) ? Team_ColorRGB(self.team) + '0.1 0.1 0.1' : self.color);
+               self.skin = Buff_Skin(self.buffs);
+               
+               setmodel(self, "models/relics/relic.md3");
+
+               if(self.buff_waypoint)
+               {
+                       //WaypointSprite_Disown(self.buff_waypoint, 1);
+                       WaypointSprite_Kill(self.buff_waypoint);
+                       buff_Waypoint_Spawn(self);
+                       if(self.buff_activetime)
+                               WaypointSprite_UpdateBuildFinished(self.buff_waypoint, time + self.buff_activetime - frametime);
+               }
+
+               self.oldbuffs = self.buffs;
+       }
+
+       if(!gameover)
+       if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
+       if(!self.buff_activetime_updated)
+       {
+               buff_SetCooldown(self.buff_activetime);
+               self.buff_activetime_updated = TRUE;
+    }
+
+       if(!self.buff_active && !self.buff_activetime)
+       if(!self.owner || self.owner.frozen || self.owner.deadflag != DEAD_NO || !self.owner.iscreature || !(self.owner.buffs & self.buffs))
+       {
+               buff_SetCooldown(autocvar_g_buffs_cooldown_respawn + frametime);
+               self.owner = world;
+               if(autocvar_g_buffs_randomize)
+                       buff_NewType(self, self.buffs);
+                       
+               if(autocvar_g_buffs_random_location || (self.spawnflags & 1))
+                       buff_Respawn(self);
+       }
+       
+       if(self.buff_activetime)
+       if(!gameover)
+       if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
+       {
+               self.buff_activetime = max(0, self.buff_activetime - frametime);
+
+               if(!self.buff_activetime)
+               {
+                       self.buff_active = TRUE;
+                       sound(self, CH_TRIGGER, "misc/strength_respawn.wav", VOL_BASE, ATTN_NORM);
+                       pointparticles(particleeffectnum("item_respawn"), CENTER_OR_VIEWOFS(self), '0 0 0', 1);
+               }
+       }
+
+       if(!self.buff_active)
+       {
+               self.alpha = 0.3;
+               self.effects &= ~(EF_FULLBRIGHT);
+               self.pflags = 0;
+       }
+       else
+       {
+               self.alpha = 1;
+               self.effects |= EF_FULLBRIGHT;
+               self.light_lev = 220 + 36 * sin(time);
+               self.pflags = PFLAGS_FULLDYNAMIC;
+
+               if(self.team && !self.buff_waypoint)
+                       buff_Waypoint_Spawn(self);
+                       
+               if(self.lifetime)
+               if(time >= self.lifetime)
+                       buff_Respawn(self);
+       }
+    
+       self.nextthink = time;
+       //self.angles_y = time * 110.1;
+}
+
+void buff_Waypoint_Reset()
+{
+       WaypointSprite_Kill(self.buff_waypoint);
+
+       if(self.buff_activetime) { buff_Waypoint_Spawn(self); }
+}
+
+void buff_Reset()
+{
+       if(autocvar_g_buffs_randomize)
+               buff_NewType(self, self.buffs);
+       self.owner = world;
+       buff_SetCooldown(autocvar_g_buffs_cooldown_activate);
+       buff_Waypoint_Reset();
+       self.buff_activetime_updated = FALSE;
+       
+       if(autocvar_g_buffs_random_location || (self.spawnflags & 1))
+               buff_Respawn(self);
+}
+
+void buff_Init(entity ent)
+{
+       if(!cvar("g_buffs")) { remove(self); return; }
+       
+       if(!teamplay && self.team) { self.team = 0; }
+
+       entity oldself = self;
+       self = ent;
+       if(!self.buffs || buff_Available(self.buffs))
+               buff_NewType(self, 0);
+       
+       self.classname = "item_buff";
+       self.solid = SOLID_TRIGGER;
+       self.flags = FL_ITEM;
+       self.think = buff_Think;
+       self.touch = buff_Touch;
+       self.reset = buff_Reset;
+       self.nextthink = time + 0.1;
+       self.gravity = 1;
+       self.movetype = MOVETYPE_TOSS;
+       self.scale = 1;
+       self.skin = Buff_Skin(self.buffs);
+       self.effects = EF_FULLBRIGHT | EF_STARDUST | EF_NOSHADOW;
+       self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
+       //self.gravity = 100;
+       self.color = Buff_Color(self.buffs);
+       self.glowmod = ((self.team) ? Team_ColorRGB(self.team) + '0.1 0.1 0.1' : self.color);
+       buff_SetCooldown(autocvar_g_buffs_cooldown_activate + game_starttime);
+       self.buff_active = !self.buff_activetime;
+       self.pflags = PFLAGS_FULLDYNAMIC;
+       
+       if(self.noalign)
+               self.movetype = MOVETYPE_NONE; // reset by random location
+
+       setmodel(self, "models/relics/relic.md3");
+       setsize(self, BUFF_MIN, BUFF_MAX);
+       
+       if(cvar("g_buffs_random_location") || (self.spawnflags & 1))
+               buff_Respawn(self);
+       
+       self = oldself;
+}
+
+void buff_Init_Compat(entity ent, float replacement)
+{
+       if(ent.spawnflags & 2)
+               ent.team = NUM_TEAM_1;
+       else if(ent.spawnflags & 4)
+               ent.team = NUM_TEAM_2;
+
+       ent.buffs = replacement;
+
+       buff_Init(ent);
+}
+
+void buff_SpawnReplacement(entity ent, entity old)
+{
+       setorigin(ent, old.origin);
+       ent.angles = old.angles;
+       ent.noalign = old.noalign;
+       
+       buff_Init(ent);
+}
+
+// mutator hooks
+MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_SplitHealthArmor)
+{
+       if(frag_deathtype == DEATH_BUFF_VENGEANCE) { return FALSE; } // oh no you don't
+
+       if(frag_target.buffs & BUFF_RESISTANCE)
+       {
+               vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage);
+               damage_take = v_x;
+               damage_save = v_y;
+       }
+
+       return FALSE;
+}
+
+void buff_Vengeance_DelayedDamage()
+{
+       if(self.enemy)
+               Damage(self.enemy, self.owner, self.owner, self.dmg, DEATH_BUFF_VENGEANCE, self.enemy.origin, '0 0 0');
+       
+       remove(self);
+       return;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerDamage_Calculate)
+{
+       if(frag_deathtype == DEATH_BUFF_VENGEANCE) { return FALSE; } // oh no you don't
+
+       if(frag_target.buffs & BUFF_SPEED)
+       if(frag_target != frag_attacker)
+               frag_damage *= autocvar_g_buffs_speed_damage_take;
+
+       if(frag_target.buffs & BUFF_MEDIC)
+       if((frag_target.health - frag_damage) <= 0)
+       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+       if(frag_attacker)
+       if(random() <= autocvar_g_buffs_medic_survive_chance)
+       if(frag_target.health - autocvar_g_buffs_medic_survive_health > 0) // not if the final result would be less than 0, medic must get health
+               frag_damage = frag_target.health - autocvar_g_buffs_medic_survive_health;
+               
+       if(frag_target.buffs & BUFF_VENGEANCE)
+       if(frag_attacker)
+       if(frag_attacker != frag_target)
+       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+       {
+               entity dmgent = spawn();
+
+               dmgent.dmg = frag_damage * autocvar_g_buffs_vengeance_damage_multiplier;
+               dmgent.enemy = frag_attacker;
+               dmgent.owner = frag_target;
+               dmgent.think = buff_Vengeance_DelayedDamage;
+               dmgent.nextthink = time + 0.1;
+       }
+
+       if(frag_target.buffs & BUFF_BASH)
+       if(frag_attacker != frag_target)
+       if(vlen(frag_force))
+               frag_force = '0 0 0';
+       
+       if(frag_attacker.buffs & BUFF_BASH)
+       if(vlen(frag_force))
+       if(frag_attacker == frag_target)
+               frag_force *= autocvar_g_buffs_bash_force_self;
+       else
+               frag_force *= autocvar_g_buffs_bash_force;
+       
+       if(frag_attacker.buffs & BUFF_DISABILITY)
+       if(frag_target != frag_attacker)
+               frag_target.buff_disability_time = time + autocvar_g_buffs_disability_time;
+
+       if(frag_attacker.buffs & BUFF_MEDIC)
+       if(SAME_TEAM(frag_attacker, frag_target))
+       if(frag_attacker != frag_target)
+       {
+               frag_target.health = min(g_pickup_healthmega_max, frag_target.health + frag_damage);
+               frag_damage = 0;
+       }
+
+       // this... is ridiculous (TODO: fix!)
+       if(frag_attacker.buffs & BUFF_VAMPIRE)
+       if(!frag_target.vehicle)
+       if(!ITEM_DAMAGE_NEEDKILL(frag_deathtype))
+       if(frag_target.deadflag == DEAD_NO)
+       if(IS_PLAYER(frag_target) || (frag_target.flags & FL_MONSTER))
+       if(frag_attacker != frag_target)
+       if(!frag_target.frozen)
+       if(frag_target.takedamage)
+       if(DIFF_TEAM(frag_attacker, frag_target))
+               frag_attacker.health = bound(0, frag_attacker.health + bound(0, frag_damage * autocvar_g_buffs_vampire_damage_steal, frag_target.health), g_pickup_healthsmall_max);
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerSpawn)
+{
+       self.buffs = 0;
+       // reset timers here to prevent them continuing after re-spawn
+       self.buff_disability_time = 0;
+       self.buff_disability_effect_time = 0;
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerPhysics)
+{
+       if(self.buffs & BUFF_SPEED)
+       {
+               self.stat_sv_maxspeed *= autocvar_g_buffs_speed_speed;
+               self.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_speed_speed;
+       }
+       
+       if(time < self.buff_disability_time)
+       {
+               self.stat_sv_maxspeed *= autocvar_g_buffs_disability_speed;
+               self.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_disability_speed;
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerJump)
+{
+       if(self.buffs & BUFF_JUMP)
+               player_jumpheight = autocvar_g_buffs_jump_height;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_MonsterMove)
+{
+       if(time < self.buff_disability_time)
+       {
+               monster_speed_walk *= autocvar_g_buffs_disability_speed;
+               monster_speed_run *= autocvar_g_buffs_disability_speed;
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerDies)
+{
+       if(self.buffs)
+       {
+               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+               self.buffs = 0;
+               
+               if(self.buff_model)
+               {
+                       remove(self.buff_model);
+                       self.buff_model = world;
+               }
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerUseKey)
+{
+       if(MUTATOR_RETURNVALUE || gameover) { return FALSE; }
+       if(self.buffs)
+       {
+               Send_Notification(NOTIF_ONE, self, MSG_MULTI, ITEM_BUFF_DROP, self.buffs);
+               Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+
+               self.buffs = 0;
+               sound(self, CH_TRIGGER, "relics/relic_effect.wav", VOL_BASE, ATTN_NORM);
+               return TRUE;
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_RemovePlayer)
+{
+       if(self.buff_model)
+       {
+               remove(self.buff_model);
+               self.buff_model = world;
+       }
+       
+       // also reset timers here to prevent them continuing after spectating
+       self.buff_disability_time = 0;
+       self.buff_disability_effect_time = 0;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_CustomizeWaypoint)
+{
+       entity e = WaypointSprite_getviewentity(other);
+
+       // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
+       // but only apply this to real players, not to spectators
+       if((self.owner.flags & FL_CLIENT) && (self.owner.buffs & BUFF_INVISIBLE) && (e == other))
+       if(DIFF_TEAM(self.owner, e))
+               return TRUE;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_OnEntityPreSpawn)
+{
+       if(autocvar_g_buffs_replace_powerups)
+       switch(self.classname)
+       {
+               case "item_strength":
+               case "item_invincible":
+               {
+                       entity e = spawn();
+                       buff_SpawnReplacement(e, self);
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_WeaponRate)
+{
+       if(self.buffs & BUFF_SPEED)
+               weapon_rate *= autocvar_g_buffs_speed_rate;
+               
+       if(time < self.buff_disability_time)
+               weapon_rate *= autocvar_g_buffs_disability_rate;
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
+{
+       if(gameover || self.deadflag != DEAD_NO) { return FALSE; }
+       
+       if(time < self.buff_disability_time)
+       if(time >= self.buff_disability_effect_time)
+       {
+               pointparticles(particleeffectnum("smoking"), self.origin + ((self.mins + self.maxs) * 0.5), '0 0 0', 1);
+               self.buff_disability_effect_time = time + 0.5;
+       }
+       
+       if(self.frozen)
+       {
+               if(self.buffs)
+               {
+                       Send_Notification(NOTIF_ALL_EXCEPT, self, MSG_INFO, INFO_ITEM_BUFF_LOST, self.netname, self.buffs);
+                       self.buffs = 0;
+               }
+       }
+               
+       if((self.buffs & BUFF_INVISIBLE) && (self.oldbuffs & BUFF_INVISIBLE))
+       if(self.alpha != autocvar_g_buffs_invisible_alpha)
+               self.alpha = autocvar_g_buffs_invisible_alpha;
+
+       if(self.buffs != self.oldbuffs)
+       {
+               if(self.oldbuffs & BUFF_AMMO)
+               {
+                       if(self.buff_ammo_prev_infitems)
+                               self.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       else
+                               self.items &= ~IT_UNLIMITED_WEAPON_AMMO;
+               }
+               else if(self.buffs & BUFF_AMMO)
+               {
+                       self.buff_ammo_prev_infitems = (self.items & IT_UNLIMITED_WEAPON_AMMO);
+                       self.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       if(!self.ammo_shells) { self.ammo_shells = 20; }
+                       if(!self.ammo_cells) { self.ammo_cells = 20; }
+                       if(!self.ammo_rockets) { self.ammo_rockets = 20; }
+                       if(!self.ammo_nails) { self.ammo_nails = 20; }
+                       if(!self.ammo_fuel) { self.ammo_fuel = 20; }
+               }
+               
+               if(self.oldbuffs & BUFF_INVISIBLE)
+               {
+                       if(time < self.strength_finished && g_instagib)
+                               self.alpha = autocvar_g_instagib_invis_alpha;
+                       else
+                               self.alpha = self.buff_invisible_prev_alpha;
+               }
+               else if(self.buffs & BUFF_INVISIBLE)
+               {
+                       if(time < self.strength_finished && g_instagib)
+                               self.buff_invisible_prev_alpha = default_player_alpha;
+                       else
+                               self.buff_invisible_prev_alpha = self.alpha;
+                       self.alpha = autocvar_g_buffs_invisible_alpha;
+               }
+               
+               if(self.oldbuffs & BUFF_FLIGHT)
+                       self.gravity = self.buff_flight_prev_gravity;
+               else if(self.buffs & BUFF_FLIGHT)
+               {
+                       self.buff_flight_prev_gravity = self.gravity;
+                       self.gravity = autocvar_g_buffs_flight_gravity;
+               }
+
+               self.oldbuffs = self.buffs;
+               if(self.buffs)
+               {
+                       if(!self.buff_model)
+                       {
+                               self.buff_model = spawn();
+                               setmodel(self.buff_model, "models/relics/relic.md3");
+                               setsize(self.buff_model, '0 0 -40', '0 0 40');
+                               setattachment(self.buff_model, self, "");
+                               setorigin(self.buff_model, '0 0 1' * (self.buff_model.maxs_z * 1));
+                               self.buff_model.owner = self;
+                               self.buff_model.scale = 0.7;
+                               self.buff_model.pflags = PFLAGS_FULLDYNAMIC;
+                               self.buff_model.light_lev = 200;
+                               self.buff_model.customizeentityforclient = buffs_BuffModel_Customize;
+                       }
+                       self.buff_model.color = Buff_Color(self.buffs);
+                       self.buff_model.glowmod = ((self.buff_model.team) ? Team_ColorRGB(self.buff_model.team) + '0.1 0.1 0.1' : self.buff_model.color);
+                       self.buff_model.skin = Buff_Skin(self.buffs);
+                       
+                       self.effects |= EF_NOSHADOW;
+               }
+               else
+               {
+                       remove(self.buff_model);
+                       self.buff_model = world;
+                       
+                       self.effects &= ~(EF_NOSHADOW);
+               }
+       }
+
+       if(self.buff_model)
+       {
+               self.buff_model.effects = self.effects;
+               self.buff_model.effects |= EF_LOWPRECISION;
+               self.buff_model.effects = self.buff_model.effects & EFMASK_CHEAP; // eat performance
+               
+               self.buff_model.alpha = self.alpha;
+       }
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_SpectateCopy)
+{
+       self.buffs = other.buffs;
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_VehicleEnter)
+{
+       vh_vehicle.buffs = vh_player.buffs;
+       vh_player.buffs = 0;
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_VehicleExit)
+{
+       vh_player.buffs = vh_vehicle.buffs;
+       vh_vehicle.buffs = 0;
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_PlayerRegen)
+{
+       if(self.buffs & BUFF_MEDIC)
+       {
+               regen_mod_rot = autocvar_g_buffs_medic_rot;
+               regen_mod_limit = regen_mod_max = autocvar_g_buffs_medic_max;
+               regen_mod_regen = autocvar_g_buffs_medic_regen;
+       }
+       
+       if(self.buffs & BUFF_SPEED)
+               regen_mod_regen = autocvar_g_buffs_speed_regen;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_GetCvars)
+{
+       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_buffs_autoreplace, "cl_buffs_autoreplace");
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":Buffs");
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(buffs_BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", Buffs");
+       return FALSE;
+}
+
+void buffs_DelayedInit()
+{
+       if(autocvar_g_buffs_spawn_count > 0)
+       if(find(world, classname, "item_buff") == world)
+       {
+               float i;
+               for(i = 0; i < autocvar_g_buffs_spawn_count; ++i)
+               {
+                       entity e = spawn();
+                       e.spawnflags |= 1; // always randomize
+                       e.velocity = randomvec() * 250; // this gets reset anyway if random location works
+                       buff_Init(e);
+               }
+       }
+}
+
+void buffs_Initialize()
+{
+       precache_model("models/relics/relic.md3");
+       precache_sound("misc/strength_respawn.wav");
+       precache_sound("misc/shield_respawn.wav");
+       precache_sound("relics/relic_effect.wav");
+       precache_sound("weapons/rocket_impact.wav");
+       precache_sound("keepaway/respawn.wav");
+
+       addstat(STAT_BUFFS, AS_INT, buffs);
+       
+       InitializeEntity(world, buffs_DelayedInit, INITPRIO_FINDTARGET);
+}
+
+MUTATOR_DEFINITION(mutator_buffs)
+{
+       MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, buffs_PlayerDamage_SplitHealthArmor, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDamage_Calculate, buffs_PlayerDamage_Calculate, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerSpawn, buffs_PlayerSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPhysics, buffs_PlayerPhysics, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerJump, buffs_PlayerJump, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterMove, buffs_MonsterMove, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SpectateCopy, buffs_SpectateCopy, CBC_ORDER_ANY);
+       MUTATOR_HOOK(VehicleEnter, buffs_VehicleEnter, CBC_ORDER_ANY);
+       MUTATOR_HOOK(VehicleExit, buffs_VehicleExit, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerRegen, buffs_PlayerRegen, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDies, buffs_PlayerDies, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerUseKey, buffs_PlayerUseKey, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MakePlayerObserver, buffs_RemovePlayer, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ClientDisconnect, buffs_RemovePlayer, CBC_ORDER_ANY);
+       MUTATOR_HOOK(OnEntityPreSpawn, buffs_OnEntityPreSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(CustomizeWaypoint, buffs_CustomizeWaypoint, CBC_ORDER_ANY);
+       MUTATOR_HOOK(WeaponRateFactor, buffs_WeaponRate, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPreThink, buffs_PlayerThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GetCvars, buffs_GetCvars, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BuildMutatorsString, buffs_BuildMutatorsString, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BuildMutatorsPrettyString, buffs_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+
+       MUTATOR_ONADD
+       {
+               buffs_Initialize();
+       }
+
+       return FALSE;
+}
diff --git a/qcsrc/server/mutators/mutator_buffs.qh b/qcsrc/server/mutators/mutator_buffs.qh
new file mode 100644 (file)
index 0000000..d8fc740
--- /dev/null
@@ -0,0 +1,25 @@
+// buff specific variables \\
+//
+// ammo
+.float buff_ammo_prev_infitems;
+// invisible
+.float buff_invisible_prev_alpha;
+// flight
+.float buff_flight_prev_gravity;
+// disability
+.float buff_disability_time;
+.float buff_disability_effect_time;
+
+// buff definitions
+.float buff_active;
+.float buff_activetime;
+.float buff_activetime_updated;
+.entity buff_waypoint;
+.float oldbuffs; // for updating effects
+.entity buff_model; // controls effects (TODO: make csqc)
+
+#define BUFF_MIN ('-16 -16 -20')
+#define BUFF_MAX ('16 16 20')
+
+// client side options
+.float cvar_cl_buffs_autoreplace;
index fb20d1cff2ea83e829708ba30bd999f2518bb7b5..2ec584db4cb23d265c5b105aceb2dbf6a3f33c7b 100644 (file)
@@ -25,6 +25,7 @@ MUTATOR_HOOKFUNCTION(campcheck_PlayerThink)
 {
        if(IS_PLAYER(self))
        if(self.deadflag == DEAD_NO)
+       if(!self.frozen)
        if(autocvar_g_campcheck_interval)
        {
                vector dist;
index 3f808499a8d4a5bd015b28ceec3a86d62797b3b2..b26fe1b9fff657fa13c38d35689ee689153d7c51 100644 (file)
@@ -35,7 +35,7 @@ MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) {
        float clean_up_and_do_nothing;
        float horiz_speed = autocvar_sv_dodging_horiz_speed;
 
-       if(self.freezetag_frozen)
+       if(self.frozen)
                horiz_speed = autocvar_sv_dodging_horiz_speed_frozen;
 
     if (self.deadflag != DEAD_NO)
@@ -169,8 +169,9 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
        tap_direction_x = 0;
        tap_direction_y = 0;
 
-       float frozen_dodging;
-       frozen_dodging = (self.freezetag_frozen && autocvar_sv_dodging_frozen);
+       float frozen_dodging, frozen_no_doubletap;
+       frozen_dodging = (self.frozen && autocvar_sv_dodging_frozen);
+       frozen_no_doubletap = (frozen_dodging && !autocvar_sv_dodging_frozen_doubletap);
 
        float dodge_detected;
        if (g_dodging == 0)
@@ -188,7 +189,7 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
 
        if (self.movement_x > 0) {
                // is this a state change?
-               if (!(self.pressedkeys & KEY_FORWARD) || frozen_dodging) {
+               if (!(self.pressedkeys & KEY_FORWARD) || frozen_no_doubletap) {
                        if ((time - self.last_FORWARD_KEY_time) < self.cvar_cl_dodging_timeout) {
                                tap_direction_x = 1.0;
                                dodge_detected = 1;
@@ -199,7 +200,7 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
 
        if (self.movement_x < 0) {
                // is this a state change?
-               if (!(self.pressedkeys & KEY_BACKWARD) || frozen_dodging) {
+               if (!(self.pressedkeys & KEY_BACKWARD) || frozen_no_doubletap) {
                        tap_direction_x = -1.0;
                        if ((time - self.last_BACKWARD_KEY_time) < self.cvar_cl_dodging_timeout)        {
                                dodge_detected = 1;
@@ -210,7 +211,7 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
 
        if (self.movement_y > 0) {
                // is this a state change?
-               if (!(self.pressedkeys & KEY_RIGHT) || frozen_dodging) {
+               if (!(self.pressedkeys & KEY_RIGHT) || frozen_no_doubletap) {
                        tap_direction_y = 1.0;
                        if ((time - self.last_RIGHT_KEY_time) < self.cvar_cl_dodging_timeout)   {
                                dodge_detected = 1;
@@ -221,7 +222,7 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
 
        if (self.movement_y < 0) {
                // is this a state change?
-               if (!(self.pressedkeys & KEY_LEFT) || frozen_dodging) {
+               if (!(self.pressedkeys & KEY_LEFT) || frozen_no_doubletap) {
                        tap_direction_y = -1.0;
                        if ((time - self.last_LEFT_KEY_time) < self.cvar_cl_dodging_timeout)    {
                                dodge_detected = 1;
diff --git a/qcsrc/server/mutators/mutator_instagib.qc b/qcsrc/server/mutators/mutator_instagib.qc
new file mode 100644 (file)
index 0000000..bd61023
--- /dev/null
@@ -0,0 +1,461 @@
+void spawnfunc_item_minst_cells (void)
+{
+       if (!g_instagib) { remove(self); return; }
+       if (!self.ammo_cells)
+               self.ammo_cells = autocvar_g_instagib_ammo_drop;
+
+       StartItem ("models/items/a_cells.md3",
+                          "misc/itempickup.wav", 45, 0,
+                          "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
+}
+
+void instagib_health_mega()
+{
+       self.max_health = 1;
+       StartItem ("models/items/g_h100.md3",
+                          "misc/megahealth.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
+                          "Extralife", IT_NAILS, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
+}
+
+.float instagib_nextthink;
+.float instagib_needammo;
+void instagib_stop_countdown(entity e)
+{
+       if (!e.instagib_needammo)
+               return;
+       Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_MINSTA_FINDAMMO);
+       e.instagib_needammo = FALSE;
+}
+void instagib_ammocheck()
+{
+       if (!IS_PLAYER(self))
+               return; // not a player
+       if (time < self.instagib_nextthink)
+               return;
+
+       if (self.deadflag || gameover)
+               instagib_stop_countdown(self);
+       else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
+               instagib_stop_countdown(self);
+       else
+       {
+               self.instagib_needammo = TRUE;
+               if (self.health == 5)
+               {
+                       Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_INSTAGIB_TERMINATED);
+               }
+               else if (self.health == 10)
+               {
+                       Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_1);
+               }
+               else if (self.health == 20)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_2);
+               }
+               else if (self.health == 30)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_3);
+               }
+               else if (self.health == 40)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_4);
+               }
+               else if (self.health == 50)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_5);
+               }
+               else if (self.health == 60)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_6);
+               }
+               else if (self.health == 70)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_7);
+               }
+               else if (self.health == 80)
+               {
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_8);
+               }
+               else if (self.health == 90)
+               {
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO);
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_9);
+               }
+               else if (self.health == 100)
+               {
+                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_MULTI, MULTI_MINSTA_FINDAMMO);
+                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
+               }
+       }
+       self.instagib_nextthink = time + 1;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MatchEnd)
+{
+       entity head;
+       FOR_EACH_PLAYER(head)
+               instagib_stop_countdown(head);
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MonsterLoot)
+{
+       other.monster_loot = spawnfunc_item_minst_cells;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MonsterSpawn)
+{
+       // always refill ammo
+       if(self.monsterid == MON_MAGE)
+               self.skin = 1;
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_BotShouldAttack)
+{
+       if(checkentity.items & IT_STRENGTH)
+               return TRUE;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_MakePlayerObserver)
+{
+       instagib_stop_countdown(self);
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerSpawn)
+{
+       self.effects |= EF_FULLBRIGHT;
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPreThink)
+{
+       instagib_ammocheck();
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerRegen)
+{
+       // no regeneration in instagib
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPowerups)
+{
+       if (!(self.effects & EF_FULLBRIGHT))
+               self.effects |= EF_FULLBRIGHT;
+
+       if (self.items & IT_STRENGTH)
+       {
+               play_countdown(self.strength_finished, "misc/poweroff.wav");
+               if (time > self.strength_finished)
+               {
+                       self.alpha = default_player_alpha;
+                       self.exteriorweaponentity.alpha = default_weapon_alpha;
+                       self.items &= ~IT_STRENGTH;
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
+               }
+       }
+       else
+       {
+               if (time < self.strength_finished)
+               {
+                       self.alpha = autocvar_g_instagib_invis_alpha;
+                       self.exteriorweaponentity.alpha = autocvar_g_instagib_invis_alpha;
+                       self.items |= IT_STRENGTH;
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
+               }
+       }
+
+       if (self.items & IT_INVINCIBLE)
+       {
+               play_countdown(self.invincible_finished, "misc/poweroff.wav");
+               if (time > self.invincible_finished)
+               {
+                       self.items &= ~IT_INVINCIBLE;
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
+               }
+       }
+       else
+       {
+               if (time < self.invincible_finished)
+               {
+                       self.items |= IT_INVINCIBLE;
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
+               }
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPhysics)
+{
+       if(self.items & IT_INVINCIBLE)
+               self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_instagib_speed_highspeed;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_SplitHealthArmor)
+{
+       damage_save = 0;
+       damage_take = frag_damage;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_ForbidThrowing)
+{
+       // weapon dropping on death handled by FilterItem
+
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
+{
+       if(autocvar_g_friendlyfire == 0 && SAME_TEAM(frag_target, frag_attacker) && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
+               frag_damage = 0;
+
+       if(IS_PLAYER(frag_target))
+       {
+               if ((frag_deathtype == DEATH_FALL)  ||
+                       (frag_deathtype == DEATH_DROWN) ||
+                       (frag_deathtype == DEATH_SLIME) ||
+                       (frag_deathtype == DEATH_LAVA))
+               {
+                       frag_damage = 0;
+               }
+
+               if(IS_PLAYER(frag_attacker))
+               if(DEATH_ISWEAPON(frag_deathtype, WEP_MINSTANEX))
+               if(frag_target.armorvalue)
+               {
+                       frag_target.armorvalue -= 1;
+                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_target.armorvalue);
+                       frag_damage = 0;
+                       frag_target.damage_dealt += 1;
+                       frag_attacker.damage_dealt += 1; // TODO change this to a future specific hitsound for armor hit
+               }
+
+               if(IS_PLAYER(frag_attacker))
+               if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
+               {
+                       frag_damage = 0;
+                       frag_mirrordamage = 0;
+                       if (frag_target != frag_attacker)
+                       {
+                               if (frag_target.health >= 1)
+                                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_SECONDARY);
+                               frag_force = '0 0 0';
+                               // keep mirrorfrag_force
+                               //frag_attacker = frag_target;
+                       }
+               }
+       }
+
+       if(IS_PLAYER(frag_attacker))
+       if(frag_mirrordamage > 0)
+       {
+               // just lose extra LIVES, don't kill the player for mirror damage
+               if(frag_attacker.armorvalue > 0)
+               {
+                       frag_attacker.armorvalue -= 1;
+                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_attacker.armorvalue);
+                       frag_attacker.damage_dealt += 1;
+               }
+               frag_mirrordamage = 0;
+       }
+
+       if(frag_target.items & IT_STRENGTH)
+               yoda = 1;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_SetStartItems)
+{
+       start_ammo_cells = cvar("g_instagib_ammo_start");
+
+       start_health = 100;
+       start_armorvalue = 0;
+       start_weapons = WEPSET_MINSTANEX;
+       warmup_start_weapons = WEPSET_MINSTANEX;
+       start_items |= IT_UNLIMITED_SUPERWEAPONS;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_FilterItem)
+{
+       if(self.classname == "item_cells")
+               return TRUE; // no normal cells?
+
+       if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
+       {
+               self.ammo_cells = autocvar_g_instagib_ammo_drop;
+               return FALSE;
+       }
+
+       if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
+       {
+               entity e = spawn();
+               setorigin(e, self.origin);
+               entity oldself;
+               oldself = self;
+               self = e;
+               spawnfunc_item_minst_cells();
+               self = oldself;
+               return TRUE;
+       }
+
+       if(self.flags & FL_POWERUP)
+               return FALSE;
+
+       if(self.ammo_cells > autocvar_g_instagib_ammo_drop && self.classname != "item_minst_cells")
+               self.ammo_cells = autocvar_g_instagib_ammo_drop;
+
+       if(self.ammo_cells && !self.weapon)
+               return FALSE;
+
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_CustomizeWaypoint)
+{
+       entity e = WaypointSprite_getviewentity(other);
+
+       // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
+       // but only apply this to real players, not to spectators
+       if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
+       if(DIFF_TEAM(self.owner, e))
+               return TRUE;
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_ItemCountdown)
+{
+       switch(self.items)
+       {
+               case IT_STRENGTH:   item_name = "item-invis"; item_color = '0 0 1'; break;
+               case IT_NAILS:      item_name = "item-extralife"; item_color = '1 0 0'; break;
+               case IT_INVINCIBLE: item_name = "item-speed"; item_color = '1 0 1'; break;
+       }
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_ItemTouch)
+{
+       if(self.ammo_cells)
+       {
+               // play some cool sounds ;)
+               if (IS_CLIENT(other))
+               {
+                       if(other.health <= 5)
+                               Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_INSTAGIB_LASTSECOND);
+                       else if(other.health < 50)
+                               Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_INSTAGIB_NARROWLY);
+               }
+
+               if(other.health < 100)
+                       other.health = 100;
+
+               return MUT_ITEMTOUCH_CONTINUE;
+       }
+
+       if(self.max_health)
+       {
+               other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_instagib_extralives);
+               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
+               return MUT_ITEMTOUCH_PICKUP;
+       }
+
+       return MUT_ITEMTOUCH_CONTINUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_OnEntityPreSpawn)
+{
+       if (!autocvar_g_powerups) { return FALSE; }
+       if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
+               return FALSE;
+
+       entity e = spawn();
+
+       if(random() < 0.3)
+               e.think = spawnfunc_item_strength;
+       else if(random() < 0.6)
+               e.think = instagib_health_mega;
+       else
+               e.think = spawnfunc_item_invincible;
+
+       e.nextthink = time + 0.1;
+       e.spawnflags = self.spawnflags;
+       e.noalign = self.noalign;
+       setorigin(e, self.origin);
+
+       return TRUE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_BuildMutatorsString)
+{
+       ret_string = strcat(ret_string, ":instagib");
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_BuildMutatorsPrettyString)
+{
+       ret_string = strcat(ret_string, ", instagib");
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_SetModname)
+{
+       modname = "instagib";
+       return TRUE;
+}
+
+MUTATOR_DEFINITION(mutator_instagib)
+{
+       MUTATOR_HOOK(MatchEnd, instagib_MatchEnd, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterDropItem, instagib_MonsterLoot, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterSpawn, instagib_MonsterSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BotShouldAttack, instagib_BotShouldAttack, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPhysics, instagib_PlayerPhysics, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerSpawn, instagib_PlayerSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDamage_Calculate, instagib_PlayerDamage, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MakePlayerObserver, instagib_MakePlayerObserver, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetStartItems, instagib_SetStartItems, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ItemTouch, instagib_ItemTouch, CBC_ORDER_ANY);
+       MUTATOR_HOOK(FilterItem, instagib_FilterItem, CBC_ORDER_ANY);
+       MUTATOR_HOOK(CustomizeWaypoint, instagib_CustomizeWaypoint, CBC_ORDER_ANY);
+       MUTATOR_HOOK(Item_RespawnCountdown, instagib_ItemCountdown, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, instagib_SplitHealthArmor, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPowerups, instagib_PlayerPowerups, CBC_ORDER_ANY);
+       MUTATOR_HOOK(ForbidThrowCurrentWeapon, instagib_ForbidThrowing, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPreThink, instagib_PlayerPreThink, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerRegen, instagib_PlayerRegen, CBC_ORDER_ANY);
+       MUTATOR_HOOK(OnEntityPreSpawn, instagib_OnEntityPreSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BuildMutatorsString, instagib_BuildMutatorsString, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BuildMutatorsPrettyString, instagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SetModname, instagib_SetModname, CBC_ORDER_ANY);
+
+       return FALSE;
+}
diff --git a/qcsrc/server/mutators/mutator_minstagib.qc b/qcsrc/server/mutators/mutator_minstagib.qc
deleted file mode 100644 (file)
index 6cce152..0000000
+++ /dev/null
@@ -1,462 +0,0 @@
-void spawnfunc_item_minst_cells (void)
-{
-       if (!g_minstagib) { remove(self); return; }
-       if (!self.ammo_cells)
-               self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-
-       StartItem ("models/items/a_cells.md3",
-                          "misc/itempickup.wav", 45, 0,
-                          "MinstaNex Ammo", IT_CELLS, 0, 0, generic_pickupevalfunc, 100);
-}
-
-void minstagib_health_mega()
-{
-       self.max_health = 1;
-       StartItem ("models/items/g_h100.md3",
-                          "misc/megahealth.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup,
-                          "Extralife", IT_NAILS, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_HIGH);
-}
-
-.float minstagib_nextthink;
-.float minstagib_needammo;
-void minstagib_stop_countdown(entity e)
-{
-       if (!e.minstagib_needammo)
-               return;
-       Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_MINSTA_FINDAMMO);
-       e.minstagib_needammo = FALSE;
-}
-void minstagib_ammocheck()
-{
-       if (!IS_PLAYER(self))
-               return; // not a player
-       if (time < self.minstagib_nextthink)
-               return;
-
-       if (self.deadflag || gameover)
-               minstagib_stop_countdown(self);
-       else if (self.ammo_cells > 0 || (self.items & IT_UNLIMITED_WEAPON_AMMO))
-               minstagib_stop_countdown(self);
-       else
-       {
-               self.minstagib_needammo = TRUE;
-               if (self.health == 5)
-               {
-                       Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_MINSTAGIB_TERMINATED);
-               }
-               else if (self.health == 10)
-               {
-                       Damage(self, self, self, 5, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_1);
-               }
-               else if (self.health == 20)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_2);
-               }
-               else if (self.health == 30)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_3);
-               }
-               else if (self.health == 40)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_4);
-               }
-               else if (self.health == 50)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_5);
-               }
-               else if (self.health == 60)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_6);
-               }
-               else if (self.health == 70)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_7);
-               }
-               else if (self.health == 80)
-               {
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_8);
-               }
-               else if (self.health == 90)
-               {
-                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MINSTA_FINDAMMO);
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-                       Send_Notification(NOTIF_ONE, self, MSG_ANNCE, ANNCE_NUM_9);
-               }
-               else if (self.health == 100)
-               {
-                       Send_Notification(NOTIF_ONE_ONLY, self, MSG_MULTI, MULTI_MINSTA_FINDAMMO);
-                       Damage(self, self, self, 10, DEATH_NOAMMO, self.origin, '0 0 0');
-               }
-       }
-       self.minstagib_nextthink = time + 1;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MatchEnd)
-{
-       entity head;
-       FOR_EACH_PLAYER(head)
-               minstagib_stop_countdown(head);
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MonsterLoot)
-{
-       other.monster_loot = spawnfunc_item_minst_cells;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MonsterSpawn)
-{
-       // always refill ammo
-       if(self.monsterid == MON_MAGE)
-               self.skin = 1;
-       
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_BotShouldAttack)
-{
-       if(checkentity.items & IT_STRENGTH)
-               return TRUE;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_MakePlayerObserver)
-{
-       minstagib_stop_countdown(self);
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerSpawn)
-{
-       self.effects |= EF_FULLBRIGHT;
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerPreThink)
-{
-       minstagib_ammocheck();
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerRegen)
-{
-       // no regeneration in minstagib
-       return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerPowerups)
-{
-       if (!(self.effects & EF_FULLBRIGHT))
-               self.effects |= EF_FULLBRIGHT;
-
-       if (self.items & IT_STRENGTH)
-       {
-               play_countdown(self.strength_finished, "misc/poweroff.wav");
-               if (time > self.strength_finished)
-               {
-                       self.alpha = default_player_alpha;
-                       self.exteriorweaponentity.alpha = default_weapon_alpha;
-                       self.items &= ~IT_STRENGTH;
-                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
-               }
-       }
-       else
-       {
-               if (time < self.strength_finished)
-               {
-                       self.alpha = autocvar_g_minstagib_invis_alpha;
-                       self.exteriorweaponentity.alpha = autocvar_g_minstagib_invis_alpha;
-                       self.items |= IT_STRENGTH;
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
-                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
-               }
-       }
-
-       if (self.items & IT_INVINCIBLE)
-       {
-               play_countdown(self.invincible_finished, "misc/poweroff.wav");
-               if (time > self.invincible_finished)
-               {
-                       self.items &= ~IT_INVINCIBLE;
-                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
-               }
-       }
-       else
-       {
-               if (time < self.invincible_finished)
-               {
-                       self.items |= IT_INVINCIBLE;
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
-                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
-               }
-       }
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerPhysics)
-{
-       if(self.items & IT_INVINCIBLE)
-               self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_minstagib_speed_highspeed;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_SplitHealthArmor)
-{
-       damage_save = 0;
-       damage_take = frag_damage;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_ForbidThrowing)
-{
-       // weapon dropping on death handled by FilterItem
-       nades_CheckThrow();
-
-       return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_PlayerDamage)
-{
-       if(autocvar_g_friendlyfire == 0 && SAME_TEAM(frag_target, frag_attacker) && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
-               frag_damage = 0;
-
-       if(IS_PLAYER(frag_target))
-       {
-               if ((frag_deathtype == DEATH_FALL)  ||
-                       (frag_deathtype == DEATH_DROWN) ||
-                       (frag_deathtype == DEATH_SLIME) ||
-                       (frag_deathtype == DEATH_LAVA))
-               {
-                       frag_damage = 0;
-               }
-
-               if(IS_PLAYER(frag_attacker))
-               if(DEATH_ISWEAPON(frag_deathtype, WEP_MINSTANEX))
-               if(frag_target.armorvalue)
-               {
-                       frag_target.armorvalue -= 1;
-                       Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_target.armorvalue);
-                       frag_damage = 0;
-                       frag_target.hitsound += 1;
-                       frag_attacker.hitsound += 1; // TODO change this to a future specific hitsound for armor hit
-               }
-
-               if(IS_PLAYER(frag_attacker))
-               if (DEATH_ISWEAPON(frag_deathtype, WEP_LASER))
-               {
-                       frag_damage = 0;
-                       frag_mirrordamage = 0;
-                       if (frag_target != frag_attacker)
-                       {
-                               if (frag_target.health >= 1)
-                                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_SECONDARY);
-                               frag_force = '0 0 0';
-                               // keep mirrorfrag_force
-                               //frag_attacker = frag_target;
-                       }
-               }
-       }
-
-       if(IS_PLAYER(frag_attacker))
-       if(frag_mirrordamage > 0)
-       {
-               // just lose extra LIVES, don't kill the player for mirror damage
-               if(frag_attacker.armorvalue > 0)
-               {
-                       frag_attacker.armorvalue -= 1;
-                       Send_Notification(NOTIF_ONE, frag_attacker, MSG_CENTER, CENTER_MINSTA_LIVES_REMAINING, frag_attacker.armorvalue);
-                       frag_attacker.hitsound += 1;
-               }
-               frag_mirrordamage = 0;
-       }
-
-       if(frag_target.items & IT_STRENGTH)
-               yoda = 1;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_SetStartItems)
-{
-       start_ammo_cells = cvar("g_minstagib_ammo_start");
-
-       start_health = 100;
-       start_armorvalue = 0;
-       start_weapons = WEPSET_MINSTANEX;
-       warmup_start_weapons = WEPSET_MINSTANEX;
-       start_items |= IT_UNLIMITED_SUPERWEAPONS;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_FilterItem)
-{
-       if(self.classname == "item_cells")
-               return TRUE; // no normal cells?
-
-       if(self.weapon == WEP_MINSTANEX && self.classname == "droppedweapon")
-       {
-               self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-               return FALSE;
-       }
-
-       if(self.weapon == WEP_ROCKET_LAUNCHER || self.weapon == WEP_NEX)
-       {
-               entity e = spawn();
-               setorigin(e, self.origin);
-               entity oldself;
-               oldself = self;
-               self = e;
-               spawnfunc_item_minst_cells();
-               self = oldself;
-               return TRUE;
-       }
-
-       if(self.flags & FL_POWERUP)
-               return FALSE;
-
-       if(self.ammo_cells > autocvar_g_minstagib_ammo_drop && self.classname != "item_minst_cells")
-               self.ammo_cells = autocvar_g_minstagib_ammo_drop;
-
-       if(self.ammo_cells && !self.weapon)
-               return FALSE;
-
-       return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_CustomizeWaypoint)
-{
-       entity e = WaypointSprite_getviewentity(other);
-
-       // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
-       // but only apply this to real players, not to spectators
-       if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
-       if(DIFF_TEAM(self.owner, e))
-               return TRUE;
-
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_ItemCountdown)
-{
-       switch(self.items)
-       {
-               case IT_STRENGTH:   item_name = "item-invis"; item_color = '0 0 1'; break;
-               case IT_NAILS:      item_name = "item-extralife"; item_color = '1 0 0'; break;
-               case IT_INVINCIBLE: item_name = "item-speed"; item_color = '1 0 1'; break;
-       }
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_ItemTouch)
-{
-       if(self.ammo_cells)
-       {
-               // play some cool sounds ;)
-               if (IS_CLIENT(other))
-               {
-                       if(other.health <= 5)
-                               Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_MINSTAGIB_LASTSECOND);
-                       else if(other.health < 50)
-                               Send_Notification(NOTIF_ONE, other, MSG_ANNCE, ANNCE_MINSTAGIB_NARROWLY);
-               }
-
-               if(other.health < 100)
-                       other.health = 100;
-
-               return MUT_ITEMTOUCH_CONTINUE;
-       }
-
-       if(self.max_health)
-       {
-               other.armorvalue = bound(other.armorvalue, 999, other.armorvalue + autocvar_g_minstagib_extralives);
-               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_EXTRALIVES);
-               return MUT_ITEMTOUCH_PICKUP;
-       }
-
-       return MUT_ITEMTOUCH_CONTINUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_OnEntityPreSpawn)
-{
-       if (!autocvar_g_powerups) { return FALSE; }
-       if (!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
-               return FALSE;
-
-       entity e = spawn();
-
-       if(random() < 0.3)
-               e.think = spawnfunc_item_strength;
-       else if(random() < 0.6)
-               e.think = minstagib_health_mega;
-       else
-               e.think = spawnfunc_item_invincible;
-
-       e.nextthink = time + 0.1;
-       e.spawnflags = self.spawnflags;
-       e.noalign = self.noalign;
-       setorigin(e, self.origin);
-
-       return TRUE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_BuildMutatorsString)
-{
-       ret_string = strcat(ret_string, ":MinstaGib");
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_BuildMutatorsPrettyString)
-{
-       ret_string = strcat(ret_string, ", MinstaGib");
-       return FALSE;
-}
-
-MUTATOR_HOOKFUNCTION(minstagib_SetModname)
-{
-       modname = "MinstaGib";
-       return TRUE;
-}
-
-MUTATOR_DEFINITION(mutator_minstagib)
-{
-       MUTATOR_HOOK(MatchEnd, minstagib_MatchEnd, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MonsterDropItem, minstagib_MonsterLoot, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MonsterSpawn, minstagib_MonsterSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BotShouldAttack, minstagib_BotShouldAttack, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPhysics, minstagib_PlayerPhysics, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerSpawn, minstagib_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_Calculate, minstagib_PlayerDamage, CBC_ORDER_ANY);
-       MUTATOR_HOOK(MakePlayerObserver, minstagib_MakePlayerObserver, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetStartItems, minstagib_SetStartItems, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ItemTouch, minstagib_ItemTouch, CBC_ORDER_ANY);
-       MUTATOR_HOOK(FilterItem, minstagib_FilterItem, CBC_ORDER_ANY);
-       MUTATOR_HOOK(CustomizeWaypoint, minstagib_CustomizeWaypoint, CBC_ORDER_ANY);
-       MUTATOR_HOOK(Item_RespawnCountdown, minstagib_ItemCountdown, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, minstagib_SplitHealthArmor, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPowerups, minstagib_PlayerPowerups, CBC_ORDER_ANY);
-       MUTATOR_HOOK(ForbidThrowCurrentWeapon, minstagib_ForbidThrowing, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerPreThink, minstagib_PlayerPreThink, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerRegen, minstagib_PlayerRegen, CBC_ORDER_ANY);
-       MUTATOR_HOOK(OnEntityPreSpawn, minstagib_OnEntityPreSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsString, minstagib_BuildMutatorsString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(BuildMutatorsPrettyString, minstagib_BuildMutatorsPrettyString, CBC_ORDER_ANY);
-       MUTATOR_HOOK(SetModname, minstagib_SetModname, CBC_ORDER_ANY);
-
-       return FALSE;
-}
index 2fad6022673c855e4fae529dfe8dc6158bba0954..da75e25ac23679fdaeea6bab190f0bc0311b2d62 100644 (file)
@@ -1,31 +1,20 @@
+.entity nade_spawnloc;
+
 void nade_timer_think()
 {
        self.skin = 8 - (self.owner.wait - time) / (autocvar_g_nades_nade_lifetime / 10);
        self.nextthink = time;
        if(!self.owner || wasfreed(self.owner))
                remove(self);
-
 }
 
 void nade_burn_spawn(entity _nade)
 {
-       float p;
-
-       switch(_nade.realowner.team)
-       {
-               case NUM_TEAM_1: p = PROJECTILE_NADE_RED_BURN; break;
-               case NUM_TEAM_2: p = PROJECTILE_NADE_BLUE_BURN; break;
-               case NUM_TEAM_3: p = PROJECTILE_NADE_YELLOW_BURN; break;
-               case NUM_TEAM_4: p = PROJECTILE_NADE_PINK_BURN; break;
-               default:                 p = PROJECTILE_NADE_BURN; break;
-       }
-
-       CSQCProjectile(_nade, TRUE, p, TRUE);
+       CSQCProjectile(_nade, TRUE, Nade_ProjectileFromID(_nade.nade_type, TRUE), TRUE);
 }
 
 void nade_spawn(entity _nade)
 {
-       float p;
        entity timer = spawn();
        setmodel(timer, "models/ok_nade_counter/ok_nade_counter.md3");
        setattachment(timer, _nade, "");
@@ -38,47 +27,529 @@ void nade_spawn(entity _nade)
        timer.owner = _nade;
        timer.skin = 10;
 
-       switch(_nade.realowner.team)
+       _nade.effects |= EF_LOWPRECISION;
+
+       CSQCProjectile(_nade, TRUE, Nade_ProjectileFromID(_nade.nade_type, FALSE), TRUE);
+}
+
+void napalm_damage(float dist, float damage, float edgedamage, float burntime)
+{
+       entity e;
+       float d;
+       vector p;
+
+       if ( damage < 0 )
+               return;
+
+       RandomSelection_Init();
+       for(e = WarpZone_FindRadius(self.origin, dist, TRUE); e; e = e.chain)
+               if(e.takedamage == DAMAGE_AIM)
+               if(self.realowner != e || autocvar_g_nades_napalm_selfdamage)
+               if(!IS_PLAYER(e) || !self.realowner || DIFF_TEAM(e, self))
+               if(!e.frozen)
+               {
+                       p = e.origin;
+                       p_x += e.mins_x + random() * (e.maxs_x - e.mins_x);
+                       p_y += e.mins_y + random() * (e.maxs_y - e.mins_y);
+                       p_z += e.mins_z + random() * (e.maxs_z - e.mins_z);
+                       d = vlen(WarpZone_UnTransformOrigin(e, self.origin) - p);
+                       if(d < dist)
+                       {
+                               e.fireball_impactvec = p;
+                               RandomSelection_Add(e, 0, string_null, 1 / (1 + d), !Fire_IsBurning(e));
+                       }
+               }
+       if(RandomSelection_chosen_ent)
        {
-               case NUM_TEAM_1: p = PROJECTILE_NADE_RED; break;
-               case NUM_TEAM_2: p = PROJECTILE_NADE_BLUE; break;
-               case NUM_TEAM_3: p = PROJECTILE_NADE_YELLOW; break;
-               case NUM_TEAM_4: p = PROJECTILE_NADE_PINK; break;
-               default:                 p = PROJECTILE_NADE; break;
+               d = vlen(WarpZone_UnTransformOrigin(RandomSelection_chosen_ent, self.origin) - RandomSelection_chosen_ent.fireball_impactvec);
+               d = damage + (edgedamage - damage) * (d / dist);
+               Fire_AddDamage(RandomSelection_chosen_ent, self.realowner, d * burntime, burntime, self.projectiledeathtype | HITTYPE_BOUNCE);
+               //trailparticles(self, particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.fireball_impactvec);
+               pointparticles(particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.fireball_impactvec - self.origin, 1);
        }
+}
 
-       CSQCProjectile(_nade, TRUE, p, TRUE);
 
+void napalm_ball_think()
+{
+       if(round_handler_IsActive())
+       if(!round_handler_IsRoundStarted())
+       {
+               remove(self);
+               return;
+       }
+
+       if(time > self.pushltime)
+       {
+               remove(self);
+               return;
+       }
+
+       vector midpoint = ((self.absmin + self.absmax) * 0.5);
+       if(pointcontents(midpoint) == CONTENT_WATER)
+       {
+               self.velocity = self.velocity * 0.5;
+
+               if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
+                       { self.velocity_z = 200; }
+       }
+
+       self.angles = vectoangles(self.velocity);
+
+       napalm_damage(autocvar_g_nades_napalm_ball_radius,autocvar_g_nades_napalm_ball_damage,
+                                 autocvar_g_nades_napalm_ball_damage,autocvar_g_nades_napalm_burntime);
+
+       self.nextthink = time + 0.1;
+}
+
+
+void nade_napalm_ball()
+{
+       entity proj;
+       vector kick;
+
+       spamsound(self, CH_SHOTS, "weapons/fireball_fire.wav", VOL_BASE, ATTEN_NORM);
+
+       proj = spawn ();
+       proj.owner = self.owner;
+       proj.realowner = self.realowner;
+       proj.team = self.owner.team;
+       proj.classname = "grenade";
+       proj.bot_dodge = TRUE;
+       proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
+       proj.movetype = MOVETYPE_BOUNCE;
+       proj.projectiledeathtype = DEATH_NADE_NAPALM;
+       PROJECTILE_MAKETRIGGER(proj);
+       setmodel(proj, "null");
+       proj.scale = 1;//0.5;
+       setsize(proj, '-4 -4 -4', '4 4 4');
+       setorigin(proj, self.origin);
+       proj.think = napalm_ball_think;
+       proj.nextthink = time;
+       proj.damageforcescale = autocvar_g_nades_napalm_ball_damageforcescale;
+       proj.effects = EF_LOWPRECISION | EF_FLAME;
+
+       kick_x =(random() - 0.5) * 2 * autocvar_g_nades_napalm_ball_spread;
+       kick_y = (random() - 0.5) * 2 * autocvar_g_nades_napalm_ball_spread;
+       kick_z = (random()/2+0.5) * autocvar_g_nades_napalm_ball_spread;
+       proj.velocity = kick;
+
+       proj.pushltime = time + autocvar_g_nades_napalm_ball_lifetime;
+
+       proj.angles = vectoangles(proj.velocity);
+       proj.flags = FL_PROJECTILE;
+       proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
+
+       //CSQCProjectile(proj, TRUE, PROJECTILE_NAPALM_FIRE, TRUE);
+}
+
+
+void napalm_fountain_think()
+{
+
+       if(round_handler_IsActive())
+       if(!round_handler_IsRoundStarted())
+       {
+               remove(self);
+               return;
+       }
+
+       if(time >= self.ltime)
+       {
+               remove(self);
+               return;
+       }
+
+       vector midpoint = ((self.absmin + self.absmax) * 0.5);
+       if(pointcontents(midpoint) == CONTENT_WATER)
+       {
+               self.velocity = self.velocity * 0.5;
+
+               if(pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
+                       { self.velocity_z = 200; }
+
+               UpdateCSQCProjectile(self);
+       }
+
+       napalm_damage(autocvar_g_nades_napalm_fountain_radius, autocvar_g_nades_napalm_fountain_damage,
+               autocvar_g_nades_napalm_fountain_edgedamage, autocvar_g_nades_napalm_burntime);
+
+       self.nextthink = time + 0.1;
+       if(time >= self.nade_special_time)
+       {
+               self.nade_special_time = time + autocvar_g_nades_napalm_fountain_delay;
+               nade_napalm_ball();
+       }
+}
+
+void nade_napalm_boom()
+{
+       entity fountain;
+       local float c;
+       for (c = 0; c < autocvar_g_nades_napalm_ball_count; c ++)
+               nade_napalm_ball();
+
+
+       fountain = spawn();
+       fountain.owner = self.owner;
+       fountain.realowner = self.realowner;
+       fountain.origin = self.origin;
+       setorigin(fountain, fountain.origin);
+       fountain.think = napalm_fountain_think;
+       fountain.nextthink = time;
+       fountain.ltime = time + autocvar_g_nades_napalm_fountain_lifetime;
+       fountain.pushltime = fountain.ltime;
+       fountain.team = self.team;
+       fountain.movetype = MOVETYPE_TOSS;
+       fountain.projectiledeathtype = DEATH_NADE_NAPALM;
+       fountain.bot_dodge = TRUE;
+       fountain.bot_dodgerating = autocvar_g_nades_napalm_fountain_damage;
+       fountain.nade_special_time = time;
+       setsize(fountain, '-16 -16 -16', '16 16 16');
+       CSQCProjectile(fountain, TRUE, PROJECTILE_NAPALM_FOUNTAIN, TRUE);
+}
+
+void nade_ice_freeze(entity freezefield, entity frost_target, float freeze_time)
+{
+       frost_target.frozen_by = freezefield.realowner;
+       pointparticles(particleeffectnum("electro_impact"), frost_target.origin, '0 0 0', 1);
+       Freeze(frost_target, 1/freeze_time, 3, FALSE);
+       if(frost_target.ballcarried)
+       if(g_keepaway) { ka_DropEvent(frost_target); }
+       else { DropBall(frost_target.ballcarried, frost_target.origin, frost_target.velocity);}
+       if(frost_target.flagcarried) { ctf_Handle_Throw(frost_target, world, DROP_THROW); }
+       if(frost_target.nade) { toss_nade(frost_target, '0 0 0', time + 0.05); }
+       
+       kh_Key_DropAll(frost_target, FALSE);
+}
+
+void nade_ice_think()
+{
+
+       if(round_handler_IsActive())
+       if(!round_handler_IsRoundStarted())
+       {
+               remove(self);
+               return;
+       }
+
+       if(time >= self.ltime)
+       {
+               if ( autocvar_g_nades_ice_explode )
+               {
+                       string expef;
+                       switch(self.realowner.team)
+                       {
+                               case NUM_TEAM_1: expef = "nade_red_explode"; break;
+                               case NUM_TEAM_2: expef = "nade_blue_explode"; break;
+                               case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
+                               case NUM_TEAM_4: expef = "nade_pink_explode"; break;
+                               default:                 expef = "nade_neutral_explode"; break;
+                       }
+                       pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1);
+                       sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
+
+                       RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+                               autocvar_g_nades_nade_radius, self, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
+                       Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+                               autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
+               }
+               remove(self);
+               return;
+       }
+
+
+       self.nextthink = time+0.1;
+
+       // gaussian
+       float randomr;
+       randomr = random();
+       randomr = exp(-5*randomr*randomr)*autocvar_g_nades_nade_radius;
+       float randomw;
+       randomw = random()*M_PI*2;
+       vector randomp;
+       randomp_x = randomr*cos(randomw);
+       randomp_y = randomr*sin(randomw);
+       randomp_z = 1;
+       pointparticles(particleeffectnum("electro_muzzleflash"), self.origin + randomp, '0 0 0', 1);
+
+       if(time >= self.nade_special_time)
+       {
+               self.nade_special_time = time+0.7;
+
+
+               pointparticles(particleeffectnum("electro_impact"), self.origin, '0 0 0', 1);
+               pointparticles(particleeffectnum("icefield"), self.origin, '0 0 0', 1);
+       }
+
+
+       float current_freeze_time = self.ltime - time - 0.1;
+
+       entity e;
+       for(e = findradius(self.origin, autocvar_g_nades_nade_radius); e; e = e.chain)
+       if(e != self)
+       if(!autocvar_g_nades_ice_teamcheck || (DIFF_TEAM(e, self.realowner) || e == self.realowner))
+       if(e.takedamage && e.deadflag == DEAD_NO)
+       if(e.health > 0)
+       if(!e.revival_time || ((time - e.revival_time) >= 1.5))
+       if(!e.frozen)
+       if(current_freeze_time > 0)
+               nade_ice_freeze(self, e, current_freeze_time);
+}
+
+void nade_ice_boom()
+{
+       entity fountain;
+       fountain = spawn();
+       fountain.owner = self.owner;
+       fountain.realowner = self.realowner;
+       fountain.origin = self.origin;
+       setorigin(fountain, fountain.origin);
+       fountain.think = nade_ice_think;
+       fountain.nextthink = time;
+       fountain.ltime = time + autocvar_g_nades_ice_freeze_time;
+       fountain.pushltime = fountain.wait = fountain.ltime;
+       fountain.team = self.team;
+       fountain.movetype = MOVETYPE_TOSS;
+       fountain.projectiledeathtype = DEATH_NADE_ICE;
+       fountain.bot_dodge = FALSE;
+       setsize(fountain, '-16 -16 -16', '16 16 16');
+       fountain.nade_special_time = time+0.3;
+       fountain.angles = self.angles;
+
+       if ( autocvar_g_nades_ice_explode )
+       {
+               setmodel(fountain, "models/grenademodel.md3");
+               entity timer = spawn();
+               setmodel(timer, "models/ok_nade_counter/ok_nade_counter.md3");
+               setattachment(timer, fountain, "");
+               timer.classname = "nade_timer";
+               timer.colormap = self.colormap;
+               timer.glowmod = self.glowmod;
+               timer.think = nade_timer_think;
+               timer.nextthink = time;
+               timer.wait = fountain.ltime;
+               timer.owner = fountain;
+               timer.skin = 10;
+       }
+       else
+               setmodel(fountain, "null");
+}
+
+void nade_translocate_boom()
+{
+       if(self.realowner.vehicle)
+               return;
+
+       vector locout = self.origin + '0 0 1' * (1 - self.realowner.mins_z - 24);
+       tracebox(locout, self.realowner.mins, self.realowner.maxs, locout, MOVE_NOMONSTERS, self.realowner);
+       locout = trace_endpos;
+
+       makevectors(self.realowner.angles);
+
+       entity oldself = self;
+       self = self.realowner;
+       MUTATOR_CALLHOOK(PortalTeleport);
+       self.realowner = self;
+       self = oldself;
+
+       TeleportPlayer(self, self.realowner, locout, self.realowner.mangle, v_forward * vlen(self.realowner.velocity), '0 0 0', '0 0 0', TELEPORT_FLAGS_TELEPORTER);
+}
+
+void nade_spawn_boom()
+{
+       entity spawnloc = spawn();
+       setorigin(spawnloc, self.origin);
+       setsize(spawnloc, self.realowner.mins, self.realowner.maxs);
+       spawnloc.movetype = MOVETYPE_NONE;
+       spawnloc.solid = SOLID_NOT;
+       spawnloc.drawonlytoclient = self.realowner;
+       spawnloc.effects = EF_STARDUST;
+       spawnloc.cnt = autocvar_g_nades_spawn_count;
+
+       if(self.realowner.nade_spawnloc)
+       {
+               remove(self.realowner.nade_spawnloc);
+               self.realowner.nade_spawnloc = world;
+       }
+
+       self.realowner.nade_spawnloc = spawnloc;
+}
+
+void nade_heal_think()
+{
+       if(time >= self.ltime)
+       {
+               remove(self);
+               return;
+       }
+       
+       self.nextthink = time;
+       
+       if(time >= self.nade_special_time)
+       {
+               self.nade_special_time = time+0.25;
+               self.nade_show_particles = 1;
+       }
+       else
+               self.nade_show_particles = 0;
+}
+
+void nade_heal_touch()
+{
+       float maxhealth;
+       float health_factor;
+       if(IS_PLAYER(other) || (other.flags & FL_MONSTER))
+       if(other.deadflag == DEAD_NO)
+       if(!other.frozen)
+       {
+               health_factor = autocvar_g_nades_heal_rate*frametime/2;
+               if ( other != self.realowner )
+               {
+                       if ( SAME_TEAM(other,self) )
+                               health_factor *= autocvar_g_nades_heal_friend;
+                       else
+                               health_factor *= autocvar_g_nades_heal_foe;
+               }
+               if ( health_factor > 0 )
+               {
+                       maxhealth = (other.flags & FL_MONSTER) ? other.max_health : g_pickup_healthmega_max;
+                       if ( other.health < maxhealth )
+                       {
+                               if ( self.nade_show_particles )
+                                       pointparticles(particleeffectnum("healing_fx"), other.origin, '0 0 0', 1);
+                               other.health = min(other.health+health_factor, maxhealth);
+                       }
+                       other.pauserothealth_finished = max(other.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);  
+               }
+               else if ( health_factor < 0 )
+               {
+                       Damage(other,self,self.realowner,-health_factor,DEATH_NADE_HEAL,other.origin,'0 0 0');
+               }
+               
+       }
+       
+       if ( IS_REAL_CLIENT(other) || (other.vehicle_flags & VHF_ISVEHICLE) )
+       {
+               entity show_red = (other.vehicle_flags & VHF_ISVEHICLE) ? other.owner : other;
+               show_red.stat_healing_orb = time+0.1;
+               show_red.stat_healing_orb_alpha = 0.75 * (self.ltime - time) / self.healer_lifetime;
+       }
+}
+
+void nade_heal_boom()
+{
+       entity healer;
+       healer = spawn();
+       healer.owner = self.owner;
+       healer.realowner = self.realowner;
+       setorigin(healer, self.origin);
+       healer.healer_lifetime = autocvar_g_nades_heal_time; // save the cvar
+       healer.ltime = time + healer.healer_lifetime;
+       healer.team = self.realowner.team;
+       healer.bot_dodge = FALSE;
+       healer.solid = SOLID_TRIGGER;
+       healer.touch = nade_heal_touch;
+
+       setmodel(healer, "models/ctf/shield.md3");
+       healer.healer_radius = autocvar_g_nades_nade_radius;
+       vector size = '1 1 1' * healer.healer_radius / 2;
+       setsize(healer,-size,size);
+       
+       Net_LinkEntity(healer, TRUE, 0, healer_send);
+       
+       healer.think = nade_heal_think;
+       healer.nextthink = time;
+       healer.SendFlags |= 1;
+}
+
+void nade_monster_boom()
+{
+       entity e = spawnmonster(self.pokenade_type, 0, self.realowner, self.realowner, self.origin, FALSE, FALSE, 1);
+       
+       if(autocvar_g_nades_pokenade_monster_lifetime > 0)
+               e.monster_lifetime = time + autocvar_g_nades_pokenade_monster_lifetime;
+       e.monster_skill = MONSTER_SKILL_INSANE;
 }
 
 void nade_boom()
 {
        string expef;
+       float nade_blast = 1;
 
-       switch(self.realowner.team)
+       switch ( self.nade_type )
        {
-               case NUM_TEAM_1: expef = "nade_red_explode"; break;
-               case NUM_TEAM_2: expef = "nade_blue_explode"; break;
-               case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
-               case NUM_TEAM_4: expef = "nade_pink_explode"; break;
-               default:                 expef = "nade_explode"; break;
+               case NADE_TYPE_NAPALM:
+                       nade_blast = autocvar_g_nades_napalm_blast;
+                       expef = "explosion_medium";
+                       break;
+               case NADE_TYPE_ICE:
+                       nade_blast = 0;
+                       expef = "electro_combo"; // hookbomb_explode electro_combo bigplasma_impact
+                       break;
+               case NADE_TYPE_TRANSLOCATE:
+                       nade_blast = 0;
+                       expef = "";
+                       break;
+               case NADE_TYPE_MONSTER:
+               case NADE_TYPE_SPAWN:
+                       nade_blast = 0;
+                       switch(self.realowner.team)
+                       {
+                               case NUM_TEAM_1: expef = "spawn_event_red"; break;
+                               case NUM_TEAM_2: expef = "spawn_event_blue"; break;
+                               case NUM_TEAM_3: expef = "spawn_event_yellow"; break;
+                               case NUM_TEAM_4: expef = "spawn_event_pink"; break;
+                               default: expef = "spawn_event_neutral"; break;
+                       }
+                       break;
+               case NADE_TYPE_HEAL:
+                       nade_blast = 0;
+                       expef = "spawn_event_red";
+                       break;
+
+               default:
+               case NADE_TYPE_NORMAL:
+                       switch(self.realowner.team)
+                       {
+                               case NUM_TEAM_1: expef = "nade_red_explode"; break;
+                               case NUM_TEAM_2: expef = "nade_blue_explode"; break;
+                               case NUM_TEAM_3: expef = "nade_yellow_explode"; break;
+                               case NUM_TEAM_4: expef = "nade_pink_explode"; break;
+                               default:                 expef = "nade_neutral_explode"; break;
+                       }
        }
 
-       sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
-       sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
        pointparticles(particleeffectnum(expef), self.origin + '0 0 1', '0 0 0', 1);
 
-       Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
+       sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM);
 
        self.takedamage = DAMAGE_NO;
-       RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
+
+       if(nade_blast)
+       {
+               RadiusDamage(self, self.realowner, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage,
                                 autocvar_g_nades_nade_radius, self, autocvar_g_nades_nade_force, self.projectiledeathtype, self.enemy);
+               Damage_DamageInfo(self.origin, autocvar_g_nades_nade_damage, autocvar_g_nades_nade_edgedamage, autocvar_g_nades_nade_radius, '1 1 1' * autocvar_g_nades_nade_force, self.projectiledeathtype, 0, self);
+       }
+
+       switch ( self.nade_type )
+       {
+               case NADE_TYPE_NAPALM: nade_napalm_boom(); break;
+               case NADE_TYPE_ICE: nade_ice_boom(); break;
+               case NADE_TYPE_TRANSLOCATE: nade_translocate_boom(); break;
+               case NADE_TYPE_SPAWN: nade_spawn_boom(); break;
+               case NADE_TYPE_HEAL: nade_heal_boom(); break;
+               case NADE_TYPE_MONSTER: nade_monster_boom(); break;
+       }
 
        remove(self);
 }
 
 void nade_touch()
 {
+       if(trace_dphitcontents & (DPCONTENTS_PLAYERCLIP | DPCONTENTS_MONSTERCLIP)) { return; }
        PROJECTILE_TOUCH;
        //setsize(self, '-2 -2 -2', '2 2 2');
        //UpdateCSQCProjectile(self);
@@ -101,6 +572,9 @@ void nade_beep()
 
 void nade_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
+       if(self.nade_type == NADE_TYPE_TRANSLOCATE || self.nade_type == NADE_TYPE_SPAWN)
+               return;
+
        if(DEATH_ISWEAPON(deathtype, WEP_LASER))
                return;
 
@@ -113,14 +587,14 @@ void nade_damage(entity inflictor, entity attacker, float damage, float deathtyp
        if(DEATH_ISWEAPON(deathtype, WEP_UZI))
                damage = self.max_health * 0.1;
 
-       if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && !(deathtype & HITTYPE_SECONDARY))
-               damage = self.max_health * 1.1;
-
-       if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN) && (deathtype & HITTYPE_SECONDARY))
+       if(DEATH_ISWEAPON(deathtype, WEP_SHOTGUN))
+       if(deathtype & HITTYPE_SECONDARY)
        {
                damage = self.max_health * 0.1;
-               force *= 15;
+               force *= 10;
        }
+       else
+               damage = self.max_health * 1.1;
 
        self.velocity += force;
 
@@ -134,8 +608,10 @@ void nade_damage(entity inflictor, entity attacker, float damage, float deathtyp
                self.think = nade_beep;
        }
 
-       self.health   -= damage;
-       self.realowner = attacker;
+       self.health       -= damage;
+       
+       if ( self.nade_type != NADE_TYPE_HEAL || IS_PLAYER(attacker) )
+               self.realowner = attacker;
 
        if(self.health <= 0)
                W_PrepareExplosionByDamage(attacker, nade_boom);
@@ -145,6 +621,9 @@ void nade_damage(entity inflictor, entity attacker, float damage, float deathtyp
 
 void toss_nade(entity e, vector _velocity, float _time)
 {
+       if(e.nade == world)
+               return;
+
        entity _nade = e.nade;
        e.nade = world;
 
@@ -157,10 +636,9 @@ void toss_nade(entity e, vector _velocity, float _time)
 
        Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
 
-       //setorigin(_nade, CENTER_OR_VIEWOFS(e) + (v_right * 10) * -1);
        setorigin(_nade, w_shotorg + (v_right * 25) * -1);
-       setmodel(_nade, "models/weapons/v_ok_grenade.md3");
-       setattachment(_nade, world, "");
+       //setmodel(_nade, "models/weapons/v_ok_grenade.md3");
+       //setattachment(_nade, world, "");
        PROJECTILE_MAKETRIGGER(_nade);
        setsize(_nade, '-16 -16 -16', '16 16 16');
        _nade.movetype = MOVETYPE_BOUNCE;
@@ -177,12 +655,16 @@ void toss_nade(entity e, vector _velocity, float _time)
                _nade.velocity = _velocity;
        else
                _nade.velocity = W_CalculateProjectileVelocity(e.velocity, _velocity, TRUE);
-               
+
        _nade.touch = nade_touch;
        _nade.health = autocvar_g_nades_nade_health;
        _nade.max_health = _nade.health;
        _nade.takedamage = DAMAGE_AIM;
        _nade.event_damage = nade_damage;
+       _nade.customizeentityforclient = func_null;
+       _nade.exteriormodeltoclient = world;
+       _nade.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
+       _nade.traileffectnum = 0;
        _nade.teleportable = TRUE;
        _nade.pushable = TRUE;
        _nade.gravity = 1;
@@ -190,6 +672,9 @@ void toss_nade(entity e, vector _velocity, float _time)
        _nade.damagedbycontents = TRUE;
        _nade.angles = vectoangles(_nade.velocity);
        _nade.flags = FL_PROJECTILE;
+       _nade.projectiledeathtype = DEATH_NADE;
+       _nade.toss_time = time;
+       _nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
 
        nade_spawn(_nade);
 
@@ -200,6 +685,56 @@ void toss_nade(entity e, vector _velocity, float _time)
        }
 
        e.nade_refire = time + autocvar_g_nades_nade_refire;
+       e.nade_timer = 0;
+}
+
+void nades_GiveBonus(entity player, float score)
+{
+       if (autocvar_g_nades)
+       if (autocvar_g_nades_bonus)
+       if (IS_REAL_CLIENT(player))
+       if (IS_PLAYER(player) && player.bonus_nades < autocvar_g_nades_bonus_max)
+       if (player.frozen == 0)
+       if (player.deadflag == DEAD_NO)
+       {
+               if ( player.bonus_nade_score < 1 )
+                       player.bonus_nade_score += score/autocvar_g_nades_bonus_score_max;
+
+               if ( player.bonus_nade_score >= 1 )
+               {
+                       Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_NADE_BONUS);
+                       play2(player,"kh/alarm.wav");
+                       player.bonus_nades++;
+                       player.bonus_nade_score -= 1;
+               }
+       }
+}
+
+void nades_RemoveBonus(entity player)
+{
+       player.bonus_nades = player.bonus_nade_score = 0;
+}
+
+float nade_customize()
+{
+       //if(IS_SPEC(other)) { return FALSE; }
+       if(other == self.realowner || (IS_SPEC(other) && other.enemy == self.realowner))
+       {
+               // somewhat hide the model, but keep the glow
+               //self.effects = 0;
+               if(self.traileffectnum)
+                       self.traileffectnum = 0;
+               self.alpha = -1;
+       }
+       else
+       {
+               //self.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+               if(!self.traileffectnum)
+                       self.traileffectnum = particleeffectnum(Nade_TrailEffect(Nade_ProjectileFromID(self.nade_type, FALSE), self.team));
+               self.alpha = 1;
+       }
+       
+       return TRUE;
 }
 
 void nade_prime()
@@ -210,29 +745,53 @@ void nade_prime()
        if(self.fake_nade)
                remove(self.fake_nade);
 
-       self.nade = spawn();
-       setmodel(self.nade, "null");
-       setattachment(self.nade, self, "bip01 l hand");
-       self.nade.classname = "nade";
-       self.nade.realowner = self;
-       self.nade.colormap = self.colormap;
-       self.nade.glowmod = self.glowmod;
-       self.nade.wait = time + autocvar_g_nades_nade_lifetime;
-       self.nade.lifetime = time;
-       self.nade.think = nade_beep;
-       self.nade.nextthink = max(self.nade.wait - 3, time);
-       self.nade.projectiledeathtype = DEATH_NADE;
-
-       self.fake_nade = spawn();
-       setmodel(self.fake_nade, "models/weapons/h_ok_grenade.iqm");
-       setattachment(self.fake_nade, self.weaponentity, "");
-       self.fake_nade.classname = "fake_nade";
-       //self.fake_nade.viewmodelforclient = self;
-       self.fake_nade.realowner = self.fake_nade.owner = self;
-       self.fake_nade.colormap = self.colormap;
-       self.fake_nade.glowmod = self.glowmod;
-       self.fake_nade.think = SUB_Remove;
-       self.fake_nade.nextthink = self.nade.wait;
+       entity n = spawn(), fn = spawn();
+
+       n.classname = "nade";
+       fn.classname = "fake_nade";
+
+       if(self.items & IT_STRENGTH && autocvar_g_nades_bonus_onstrength)
+               n.nade_type = self.nade_type;
+       else if (self.bonus_nades >= 1)
+       {
+               n.nade_type = self.nade_type;
+               n.pokenade_type = self.pokenade_type;
+               self.bonus_nades -= 1;
+       }
+       else
+       {
+               n.nade_type = ((autocvar_g_nades_client_select) ? self.cvar_cl_nade_type : autocvar_g_nades_nade_type);
+               n.pokenade_type = ((autocvar_g_nades_client_select) ? self.cvar_cl_pokenade_type : autocvar_g_nades_pokenade_monster_type);
+       }
+       
+       n.nade_type = bound(1, n.nade_type, NADE_TYPE_LAST);
+
+       setmodel(n, "models/weapons/v_ok_grenade.md3");
+       //setattachment(n, self, "bip01 l hand");
+       n.exteriormodeltoclient = self;
+       n.customizeentityforclient = nade_customize;
+       n.traileffectnum = particleeffectnum(Nade_TrailEffect(Nade_ProjectileFromID(n.nade_type, FALSE), self.team));
+       n.colormod = Nade_Color(n.nade_type);
+       n.realowner = self;
+       n.colormap = self.colormap;
+       n.glowmod = self.glowmod;
+       n.wait = time + autocvar_g_nades_nade_lifetime;
+       n.lifetime = time;
+       n.think = nade_beep;
+       n.nextthink = max(n.wait - 3, time);
+       n.projectiledeathtype = DEATH_NADE;
+
+       setmodel(fn, "models/weapons/h_ok_grenade.iqm");
+       setattachment(fn, self.weaponentity, "");
+       fn.realowner = fn.owner = self;
+       fn.colormod = Nade_Color(n.nade_type);
+       fn.colormap = self.colormap;
+       fn.glowmod = self.glowmod;
+       fn.think = SUB_Remove;
+       fn.nextthink = n.wait;
+
+       self.nade = n;
+       self.fake_nade = fn;
 }
 
 float CanThrowNade()
@@ -285,21 +844,55 @@ void nades_CheckThrow()
        }
 }
 
+void nades_Clear(entity player)
+{
+       if(player.nade)
+               remove(player.nade);
+       if(player.fake_nade)
+               remove(player.fake_nade);
+
+       player.nade = player.fake_nade = world;
+       player.nade_timer = 0;
+}
+
+MUTATOR_HOOKFUNCTION(nades_CheckThrow)
+{
+       if(MUTATOR_RETURNVALUE) { nades_CheckThrow(); }
+       return FALSE;
+}
+
 MUTATOR_HOOKFUNCTION(nades_VehicleEnter)
 {
-       if(other.nade)
-               toss_nade(other, '0 0 100', max(other.nade.wait, time + 0.05));
+       if(vh_player.nade)
+               toss_nade(vh_player, '0 0 100', max(vh_player.nade.wait, time + 0.05));
 
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
 {
-       float key_pressed = ((g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK)) ? self.button16 : self.BUTTON_HOOK);
+       if(!IS_PLAYER(self)) { return FALSE; }
+
+       float key_pressed = self.BUTTON_HOOK;
+       float time_score;
 
+       if(g_grappling_hook || client_hasweapon(self, WEP_HOOK, FALSE, FALSE) || (weaponsInMap & WEPSET_HOOK) || g_jetpack || self.items & IT_JETPACK)
+               key_pressed = self.button16; // if hook/jetpack is enabled, use an alternate key
+               
        if(self.nade)
-               if(self.nade.wait - 0.1 <= time)
-                       toss_nade(self, '0 0 0', time + 0.05);
+       {
+               self.nade_timer = bound(0, (time - self.nade.lifetime) / autocvar_g_nades_nade_lifetime, 1);
+               //print(sprintf("%d %d\n", self.nade_timer, time - self.nade.lifetime));
+               makevectors(self.angles);
+               self.nade.velocity = self.velocity;
+
+               setorigin(self.nade, self.origin + self.view_ofs + v_forward * 8 + v_right * -8 + v_up * 0);
+               self.nade.angles_y = self.angles_y;
+       }
+
+       if(self.nade)
+       if(self.nade.wait - 0.1 <= time)
+               toss_nade(self, '0 0 0', time + 0.05);
 
        if(CanThrowNade())
        if(self.nade_refire < time)
@@ -322,6 +915,88 @@ MUTATOR_HOOKFUNCTION(nades_PlayerPreThink)
                }
        }
 
+       if(IS_PLAYER(self))
+       {
+               if ( autocvar_g_nades_bonus && autocvar_g_nades )
+               {
+                       entity key;
+                       float key_count = 0;
+                       FOR_EACH_KH_KEY(key) if(key.owner == self) { ++key_count; }
+
+                       if(self.flagcarried || self.ballcarried) // this player is important
+                               time_score = autocvar_g_nades_bonus_score_time_flagcarrier;
+                       else
+                               time_score = autocvar_g_nades_bonus_score_time;
+                               
+                       if(key_count)
+                               time_score = autocvar_g_nades_bonus_score_time_flagcarrier * key_count; // multiply by the number of keys the player is holding
+
+                       if(autocvar_g_nades_bonus_client_select)
+                       {
+                               self.nade_type = self.cvar_cl_nade_type;
+                               self.pokenade_type = self.cvar_cl_pokenade_type;
+                       }
+                       else
+                       {
+                               self.nade_type = autocvar_g_nades_bonus_type;
+                               self.pokenade_type = autocvar_g_nades_pokenade_monster_type;
+                       }
+                               
+                       self.nade_type = bound(1, self.nade_type, NADE_TYPE_LAST);
+
+                       if(self.bonus_nade_score >= 0 && autocvar_g_nades_bonus_score_max)
+                               nades_GiveBonus(self, time_score / autocvar_g_nades_bonus_score_max);
+               }
+               else
+               {
+                       self.bonus_nades = self.bonus_nade_score = 0;
+               }
+       }
+
+       float n = 0;
+       entity o = world;
+       if(self.freezetag_frozen_timeout > 0 && time >= self.freezetag_frozen_timeout)
+               n = -1;
+       else
+       {
+               vector revive_extra_size = '1 1 1' * autocvar_g_freezetag_revive_extra_size;
+               n = 0;
+               FOR_EACH_PLAYER(other) if(self != other)
+               {
+                       if(other.deadflag == DEAD_NO)
+                       if(other.frozen == 0)
+                       if(SAME_TEAM(other, self))
+                       if(boxesoverlap(self.absmin - revive_extra_size, self.absmax + revive_extra_size, other.absmin, other.absmax))
+                       {
+                               if(!o)
+                                       o = other;
+                               if(self.frozen == 1)
+                                       other.reviving = TRUE;
+                               ++n;
+                       }
+               }
+       }
+
+       if(n && self.frozen == 3) // OK, there is at least one teammate reviving us
+       {
+               self.revive_progress = bound(0, self.revive_progress + frametime * max(1/60, autocvar_g_freezetag_revive_speed), 1);
+               self.health = max(1, self.revive_progress * start_health);
+
+               if(self.revive_progress >= 1)
+               {
+                       Unfreeze(self);
+
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_FREEZETAG_REVIVED, o.netname);
+                       Send_Notification(NOTIF_ONE, o, MSG_CENTER, CENTER_FREEZETAG_REVIVE, self.netname);
+               }
+
+               FOR_EACH_PLAYER(other) if(other.reviving)
+               {
+                       other.revive_progress = self.revive_progress;
+                       other.reviving = FALSE;
+               }
+       }
+
        return FALSE;
 }
 
@@ -332,24 +1007,113 @@ MUTATOR_HOOKFUNCTION(nades_PlayerSpawn)
        else
                self.nade_refire  = time + autocvar_g_nades_nade_refire;
 
+       if(autocvar_g_nades_bonus_client_select)
+               self.nade_type = self.cvar_cl_nade_type;
+
+       self.nade_timer = 0;
+
+       if(self.nade_spawnloc)
+       {
+               setorigin(self, self.nade_spawnloc.origin);
+               self.nade_spawnloc.cnt -= 1;
+               
+               if(self.nade_spawnloc.cnt <= 0)
+               {
+                       remove(self.nade_spawnloc);
+                       self.nade_spawnloc = world;
+               }
+       }
+
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(nades_PlayerDies)
 {
-       if(self.nade)
-               toss_nade(self, '0 0 100', max(self.nade.wait, time + 0.05));
+       if(frag_target.nade)
+       if(!frag_target.frozen || !autocvar_g_freezetag_revive_nade)
+               toss_nade(frag_target, '0 0 100', max(frag_target.nade.wait, time + 0.05));
+
+       float killcount_bonus = ((frag_attacker.killcount >= 1) ? bound(0, autocvar_g_nades_bonus_score_minor * frag_attacker.killcount, autocvar_g_nades_bonus_score_medium) : autocvar_g_nades_bonus_score_minor);
+
+       if(IS_PLAYER(frag_attacker))
+       {
+               if (SAME_TEAM(frag_attacker, frag_target) || frag_attacker == frag_target)
+                       nades_RemoveBonus(frag_attacker);
+               else if(frag_target.flagcarried)
+                       nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_medium);
+               else if(autocvar_g_nades_bonus_score_spree && frag_attacker.killcount > 1)
+               {
+                       #define SPREE_ITEM(counta,countb,center,normal,gentle) \
+                               case counta: { nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_spree); break; }
+                       switch(frag_attacker.killcount)
+                       {
+                               KILL_SPREE_LIST
+                               default: nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_minor); break;
+                       }
+                       #undef SPREE_ITEM
+               }
+               else
+                       nades_GiveBonus(frag_attacker, killcount_bonus);
+       }
+
+       nades_RemoveBonus(frag_target);
+
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(nades_PlayerDamage)
+{
+       if(frag_target.frozen)
+       if(autocvar_g_freezetag_revive_nade)
+       if(frag_attacker == frag_target)
+       if(frag_deathtype == DEATH_NADE)
+       if(time - frag_inflictor.toss_time <= 0.1)
+       {
+               Unfreeze(frag_target);
+               frag_target.health = autocvar_g_freezetag_revive_nade_health;
+               pointparticles(particleeffectnum("iceorglass"), frag_target.origin, '0 0 0', 3);
+               frag_damage = 0;
+               frag_force = '0 0 0';
+               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_FREEZETAG_REVIVED_NADE, frag_target.netname);
+               Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_FREEZETAG_REVIVE_SELF);
+       }
+       
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(nades_MonsterDies)
+{
+       if(IS_PLAYER(frag_attacker))
+       if(DIFF_TEAM(frag_attacker, self))
+       if(!(self.spawnflags & MONSTERFLAG_SPAWNED))
+               nades_GiveBonus(frag_attacker, autocvar_g_nades_bonus_score_minor);
 
        return FALSE;
 }
 
 MUTATOR_HOOKFUNCTION(nades_RemovePlayer)
 {
-       if(self.nade)
-               remove(self.nade);
+       nades_Clear(self);
+       nades_RemoveBonus(self);
+       return FALSE;
+}
 
-       if(self.fake_nade)
-               remove(self.fake_nade);
+MUTATOR_HOOKFUNCTION(nades_SpectateCopy)
+{
+       self.nade_timer = other.nade_timer;
+       self.nade_type = other.nade_type;
+       self.pokenade_type = other.pokenade_type;
+       self.bonus_nades = other.bonus_nades;
+       self.bonus_nade_score = other.bonus_nade_score;
+       self.stat_healing_orb = other.stat_healing_orb;
+       self.stat_healing_orb_alpha = other.stat_healing_orb_alpha;
+       return FALSE;
+}
+
+MUTATOR_HOOKFUNCTION(nades_GetCvars)
+{
+       GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_nade_type, "cl_nade_type");
+       GetCvars_handleString(get_cvars_s, get_cvars_f, cvar_cl_pokenade_type, "cl_pokenade_type");
 
        return FALSE;
 }
@@ -366,31 +1130,50 @@ MUTATOR_HOOKFUNCTION(nades_BuildMutatorsPrettyString)
        return FALSE;
 }
 
+void nades_Initialize()
+{
+       addstat(STAT_NADE_TIMER, AS_FLOAT, nade_timer);
+       addstat(STAT_NADE_BONUS, AS_FLOAT, bonus_nades);
+       addstat(STAT_NADE_BONUS_TYPE, AS_INT, nade_type);
+       addstat(STAT_NADE_BONUS_SCORE, AS_FLOAT, bonus_nade_score);
+       addstat(STAT_HEALING_ORB, AS_FLOAT, stat_healing_orb);
+       addstat(STAT_HEALING_ORB_ALPHA, AS_FLOAT, stat_healing_orb_alpha);
+       
+       precache_model("models/ok_nade_counter/ok_nade_counter.md3");
+       precache_model("models/weapons/h_ok_grenade.iqm");
+       precache_model("models/weapons/v_ok_grenade.md3");
+       precache_model("models/ctf/shield.md3");
+
+       precache_sound("weapons/rocket_impact.wav");
+       precache_sound("weapons/grenade_bounce1.wav");
+       precache_sound("weapons/grenade_bounce2.wav");
+       precache_sound("weapons/grenade_bounce3.wav");
+       precache_sound("weapons/grenade_bounce4.wav");
+       precache_sound("weapons/grenade_bounce5.wav");
+       precache_sound("weapons/grenade_bounce6.wav");
+       precache_sound("overkill/grenadebip.ogg");
+}
+
 MUTATOR_DEFINITION(mutator_nades)
 {
+       MUTATOR_HOOK(ForbidThrowCurrentWeapon, nades_CheckThrow, CBC_ORDER_LAST);
        MUTATOR_HOOK(VehicleEnter, nades_VehicleEnter, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerPreThink, nades_PlayerPreThink, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerSpawn, nades_PlayerSpawn, CBC_ORDER_ANY);
-       MUTATOR_HOOK(PlayerDies, nades_PlayerDies, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerDies, nades_PlayerDies, CBC_ORDER_LAST);
+       MUTATOR_HOOK(PlayerDamage_Calculate, nades_PlayerDamage, CBC_ORDER_ANY);
+       MUTATOR_HOOK(MonsterDies, nades_MonsterDies, CBC_ORDER_ANY);
        MUTATOR_HOOK(MakePlayerObserver, nades_RemovePlayer, CBC_ORDER_ANY);
        MUTATOR_HOOK(ClientDisconnect, nades_RemovePlayer, CBC_ORDER_ANY);
+       MUTATOR_HOOK(SpectateCopy, nades_SpectateCopy, CBC_ORDER_ANY);
+       MUTATOR_HOOK(GetCvars, nades_GetCvars, CBC_ORDER_ANY);
+       MUTATOR_HOOK(reset_map_global, nades_RemovePlayer, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsString, nades_BuildMutatorsString, CBC_ORDER_ANY);
        MUTATOR_HOOK(BuildMutatorsPrettyString, nades_BuildMutatorsPrettyString, CBC_ORDER_ANY);
 
        MUTATOR_ONADD
        {
-               precache_model("models/ok_nade_counter/ok_nade_counter.md3");
-
-               precache_model("models/weapons/h_ok_grenade.iqm");
-               precache_model("models/weapons/v_ok_grenade.md3");
-               precache_sound("weapons/rocket_impact.wav");
-               precache_sound("weapons/grenade_bounce1.wav");
-               precache_sound("weapons/grenade_bounce2.wav");
-               precache_sound("weapons/grenade_bounce3.wav");
-               precache_sound("weapons/grenade_bounce4.wav");
-               precache_sound("weapons/grenade_bounce5.wav");
-               precache_sound("weapons/grenade_bounce6.wav");
-               precache_sound("overkill/grenadebip.ogg");
+               nades_Initialize();
        }
 
        return FALSE;
index 1940f4e0520c0c051bda605b4f5bed3173bf85bc..c6c30c6d53210dfee9143e12646831e7b727f147 100644 (file)
@@ -1,5 +1,26 @@
 .entity nade;
 .entity fake_nade;
+.float nade_timer;
 .float nade_refire;
+.float bonus_nades;
+.float nade_special_time;
+.float bonus_nade_score;
+.float nade_type;
+.string pokenade_type;
+.entity nade_damage_target;
+.float cvar_cl_nade_type;
+.string cvar_cl_pokenade_type;
+.float toss_time;
+.float stat_healing_orb;
+.float stat_healing_orb_alpha;
+.float nade_show_particles;
 
-void() nades_CheckThrow;
+void toss_nade(entity e, vector _velocity, float _time);
+
+// Remove nades that are being thrown
+void(entity player) nades_Clear;
+
+// Give a bonus grenade to a player
+void(entity player, float score) nades_GiveBonus;
+// Remove all bonus nades from a player
+void(entity player) nades_RemoveBonus;
index e53c80f848cca975344b6e2025076bdecfec6c33..ffae9543b95c663527fe29a6abe49f527453c94f 100644 (file)
@@ -57,7 +57,7 @@ MUTATOR_HOOKFUNCTION(msnt_PlayerSpawn)
                        if(team_mate.msnt_timer < time)
                        if(SAME_TEAM(self, team_mate))
                        if(time > team_mate.spawnshieldtime) // spawn shielding
-                       if(team_mate.freezetag_frozen == 0)
+                       if(team_mate.frozen == 0)
                        if(team_mate != self)
                        {
                                tracebox(team_mate.origin, PL_MIN, PL_MAX, team_mate.origin - '0 0 100', MOVE_WORLDONLY, team_mate);
index fabf13639cf89d6ccf4ba810a099d303a74d0ff7..30b01b0daa0933351e754df39d45503c17ca2a66 100644 (file)
@@ -19,13 +19,15 @@ void PlayerTouchExplode(entity p1, entity p2)
 MUTATOR_HOOKFUNCTION(touchexplode_PlayerThink)
 {
        if(time > self.touchexplode_time)
-       if (!gameover)
+       if(!gameover)
+       if(!self.frozen)
        if(IS_PLAYER(self))
        if(self.deadflag == DEAD_NO)
        if (!IS_INDEPENDENT_PLAYER(self))
        FOR_EACH_PLAYER(other) if(self != other)
        {
                if(time > other.touchexplode_time)
+               if(!other.frozen)
                if(other.deadflag == DEAD_NO)
                if (!IS_INDEPENDENT_PLAYER(other))
                if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax))
diff --git a/qcsrc/server/mutators/mutators.qc b/qcsrc/server/mutators/mutators.qc
new file mode 100644 (file)
index 0000000..2f96e9e
--- /dev/null
@@ -0,0 +1,29 @@
+void mutators_add()
+{
+       #define CHECK_MUTATOR_ADD(mut_cvar,mut_name,dependence) \
+               { if(cvar(mut_cvar) && dependence) { MUTATOR_ADD(mut_name); } }
+
+       CHECK_MUTATOR_ADD("g_dodging", mutator_dodging, 1);
+       CHECK_MUTATOR_ADD("g_spawn_near_teammate", mutator_spawn_near_teammate, teamplay);
+       CHECK_MUTATOR_ADD("g_physical_items", mutator_physical_items, 1);
+       CHECK_MUTATOR_ADD("g_touchexplode", mutator_touchexplode, 1);
+       CHECK_MUTATOR_ADD("g_instagib", mutator_instagib, !g_nexball);
+       CHECK_MUTATOR_ADD("g_invincible_projectiles", mutator_invincibleprojectiles, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_new_toys", mutator_new_toys, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_nix", mutator_nix, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_rocket_flying", mutator_rocketflying, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_vampire", mutator_vampire, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_superspectate", mutator_superspec, 1);
+       CHECK_MUTATOR_ADD("g_pinata", mutator_pinata, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_midair", mutator_midair, 1);
+       CHECK_MUTATOR_ADD("g_bloodloss", mutator_bloodloss, !cvar("g_instagib"));
+       CHECK_MUTATOR_ADD("g_random_gravity", mutator_random_gravity, 1);
+       CHECK_MUTATOR_ADD("g_multijump", mutator_multijump, 1);
+       CHECK_MUTATOR_ADD("g_melee_only", mutator_melee_only, !cvar("g_instagib") && !g_nexball);
+       CHECK_MUTATOR_ADD("g_nades", mutator_nades, 1);
+       CHECK_MUTATOR_ADD("g_sandbox", sandbox, 1);
+       CHECK_MUTATOR_ADD("g_campcheck", mutator_campcheck, 1);
+       CHECK_MUTATOR_ADD("g_buffs", mutator_buffs, 1);
+
+       #undef CHECK_MUTATOR_ADD
+}
index ecab77c88025dff20bf63c4778f811dbd5261da4..955ba1a526f24b5bd0f4d0d5d1e1eeefd29d6352 100644 (file)
@@ -9,6 +9,9 @@ MUTATOR_DECLARATION(gamemode_onslaught);
 MUTATOR_DECLARATION(gamemode_domination);
 MUTATOR_DECLARATION(gamemode_lms);
 MUTATOR_DECLARATION(gamemode_invasion);
+MUTATOR_DECLARATION(gamemode_cts);
+MUTATOR_DECLARATION(gamemode_race);
+MUTATOR_DECLARATION(gamemode_tdm);
 
 MUTATOR_DECLARATION(mutator_dodging);
 MUTATOR_DECLARATION(mutator_invincibleprojectiles);
@@ -19,7 +22,7 @@ MUTATOR_DECLARATION(mutator_spawn_near_teammate);
 MUTATOR_DECLARATION(mutator_physical_items);
 MUTATOR_DECLARATION(mutator_vampire);
 MUTATOR_DECLARATION(mutator_superspec);
-MUTATOR_DECLARATION(mutator_minstagib);
+MUTATOR_DECLARATION(mutator_instagib);
 MUTATOR_DECLARATION(mutator_touchexplode);
 MUTATOR_DECLARATION(mutator_pinata);
 MUTATOR_DECLARATION(mutator_midair);
@@ -29,5 +32,6 @@ MUTATOR_DECLARATION(mutator_multijump);
 MUTATOR_DECLARATION(mutator_melee_only);
 MUTATOR_DECLARATION(mutator_nades);
 MUTATOR_DECLARATION(mutator_campcheck);
+MUTATOR_DECLARATION(mutator_buffs);
 
 MUTATOR_DECLARATION(sandbox);
diff --git a/qcsrc/server/mutators/mutators_include.qc b/qcsrc/server/mutators/mutators_include.qc
new file mode 100644 (file)
index 0000000..220bd05
--- /dev/null
@@ -0,0 +1,37 @@
+#include "base.qc"
+#include "gamemode_assault.qc"
+#include "gamemode_ca.qc"
+#include "gamemode_ctf.qc"
+#include "gamemode_domination.qc"
+#include "gamemode_freezetag.qc"
+#include "gamemode_keyhunt.qc"
+#include "gamemode_keepaway.qc"
+#include "gamemode_nexball.qc"
+#include "gamemode_onslaught.qc"
+#include "gamemode_lms.qc"
+#include "gamemode_invasion.qc"
+#include "gamemode_race.qc"
+#include "gamemode_cts.qc"
+#include "gamemode_tdm.qc"
+
+#include "mutator_invincibleproj.qc"
+#include "mutator_new_toys.qc"
+#include "mutator_nix.qc"
+#include "mutator_dodging.qc"
+#include "mutator_rocketflying.qc"
+#include "mutator_vampire.qc"
+#include "mutator_spawn_near_teammate.qc"
+#include "mutator_physical_items.qc"
+#include "sandbox.qc"
+#include "mutator_superspec.qc"
+#include "mutator_instagib.qc"
+#include "mutator_touchexplode.qc"
+#include "mutator_pinata.qc"
+#include "mutator_midair.qc"
+#include "mutator_bloodloss.qc"
+#include "mutator_random_gravity.qc"
+#include "mutator_multijump.qc"
+#include "mutator_melee_only.qc"
+#include "mutator_nades.qc"
+#include "mutator_campcheck.qc"
+#include "mutator_buffs.qc"
diff --git a/qcsrc/server/mutators/mutators_include.qh b/qcsrc/server/mutators/mutators_include.qh
new file mode 100644 (file)
index 0000000..08841db
--- /dev/null
@@ -0,0 +1,17 @@
+#include "base.qh"
+#include "mutators.qh"
+#include "gamemode_assault.qh"
+#include "gamemode_ca.qh"
+#include "gamemode_ctf.qh"
+#include "gamemode_domination.qh"
+#include "gamemode_keyhunt.qh"
+#include "gamemode_keepaway.qh"
+#include "gamemode_nexball.qh"
+#include "gamemode_lms.qh"
+#include "gamemode_invasion.qh"
+#include "gamemode_race.qh"
+#include "gamemode_cts.qh"
+
+#include "mutator_dodging.qh"
+#include "mutator_nades.qh"
+#include "mutator_buffs.qh"
index 1ae22e2029f7ff518aff3b21533a54a07163673d..288b2477597c00114d0a3b0246c296f3e1360b51 100644 (file)
@@ -13,8 +13,11 @@ sys-post.qh
 ../warpzonelib/server.qh
 
 ../common/constants.qh
+../common/stats.qh
 ../common/teams.qh
 ../common/util.qh
+../common/nades.qh
+../common/buffs.qh
 ../common/test.qh
 ../common/counting.qh
 ../common/items.qh
@@ -37,19 +40,7 @@ defs.qh              // Should rename this, it has fields and globals
 ../common/notifications.qh // must be after autocvars
 ../common/deathtypes.qh // must be after notifications
 
-mutators/base.qh
-mutators/mutators.qh
-mutators/gamemode_assault.qh
-mutators/gamemode_ca.qh
-mutators/gamemode_ctf.qh
-mutators/gamemode_domination.qh
-mutators/gamemode_keyhunt.qh // TODO fix this
-mutators/gamemode_keepaway.qh
-mutators/gamemode_nexball.qh 
-mutators/gamemode_lms.qh
-mutators/gamemode_invasion.qh
-mutators/mutator_dodging.qh
-mutators/mutator_nades.qh
+mutators/mutators_include.qh
 
 //// tZork Turrets ////
 tturrets/include/turrets_early.qh
@@ -88,6 +79,8 @@ scores.qh
 
 spawnpoints.qh
 
+mapvoting.qh
+
 ipban.qh
 
 race.qh
@@ -106,6 +99,8 @@ scores_rules.qc
 
 miscfunctions.qc
 
+mutators/mutators.qc
+
 waypointsprites.qc
 
 bot/bot.qc
@@ -131,6 +126,8 @@ pathlib/pathlib.qh
 g_world.qc
 g_casings.qc
 
+mapvoting.qc
+
 t_jumppads.qc
 t_teleporters.qc
 
@@ -214,6 +211,9 @@ target_music.qc
 
 ../common/items.qc
 
+../common/nades.qc
+../common/buffs.qc
+
 
 accuracy.qc
 ../csqcmodellib/sv_model.qc
@@ -234,38 +234,7 @@ round_handler.qc
 
 ../common/monsters/spawn.qc
 
-mutators/base.qc
-mutators/gamemode_assault.qc
-mutators/gamemode_ca.qc
-mutators/gamemode_ctf.qc
-mutators/gamemode_domination.qc
-mutators/gamemode_freezetag.qc
-mutators/gamemode_keyhunt.qc
-mutators/gamemode_keepaway.qc
-mutators/gamemode_nexball.qc
-mutators/gamemode_onslaught.qc
-mutators/gamemode_lms.qc
-mutators/gamemode_invasion.qc
-mutators/mutator_invincibleproj.qc
-mutators/mutator_new_toys.qc
-mutators/mutator_nix.qc
-mutators/mutator_dodging.qc
-mutators/mutator_rocketflying.qc
-mutators/mutator_vampire.qc
-mutators/mutator_spawn_near_teammate.qc
-mutators/mutator_physical_items.qc
-mutators/sandbox.qc
-mutators/mutator_superspec.qc
-mutators/mutator_minstagib.qc
-mutators/mutator_touchexplode.qc
-mutators/mutator_pinata.qc
-mutators/mutator_midair.qc
-mutators/mutator_bloodloss.qc
-mutators/mutator_random_gravity.qc
-mutators/mutator_multijump.qc
-mutators/mutator_melee_only.qc
-mutators/mutator_nades.qc
-mutators/mutator_campcheck.qc
+mutators/mutators_include.qc
 
 ../warpzonelib/anglestransform.qc
 ../warpzonelib/mathlib.qc
index e6d7a43accca9535df7edb251036e6669c9e2da3..8cc7d322c4e3a3fedb09346a9f9fe559fb67d137 100644 (file)
@@ -1,3 +1,72 @@
+float race_readTime(string map, float pos)
+{
+       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+       return stof(db_get(ServerProgsDB, strcat(map, rr, "time", ftos(pos))));
+}
+
+string race_readUID(string map, float pos)
+{
+       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+       return db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos)));
+}
+
+float race_readPos(string map, float t)
+{
+       float i;
+       for (i = 1; i <= RANKINGS_CNT; ++i)
+       if (race_readTime(map, i) == 0 || race_readTime(map, i) > t)
+               return i;
+
+       return 0; // pos is zero if unranked
+}
+
+void race_writeTime(string map, float t, string myuid)
+{
+       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+       float newpos;
+       newpos = race_readPos(map, t);
+
+       float i, prevpos = 0;
+       for(i = 1; i <= RANKINGS_CNT; ++i)
+       {
+               if(race_readUID(map, i) == myuid)
+                       prevpos = i;
+       }
+       if (prevpos)
+       {
+               // player improved his existing record, only have to iterate on ranks between new and old recs
+               for (i = prevpos; i > newpos; --i)
+               {
+                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
+               }
+       }
+       else
+       {
+               // player has no ranked record yet
+               for (i = RANKINGS_CNT; i > newpos; --i)
+               {
+                       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(map, i - 1)));
+                       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(map, i - 1));
+               }
+       }
+
+       // store new time itself
+       db_put(ServerProgsDB, strcat(map, rr, "time", ftos(newpos)), ftos(t));
+       db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(newpos)), myuid);
+}
+
+string race_readName(string map, float pos)
+{
+       string rr = (g_cts) ? CTS_RECORD : RACE_RECORD;
+
+       return uid2name(db_get(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(pos))));
+}
+
+
 #define MAX_CHECKPOINTS 255
 
 void spawnfunc_target_checkpoint();
@@ -72,6 +141,9 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only
        if(recordholder == e.netname)
                recordholder = "";
 
+       if(!IS_REAL_CLIENT(e))
+               return;
+
        if(!spec)
                msg_entity = e;
        WRITESPECTATABLE_MSG_ONE({
@@ -91,13 +163,6 @@ void race_SendNextCheckpoint(entity e, float spec) // qualifying only
        });
 }
 
-void race_InitSpectator()
-{
-       if(g_race_qualifying)
-               if(msg_entity.enemy.race_laptime)
-                       race_SendNextCheckpoint(msg_entity.enemy, 1);
-}
-
 void race_send_recordtime(float msg)
 {
        // send the server best time
@@ -121,6 +186,9 @@ void race_SendRankings(float pos, float prevpos, float del, float msg)
 
 void race_SendStatus(float id, entity e)
 {
+       if(!IS_REAL_CLIENT(e))
+               return;
+
        float msg;
        if (id == 0)
                msg = MSG_ONE;
@@ -136,7 +204,9 @@ void race_SendStatus(float id, entity e)
        });
 }
 
-void race_setTime(string map, float t, string myuid, string mynetname, entity e) { // netname only used TEMPORARILY for printing
+void race_setTime(string map, float t, string myuid, string mynetname, entity e)
+{
+       // netname only used TEMPORARILY for printing
        float newpos, player_prevpos;
        newpos = race_readPos(map, t);
 
@@ -156,7 +226,10 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e)
                race_SendStatus(0, e); // "fail"
                Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FAIL_RANKED, mynetname, player_prevpos, t, oldrec);
                return;
-       } else if (!newpos) { // no ranking, time worse than the worst ranked
+       }
+       else if (!newpos)
+       {
+               // no ranking, time worse than the worst ranked
                oldrec = race_readTime(GetMapname(), RANKINGS_CNT);
                race_SendStatus(0, e); // "fail"
                Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_RACE_FAIL_UNRANKED, mynetname, RANKINGS_CNT, t, oldrec);
@@ -178,7 +251,8 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e)
        // store new ranking
        race_writeTime(GetMapname(), t, myuid);
 
-       if (newpos == 1) {
+       if (newpos == 1)
+       {
                write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t));
                race_send_recordtime(MSG_ALL);
        }
@@ -208,7 +282,8 @@ void race_setTime(string map, float t, string myuid, string mynetname, entity e)
        }
 }
 
-void race_deleteTime(string map, float pos) {
+void race_deleteTime(string map, float pos)
+{
        string rr;
        if(g_cts)
                rr = CTS_RECORD;
@@ -216,12 +291,15 @@ void race_deleteTime(string map, float pos) {
                rr = RACE_RECORD;
 
        float i;
-       for (i = pos; i <= RANKINGS_CNT; ++i) {
-               if (i == RANKINGS_CNT) {
+       for (i = pos; i <= RANKINGS_CNT; ++i)
+       {
+               if (i == RANKINGS_CNT)
+               {
                        db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), string_null);
                        db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), string_null);
                }
-               else {
+               else
+               {
                        db_put(ServerProgsDB, strcat(map, rr, "time", ftos(i)), ftos(race_readTime(GetMapname(), i+1)));
                        db_put(ServerProgsDB, strcat(map, rr, "crypto_idfp", ftos(i)), race_readUID(GetMapname(), i+1));
                }
@@ -294,7 +372,8 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                        if(recordholder == e.netname)
                                recordholder = "";
 
-                       if(t != 0) {
+                       if(t != 0)
+                       {
                                if(cp == race_timed_checkpoint)
                                {
                                        race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e);
@@ -326,18 +405,21 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                        recordholder = "";
                }
 
-               msg_entity = e;
-               if(g_race_qualifying)
+               if(IS_REAL_CLIENT(e))
                {
-                       WRITESPECTATABLE_MSG_ONE_VARNAME(dummy1, {
-                               WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                               WriteByte(MSG_ONE, TE_CSQC_RACE);
-                               WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
-                               WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
-                               WriteInt24_t(MSG_ONE, t); // time to that intermediate
-                               WriteInt24_t(MSG_ONE, recordtime); // previously best time
-                               WriteString(MSG_ONE, recordholder); // record holder
-                       });
+                       msg_entity = e;
+                       if(g_race_qualifying)
+                       {
+                               WRITESPECTATABLE_MSG_ONE_VARNAME(dummy1, {
+                                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                                       WriteByte(MSG_ONE, TE_CSQC_RACE);
+                                       WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
+                                       WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+                                       WriteInt24_t(MSG_ONE, t); // time to that intermediate
+                                       WriteInt24_t(MSG_ONE, recordtime); // previously best time
+                                       WriteString(MSG_ONE, recordholder); // record holder
+                               });
+                       }
                }
        }
        else // RACE! Not Qualifying
@@ -354,49 +436,55 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                else
                        lself = lother = othtime = 0;
 
-               msg_entity = e;
-               WRITESPECTATABLE_MSG_ONE_VARNAME(dummy2, {
-                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                       WriteByte(MSG_ONE, TE_CSQC_RACE);
-                       WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE);
-                       WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
-                       if(e == oth)
-                       {
-                               WriteInt24_t(MSG_ONE, 0);
-                               WriteByte(MSG_ONE, 0);
-                               WriteString(MSG_ONE, "");
-                       }
-                       else
-                       {
-                               WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
-                               WriteByte(MSG_ONE, lself - lother);
-                               WriteString(MSG_ONE, oth.netname); // record holder
-                       }
-               });
+               if(IS_REAL_CLIENT(e))
+               {
+                       msg_entity = e;
+                       WRITESPECTATABLE_MSG_ONE_VARNAME(dummy2, {
+                               WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                               WriteByte(MSG_ONE, TE_CSQC_RACE);
+                               WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE);
+                               WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+                               if(e == oth)
+                               {
+                                       WriteInt24_t(MSG_ONE, 0);
+                                       WriteByte(MSG_ONE, 0);
+                                       WriteString(MSG_ONE, "");
+                               }
+                               else
+                               {
+                                       WriteInt24_t(MSG_ONE, TIME_ENCODE(time - race_checkpoint_lasttimes[cp]));
+                                       WriteByte(MSG_ONE, lself - lother);
+                                       WriteString(MSG_ONE, oth.netname); // record holder
+                               }
+                       });
+               }
 
                race_checkpoint_lastplayers[cp] = e;
                race_checkpoint_lasttimes[cp] = time;
                race_checkpoint_lastlaps[cp] = lself;
 
-               msg_entity = oth;
-               WRITESPECTATABLE_MSG_ONE_VARNAME(dummy3, {
-                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                       WriteByte(MSG_ONE, TE_CSQC_RACE);
-                       WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT);
-                       WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
-                       if(e == oth)
-                       {
-                               WriteInt24_t(MSG_ONE, 0);
-                               WriteByte(MSG_ONE, 0);
-                               WriteString(MSG_ONE, "");
-                       }
-                       else
-                       {
-                               WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
-                               WriteByte(MSG_ONE, lother - lself);
-                               WriteString(MSG_ONE, e.netname); // record holder
-                       }
-               });
+               if(IS_REAL_CLIENT(oth))
+               {
+                       msg_entity = oth;
+                       WRITESPECTATABLE_MSG_ONE_VARNAME(dummy3, {
+                               WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                               WriteByte(MSG_ONE, TE_CSQC_RACE);
+                               WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT);
+                               WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+                               if(e == oth)
+                               {
+                                       WriteInt24_t(MSG_ONE, 0);
+                                       WriteByte(MSG_ONE, 0);
+                                       WriteString(MSG_ONE, "");
+                               }
+                               else
+                               {
+                                       WriteInt24_t(MSG_ONE, TIME_ENCODE(time - othtime));
+                                       WriteByte(MSG_ONE, lother - lself);
+                                       WriteString(MSG_ONE, e.netname); // record holder
+                               }
+                       });
+               }
        }
 }
 
@@ -408,6 +496,9 @@ void race_ClearTime(entity e)
        e.race_penalty_accumulator = 0;
        e.race_lastpenalty = world;
 
+       if(!IS_REAL_CLIENT(e))
+               return;
+
        msg_entity = e;
        WRITESPECTATABLE_MSG_ONE({
                WriteByte(MSG_ONE, SVC_TEMPENTITY);
@@ -476,7 +567,8 @@ void checkpoint_passed()
 
        other.porto_forbidden = 2; // decreased by 1 each StartFrame
 
-       if(defrag_ents) {
+       if(defrag_ents)
+       {
                if(self.race_checkpoint == -2)
                {
                        self.race_checkpoint = other.race_checkpoint;
@@ -484,7 +576,8 @@ void checkpoint_passed()
 
                float largest_cp_id = 0;
                float cp_amount = 0;
-               for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+               for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+               {
                        cp_amount += 1;
                        if(cp.race_checkpoint > largest_cp_id) // update the finish id if someone hit a new checkpoint
                        {
@@ -494,13 +587,15 @@ void checkpoint_passed()
                                race_highest_checkpoint = largest_cp_id + 1;
                                race_timed_checkpoint = largest_cp_id + 1;
 
-                               for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+                               for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+                               {
                                        if(cp.race_checkpoint == -2) // set defragcpexists to -1 so that the cp id file will be rewritten when someone finishes
                                                defragcpexists = -1;
                                }
                        }
                }
-               if(cp_amount == 0) {
+               if(cp_amount == 0)
+               {
                        for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
                                cp.race_checkpoint = 1;
                        race_highest_checkpoint = 1;
@@ -675,7 +770,8 @@ void trigger_race_checkpoint_verify()
                        while((l = fgets(fh)))
                        {
                                len = tokenize_console(l);
-                               if(len != 2) {
+                               if(len != 2)
+                               {
                                        defragcpexists = -1; // something's wrong in the defrag cp file, set defragcpexists to -1 so that it will be rewritten when someone finishes
                                        continue;
                                }
@@ -689,19 +785,23 @@ void trigger_race_checkpoint_verify()
 
        g_race_qualifying = qual;
 
-       if(race_timed_checkpoint) {
-               if(defrag_ents) {
+       if(race_timed_checkpoint)
+       {
+               if(defrag_ents)
+               {
                        for(cp = world; (cp = find(cp, classname, "target_startTimer"));)
                                WaypointSprite_UpdateSprites(cp.sprite, "race-start", "", "");
                        for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
                                WaypointSprite_UpdateSprites(cp.sprite, "race-finish", "", "");
 
-                       for(cp = world; (cp = find(cp, classname, "target_checkpoint"));) {
+                       for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
+                       {
                                if(cp.race_checkpoint == -2) // something's wrong with the defrag cp file or it has not been written yet, set defragcpexists to -1 so that it will be rewritten when someone finishes
                                        defragcpexists = -1;
                        }
 
-                       if(defragcpexists != -1){
+                       if(defragcpexists != -1)
+                       {
                                float largest_cp_id = 0;
                                for(cp = world; (cp = find(cp, classname, "target_checkpoint"));)
                                        if(cp.race_checkpoint > largest_cp_id)
@@ -710,14 +810,17 @@ void trigger_race_checkpoint_verify()
                                        cp.race_checkpoint = largest_cp_id + 1; // finish line
                                race_highest_checkpoint = largest_cp_id + 1;
                                race_timed_checkpoint = largest_cp_id + 1;
-                       } else {
+                       }
+                       else
+                       {
                                for(cp = world; (cp = find(cp, classname, "target_stopTimer"));)
                                        cp.race_checkpoint = 255; // finish line
                                race_highest_checkpoint = 255;
                                race_timed_checkpoint = 255;
                        }
                }
-               else {
+               else
+               {
                        for(cp = world; (cp = find(cp, classname, "trigger_race_checkpoint")); )
                                if(cp.sprite)
                                {
@@ -729,11 +832,13 @@ void trigger_race_checkpoint_verify()
                }
        }
 
-       if(defrag_ents) {
+       if(defrag_ents)
+       {
                entity trigger, targ;
                for(trigger = world; (trigger = find(trigger, classname, "trigger_multiple")); )
                        for(targ = world; (targ = find(targ, targetname, trigger.target)); )
-                               if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer") {
+                               if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer")
+                               {
                                        trigger.wait = 0;
                                        trigger.delay = 0;
                                        targ.wait = 0;
@@ -791,11 +896,7 @@ vector trigger_race_checkpoint_spawn_evalfunc(entity player, entity spot, vector
 void spawnfunc_trigger_race_checkpoint()
 {
        vector o;
-       if(!g_race && !g_cts)
-       {
-               remove(self);
-               return;
-       }
+       if(!g_race && !g_cts) { remove(self); return; }
 
        EXACTTRIGGER_INIT;
 
@@ -843,11 +944,7 @@ void spawnfunc_trigger_race_checkpoint()
 void spawnfunc_target_checkpoint() // defrag entity
 {
        vector o;
-       if(!g_race && !g_cts)
-       {
-               remove(self);
-               return;
-       }
+       if(!g_race && !g_cts) { remove(self); return; }
        defrag_ents = 1;
 
        EXACTTRIGGER_INIT;
@@ -926,57 +1023,9 @@ void race_RetractPlayer()
        self.race_checkpoint = self.race_respawn_checkpoint;
 }
 
-void race_PreDie()
-{
-       if(!g_race && !g_cts)
-               return;
-
-       race_AbandonRaceCheck(self);
-}
-
-void race_PreSpawn()
-{
-       if(!g_race && !g_cts)
-               return;
-       if(self.killcount == -666 /* initial spawn */ || g_race_qualifying) // spawn
-               race_PreparePlayer();
-       else // respawn
-               race_RetractPlayer();
-
-       race_AbandonRaceCheck(self);
-}
-
-void race_PostSpawn(entity spot)
-{
-       if(!g_race && !g_cts)
-               return;
-
-       if(spot.target == "")
-               // Emergency: this wasn't a real spawnpoint. Can this ever happen?
-               race_PreparePlayer();
-
-       // if we need to respawn, do it right
-       self.race_respawn_checkpoint = self.race_checkpoint;
-       self.race_respawn_spotref = spot;
-
-       self.race_place = 0;
-}
-
-void race_PreSpawnObserver()
-{
-       if(!g_race && !g_cts)
-               return;
-       race_PreparePlayer();
-       self.race_checkpoint = -1;
-}
-
 void spawnfunc_info_player_race (void)
 {
-       if(!g_race && !g_cts)
-       {
-               remove(self);
-               return;
-       }
+       if(!g_race && !g_cts) { remove(self); return; }
        ++race_spawns;
        spawnfunc_info_player_deathmatch();
 
@@ -1010,63 +1059,37 @@ void race_ClearRecords()
        self = e;
 }
 
-void race_ReadyRestart()
-{
-       float s;
-
-       Score_NicePrint(world);
-
-       race_ClearRecords();
-       PlayerScore_Sort(race_place, 0, 1, 0);
-
-       entity e;
-       FOR_EACH_CLIENT(e)
-       {
-               if(e.race_place)
-               {
-                       s = PlayerScore_Add(e, SP_RACE_FASTEST, 0);
-                       if(!s)
-                               e.race_place = 0;
-               }
-               print(e.netname, " = ", ftos(e.race_place), "\n");
-       }
-
-       if(g_race_qualifying == 2)
-       {
-               g_race_qualifying = 0;
-               independent_players = 0;
-               cvar_set("fraglimit", ftos(race_fraglimit));
-               cvar_set("leadlimit", ftos(race_leadlimit));
-               cvar_set("timelimit", ftos(race_timelimit));
-               ScoreRules_race();
-       }
-}
-
 void race_ImposePenaltyTime(entity pl, float penalty, string reason)
 {
        if(g_race_qualifying)
        {
                pl.race_penalty_accumulator += penalty;
-               msg_entity = pl;
-               WRITESPECTATABLE_MSG_ONE({
-                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                       WriteByte(MSG_ONE, TE_CSQC_RACE);
-                       WriteByte(MSG_ONE, RACE_NET_PENALTY_QUALIFYING);
-                       WriteShort(MSG_ONE, TIME_ENCODE(penalty));
-                       WriteString(MSG_ONE, reason);
-               });
+               if(IS_REAL_CLIENT(pl))
+               {
+                       msg_entity = pl;
+                       WRITESPECTATABLE_MSG_ONE({
+                               WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                               WriteByte(MSG_ONE, TE_CSQC_RACE);
+                               WriteByte(MSG_ONE, RACE_NET_PENALTY_QUALIFYING);
+                               WriteShort(MSG_ONE, TIME_ENCODE(penalty));
+                               WriteString(MSG_ONE, reason);
+                       });
+               }
        }
        else
        {
                pl.race_penalty = time + penalty;
-               msg_entity = pl;
-               WRITESPECTATABLE_MSG_ONE_VARNAME(dummy, {
-                       WriteByte(MSG_ONE, SVC_TEMPENTITY);
-                       WriteByte(MSG_ONE, TE_CSQC_RACE);
-                       WriteByte(MSG_ONE, RACE_NET_PENALTY_RACE);
-                       WriteShort(MSG_ONE, TIME_ENCODE(penalty));
-                       WriteString(MSG_ONE, reason);
-               });
+               if(IS_REAL_CLIENT(pl))
+               {
+                       msg_entity = pl;
+                       WRITESPECTATABLE_MSG_ONE_VARNAME(dummy, {
+                               WriteByte(MSG_ONE, SVC_TEMPENTITY);
+                               WriteByte(MSG_ONE, TE_CSQC_RACE);
+                               WriteByte(MSG_ONE, RACE_NET_PENALTY_RACE);
+                               WriteShort(MSG_ONE, TIME_ENCODE(penalty));
+                               WriteString(MSG_ONE, reason);
+                       });
+               }
        }
 }
 
index f6cc54a15e1522dc1ddd724cf6cdc328f44b95bf..09b4b36ce4aadbb1619ae6d56c1d1b2df8a54143 100644 (file)
@@ -1,14 +1,4 @@
-void race_InitSpectator();
-void race_PreSpawnObserver();
-void race_PreSpawn();
-void race_PostSpawn(entity spot);
-void race_PreDie();
-void race_ReadyRestart();
-float race_teams;
 float race_spawns;
-float race_PreviousCheckpoint(float f);
-float race_NextCheckpoint(float f);
-void race_AbandonRaceCheck(entity p);
 float race_highest_place_spawn; // number of places; a place higher gets spawned at 0
 float race_lowest_place_spawn; // where to spawn in qualifying
 float race_fraglimit;
@@ -18,8 +8,6 @@ float race_timelimit;
 .float race_started;
 .float race_completed;
 float race_completing;
-void race_ImposePenaltyTime(entity pl, float penalty, string reason);
-void race_StartCompleting();
 
 .float race_movetime; // for reading
 .float race_movetime_frac; // fractional accumulator for higher accuracy (helper for writing)
@@ -28,4 +16,13 @@ void race_StartCompleting();
 .float race_respawn_checkpoint;
 .entity race_respawn_spotref; // try THIS spawn in case you respawn
 
+// definitions for functions used outside race.qc
+float race_PreviousCheckpoint(float f);
+float race_NextCheckpoint(float f);
+void race_AbandonRaceCheck(entity p);
+void race_ImposePenaltyTime(entity pl, float penalty, string reason);
+void race_StartCompleting();
 float race_GetFractionalLapCount(entity e);
+float race_readTime(string map, float pos);
+string race_readUID(string map, float pos);
+string race_readName(string map, float pos);
index 3a8b830d74c04e82063566368b0c949bc7f52878..7b3742f0136c0367e58ad17306d3f62faaa0b710 100644 (file)
@@ -263,9 +263,6 @@ float PlayerScore_Clear(entity player)
 
        if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
 
-       if(g_cts) return 0; // in CTS, you don't lose score by observing
-       if(g_race && g_race_qualifying) return 0; // in qualifying, you don't lose score by observing
-
        sk = player.scorekeeper;
        for(i = 0; i < MAX_SCORE; ++i)
        {
index c55195c8375597551638a1e6ee4a1cbef561e1f6..fbbf93803707f0a406678b04776d79600a8cef02 100644 (file)
@@ -65,34 +65,6 @@ void ScoreRules_kh(float teams)
        ScoreRules_basics_end();
 }
 
-// Race stuff
-#define ST_RACE_LAPS 1
-#define SP_RACE_LAPS 4
-#define SP_RACE_TIME 5
-#define SP_RACE_FASTEST 6
-void ScoreRules_race()
-{
-       ScoreRules_basics(race_teams, 0, 0, FALSE);
-       if(race_teams)
-       {
-               ScoreInfo_SetLabel_TeamScore(  ST_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME,    "time",      SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest",   SFL_LOWER_IS_BETTER | SFL_TIME);
-       }
-       else if(g_race_qualifying)
-       {
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest",   SFL_SORT_PRIO_PRIMARY | SFL_LOWER_IS_BETTER | SFL_TIME);
-       }
-       else
-       {
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_TIME,    "time",      SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER | SFL_TIME);
-               ScoreInfo_SetLabel_PlayerScore(SP_RACE_FASTEST, "fastest",   SFL_LOWER_IS_BETTER | SFL_TIME);
-       }
-       ScoreRules_basics_end();
-}
-
 // Nexball stuff
 #define ST_NEXBALL_GOALS 1
 #define SP_NEXBALL_GOALS 4
index 06b484e18c3e33c94499773a4fa8fd86eccc0cb6..607629e42578834ed10e98c99ac66b28c82a8148 100644 (file)
@@ -2,4 +2,4 @@
 float spawnpoint_nag;
 float SpawnEvent_Send(entity to, float sf);
 entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck);
-
+entity SelectSpawnPoint (float anypoint);
index 73e733be8f97d927c521c62a48751cfa0ca88c48..b25528e1645ccf1f635a20e5ae2866dc05eaf045 100644 (file)
@@ -62,7 +62,7 @@ void CreatureFrame (void)
                                                if (self.watersound_finished < time)
                                                {
                                                        self.watersound_finished = time + 0.5;
-                                                       sound (self, CH_PLAYER, "player/lava.wav", VOL_BASE, ATTEN_NORM);
+                                                       sound (self, CH_PLAYER_SINGLE, "player/lava.wav", VOL_BASE, ATTEN_NORM);
                                                }
                                                Damage (self, world, world, autocvar_g_balance_contents_playerdamage_lava * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_LAVA, self.origin, '0 0 0');
                                        }
@@ -71,7 +71,7 @@ void CreatureFrame (void)
                                                if (self.watersound_finished < time)
                                                {
                                                        self.watersound_finished = time + 0.5;
-                                                       sound (self, CH_PLAYER, "player/slime.wav", VOL_BASE, ATTEN_NORM);
+                                                       sound (self, CH_PLAYER_SINGLE, "player/slime.wav", VOL_BASE, ATTEN_NORM);
                                                }
                                                Damage (self, world, world, autocvar_g_balance_contents_playerdamage_slime * autocvar_g_balance_contents_damagerate * self.waterlevel, DEATH_SLIME, self.origin, '0 0 0');
                                        }
@@ -94,7 +94,7 @@ void CreatureFrame (void)
                {
                        // check for falling damage
                        float velocity_len = vlen(self.velocity);
-                       if(!self.hook.state && !(g_cts && !autocvar_g_cts_selfdamage))
+                       if(!self.hook.state)
                        {
                                dm = vlen(self.oldvelocity) - velocity_len; // dm is now the velocity DECREASE. Velocity INCREASE should never cause a sound or any damage.
                                if (self.deadflag)
@@ -155,7 +155,6 @@ float game_delay;
 float game_delay_last;
 
 float RedirectionThink();
-entity SelectSpawnPoint (float anypoint);
 void StartFrame (void)
 {
        execute_next_frame();
index 8878a3199b2ffd963dde68360f916df87ce94d0d..238c6cec506240d758fb262853bb3345f7b9dbf4 100644 (file)
@@ -23,7 +23,7 @@ var float  autocvar_cl_fullbright_items = 0;
 var vector autocvar_cl_weapon_stay_color = '2 0.5 0.5';
 var float  autocvar_cl_weapon_stay_alpha = 0.75;
 var float  autocvar_cl_simple_items = 0;
-var string autocvr_cl_simpleitems_postfix = "_simple";
+var string autocvar_cl_simpleitems_postfix = "_simple";
 .float  spawntime;
 .float  gravity;
 .vector colormod;
@@ -154,14 +154,14 @@ void ItemRead(float _IsNew)
 
 
 
-            if(fexists(sprintf("%s%s.md3", _fn2, autocvr_cl_simpleitems_postfix)))
-                self.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvr_cl_simpleitems_postfix));
-            else if(fexists(sprintf("%s%s.dpm", _fn2, autocvr_cl_simpleitems_postfix)))
-                self.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvr_cl_simpleitems_postfix));
-            else if(fexists(sprintf("%s%s.iqm", _fn2, autocvr_cl_simpleitems_postfix)))
-                self.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvr_cl_simpleitems_postfix));
-            else if(fexists(sprintf("%s%s.obj", _fn2, autocvr_cl_simpleitems_postfix)))
-                self.mdl = strzone(sprintf("%s%s.obj", _fn2, autocvr_cl_simpleitems_postfix));
+            if(fexists(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix)))
+                self.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix));
+            else if(fexists(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix)))
+                self.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix));
+            else if(fexists(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix)))
+                self.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix));
+            else if(fexists(sprintf("%s%s.obj", _fn2, autocvar_cl_simpleitems_postfix)))
+                self.mdl = strzone(sprintf("%s%s.obj", _fn2, autocvar_cl_simpleitems_postfix));
             else
             {
                 self.draw = ItemDraw;
index beccc7179450e7d951713e9c3b94931178e105da..353e5e9feb4f4b64c146cb2f456c49181b13fa93 100644 (file)
@@ -528,7 +528,7 @@ void func_bobbing_controller_think()
        vector v;
        self.nextthink = time + 0.1;
 
-       if (!(self.owner.active == ACTIVE_ACTIVE))
+       if(self.owner.active != ACTIVE_ACTIVE)
        {
                self.owner.velocity = '0 0 0';
                return;
@@ -745,7 +745,7 @@ void button_reset()
 
 void button_use()
 {
-       if (!(self.active == ACTIVE_ACTIVE))
+       if(self.active != ACTIVE_ACTIVE)
                return;
 
        self.enemy = activator;
@@ -788,7 +788,7 @@ When a button is touched, it moves some distance in the direction of it's angle,
 "speed"                override the default 40 speed
 "wait"         override the default 1 second wait (-1 = never return)
 "lip"          override the default 4 pixel lip remaining at end of move
-"health"       if set, the button must be killed instead of touched. If set to -1, the button will fire on ANY attack, even damageless ones like the MinstaGib laser
+"health"       if set, the button must be killed instead of touched. If set to -1, the button will fire on ANY attack, even damageless ones like the InstaGib laser
 "sounds"
 0) steam metal
 1) wooden clunk
@@ -1012,14 +1012,14 @@ float door_check_keys(void) {
                // some keys were used
                if (other.key_door_messagetime <= time) {
                        play2(other, "misc/talk.wav");
-                       centerprint(other, strcat("You also need ", item_keys_keylist(door.itemkeys), "!"));
+                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(door.itemkeys));
                        other.key_door_messagetime = time + 2;
                }
        } else {
                // no keys were used
                if (other.key_door_messagetime <= time) {
                        play2(other, "misc/talk.wav");
-                       centerprint(other, strcat("You need ", item_keys_keylist(door.itemkeys), "!"));
+                       Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(door.itemkeys));
                        other.key_door_messagetime = time + 2;
                }
        }
@@ -1027,7 +1027,7 @@ float door_check_keys(void) {
        if (door.itemkeys) {
                // door is now unlocked
                play2(other, "misc/talk.wav");
-               centerprint(other, "Door unlocked!");
+               Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_UNLOCKED);
                return TRUE;
        } else
                return FALSE;
@@ -1940,7 +1940,7 @@ void func_fourier_controller_think()
        float n, i, t;
 
        self.nextthink = time + 0.1;
-       if (!(self.owner.active == ACTIVE_ACTIVE))
+       if(self.owner.active != ACTIVE_ACTIVE)
        {
                self.owner.velocity = '0 0 0';
                return;
@@ -2073,7 +2073,7 @@ void func_vectormamamam_controller_think()
 {
        self.nextthink = time + 0.1;
 
-       if (!(self.owner.active == ACTIVE_ACTIVE))
+       if(self.owner.active != ACTIVE_ACTIVE)
        {
                self.owner.velocity = '0 0 0';
                return;
index bb1128bd60e8c532c217de9d8f9d99f9c0404d27..86a87c043d1fd5b781c13201bdb6d242435286b0 100644 (file)
@@ -114,18 +114,24 @@ void spawnfunc_target_give()
        InitializeEntity(self, target_give_init, INITPRIO_FINDTARGET);
 }
 
-//void spawnfunc_item_flight()       /* not supported */
-//void spawnfunc_item_haste()        /* not supported */
+//void spawnfunc_item_flight()       /* handled by buffs mutator or jetpack */
+//void spawnfunc_item_haste()        /* handled by buffs mutator */
 //void spawnfunc_item_health()       /* handled in t_quake.qc */
 //void spawnfunc_item_health_large() /* handled in t_items.qc */
 //void spawnfunc_item_health_small() /* handled in t_items.qc */
 //void spawnfunc_item_health_mega()  /* handled in t_items.qc */
-//void spawnfunc_item_invis()        /* not supported */
-//void spawnfunc_item_regen()        /* not supported */
+//void spawnfunc_item_invis()        /* handled by buffs mutator */
+//void spawnfunc_item_regen()        /* handled by buffs mutator */
 
 // CTF spawnfuncs handled in mutators/gamemode_ctf.qc now
 
-void spawnfunc_item_flight()         { spawnfunc_item_jetpack();       }
+void spawnfunc_item_flight()
+{
+       if(!cvar("g_buffs") || !cvar("g_buffs_flight"))
+               spawnfunc_item_jetpack();
+       else
+               buff_Init_Compat(self, BUFF_FLIGHT);
+}
 
 .float notteam;
 .float notsingle;
index 600af861ac956c55cba7a867ee567aa03b59bc5a..cd1b374e6b247fab04cf6d8d85cfea5f67c7da6f 100644 (file)
@@ -28,10 +28,11 @@ void target_music_use()
 {
        if(!activator)
                return;
-       if(!IS_REAL_CLIENT(activator))
-               return;
-       msg_entity = activator;
-       target_music_sendto(MSG_ONE, 1);
+       if(IS_REAL_CLIENT(activator))
+       {
+               msg_entity = activator;
+               target_music_sendto(MSG_ONE, 1);
+       }
        entity head;
        FOR_EACH_SPEC(head) if(head.enemy == activator) { msg_entity = head; target_music_sendto(MSG_ONE, 1); }
 }
index a0c80dbd2132b144f2ce0929249aca17d12050d5..285e52c80f0a68580a14aa7cb13d4525017123b1 100644 (file)
@@ -13,7 +13,6 @@ void TeamchangeFrags(entity e)
        PlayerScore_Clear(e);
 }
 
-void tdm_init();
 void entcs_init();
 
 void LogTeamchange(float player_id, float team_number, float type)
@@ -83,7 +82,10 @@ void InitGameplayMode()
        if(g_tdm)
        {
                ActivateTeamplay();
-               tdm_init();
+               fraglimit_override = autocvar_g_tdm_point_limit;
+               leadlimit_override = autocvar_g_tdm_point_leadlimit;
+               MUTATOR_ADD(gamemode_tdm);
+
                if(autocvar_g_tdm_team_spawns)
                        have_team_spawns = -1; // request team spawns
        }
@@ -94,6 +96,10 @@ void InitGameplayMode()
                fraglimit_override = autocvar_g_domination_point_limit;
                leadlimit_override = autocvar_g_domination_point_leadlimit;
                MUTATOR_ADD(gamemode_domination);
+
+               if(autocvar_g_domination_roundbased && autocvar_g_domination_roundbased_point_limit)
+                       fraglimit_override = autocvar_g_domination_roundbased_point_limit;
+
                have_team_spawns = -1; // request team spawns
        }
 
@@ -159,7 +165,6 @@ void InitGameplayMode()
 
        if(g_race)
        {
-
                if(autocvar_g_race_teams)
                {
                        ActivateTeamplay();
@@ -172,6 +177,8 @@ void InitGameplayMode()
                qualifying_override = autocvar_g_race_qualifying_timelimit_override;
                fraglimit_override = autocvar_g_race_laps_limit;
                leadlimit_override = 0; // currently not supported by race
+
+               MUTATOR_ADD(gamemode_race);
        }
 
        if(g_cts)
@@ -179,6 +186,7 @@ void InitGameplayMode()
                g_race_qualifying = 1;
                fraglimit_override = 0;
                leadlimit_override = 0;
+               MUTATOR_ADD(gamemode_cts);
        }
 
        if(g_nexball)
@@ -248,12 +256,8 @@ void InitGameplayMode()
        }
 
        if(g_race || g_cts)
-       {
-               if(g_race_qualifying)
-                       independent_players = 1;
-
-               ScoreRules_race();
-       }
+       if(g_race_qualifying)
+               independent_players = 1;
 
        InitializeEntity(world, default_delayedinit, INITPRIO_GAMETYPE_FALLBACK);
 }
@@ -317,6 +321,9 @@ string getwelcomemessage(void)
        if (g_grappling_hook)
                s = strcat(s, "\n\n^3grappling hook^8 is enabled, press 'e' to use it\n");
 
+       if (cvar("g_nades"))
+               s = strcat(s, "\n\n^3nades^8 are enabled, press 'g' to use them\n");
+
        if(cache_lastmutatormsg != autocvar_g_mutatormsg)
        {
                if(cache_lastmutatormsg)
@@ -420,10 +427,7 @@ void CheckAllowedTeams (entity for_whom)
        else
        {
                // cover anything else by treating it like tdm with no teams spawned
-               if(g_race)
-                       dm = race_teams;
-               else
-                       dm = 2;
+               dm = 2;
 
                ret_float = dm;
                MUTATOR_CALLHOOK(GetTeamCount);
@@ -511,7 +515,7 @@ void GetTeamCounts(entity ignore)
        FOR_EACH_CLIENT(head)
        {
                float t;
-               if(IS_PLAYER(head))
+               if(IS_PLAYER(head) || head.caplayer)
                        t = head.team;
                else if(head.team_forced > 0)
                        t = head.team_forced; // reserve the spot
@@ -661,16 +665,8 @@ float FindSmallestTeam(entity pl, float ignore_pl)
        {
                if(autocvar_g_campaign && pl && IS_REAL_CLIENT(pl))
                        return 1; // special case for campaign and player joining
-               else if(g_domination)
-                       error("Too few teams available for domination\n");
-               else if(g_ctf)
-                       error("Too few teams available for ctf\n");
-               else if(g_keyhunt)
-                       error("Too few teams available for key hunt\n");
-               else if(g_freezetag)
-                       error("Too few teams available for freeze tag\n");
                else
-                       error("Too few teams available for team deathmatch\n");
+                       error(sprintf("Too few teams available for %s\n", MapInfo_Type_ToString(MapInfo_CurrentGametype())));
        }
 
        // count how many players are in each team
@@ -825,7 +821,7 @@ void SV_ChangeTeam(float _color)
        }
 
        if((autocvar_g_campaign) || (autocvar_g_changeteam_banned && self.wasplayer)) {
-               sprint(self, "Team changes not allowed\n");
+               Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_TEAMCHANGE_NOTALLOWED);
                return; // changing teams is not allowed
        }
 
@@ -835,7 +831,7 @@ void SV_ChangeTeam(float _color)
                GetTeamCounts(self);
                if(!TeamSmallerEqThanTeam(dteam, steam, self))
                {
-                       sprint(self, "Cannot change to a larger/better/shinier team\n");
+                       Send_Notification(NOTIF_ONE, self, MSG_INFO, INFO_TEAMCHANGE_LARGERTEAM);
                        return;
                }
        }
@@ -996,46 +992,5 @@ void ShufflePlayerOutOfTeam (float source_team)
 
        if(selected.deadflag == DEAD_NO)
                Damage(selected, selected, selected, 100000, DEATH_AUTOTEAMCHANGE, selected.origin, '0 0 0');
-       centerprint(selected, strcat("You have been moved into a different team to improve team balance\nYou are now on: ", Team_ColoredFullName(selected.team)));
-}
-
-// code from here on is just to support maps that don't have team entities
-void tdm_spawnteam (string teamname, float teamcolor)
-{
-       entity e;
-       e = spawn();
-       e.classname = "tdm_team";
-       e.netname = teamname;
-       e.cnt = teamcolor;
-       e.team = e.cnt + 1;
-}
-
-// spawn some default teams if the map is not set up for tdm
-void tdm_spawnteams()
-{
-       float numteams;
-
-       numteams = autocvar_g_tdm_teams_override;
-       if(numteams < 2)
-               numteams = autocvar_g_tdm_teams;
-       numteams = bound(2, numteams, 4);
-
-       tdm_spawnteam("Red", NUM_TEAM_1-1);
-       tdm_spawnteam("Blue", NUM_TEAM_2-1);
-       if(numteams >= 3)
-               tdm_spawnteam("Yellow", NUM_TEAM_3-1);
-       if(numteams >= 4)
-               tdm_spawnteam("Pink", NUM_TEAM_4-1);
-}
-
-void tdm_delayedinit()
-{
-       // if no teams are found, spawn defaults
-       if (find(world, classname, "tdm_team") == world)
-               tdm_spawnteams();
-}
-
-void tdm_init()
-{
-       InitializeEntity(world, tdm_delayedinit, INITPRIO_GAMETYPE);
+       Send_Notification(NOTIF_ONE, selected, MSG_CENTER, CENTER_DEATH_SELF_AUTOTEAMCHANGE, selected.team);
 }
index 9fce826a2df307d0c74c4658d4d745908182abc9..26a3dc04e42992eae003a698465b5659e525665e 100644 (file)
@@ -102,7 +102,7 @@ void turret_plasma_std_init()
     self.firecheck_flags |= TFL_FIRECHECK_AFF;
 
     // Our fireing routine
-    if(g_minstagib)
+    if(g_instagib)
         self.turret_firefunc  = turret_plasma_minsta_attack;
     else
         self.turret_firefunc  = turret_plasma_attack;
index 2ee34b928f0da2aa62493892162f9100a50c85a4..9042bd4e810be0b9382d845ee99dd49902a9bfda 100644 (file)
@@ -608,6 +608,12 @@ void vehicles_enter()
 
     if(self.phase > time)
         return;
+    if(other.frozen)
+        return;
+    if(other.vehicle)
+        return;
+    if(other.deadflag != DEAD_NO)
+        return;
 
     if(teamplay)
     if(self.team)
index 0ad23a137ec53177cf29fb60390b8ba28f6512ee..ea2cf8bf0560dfee7a879789377231dc82e8cd0f 100644 (file)
@@ -263,7 +263,7 @@ void lgbeam_think()
                return;
        }
 
-       if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.freezetag_frozen)
+       if (owner_player.weaponentity.state != WS_INUSE || !lgbeam_checkammo() || owner_player.deadflag != DEAD_NO || !owner_player.BUTTON_ATCK || owner_player.frozen)
        {
                if(self == owner_player.lgbeam)
                        owner_player.lgbeam = world;
index ec36f5d32541cea2fbca1c8fa29572b0e1994d06..e91fb5fb6b77b70889548d314c7065893ddddb03 100644 (file)
@@ -195,7 +195,7 @@ void W_Mine_Think (void)
 
        // a player's mines shall explode if he disconnects or dies
        // TODO: Do this on team change too -- Samual: But isn't a player killed when they switch teams?
-       if(!IS_PLAYER(self.realowner) || self.realowner.deadflag != DEAD_NO || self.realowner.freezetag_frozen)
+       if(!IS_PLAYER(self.realowner) || self.realowner.deadflag != DEAD_NO || self.realowner.frozen)
        {
                other = world;
                self.projectiledeathtype |= HITTYPE_BOUNCE;
@@ -207,7 +207,7 @@ void W_Mine_Think (void)
        head = findradius(self.origin, autocvar_g_balance_minelayer_proximityradius);
        while(head)
        {
-               if(IS_PLAYER(head) && head.deadflag == DEAD_NO && !head.freezetag_frozen)
+               if(IS_PLAYER(head) && head.deadflag == DEAD_NO && !head.frozen)
                if(head != self.realowner && DIFF_TEAM(head, self.realowner)) // don't trigger for team mates
                if(!self.mine_time)
                {
index 9fb80c6d515d3a03bfee39e7efccea6f4fce6792..becb2e8b7cd7a15a71a14e8ea01d119558d3907f 100644 (file)
@@ -75,7 +75,7 @@ void W_MinstaNex_Attack (void)
                        break;
        }
 
-       W_DecreaseAmmo(ammo_cells, ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo), autocvar_g_balance_minstanex_reload_ammo);
+       W_DecreaseAmmo(ammo_cells, ((g_instagib) ? 1 : autocvar_g_balance_minstanex_ammo), autocvar_g_balance_minstanex_reload_ammo);
 }
 
 void spawnfunc_weapon_minstanex (void); // defined in t_items.qc
@@ -86,7 +86,7 @@ float w_minstanex(float req)
        float minstanex_ammo;
 
        // now multiple WR_s use this
-       minstanex_ammo = ((g_minstagib) ? 1 : autocvar_g_balance_minstanex_ammo);
+       minstanex_ammo = ((g_instagib) ? 1 : autocvar_g_balance_minstanex_ammo);
 
        if (req == WR_AIM)
        {
@@ -115,14 +115,14 @@ float w_minstanex(float req)
                        if (self.jump_interval <= time)
                        if (weapon_prepareattack(1, -1))
                        {
-                               // handle refire manually, so that primary and secondary can be fired without conflictions (important for minstagib)
+                               // handle refire manually, so that primary and secondary can be fired without conflictions (important for instagib)
                                self.jump_interval = time + autocvar_g_balance_minstanex_laser_refire * W_WeaponRateFactor();
 
                                // decrease ammo for the laser?
                                if(autocvar_g_balance_minstanex_laser_ammo)
                                        W_DecreaseAmmo(ammo_cells, autocvar_g_balance_minstanex_laser_ammo, autocvar_g_balance_minstanex_reload_ammo);
 
-                               // ugly minstagib hack to reuse the fire mode of the laser
+                               // ugly instagib hack to reuse the fire mode of the laser
                                float w;
                                w = self.weapon;
                                self.weapon = WEP_LASER;
index 69376e86091a684c6030bd717b500f57bdfac6cf..92e9e5affd847cbdc578d8d41239ff7d3ba9c4d0 100644 (file)
@@ -53,6 +53,19 @@ a_shells_simple // shells
 
 ////////// WEAPONS //////////
 
+g_arc_simple // arc
+{
+       deformVertexes autosprite
+       cull none
+       nopicmip
+
+       {
+               map models/weapons/g_arc_simple
+               blendfunc blend
+
+       }
+}
+
 g_crylink_simple // crylink
 {
        deformVertexes autosprite
@@ -79,7 +92,7 @@ g_electro_simple // electro
        }
 }
 
-g_nex_simple // nex
+g_nex_simple // vortex
 {
        deformVertexes autosprite
        cull none
@@ -118,7 +131,7 @@ g_gl_simple // mortar
        }
 }
 
-g_rl_simple // rocket launcher
+g_rl_simple // devastator
 {
        deformVertexes autosprite
        cull none
@@ -157,19 +170,6 @@ g_uzi_simple // machine gun
        }
 }
 
-g_uzi_simple // machine gun
-{
-       deformVertexes autosprite
-       cull none
-       nopicmip
-
-       {
-               map models/weapons/g_uzi_simple
-               blendfunc blend
-
-       }
-}
-
 g_campingrifle_simple // sniper rifle
 {
        deformVertexes autosprite
@@ -222,7 +222,7 @@ g_hookgun_simple // hook gun
        }
 }
 
-g_laser_simple // laser
+g_laser_simple // blaster
 {
        deformVertexes autosprite
        cull none
@@ -248,7 +248,7 @@ g_minelayer_simple // minelayer
        }
 }
 
-g_minstanex_simple // minstanex
+g_minstanex_simple // vaporizer
 {
        deformVertexes autosprite
        cull none
@@ -475,4 +475,4 @@ g_fuelregen_simple // fuel regen powerup
                blendfunc blend
 
        }
-}
\ No newline at end of file
+}
diff --git a/sound/tutorial/1-welcome.ogg b/sound/tutorial/1-welcome.ogg
deleted file mode 100644 (file)
index 05ff8eb..0000000
Binary files a/sound/tutorial/1-welcome.ogg and /dev/null differ
diff --git a/sound/tutorial/10-at_corp_switch.ogg b/sound/tutorial/10-at_corp_switch.ogg
deleted file mode 100644 (file)
index d312e51..0000000
Binary files a/sound/tutorial/10-at_corp_switch.ogg and /dev/null differ
diff --git a/sound/tutorial/11-behind_glass.ogg b/sound/tutorial/11-behind_glass.ogg
deleted file mode 100644 (file)
index 89fadfc..0000000
Binary files a/sound/tutorial/11-behind_glass.ogg and /dev/null differ
diff --git a/sound/tutorial/12-crylink.ogg b/sound/tutorial/12-crylink.ogg
deleted file mode 100644 (file)
index 1b69ddf..0000000
Binary files a/sound/tutorial/12-crylink.ogg and /dev/null differ
diff --git a/sound/tutorial/13-no_imitations.ogg b/sound/tutorial/13-no_imitations.ogg
deleted file mode 100644 (file)
index 2939a80..0000000
Binary files a/sound/tutorial/13-no_imitations.ogg and /dev/null differ
diff --git a/sound/tutorial/14-room_with_switch.ogg b/sound/tutorial/14-room_with_switch.ogg
deleted file mode 100644 (file)
index c311f4e..0000000
Binary files a/sound/tutorial/14-room_with_switch.ogg and /dev/null differ
diff --git a/sound/tutorial/15-x_marks_the_spot.ogg b/sound/tutorial/15-x_marks_the_spot.ogg
deleted file mode 100644 (file)
index b3781c6..0000000
Binary files a/sound/tutorial/15-x_marks_the_spot.ogg and /dev/null differ
diff --git a/sound/tutorial/16-shoot_with_electro.ogg b/sound/tutorial/16-shoot_with_electro.ogg
deleted file mode 100644 (file)
index 6a142d9..0000000
Binary files a/sound/tutorial/16-shoot_with_electro.ogg and /dev/null differ
diff --git a/sound/tutorial/17-deeper.ogg b/sound/tutorial/17-deeper.ogg
deleted file mode 100644 (file)
index 7da896c..0000000
Binary files a/sound/tutorial/17-deeper.ogg and /dev/null differ
diff --git a/sound/tutorial/18-fire_then_fire.ogg b/sound/tutorial/18-fire_then_fire.ogg
deleted file mode 100644 (file)
index 2d5d382..0000000
Binary files a/sound/tutorial/18-fire_then_fire.ogg and /dev/null differ
diff --git a/sound/tutorial/19-activates_the_buried_switch.ogg b/sound/tutorial/19-activates_the_buried_switch.ogg
deleted file mode 100644 (file)
index 76940bc..0000000
Binary files a/sound/tutorial/19-activates_the_buried_switch.ogg and /dev/null differ
diff --git a/sound/tutorial/2-jumppad.ogg b/sound/tutorial/2-jumppad.ogg
deleted file mode 100644 (file)
index 964efa2..0000000
Binary files a/sound/tutorial/2-jumppad.ogg and /dev/null differ
diff --git a/sound/tutorial/20-at_corp_says_you_are_smart.ogg b/sound/tutorial/20-at_corp_says_you_are_smart.ogg
deleted file mode 100644 (file)
index fd5f9fd..0000000
Binary files a/sound/tutorial/20-at_corp_says_you_are_smart.ogg and /dev/null differ
diff --git a/sound/tutorial/21-rocket_launcher.ogg b/sound/tutorial/21-rocket_launcher.ogg
deleted file mode 100644 (file)
index 31824d0..0000000
Binary files a/sound/tutorial/21-rocket_launcher.ogg and /dev/null differ
diff --git a/sound/tutorial/22-as_a_special_feature.ogg b/sound/tutorial/22-as_a_special_feature.ogg
deleted file mode 100644 (file)
index f2ccfda..0000000
Binary files a/sound/tutorial/22-as_a_special_feature.ogg and /dev/null differ
diff --git a/sound/tutorial/23-hold_the_fire_button.ogg b/sound/tutorial/23-hold_the_fire_button.ogg
deleted file mode 100644 (file)
index b5f43b2..0000000
Binary files a/sound/tutorial/23-hold_the_fire_button.ogg and /dev/null differ
diff --git a/sound/tutorial/24-guide_the_rocket.ogg b/sound/tutorial/24-guide_the_rocket.ogg
deleted file mode 100644 (file)
index 9271d61..0000000
Binary files a/sound/tutorial/24-guide_the_rocket.ogg and /dev/null differ
diff --git a/sound/tutorial/25-omg_laser.ogg b/sound/tutorial/25-omg_laser.ogg
deleted file mode 100644 (file)
index ad53e9a..0000000
Binary files a/sound/tutorial/25-omg_laser.ogg and /dev/null differ
diff --git a/sound/tutorial/26-the_red_platform.ogg b/sound/tutorial/26-the_red_platform.ogg
deleted file mode 100644 (file)
index 48b6ced..0000000
Binary files a/sound/tutorial/26-the_red_platform.ogg and /dev/null differ
diff --git a/sound/tutorial/27-wga.ogg b/sound/tutorial/27-wga.ogg
deleted file mode 100644 (file)
index 3066024..0000000
Binary files a/sound/tutorial/27-wga.ogg and /dev/null differ
diff --git a/sound/tutorial/28-grappling_hook.ogg b/sound/tutorial/28-grappling_hook.ogg
deleted file mode 100644 (file)
index e46ea02..0000000
Binary files a/sound/tutorial/28-grappling_hook.ogg and /dev/null differ
diff --git a/sound/tutorial/29-hooker.ogg b/sound/tutorial/29-hooker.ogg
deleted file mode 100644 (file)
index d297b4e..0000000
Binary files a/sound/tutorial/29-hooker.ogg and /dev/null differ
diff --git a/sound/tutorial/3-death.ogg b/sound/tutorial/3-death.ogg
deleted file mode 100644 (file)
index 87d40d0..0000000
Binary files a/sound/tutorial/3-death.ogg and /dev/null differ
diff --git a/sound/tutorial/30-destination_of_the_hook.ogg b/sound/tutorial/30-destination_of_the_hook.ogg
deleted file mode 100644 (file)
index 5b17502..0000000
Binary files a/sound/tutorial/30-destination_of_the_hook.ogg and /dev/null differ
diff --git a/sound/tutorial/31-pogo_stick.ogg b/sound/tutorial/31-pogo_stick.ogg
deleted file mode 100644 (file)
index 19ef0a9..0000000
Binary files a/sound/tutorial/31-pogo_stick.ogg and /dev/null differ
diff --git a/sound/tutorial/32-way_to_go_champ.ogg b/sound/tutorial/32-way_to_go_champ.ogg
deleted file mode 100644 (file)
index aab3ce4..0000000
Binary files a/sound/tutorial/32-way_to_go_champ.ogg and /dev/null differ
diff --git a/sound/tutorial/33-cr-vi.ogg b/sound/tutorial/33-cr-vi.ogg
deleted file mode 100644 (file)
index 5d19619..0000000
Binary files a/sound/tutorial/33-cr-vi.ogg and /dev/null differ
diff --git a/sound/tutorial/34-pierce_walls.ogg b/sound/tutorial/34-pierce_walls.ogg
deleted file mode 100644 (file)
index c50042d..0000000
Binary files a/sound/tutorial/34-pierce_walls.ogg and /dev/null differ
diff --git a/sound/tutorial/35-shoot_your_instructor.ogg b/sound/tutorial/35-shoot_your_instructor.ogg
deleted file mode 100644 (file)
index 5c27ef8..0000000
Binary files a/sound/tutorial/35-shoot_your_instructor.ogg and /dev/null differ
diff --git a/sound/tutorial/36-hit_me.ogg b/sound/tutorial/36-hit_me.ogg
deleted file mode 100644 (file)
index eccbc9a..0000000
Binary files a/sound/tutorial/36-hit_me.ogg and /dev/null differ
diff --git a/sound/tutorial/36-just_shoot_it.ogg b/sound/tutorial/36-just_shoot_it.ogg
deleted file mode 100644 (file)
index 4b1c30a..0000000
Binary files a/sound/tutorial/36-just_shoot_it.ogg and /dev/null differ
diff --git a/sound/tutorial/37-I_am_waiting.ogg b/sound/tutorial/37-I_am_waiting.ogg
deleted file mode 100644 (file)
index 78a6cfb..0000000
Binary files a/sound/tutorial/37-I_am_waiting.ogg and /dev/null differ
diff --git a/sound/tutorial/38-impatient.ogg b/sound/tutorial/38-impatient.ogg
deleted file mode 100644 (file)
index 0b8d173..0000000
Binary files a/sound/tutorial/38-impatient.ogg and /dev/null differ
diff --git a/sound/tutorial/39-srs_trouble.ogg b/sound/tutorial/39-srs_trouble.ogg
deleted file mode 100644 (file)
index ae3bace..0000000
Binary files a/sound/tutorial/39-srs_trouble.ogg and /dev/null differ
diff --git a/sound/tutorial/4-big_jump.ogg b/sound/tutorial/4-big_jump.ogg
deleted file mode 100644 (file)
index 24d5032..0000000
Binary files a/sound/tutorial/4-big_jump.ogg and /dev/null differ
diff --git a/sound/tutorial/5-to_the_left_to_the_left.ogg b/sound/tutorial/5-to_the_left_to_the_left.ogg
deleted file mode 100644 (file)
index 3a3830a..0000000
Binary files a/sound/tutorial/5-to_the_left_to_the_left.ogg and /dev/null differ
diff --git a/sound/tutorial/6-air_friction.ogg b/sound/tutorial/6-air_friction.ogg
deleted file mode 100644 (file)
index 811fbe6..0000000
Binary files a/sound/tutorial/6-air_friction.ogg and /dev/null differ
diff --git a/sound/tutorial/7-rocket_at_you.ogg b/sound/tutorial/7-rocket_at_you.ogg
deleted file mode 100644 (file)
index 5163486..0000000
Binary files a/sound/tutorial/7-rocket_at_you.ogg and /dev/null differ
diff --git a/sound/tutorial/8-shoot-switch.ogg b/sound/tutorial/8-shoot-switch.ogg
deleted file mode 100644 (file)
index 5615297..0000000
Binary files a/sound/tutorial/8-shoot-switch.ogg and /dev/null differ
diff --git a/sound/tutorial/9-unbreakable.ogg b/sound/tutorial/9-unbreakable.ogg
deleted file mode 100644 (file)
index 852b537..0000000
Binary files a/sound/tutorial/9-unbreakable.ogg and /dev/null differ
diff --git a/sound/tutorial/frag_on.ogg b/sound/tutorial/frag_on.ogg
deleted file mode 100644 (file)
index e8636cb..0000000
Binary files a/sound/tutorial/frag_on.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-at_corp_rap.ogg b/sound/tutorial/misc-at_corp_rap.ogg
deleted file mode 100644 (file)
index 9ec4f4a..0000000
Binary files a/sound/tutorial/misc-at_corp_rap.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-detonate.ogg b/sound/tutorial/misc-detonate.ogg
deleted file mode 100644 (file)
index 695c592..0000000
Binary files a/sound/tutorial/misc-detonate.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-did_yoda_show_you_that.ogg b/sound/tutorial/misc-did_yoda_show_you_that.ogg
deleted file mode 100644 (file)
index cec140a..0000000
Binary files a/sound/tutorial/misc-did_yoda_show_you_that.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-door.ogg b/sound/tutorial/misc-door.ogg
deleted file mode 100644 (file)
index 93c9532..0000000
Binary files a/sound/tutorial/misc-door.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-emergency_tele.ogg b/sound/tutorial/misc-emergency_tele.ogg
deleted file mode 100644 (file)
index efa552a..0000000
Binary files a/sound/tutorial/misc-emergency_tele.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-excellent.ogg b/sound/tutorial/misc-excellent.ogg
deleted file mode 100644 (file)
index 76691ae..0000000
Binary files a/sound/tutorial/misc-excellent.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-good_work.ogg b/sound/tutorial/misc-good_work.ogg
deleted file mode 100644 (file)
index 0b90df0..0000000
Binary files a/sound/tutorial/misc-good_work.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-nice.ogg b/sound/tutorial/misc-nice.ogg
deleted file mode 100644 (file)
index 06b711d..0000000
Binary files a/sound/tutorial/misc-nice.ogg and /dev/null differ
diff --git a/sound/tutorial/misc-very_impressive.ogg b/sound/tutorial/misc-very_impressive.ogg
deleted file mode 100644 (file)
index 49082a5..0000000
Binary files a/sound/tutorial/misc-very_impressive.ogg and /dev/null differ
index 9be8795362b66ed72e60102c6f90458ed6518ddc..a0c06485b20cb4b950049f05c5bc00ed9a5be66c 100644 (file)
@@ -40,7 +40,7 @@
 \g_pinata\Players will drop all weapons they possessed when they are killed
 \g_weapon_stay\Weapons stay after they are picked up
 \g_weaponarena\Selecting a weapon arena will give all players that weapon at spawn as well as unlimited ammo, and disable all other weapon pickups.
-\g_minstagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
+\g_instagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
 \g_nix\No items Xonotic - instead of pickup items, everyone plays with the same weapon. After some time, a countdown will start, after which everyone will switch to another weapon.
 \g_nix_with_laser\Always carry the laser as an additional weapon in Nix
 \XonoticMultiplayerDialog/Select all\Select all maps
index ed455da109ec80f9c511389eebea5c9f7267e1e9..7ba71e27452e14ebe90b663a431fe828f26060f4 100644 (file)
@@ -42,7 +42,7 @@
 \g_weapon_stay\Alle Waffen bleiben liegen, auch wenn sie aufgenommen wurden
 \g_weaponarena\Waffen-Arenen: Die Auswahl einer Waffen-Arena führt dazu, dass jeder Spieler mit der gewählten Waffe startet. Diese hat unendlich viel Munition, andere Waffen sind nicht vorhanden - Spezielle Waffen-Arenen: Spieler starten mit allen Waffen und unendlich viel Munition
 \menu_weaponarena_with_laser\Aktiviere auch den Laser in der Waffen-Arena
-\g_minstagib\Alle Spieler starten mit der MinstaNex, eine elektromagnetische Schienenkanone mit unendlich viel Schaden. Wenn ein Spieler keine Munition mehr hat, bleiben ihm 10 Sekunden um neue zu finden, ansonsten stirbt er. Der 2. Feuermodus ist Laser, welcher keinen Schaden hinzufügen kann. Dieser eignet sich gut für Tricksprünge
+\g_instagib\Alle Spieler starten mit der MinstaNex, eine elektromagnetische Schienenkanone mit unendlich viel Schaden. Wenn ein Spieler keine Munition mehr hat, bleiben ihm 10 Sekunden um neue zu finden, ansonsten stirbt er. Der 2. Feuermodus ist Laser, welcher keinen Schaden hinzufügen kann. Dieser eignet sich gut für Tricksprünge
 \g_nix\Es gibt keine aufzusammelnden Gegenstände in Xonotic - Anstelle der Möglichkeit Waffen aufzusammeln, spielen alle mit der gleichen Waffe. Nach einiger Zeit startet ein Countdown, danach wechseln alle Spieler zu einer neuen gleichen Waffe
 \g_nix_with_laser\In Nix ist als zweite Waffe der Laser vorhanden
 \XonoticMultiplayerDialog/Select all\Wähle alle Maps
index 17c8939df8251912bc633e44e38003c1e81a18b1..4cab5a6383672ed299bb7e868953e5c07c4908f5 100644 (file)
@@ -41,7 +41,7 @@
 \g_weapon_stay\Las armas quedan despues de que son tomadas
 \g_weaponarena\Seleccionando un arma, dara a todos los jugadores cual arma se eligió asi como infinita munición, y deshabilita cualquier otra toma de arma.
 \menu_weaponarena_with_laser\Tambien habilita el láser en la arena
-\g_minstagib\Los jugadores tendran Minstanex, el cual es un railgun con daño infinito. Si el jugador queda sin munición, tendra 10 segundos para buscar mas o morira. El modo de disparo secundario es un laser que no inflige daño y es bueno para hacer bromas.
+\g_instagib\Los jugadores tendran Minstanex, el cual es un railgun con daño infinito. Si el jugador queda sin munición, tendra 10 segundos para buscar mas o morira. El modo de disparo secundario es un laser que no inflige daño y es bueno para hacer bromas.
 \g_nix\Xonotic sin items - en vez de recoger items, todos juegan con la misma arma. Despues de algún tiempo, comienza una cuenta regresiva, despues del cual todos juegan con otra arma.
 \g_nix_with_laser\Siempre lleva el láser como arma adicional en Nix
 \XonoticMultiplayerDialog/Select all\Seleccionar todos los mapas
index 2fc82b5b4f81df66eb678839955f4d32839ff23c..3f3819e496e38b0406b9b7c2cabd6013335c650d 100644 (file)
@@ -40,7 +40,7 @@
 \g_pinata\Les joueurs lâchent toutes leurs armes quand ils meurent
 \g_weapon_stay\Les armes restent où elles sont lorsqu'elles sont ramassées
 \g_weaponarena\Sélectionner une arène avec une seule arme fera apparaître les joueurs avec cette arme et des munitions illimitées, et désactive toutes les autres armes
-\g_minstagib\Tous les joueurs reçoivent un Minstanex, qui est un fusil de précision d'une puissance infinie. Si vous êtes à court de munition, vous mourrez dans les 10 secondes à moins de parvenir à recharger votre arme. Le tir secondaire est un laser qui n'inflige aucun dégât et qui est utile pour sauter sur de longues distances.
+\g_instagib\Tous les joueurs reçoivent un Minstanex, qui est un fusil de précision d'une puissance infinie. Si vous êtes à court de munition, vous mourrez dans les 10 secondes à moins de parvenir à recharger votre arme. Le tir secondaire est un laser qui n'inflige aucun dégât et qui est utile pour sauter sur de longues distances.
 \g_nix\No Items Xonotic - tous les joueurs jouent avec la même arme, et celle-ci change régulièrement.
 \g_nix_with_laser\Autoriser le laser en plus de l'arme courante dans le mode Nix
 \XonoticMultiplayerDialog/Select all\Sélectionner toutes les cartes
index 81347c7577f0af6e28da4d2329f728382fdc148d..4080f0286c2ed683a0a298ceb270c789143dab23 100644 (file)
@@ -42,7 +42,7 @@
 \g_weapon_stay\A fegyverek a helyükön maradnak, még azután is, hogy valaki felvette őket
 \g_weaponarena\A kiválasztott fegyver aréna minden játékosnak ugyanazt a fegyvert biztosítja korlátlan lőszerrel, és letiltja minden más fegyver felvételét
 \menu_weaponarena_with_laser\A lézer is engedélyezett a fegyver arénában
-\g_minstagib\A játékosok egy Minstanex-et kapnak, ami egy azonnal ölő mesterlövész fegyver. Ha a játékos kifogy a lőszerből, 10 másodperce van muníciót találni, vagy meghal. A másodlagos tűz mód a lézer, amely nem okoz kárt, de jól jön trükkös ugrások végrehajtásánál
+\g_instagib\A játékosok egy Minstanex-et kapnak, ami egy azonnal ölő mesterlövész fegyver. Ha a játékos kifogy a lőszerből, 10 másodperce van muníciót találni, vagy meghal. A másodlagos tűz mód a lézer, amely nem okoz kárt, de jól jön trükkös ugrások végrehajtásánál
 \g_nix\Xonotic felvehető fegyverek nélkül – Mindenki ugyanazzal a fegyverrel játszik. Kis idő után visszaszámlálás indul, amely végén mindenki fegyvert vált
 \g_nix_with_laser\Mindig legyen a lézer a Nix mellett kiegészítésül 
 
index e1d1825dddd850a4cea441ce6d7504793003b34f..03169993cc023099882a68965f0057061a4a695f 100644 (file)
@@ -40,7 +40,7 @@
 \g_pinata\I giocatori rilasceranno tutte le armi che possedevano appena vengono uccisi
 \g_weapon_stay\Le armi rimangono dopo che vengono raccolte
 \g_weaponarena\Selezionando un'arena dedicata ad un'arma si darà a tutti i giocatori quell'arma con munizioni infinite, e disabiliterà tutti gli altri raccoglimenti delle armi.
-\g_minstagib\Ai giocatori sarà dato il Minstanex, che è un railgun con danni illimitati. Se il giocatore rimane senza munizioni, avrà 10 secondi per trovarne alcune, altrimenti morirà. Il fuoco secondario è un laser che non infligge nessun danno ed è buono per effettuare vari trickjump.
+\g_instagib\Ai giocatori sarà dato il Minstanex, che è un railgun con danni illimitati. Se il giocatore rimane senza munizioni, avrà 10 secondi per trovarne alcune, altrimenti morirà. Il fuoco secondario è un laser che non infligge nessun danno ed è buono per effettuare vari trickjump.
 \g_nix\"No items Xonotic" - invece di raccogliere oggetti, ognuno giocherà con la stessa arma. Dopo un pò di tempo, un conto alla rovescia inizierà, dopo il quale ognuno passerà ad un'altra arma.
 \g_nix_with_laser\Porta sempre il laser come arma aggiuntiva nella modalità "No items Xonotic"
 \XonoticMultiplayerDialog/Seleziona tutto\Seleziona tutte le mappe
index 9a6d72fbc51d9bb8801465d9840f1c25a150c63a..c5b5fccf599a858279aaf8752a3025428fe6c85a 100644 (file)
@@ -41,7 +41,7 @@
 \g_weapon_stay\Всё собранное оружие остаётся после возрождений
 \g_weaponarena\Selecting a weapon arena will give all players that weapon at spawn as well as unlimited ammo, and disable all other weapon pickups.
 \menu_weaponarena_with_laser\Also enable the laser in the weapon arena
-\g_minstagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
+\g_instagib\Players will be given the Minstanex, which is a railgun with infinite damage. If the player runs out of ammo, he will have 10 seconds to find some or if he fails to do so, face death. The secondary fire mode is a laser which does not inflict any damage and is good for doing trickjumps.
 \g_nix\No items Xonotic - instead of pickup items, everyone plays with the same weapon. After some time, a countdown will start, after which everyone will switch to another weapon.
 \g_nix_with_laser\Always carry the laser as an additional weapon in Nix
 \XonoticMultiplayerDialog/Select all\Выбрать все карты
index 31695a6315400860e849782bed2131e298ee2f4d..bece5dc112520f8eb3589302f707fc5d60e86407 100644 (file)
@@ -41,7 +41,7 @@
 \g_weapon_stay\Зброя залишається після того, як була підібраною
 \g_weaponarena\Вибір арени з окремою зброєю дасть гравцям цю зброю і необмежену кількість боєприпасів до неї, і прибере з мапи всю іншу зброю
 \menu_weaponarena_with_laser\Зробити лазер доступним на аренах
-\g_minstagib\Гравці отримують МінстаНекс, рейкову гармату яка вбиває одним пострілом. Якщо гравець витратить усі боєприпаси, у нього буде десять секунд щоб поновити його, інакше він загине. Альтернативний вогонь гармати це лазер який не наносить шкоди, корисний для трюків
+\g_instagib\Гравці отримують МінстаНекс, рейкову гармату яка вбиває одним пострілом. Якщо гравець витратить усі боєприпаси, у нього буде десять секунд щоб поновити його, інакше він загине. Альтернативний вогонь гармати це лазер який не наносить шкоди, корисний для трюків
 \g_nix\Нікс (No items Xonotic) - замість того щоб підбирати предмети, всі гравці грають з однією зброєю. Через деякий час почнеться відлік, і зброя у всіх зміниться на іншу
 \g_nix_with_laser\Зробити лазер доступним у Нікс
 \XonoticMultiplayerDialog/Обрати все\Обрати всі мапи
index 80305a5fe299f855717758a9b52fd6ba862951c9..eb768df231f9023827cbffe4b55c681c366cedbd 100644 (file)
@@ -1,18 +1,28 @@
-alias weapon_laser "impulse 230"
+alias weapon_blaster "impulse 230"
 alias weapon_shotgun "impulse 231"
-alias weapon_uzi "impulse 232"
-alias weapon_grenadelauncher "impulse 233"
+alias weapon_machinegun "impulse 232"
+alias weapon_mortar "impulse 233"
 alias weapon_minelayer "impulse 234"
 alias weapon_electro "impulse 235"
 alias weapon_crylink "impulse 236"
-alias weapon_nex "impulse 237"
+alias weapon_vortex "impulse 237"
 alias weapon_hagar "impulse 238"
-alias weapon_rocketlauncher "impulse 239"
+alias weapon_devastator "impulse 239"
 alias weapon_porto "impulse 240"
-alias weapon_minstanex "impulse 241"
+alias weapon_vaporizer "impulse 241"
 alias weapon_hook "impulse 242"
 alias weapon_hlac "impulse 243"
 alias weapon_tuba "impulse 244"
 alias weapon_rifle "impulse 245"
 alias weapon_fireball "impulse 246"
 alias weapon_seeker "impulse 247"
+alias weapon_shockwave "impulse 248"
+alias weapon_arc "impulse 249"
+
+// Backwards compatibility with 0.7.0
+alias weapon_laser "weapon_blaster"
+alias weapon_uzi "weapon_machinegun"
+alias weapon_grenadelauncher "weapon_mortar"
+alias weapon_nex "weapon_vortex"
+alias weapon_rocketlauncher "weapon_devastator"
+alias weapon_minstanex "weapon_vaporizer"
index 9fe937716a1d5d78f25ea2509a52fba7d0dd508f..b9f5b8200d198626011ebf95aa8fdf021d75d675 100644 (file)
@@ -5,13 +5,13 @@ Merlijn Hofstra
 Peter "Morphed" Pielak
 Samual "Ares" Lenks
 Tyler "-z-" Mulligan
+Zac "Mario" Jardine
 
 
 **Extended Team
 Debugger
 Jan "zykure" Behrens
 Łukasz "kuniu the frogg" Polek
-Mario
 Marvin "Mirio" Beck
 Matthias "matthiaskrgr" Krüger
 MrBougo
@@ -75,6 +75,7 @@ Samual "Ares" Lenks
 Rudolf "divVerent" Polzer
 Jakob "tZork" Markström Gröhn
 Rasmus "FruitieX" Eskola
+Zac "Mario" Jardine
 
 *Marketing / PR
 Tyler "-z-" Mulligan
@@ -113,6 +114,8 @@ Oleh "BlaXpirit" Prypin
 Przemysław "atheros" Grzywacz
 Robert "ai" Kuroto
 The player with the unnecessarily long name
+Mattia "Melanosuchus" Basaglia
+TimePath
 
 
 **Translators